wayfinder-paths 0.1.6__py3-none-any.whl → 0.1.8__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 +0 -10
- wayfinder_paths/adapters/balance_adapter/adapter.py +0 -20
- wayfinder_paths/adapters/balance_adapter/test_adapter.py +0 -30
- wayfinder_paths/adapters/brap_adapter/adapter.py +3 -2
- wayfinder_paths/adapters/brap_adapter/test_adapter.py +9 -13
- wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py +14 -7
- wayfinder_paths/adapters/hyperliquid_adapter/__init__.py +18 -0
- wayfinder_paths/adapters/hyperliquid_adapter/adapter.py +1093 -0
- wayfinder_paths/adapters/hyperliquid_adapter/executor.py +549 -0
- wayfinder_paths/adapters/hyperliquid_adapter/manifest.yaml +8 -0
- wayfinder_paths/adapters/hyperliquid_adapter/paired_filler.py +1050 -0
- wayfinder_paths/adapters/hyperliquid_adapter/test_adapter.py +126 -0
- wayfinder_paths/adapters/hyperliquid_adapter/test_adapter_live.py +219 -0
- wayfinder_paths/adapters/hyperliquid_adapter/test_utils.py +220 -0
- wayfinder_paths/adapters/hyperliquid_adapter/utils.py +134 -0
- wayfinder_paths/adapters/ledger_adapter/test_adapter.py +7 -6
- wayfinder_paths/adapters/pool_adapter/README.md +3 -28
- wayfinder_paths/adapters/pool_adapter/adapter.py +0 -72
- wayfinder_paths/adapters/pool_adapter/examples.json +0 -43
- wayfinder_paths/adapters/pool_adapter/test_adapter.py +4 -54
- wayfinder_paths/adapters/token_adapter/test_adapter.py +4 -14
- wayfinder_paths/core/adapters/models.py +9 -4
- wayfinder_paths/core/analytics/__init__.py +11 -0
- wayfinder_paths/core/analytics/bootstrap.py +57 -0
- wayfinder_paths/core/analytics/stats.py +48 -0
- wayfinder_paths/core/analytics/test_analytics.py +170 -0
- wayfinder_paths/core/clients/BRAPClient.py +1 -0
- wayfinder_paths/core/clients/LedgerClient.py +2 -7
- wayfinder_paths/core/clients/PoolClient.py +0 -16
- wayfinder_paths/core/clients/WalletClient.py +0 -27
- wayfinder_paths/core/clients/protocols.py +104 -18
- wayfinder_paths/scripts/make_wallets.py +9 -0
- wayfinder_paths/scripts/run_strategy.py +124 -0
- wayfinder_paths/strategies/basis_trading_strategy/README.md +213 -0
- wayfinder_paths/strategies/basis_trading_strategy/__init__.py +3 -0
- wayfinder_paths/strategies/basis_trading_strategy/constants.py +1 -0
- wayfinder_paths/strategies/basis_trading_strategy/examples.json +16 -0
- wayfinder_paths/strategies/basis_trading_strategy/manifest.yaml +23 -0
- wayfinder_paths/strategies/basis_trading_strategy/snapshot_mixin.py +1011 -0
- wayfinder_paths/strategies/basis_trading_strategy/strategy.py +4522 -0
- wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py +727 -0
- wayfinder_paths/strategies/basis_trading_strategy/types.py +39 -0
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/examples.json +1 -9
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +36 -5
- wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +367 -278
- wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +204 -7
- {wayfinder_paths-0.1.6.dist-info → wayfinder_paths-0.1.8.dist-info}/METADATA +32 -3
- {wayfinder_paths-0.1.6.dist-info → wayfinder_paths-0.1.8.dist-info}/RECORD +50 -27
- {wayfinder_paths-0.1.6.dist-info → wayfinder_paths-0.1.8.dist-info}/LICENSE +0 -0
- {wayfinder_paths-0.1.6.dist-info → wayfinder_paths-0.1.8.dist-info}/WHEEL +0 -0
|
@@ -61,13 +61,11 @@ def strategy():
|
|
|
61
61
|
return (True, 1000000000)
|
|
62
62
|
|
|
63
63
|
s.balance_adapter.get_balance = AsyncMock(side_effect=get_balance_side_effect)
|
|
64
|
-
s.balance_adapter.get_all_balances = AsyncMock(
|
|
65
|
-
return_value=(True, {"balances": []})
|
|
66
|
-
)
|
|
67
64
|
|
|
68
65
|
if hasattr(s, "token_adapter") and s.token_adapter:
|
|
69
66
|
default_usdc = {
|
|
70
67
|
"id": "usd-coin-base",
|
|
68
|
+
"token_id": "usd-coin-base",
|
|
71
69
|
"symbol": "USDC",
|
|
72
70
|
"name": "USD Coin",
|
|
73
71
|
"decimals": 6,
|
|
@@ -77,6 +75,7 @@ def strategy():
|
|
|
77
75
|
|
|
78
76
|
default_pool_token = {
|
|
79
77
|
"id": "test-pool-base",
|
|
78
|
+
"token_id": "test-pool-base",
|
|
80
79
|
"symbol": "POOL",
|
|
81
80
|
"name": "Test Pool",
|
|
82
81
|
"decimals": 18,
|
|
@@ -100,6 +99,7 @@ def strategy():
|
|
|
100
99
|
True,
|
|
101
100
|
{
|
|
102
101
|
"id": "ethereum-base",
|
|
102
|
+
"token_id": "ethereum-base",
|
|
103
103
|
"symbol": "ETH",
|
|
104
104
|
"name": "Ethereum",
|
|
105
105
|
"decimals": 18,
|
|
@@ -210,6 +210,7 @@ def strategy():
|
|
|
210
210
|
s.DEPOSIT_USDC = 0
|
|
211
211
|
s.usdc_token_info = {
|
|
212
212
|
"id": "usd-coin-base",
|
|
213
|
+
"token_id": "usd-coin-base",
|
|
213
214
|
"symbol": "USDC",
|
|
214
215
|
"name": "USD Coin",
|
|
215
216
|
"decimals": 6,
|
|
@@ -218,6 +219,7 @@ def strategy():
|
|
|
218
219
|
}
|
|
219
220
|
s.gas_token = {
|
|
220
221
|
"id": "ethereum-base",
|
|
222
|
+
"token_id": "ethereum-base",
|
|
221
223
|
"symbol": "ETH",
|
|
222
224
|
"name": "Ethereum",
|
|
223
225
|
"decimals": 18,
|
|
@@ -226,6 +228,7 @@ def strategy():
|
|
|
226
228
|
}
|
|
227
229
|
s.current_pool = {
|
|
228
230
|
"id": "usd-coin-base",
|
|
231
|
+
"token_id": "usd-coin-base",
|
|
229
232
|
"symbol": "USDC",
|
|
230
233
|
"decimals": 6,
|
|
231
234
|
"chain": {"code": "base", "id": 8453, "name": "Base"},
|
|
@@ -248,9 +251,6 @@ def strategy():
|
|
|
248
251
|
side_effect=get_token_price_side_effect
|
|
249
252
|
)
|
|
250
253
|
|
|
251
|
-
async def mock_sweep_wallet(target_token):
|
|
252
|
-
pass
|
|
253
|
-
|
|
254
254
|
async def mock_refresh_current_pool_balance():
|
|
255
255
|
pass
|
|
256
256
|
|
|
@@ -260,7 +260,6 @@ def strategy():
|
|
|
260
260
|
async def mock_has_idle_assets(balances, target):
|
|
261
261
|
return True
|
|
262
262
|
|
|
263
|
-
s._sweep_wallet = mock_sweep_wallet
|
|
264
263
|
s._refresh_current_pool_balance = mock_refresh_current_pool_balance
|
|
265
264
|
s._rebalance_gas = mock_rebalance_gas
|
|
266
265
|
s._has_idle_assets = mock_has_idle_assets
|
|
@@ -348,3 +347,201 @@ async def test_error_cases(strategy):
|
|
|
348
347
|
f"Expected {example_name} update to "
|
|
349
348
|
f"{'succeed' if expected_success else 'fail'} but got opposite"
|
|
350
349
|
)
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
@pytest.mark.asyncio
|
|
353
|
+
async def test_token_tracking_initialization(strategy):
|
|
354
|
+
"""Test that tracked_token_ids and tracked_balances are initialized."""
|
|
355
|
+
assert hasattr(strategy, "tracked_token_ids")
|
|
356
|
+
assert hasattr(strategy, "tracked_balances")
|
|
357
|
+
assert isinstance(strategy.tracked_token_ids, set)
|
|
358
|
+
assert isinstance(strategy.tracked_balances, dict)
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
@pytest.mark.asyncio
|
|
362
|
+
async def test_track_token(strategy):
|
|
363
|
+
"""Test that _track_token adds tokens to tracked state."""
|
|
364
|
+
test_token_id = "test-token-base"
|
|
365
|
+
test_balance = 1000000
|
|
366
|
+
|
|
367
|
+
strategy._track_token(test_token_id, test_balance)
|
|
368
|
+
|
|
369
|
+
assert test_token_id in strategy.tracked_token_ids
|
|
370
|
+
assert strategy.tracked_balances.get(test_token_id) == test_balance
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
@pytest.mark.asyncio
|
|
374
|
+
async def test_update_balance(strategy):
|
|
375
|
+
"""Test that _update_balance updates tracked balances."""
|
|
376
|
+
test_token_id = "test-token-base"
|
|
377
|
+
initial_balance = 1000000
|
|
378
|
+
updated_balance = 2000000
|
|
379
|
+
|
|
380
|
+
strategy._track_token(test_token_id, initial_balance)
|
|
381
|
+
assert strategy.tracked_balances.get(test_token_id) == initial_balance
|
|
382
|
+
|
|
383
|
+
strategy._update_balance(test_token_id, updated_balance)
|
|
384
|
+
assert strategy.tracked_balances.get(test_token_id) == updated_balance
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
@pytest.mark.asyncio
|
|
388
|
+
async def test_get_non_zero_tracked_tokens(strategy):
|
|
389
|
+
"""Test that _get_non_zero_tracked_tokens returns only non-zero balances."""
|
|
390
|
+
strategy._track_token("token-1", 1000000)
|
|
391
|
+
strategy._track_token("token-2", 0)
|
|
392
|
+
strategy._track_token("token-3", 5000000)
|
|
393
|
+
|
|
394
|
+
non_zero = strategy._get_non_zero_tracked_tokens()
|
|
395
|
+
|
|
396
|
+
assert len(non_zero) == 2
|
|
397
|
+
token_ids = [token_id for token_id, _ in non_zero]
|
|
398
|
+
assert "token-1" in token_ids
|
|
399
|
+
assert "token-3" in token_ids
|
|
400
|
+
assert "token-2" not in token_ids
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
@pytest.mark.asyncio
|
|
404
|
+
async def test_refresh_tracked_balances(strategy):
|
|
405
|
+
"""Test that _refresh_tracked_balances updates all tracked token balances."""
|
|
406
|
+
# Track some tokens
|
|
407
|
+
strategy._track_token("usd-coin-base")
|
|
408
|
+
strategy._track_token("ethereum-base")
|
|
409
|
+
|
|
410
|
+
# Refresh balances
|
|
411
|
+
await strategy._refresh_tracked_balances()
|
|
412
|
+
|
|
413
|
+
# Verify balances were fetched
|
|
414
|
+
assert "usd-coin-base" in strategy.tracked_balances
|
|
415
|
+
assert "ethereum-base" in strategy.tracked_balances
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
@pytest.mark.asyncio
|
|
419
|
+
async def test_deposit_tracks_usdc(strategy):
|
|
420
|
+
"""Test that deposit operation tracks USDC token."""
|
|
421
|
+
# Clear tracked state
|
|
422
|
+
strategy.tracked_token_ids.clear()
|
|
423
|
+
strategy.tracked_balances.clear()
|
|
424
|
+
|
|
425
|
+
# Perform deposit
|
|
426
|
+
ok, _ = await strategy.deposit(main_token_amount=100.0)
|
|
427
|
+
|
|
428
|
+
# Verify USDC is tracked
|
|
429
|
+
assert ok
|
|
430
|
+
usdc_token_id = strategy.usdc_token_info.get("token_id")
|
|
431
|
+
assert usdc_token_id in strategy.tracked_token_ids
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
@pytest.mark.asyncio
|
|
435
|
+
async def test_sweep_wallet_uses_tracked_tokens(strategy):
|
|
436
|
+
"""Test that _sweep_wallet only swaps tracked tokens."""
|
|
437
|
+
# Import the real implementation to restore it
|
|
438
|
+
from wayfinder_paths.strategies.stablecoin_yield_strategy.strategy import (
|
|
439
|
+
StablecoinYieldStrategy,
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
# Restore the real _sweep_wallet method (fixture mocks it as a no-op)
|
|
443
|
+
strategy._sweep_wallet = StablecoinYieldStrategy._sweep_wallet.__get__(
|
|
444
|
+
strategy, StablecoinYieldStrategy
|
|
445
|
+
)
|
|
446
|
+
|
|
447
|
+
# Setup: track some tokens with balances
|
|
448
|
+
strategy._track_token("token-1", 1000000)
|
|
449
|
+
strategy._track_token("token-2", 2000000)
|
|
450
|
+
|
|
451
|
+
# Track the actual token IDs to avoid issues with gas token
|
|
452
|
+
# Make sure we're not accidentally matching gas token
|
|
453
|
+
assert "token-1" in strategy.tracked_token_ids
|
|
454
|
+
assert "token-2" in strategy.tracked_token_ids
|
|
455
|
+
|
|
456
|
+
# Mock balance adapter to return fresh balances
|
|
457
|
+
async def get_balance_mock(token_id, **kwargs):
|
|
458
|
+
balance = strategy.tracked_balances.get(token_id, 0)
|
|
459
|
+
# Return the balance, ensuring it's an int
|
|
460
|
+
return (True, int(balance) if balance else 0)
|
|
461
|
+
|
|
462
|
+
# Create a new AsyncMock that will track calls
|
|
463
|
+
new_mock = AsyncMock(side_effect=get_balance_mock)
|
|
464
|
+
strategy.balance_adapter.get_balance = new_mock
|
|
465
|
+
|
|
466
|
+
# Mock brap adapter swap
|
|
467
|
+
strategy.brap_adapter.swap_from_token_ids = AsyncMock(
|
|
468
|
+
return_value=(True, "Swap successful")
|
|
469
|
+
)
|
|
470
|
+
|
|
471
|
+
target_token = {
|
|
472
|
+
"token_id": "usd-coin-base",
|
|
473
|
+
"address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
|
|
474
|
+
"chain": {"code": "base", "name": "Base"},
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
# Call sweep
|
|
478
|
+
await strategy._sweep_wallet(target_token)
|
|
479
|
+
|
|
480
|
+
# Verify that swap was called for tracked tokens (should be called twice, once for each token)
|
|
481
|
+
# If this fails, check: balance_adapter.get_balance was called, tracked_balances has values,
|
|
482
|
+
# and tokens pass the gas/target token checks
|
|
483
|
+
assert strategy.brap_adapter.swap_from_token_ids.call_count >= 1, (
|
|
484
|
+
f"Expected at least 1 swap call, got {strategy.brap_adapter.swap_from_token_ids.call_count}. "
|
|
485
|
+
f"Tracked tokens: {strategy.tracked_token_ids}, "
|
|
486
|
+
f"Tracked balances: {strategy.tracked_balances}, "
|
|
487
|
+
f"Get balance calls: {new_mock.call_count}, "
|
|
488
|
+
f"balance_adapter mock is: {id(strategy.balance_adapter.get_balance)}, new_mock is: {id(new_mock)}"
|
|
489
|
+
)
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
@pytest.mark.asyncio
|
|
493
|
+
async def test_get_non_gas_balances_uses_tracked_state(strategy):
|
|
494
|
+
"""Test that _get_non_gas_balances only checks tracked tokens."""
|
|
495
|
+
# Setup tracked tokens
|
|
496
|
+
usdc_token_id = "usd-coin-base"
|
|
497
|
+
pool_token_id = "test-pool-base"
|
|
498
|
+
|
|
499
|
+
strategy._track_token(usdc_token_id, 100000000)
|
|
500
|
+
strategy._track_token(pool_token_id, 50000000000000000000)
|
|
501
|
+
|
|
502
|
+
# Mock refresh
|
|
503
|
+
strategy.balance_adapter.get_balance = AsyncMock(
|
|
504
|
+
side_effect=lambda token_id, **kwargs: (
|
|
505
|
+
True,
|
|
506
|
+
strategy.tracked_balances.get(token_id, 0),
|
|
507
|
+
)
|
|
508
|
+
)
|
|
509
|
+
|
|
510
|
+
# Get non-gas balances
|
|
511
|
+
balances = await strategy._get_non_gas_balances()
|
|
512
|
+
|
|
513
|
+
# Verify only tracked tokens are returned (excluding gas)
|
|
514
|
+
token_ids = [b["token_id"] for b in balances]
|
|
515
|
+
assert usdc_token_id in token_ids or pool_token_id in token_ids
|
|
516
|
+
assert len(balances) <= len(strategy.tracked_token_ids)
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
@pytest.mark.asyncio
|
|
520
|
+
async def test_partial_liquidate_uses_tracked_tokens(strategy):
|
|
521
|
+
"""Test that partial_liquidate only liquidates tracked tokens."""
|
|
522
|
+
# Setup tracked tokens with balances
|
|
523
|
+
strategy._track_token("usd-coin-base", 50000000) # 50 USDC
|
|
524
|
+
strategy._track_token("test-pool-base", 100000000000000000000) # 100 POOL tokens
|
|
525
|
+
|
|
526
|
+
# Mock balance and token adapters
|
|
527
|
+
strategy.balance_adapter.get_balance = AsyncMock(
|
|
528
|
+
side_effect=lambda token_id, **kwargs: (
|
|
529
|
+
True,
|
|
530
|
+
strategy.tracked_balances.get(token_id, 0),
|
|
531
|
+
)
|
|
532
|
+
)
|
|
533
|
+
|
|
534
|
+
strategy.token_adapter.get_token_price = AsyncMock(
|
|
535
|
+
return_value=(True, {"current_price": 1.0})
|
|
536
|
+
)
|
|
537
|
+
|
|
538
|
+
strategy.brap_adapter.swap_from_token_ids = AsyncMock(
|
|
539
|
+
return_value=(True, "Swap successful")
|
|
540
|
+
)
|
|
541
|
+
|
|
542
|
+
# Call partial liquidate
|
|
543
|
+
ok, msg = await strategy.partial_liquidate(usd_value=75.0)
|
|
544
|
+
|
|
545
|
+
# Verify success
|
|
546
|
+
assert ok
|
|
547
|
+
assert "liquidation completed" in msg.lower()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: wayfinder-paths
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.8
|
|
4
4
|
Summary: Wayfinder Path: strategies and adapters
|
|
5
5
|
Author: Wayfinder
|
|
6
6
|
Author-email: dev@wayfinder.ai
|
|
@@ -10,6 +10,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
10
10
|
Requires-Dist: aiohttp (>=3.13.0,<4.0.0)
|
|
11
11
|
Requires-Dist: eth-account (>=0.13.7,<0.14.0)
|
|
12
12
|
Requires-Dist: httpx (>=0.28.1,<0.29.0)
|
|
13
|
+
Requires-Dist: hyperliquid-python-sdk (>=0.21.0,<0.22.0)
|
|
13
14
|
Requires-Dist: loguru (>=0.7.3,<0.8.0)
|
|
14
15
|
Requires-Dist: numpy (>=1.26.0,<2.0.0)
|
|
15
16
|
Requires-Dist: pandas (>=2.2.0,<3.0.0)
|
|
@@ -124,6 +125,7 @@ We welcome contributions! This is an open-source project where community members
|
|
|
124
125
|
### Contributor Guidelines
|
|
125
126
|
|
|
126
127
|
#### For Adapters
|
|
128
|
+
|
|
127
129
|
- **Start from the template**: Copy `wayfinder_paths/templates/adapter/` as a starting point
|
|
128
130
|
- Extend `BaseAdapter` from `wayfinder_paths/core/adapters/BaseAdapter.py`
|
|
129
131
|
- Create a `manifest.yaml` (template at `wayfinder_paths/templates/adapter/manifest.yaml`) with:
|
|
@@ -137,6 +139,7 @@ We welcome contributions! This is an open-source project where community members
|
|
|
137
139
|
- Validate your manifest: `just validate-manifests`
|
|
138
140
|
|
|
139
141
|
#### For Strategies
|
|
142
|
+
|
|
140
143
|
- **Start from the template**: Use `just create-strategy "Strategy Name"` to create a new strategy with its own wallet, or copy `wayfinder_paths/templates/strategy/` manually
|
|
141
144
|
- Extend `Strategy` from `wayfinder_paths/core/strategies/Strategy.py`
|
|
142
145
|
- Create a `manifest.yaml` (template at `wayfinder_paths/templates/strategy/manifest.yaml`) with:
|
|
@@ -150,6 +153,7 @@ We welcome contributions! This is an open-source project where community members
|
|
|
150
153
|
- Validate your manifest: `just validate-manifests`
|
|
151
154
|
|
|
152
155
|
#### General Guidelines
|
|
156
|
+
|
|
153
157
|
- **Code Quality**: Follow existing patterns and use type hints
|
|
154
158
|
- **Testing**: See [TESTING.md](TESTING.md) - minimum: smoke test for strategies, basic tests for adapters
|
|
155
159
|
- **Documentation**: Update README files and add docstrings
|
|
@@ -204,6 +208,7 @@ poetry run python wayfinder_paths/run_strategy.py your_strategy --action status
|
|
|
204
208
|
## 🏗️ Architecture
|
|
205
209
|
|
|
206
210
|
### Client System
|
|
211
|
+
|
|
207
212
|
The platform uses a unified client system for all API interactions. Clients are thin wrappers that handle low-level API calls, authentication, and network communication. **Strategies should not call clients directly** - use adapters instead for domain-specific operations.
|
|
208
213
|
|
|
209
214
|
### Clients vs Adapters
|
|
@@ -230,6 +235,7 @@ Adapter manifests declare the capabilities an adapter provides and the clients i
|
|
|
230
235
|
**Template:** Copy `wayfinder_paths/templates/adapter/manifest.yaml` as a starting point.
|
|
231
236
|
|
|
232
237
|
**Schema:**
|
|
238
|
+
|
|
233
239
|
```yaml
|
|
234
240
|
schema_version: "0.1"
|
|
235
241
|
entrypoint: "adapters.my_adapter.adapter.MyAdapter"
|
|
@@ -242,12 +248,14 @@ dependencies:
|
|
|
242
248
|
```
|
|
243
249
|
|
|
244
250
|
**Fields:**
|
|
251
|
+
|
|
245
252
|
- `schema_version`: Manifest schema version (currently `"0.1"`)
|
|
246
253
|
- `entrypoint`: Full Python import path to the adapter class (required)
|
|
247
254
|
- `capabilities`: List of abstract capabilities this adapter provides (required, non-empty)
|
|
248
255
|
- `dependencies`: List of client class names from `core.clients` that this adapter requires (required, non-empty)
|
|
249
256
|
|
|
250
257
|
**Example** (`wayfinder_paths/adapters/pool_adapter/manifest.yaml`):
|
|
258
|
+
|
|
251
259
|
```yaml
|
|
252
260
|
schema_version: "0.1"
|
|
253
261
|
entrypoint: "adapters.pool_adapter.adapter.PoolAdapter"
|
|
@@ -268,6 +276,7 @@ Strategy manifests declare permissions and required adapters with their capabili
|
|
|
268
276
|
**Template:** Copy `wayfinder_paths/templates/strategy/manifest.yaml` as a starting point.
|
|
269
277
|
|
|
270
278
|
**Schema:**
|
|
279
|
+
|
|
271
280
|
```yaml
|
|
272
281
|
schema_version: "0.1"
|
|
273
282
|
entrypoint: "strategies.my_strategy.strategy.MyStrategy"
|
|
@@ -281,6 +290,7 @@ adapters:
|
|
|
281
290
|
```
|
|
282
291
|
|
|
283
292
|
**Fields:**
|
|
293
|
+
|
|
284
294
|
- `schema_version`: Manifest schema version (currently `"0.1"`)
|
|
285
295
|
- `entrypoint`: Full Python import path to the strategy class (required)
|
|
286
296
|
- `name`: Strategy directory name (optional, used for wallet lookup - defaults to directory name)
|
|
@@ -290,6 +300,7 @@ adapters:
|
|
|
290
300
|
- `capabilities`: List of capabilities required from this adapter
|
|
291
301
|
|
|
292
302
|
**Example** (`wayfinder_paths/strategies/stablecoin_yield_strategy/manifest.yaml`):
|
|
303
|
+
|
|
293
304
|
```yaml
|
|
294
305
|
schema_version: "0.1"
|
|
295
306
|
entrypoint: "strategies.stablecoin_yield_strategy.strategy.StablecoinYieldStrategy"
|
|
@@ -307,12 +318,14 @@ adapters:
|
|
|
307
318
|
#### Manifest Validation
|
|
308
319
|
|
|
309
320
|
Manifests are automatically validated to ensure:
|
|
321
|
+
|
|
310
322
|
- Schema compliance (all required fields present, correct types)
|
|
311
323
|
- Entrypoint classes exist and are importable
|
|
312
324
|
- Dependencies are valid client classes
|
|
313
325
|
- Permissions policies are non-empty
|
|
314
326
|
|
|
315
327
|
**Validate locally:**
|
|
328
|
+
|
|
316
329
|
```bash
|
|
317
330
|
# Validate all manifests
|
|
318
331
|
just validate-manifests
|
|
@@ -347,6 +360,7 @@ The `validate_manifests.py` script performs multi-stage validation:
|
|
|
347
360
|
- Policy syntax is not parsed/validated (assumed to be valid at runtime)
|
|
348
361
|
|
|
349
362
|
**Validation Flow:**
|
|
363
|
+
|
|
350
364
|
```
|
|
351
365
|
For each manifest file:
|
|
352
366
|
1. Load YAML → Parse with Pydantic (schema validation)
|
|
@@ -356,6 +370,7 @@ For each manifest file:
|
|
|
356
370
|
```
|
|
357
371
|
|
|
358
372
|
The script automatically discovers all manifests by scanning:
|
|
373
|
+
|
|
359
374
|
- `wayfinder_paths/adapters/*/manifest.yaml` for adapter manifests
|
|
360
375
|
- `wayfinder_paths/strategies/*/manifest.yaml` for strategy manifests
|
|
361
376
|
|
|
@@ -366,12 +381,15 @@ All errors are collected and reported at the end, with the script exiting with c
|
|
|
366
381
|
Capabilities are abstract operation identifiers (e.g., `"pool.read"`, `"swap.execute"`) declared in manifests. They represent what operations an adapter can perform, not specific method names. The manifest is the **single source of truth** for capabilities—they are not duplicated in code.
|
|
367
382
|
|
|
368
383
|
When creating an adapter:
|
|
384
|
+
|
|
369
385
|
1. Declare capabilities in your `manifest.yaml`
|
|
370
386
|
2. Implement methods that fulfill those capabilities
|
|
371
387
|
3. Capabilities are validated at manifest validation time (entrypoint must be importable)
|
|
372
388
|
|
|
373
389
|
### Configuration
|
|
390
|
+
|
|
374
391
|
Configuration is split between:
|
|
392
|
+
|
|
375
393
|
- **User Config**: Your credentials and preferences
|
|
376
394
|
- **System Config**: Platform settings
|
|
377
395
|
- **Strategy Config**: Strategy-specific parameters
|
|
@@ -383,9 +401,11 @@ See [CONFIG_GUIDE.md](wayfinder_paths/CONFIG_GUIDE.md) for details.
|
|
|
383
401
|
Wayfinder Paths supports two authentication methods:
|
|
384
402
|
|
|
385
403
|
#### 1. Service Account Authentication (API Key)
|
|
404
|
+
|
|
386
405
|
For backend services and automated systems with higher rate limits:
|
|
387
406
|
|
|
388
407
|
**Option A: Pass to Strategy Constructor**
|
|
408
|
+
|
|
389
409
|
```python
|
|
390
410
|
from wayfinder_paths.strategies.stablecoin_yield_strategy.strategy import StablecoinYieldStrategy
|
|
391
411
|
|
|
@@ -396,19 +416,21 @@ strategy = StablecoinYieldStrategy(
|
|
|
396
416
|
```
|
|
397
417
|
|
|
398
418
|
**Option B: Set Environment Variable**
|
|
419
|
+
|
|
399
420
|
```bash
|
|
400
421
|
export WAYFINDER_API_KEY="sk_live_abc123..."
|
|
401
422
|
# All clients will automatically discover and use this
|
|
402
423
|
```
|
|
403
424
|
|
|
404
425
|
**Option C: Add to config.json**
|
|
426
|
+
|
|
405
427
|
```json
|
|
406
428
|
{
|
|
407
429
|
"user": {
|
|
408
430
|
"api_key": "sk_live_abc123..."
|
|
409
431
|
},
|
|
410
432
|
"system": {
|
|
411
|
-
"api_key": "sk_live_abc123..."
|
|
433
|
+
"api_key": "sk_live_abc123..." // Alternative: system-level API key
|
|
412
434
|
}
|
|
413
435
|
}
|
|
414
436
|
```
|
|
@@ -418,6 +440,7 @@ export WAYFINDER_API_KEY="sk_live_abc123..."
|
|
|
418
440
|
**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.
|
|
419
441
|
|
|
420
442
|
#### 2. Personal Access Authentication (OAuth)
|
|
443
|
+
|
|
421
444
|
For standalone SDK users with username/password:
|
|
422
445
|
|
|
423
446
|
```json
|
|
@@ -425,12 +448,13 @@ For standalone SDK users with username/password:
|
|
|
425
448
|
"user": {
|
|
426
449
|
"username": "your_username",
|
|
427
450
|
"password": "your_password",
|
|
428
|
-
"refresh_token": null
|
|
451
|
+
"refresh_token": null // Optional: use refresh token instead
|
|
429
452
|
}
|
|
430
453
|
}
|
|
431
454
|
```
|
|
432
455
|
|
|
433
456
|
**How It Works:**
|
|
457
|
+
|
|
434
458
|
- API keys are automatically discovered by all clients (no need to pass explicitly)
|
|
435
459
|
- When an API key is available, it's used for all API requests (including public endpoints) for rate limiting
|
|
436
460
|
- If no API key is found, the system falls back to OAuth authentication
|
|
@@ -613,6 +637,7 @@ just create-wallets
|
|
|
613
637
|
```
|
|
614
638
|
|
|
615
639
|
This creates:
|
|
640
|
+
|
|
616
641
|
- `main` wallet - your main wallet for testing (labeled "main" in wallets.json)
|
|
617
642
|
- `wallets.json` - wallet addresses and private keys for local testing
|
|
618
643
|
|
|
@@ -688,12 +713,14 @@ This package follows [Semantic Versioning](https://semver.org/) (SemVer) and is
|
|
|
688
713
|
3. **Dependent changes**: Only after publishing can dependent changes be merged in other applications
|
|
689
714
|
|
|
690
715
|
**Why this order matters:**
|
|
716
|
+
|
|
691
717
|
- Other applications depend on this package from PyPI
|
|
692
718
|
- They cannot merge changes that depend on new versions until those versions are available on PyPI
|
|
693
719
|
- Publishing from `main` ensures the published version matches what's in the repository
|
|
694
720
|
- This prevents dependency resolution failures in downstream applications
|
|
695
721
|
|
|
696
722
|
**Example workflow:**
|
|
723
|
+
|
|
697
724
|
```bash
|
|
698
725
|
# 1. Make changes in a feature branch
|
|
699
726
|
git checkout -b feature/new-adapter
|
|
@@ -726,6 +753,7 @@ just publish
|
|
|
726
753
|
```
|
|
727
754
|
|
|
728
755
|
**Important:**
|
|
756
|
+
|
|
729
757
|
- ⚠️ **Publishing is only allowed from the `main` branch** - the publish command will fail if run from any other branch
|
|
730
758
|
- ⚠️ **Versions must be unique** - ensure the version in `pyproject.toml` has been bumped and is unique
|
|
731
759
|
- ⚠️ **Follow the order of operations** - see [Versioning](#-versioning) section above for the required workflow
|
|
@@ -748,6 +776,7 @@ pip install git+https://github.com/wayfinder-ai/wayfinder-paths.git
|
|
|
748
776
|
### Managing Package Access
|
|
749
777
|
|
|
750
778
|
To add collaborators who can publish updates:
|
|
779
|
+
|
|
751
780
|
1. Go to https://pypi.org/project/wayfinder-paths/
|
|
752
781
|
2. Click "Manage" → "Collaborators"
|
|
753
782
|
3. Add users as "Maintainers" (can publish) or "Owners" (full control)
|
|
@@ -2,59 +2,72 @@ wayfinder_paths/CONFIG_GUIDE.md,sha256=PN2ClAZ8FCF16_sstaUxbfvQkVAyXdtRvTrrj-qJP
|
|
|
2
2
|
wayfinder_paths/__init__.py,sha256=YgOg-PRPT3ROh0zg6hgQyQE-YFkFGw6TM77zDvB4_sE,427
|
|
3
3
|
wayfinder_paths/abis/generic/erc20.json,sha256=geyzVzdTNt3u1XHKxi4seszP_GIWIzPTl0FYgiftRnM,9336
|
|
4
4
|
wayfinder_paths/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
-
wayfinder_paths/adapters/balance_adapter/README.md,sha256=
|
|
6
|
-
wayfinder_paths/adapters/balance_adapter/adapter.py,sha256=
|
|
5
|
+
wayfinder_paths/adapters/balance_adapter/README.md,sha256=rRq--g4y7X7UOs1KK8c0e-4f-fItZEgHnaTRw0kR76I,3683
|
|
6
|
+
wayfinder_paths/adapters/balance_adapter/adapter.py,sha256=byfucmlGXT4_qGD4eeTvLw5X-2NHgHtiV0uOKp73CfE,8355
|
|
7
7
|
wayfinder_paths/adapters/balance_adapter/examples.json,sha256=3R1M4B_VsIy29viAuFT9nQbnQShWl8ZbU-rnSNWUW9U,129
|
|
8
8
|
wayfinder_paths/adapters/balance_adapter/manifest.yaml,sha256=vp2VoQJf-TxFxgkTsUJ1AEeeOoImM_QjrGYCmjyEQYI,189
|
|
9
|
-
wayfinder_paths/adapters/balance_adapter/test_adapter.py,sha256=
|
|
9
|
+
wayfinder_paths/adapters/balance_adapter/test_adapter.py,sha256=Z8iTRU0Rv1UsODuVSo5q4j-DrTXMd4YRxvaxLdZE4Us,1878
|
|
10
10
|
wayfinder_paths/adapters/brap_adapter/README.md,sha256=euWkSBR6OkYtebhvdNR_PL64sKbzKD5bg5hrYTIWZ1c,7905
|
|
11
11
|
wayfinder_paths/adapters/brap_adapter/__init__.py,sha256=jpqxZ-Bv_8kBo-lhgO_QCWaVZNq_WwlkNBHD4RsqOJg,90
|
|
12
|
-
wayfinder_paths/adapters/brap_adapter/adapter.py,sha256=
|
|
12
|
+
wayfinder_paths/adapters/brap_adapter/adapter.py,sha256=OCXlNxIR7vQUktaoEeM55VcFOXR-PucNJW1NpBkNEUs,26828
|
|
13
13
|
wayfinder_paths/adapters/brap_adapter/examples.json,sha256=KWuAklUspd2uvk0s2ey8gczg4nbzhdwxQqzhascyMiQ,5287
|
|
14
14
|
wayfinder_paths/adapters/brap_adapter/manifest.yaml,sha256=bJ8o4j9ZPjfnLxXxHfekoXKUHoBkXmWQ3nokTH1aya4,240
|
|
15
|
-
wayfinder_paths/adapters/brap_adapter/test_adapter.py,sha256=
|
|
15
|
+
wayfinder_paths/adapters/brap_adapter/test_adapter.py,sha256=w2q35tcE7j2QG53jSm_XZgIk7OKL4O51fnFuGMVRSNQ,10754
|
|
16
16
|
wayfinder_paths/adapters/hyperlend_adapter/__init__.py,sha256=DsWOnEn-Tlu9ZoIoGaFeSqOYI3b4lXGVK3_FTntWpLw,139
|
|
17
17
|
wayfinder_paths/adapters/hyperlend_adapter/adapter.py,sha256=QevMiOrztvTRHx7vA_dAQGX3ioUFdLY4aVOfsT-DXX8,10555
|
|
18
18
|
wayfinder_paths/adapters/hyperlend_adapter/manifest.yaml,sha256=Ugc0jNf3txAQRGAXlVvTN3Mbdc4-fUMS1yVs0SZcBwI,259
|
|
19
|
-
wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py,sha256=
|
|
19
|
+
wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py,sha256=iLnrALVnK7JWJV2KFDqBYZlr1ShW1tjHC-kCV6-FlgE,9558
|
|
20
|
+
wayfinder_paths/adapters/hyperliquid_adapter/__init__.py,sha256=QpA258RzVbxzsha86HQduAuNVG0g0qvsI5OcZunQ8DQ,467
|
|
21
|
+
wayfinder_paths/adapters/hyperliquid_adapter/adapter.py,sha256=kG0oBi07OI4JNwDs14cGJ15qDSoNKX6_v-CUHlsctGQ,36598
|
|
22
|
+
wayfinder_paths/adapters/hyperliquid_adapter/executor.py,sha256=uibNnfsgB_KMOYpZzaSDTsiKGQPIKwZyZ6uH34-Xu4A,17447
|
|
23
|
+
wayfinder_paths/adapters/hyperliquid_adapter/manifest.yaml,sha256=IOK5kFaOuqqEcf3EuY5oXufEaUQNoz2oBXRGVbCdSXQ,206
|
|
24
|
+
wayfinder_paths/adapters/hyperliquid_adapter/paired_filler.py,sha256=nOBsrAka8PKv5h8SuoJuLTH4HYS4n0vpTIADUCyDKlA,37546
|
|
25
|
+
wayfinder_paths/adapters/hyperliquid_adapter/test_adapter.py,sha256=JEDeIMSTdrgcSy4BGSVB0CixQzl3NsKpukOZ9mRu3kE,4542
|
|
26
|
+
wayfinder_paths/adapters/hyperliquid_adapter/test_adapter_live.py,sha256=z3vi6AoIkQmOcUW1WyxIPWfv0SIuSNWNp9ABOIkBjzM,7689
|
|
27
|
+
wayfinder_paths/adapters/hyperliquid_adapter/test_utils.py,sha256=2gSrXJgtfrTqNOQIhBS92vUkfcwhFsMLgFRkf1bzLy8,7290
|
|
28
|
+
wayfinder_paths/adapters/hyperliquid_adapter/utils.py,sha256=WjLEaNVvcB8FfYlTrwZBrmw7k2MLS5KhBeW4NNoLlVI,4254
|
|
20
29
|
wayfinder_paths/adapters/ledger_adapter/README.md,sha256=OIFbJIlck91K3kBKbkPfOWUDx7tJgDjwCAcBLm7FNK4,4104
|
|
21
30
|
wayfinder_paths/adapters/ledger_adapter/__init__.py,sha256=DK9GShIUiQ57YKSqhCKoS43GCweBxi0lzkUQ9sYVxUA,96
|
|
22
31
|
wayfinder_paths/adapters/ledger_adapter/adapter.py,sha256=6Fjxltvn9iXp_-CZtN7lDz1Xt0lWaNQX2drx6lgeryw,10260
|
|
23
32
|
wayfinder_paths/adapters/ledger_adapter/examples.json,sha256=DdqTSe4vnBrfIycQVQQ_JZom7fBGHbL7MR4ppK9ljCY,3936
|
|
24
33
|
wayfinder_paths/adapters/ledger_adapter/manifest.yaml,sha256=121VPXNpx13vO9qoBww47Wvpi29JLn5WoIFnudCkDYs,271
|
|
25
|
-
wayfinder_paths/adapters/ledger_adapter/test_adapter.py,sha256=
|
|
26
|
-
wayfinder_paths/adapters/pool_adapter/README.md,sha256=
|
|
34
|
+
wayfinder_paths/adapters/ledger_adapter/test_adapter.py,sha256=Z1-rPP9k5fI-8ofWMKgU3syzNegKGH_hGO6CKApQj1c,7470
|
|
35
|
+
wayfinder_paths/adapters/pool_adapter/README.md,sha256=ttfG4aP_Y0Bl7DXxPlrAhrubOs9Yu0mtki3h7JqWvxQ,5293
|
|
27
36
|
wayfinder_paths/adapters/pool_adapter/__init__.py,sha256=rv56pYzz2Gqiz33uoPJktCQRe3CRt8U9ry5GbjVgK3A,90
|
|
28
|
-
wayfinder_paths/adapters/pool_adapter/adapter.py,sha256=
|
|
29
|
-
wayfinder_paths/adapters/pool_adapter/examples.json,sha256=
|
|
37
|
+
wayfinder_paths/adapters/pool_adapter/adapter.py,sha256=D3J9Bx7urFZjuqfmexg-wDjngKfaeeXi5aNgQXQ2W_Y,7249
|
|
38
|
+
wayfinder_paths/adapters/pool_adapter/examples.json,sha256=FS0cssPu2KB05MmzG4Hc0Ka0DzOn_0nogqfHBGLJns8,2295
|
|
30
39
|
wayfinder_paths/adapters/pool_adapter/manifest.yaml,sha256=z-OQYBsl2RdV6M34RZzqtQTAFHtQod0po_JD_-9ElNM,217
|
|
31
|
-
wayfinder_paths/adapters/pool_adapter/test_adapter.py,sha256=
|
|
40
|
+
wayfinder_paths/adapters/pool_adapter/test_adapter.py,sha256=AYk4YWf0H3FXNBc1NKVmXuLQvE7dpMU-QrCp0XWQYFw,5954
|
|
32
41
|
wayfinder_paths/adapters/token_adapter/README.md,sha256=d2tMJte6HBu62CCYXdjS8GHZXj5f2fU03uZAO6pscBI,2698
|
|
33
42
|
wayfinder_paths/adapters/token_adapter/__init__.py,sha256=nEmxrvffEygn3iKH3cZTNLkhnUUhlUAEtshmrFRAjq8,62
|
|
34
43
|
wayfinder_paths/adapters/token_adapter/adapter.py,sha256=JEb7A8wJYHxENFhJ6upAgnQAbPZeVfYi6OGs1hiHxnA,3432
|
|
35
44
|
wayfinder_paths/adapters/token_adapter/examples.json,sha256=RW-3xazj4wbTPl-AVrzduRH1NCXx8m7-06bRMOUJ-lc,3626
|
|
36
45
|
wayfinder_paths/adapters/token_adapter/manifest.yaml,sha256=KQgbHAUaJ6JYjTlOJ9HGeRxwmICXVV01qRwW8wJPKMM,143
|
|
37
|
-
wayfinder_paths/adapters/token_adapter/test_adapter.py,sha256=
|
|
46
|
+
wayfinder_paths/adapters/token_adapter/test_adapter.py,sha256=oEhV5OooRh1oGnaTTMKtdU9oqvHBKR25KgL6-ZB6Mzo,4304
|
|
38
47
|
wayfinder_paths/config.example.json,sha256=gDvS7W-cbaNe2IV7Q72di_PYpCDKODojELaXdd77Gx4,605
|
|
39
48
|
wayfinder_paths/conftest.py,sha256=pqDNijXn9_zmbAdkt_2a18UQLjtsDkNTBJVTgC6H2nA,1136
|
|
40
49
|
wayfinder_paths/core/__init__.py,sha256=AJK8oS2dCVuJ2pmSxqXOCvuWacNaVEU3yALEqsD3rog,398
|
|
41
50
|
wayfinder_paths/core/adapters/BaseAdapter.py,sha256=bzc3ER7aKOsmk9cxyoJxGdI54eibbpcMC8nGYJUrsp0,2033
|
|
42
51
|
wayfinder_paths/core/adapters/__init__.py,sha256=ZqzkliXm5RjWxYJyJR88XHb3npZFiThk7HoVZe3JF60,108
|
|
43
52
|
wayfinder_paths/core/adapters/base.py,sha256=j10cZ5NwqaAhN2mH_j24tG8r7_7NWtx8F6S7sJ9wOi8,100
|
|
44
|
-
wayfinder_paths/core/adapters/models.py,sha256=
|
|
53
|
+
wayfinder_paths/core/adapters/models.py,sha256=06XyteSyCK9zV3MwetBWFmYgufvwwLVWpZBVy-XiO3k,1006
|
|
54
|
+
wayfinder_paths/core/analytics/__init__.py,sha256=AtcSpt2vPpCNgdDaFDLhyZZpKa0QXK6onvg_dTyGTD4,263
|
|
55
|
+
wayfinder_paths/core/analytics/bootstrap.py,sha256=lb_PjL4Vh3O2F8eXgvAbnAFevJczRF59ODG-dxtpCZ8,1782
|
|
56
|
+
wayfinder_paths/core/analytics/stats.py,sha256=qE6h0j8TZAbqbVpDeYlVKe0YbV5CENQcHbREzKyZ_s8,1426
|
|
57
|
+
wayfinder_paths/core/analytics/test_analytics.py,sha256=DNkVTsbWPLc9I1eeCD5wsPPqUDgN-npbGRhBgMKn3GM,5580
|
|
45
58
|
wayfinder_paths/core/clients/AuthClient.py,sha256=scz8GvnabNYAQq_XYDcLP2lf2LZqurQOixA7MMAfbCY,2796
|
|
46
|
-
wayfinder_paths/core/clients/BRAPClient.py,sha256
|
|
59
|
+
wayfinder_paths/core/clients/BRAPClient.py,sha256=-cL05ELlroi3pUfT_5nF8Axie2a0n19npnuP408bkAQ,3744
|
|
47
60
|
wayfinder_paths/core/clients/ClientManager.py,sha256=2p8oEFnCxKCH_TBMKo9gMLAwzwLgeotdgFod8wpoa04,8135
|
|
48
61
|
wayfinder_paths/core/clients/HyperlendClient.py,sha256=6yAhojEbjrRC7YLckwGL_2z5lwI4xnrRVNzxspqKSTg,6173
|
|
49
|
-
wayfinder_paths/core/clients/LedgerClient.py,sha256=
|
|
50
|
-
wayfinder_paths/core/clients/PoolClient.py,sha256=
|
|
62
|
+
wayfinder_paths/core/clients/LedgerClient.py,sha256=M6VlG0yq3H4rQt6qRxc0QQVd7GoPXJpj2FcD0RM_C_k,14430
|
|
63
|
+
wayfinder_paths/core/clients/PoolClient.py,sha256=EMIRRw7nh2bha-Qb5uOcIRgbnnu_v5FIvDU0D61nXGI,3475
|
|
51
64
|
wayfinder_paths/core/clients/SimulationClient.py,sha256=ViQmXCQKwhpnZA-YkfIgArrpxGr1U11lZNlbBIak1MU,6364
|
|
52
65
|
wayfinder_paths/core/clients/TokenClient.py,sha256=zg39K-uA1ObkNEcxoXviA1QYSd-fxQXxjBHFOeClY9E,2788
|
|
53
66
|
wayfinder_paths/core/clients/TransactionClient.py,sha256=APs-8lMdgBnE40wOn5L8_lEdJ3DddTZFcQbW0tIfJWg,2040
|
|
54
|
-
wayfinder_paths/core/clients/WalletClient.py,sha256=
|
|
67
|
+
wayfinder_paths/core/clients/WalletClient.py,sha256=Vc2AwllBxUzkdZKKVRrPR4gl8mtvffRxz5QbrpxcH-0,2819
|
|
55
68
|
wayfinder_paths/core/clients/WayfinderClient.py,sha256=lLdmD58gAyx5N4yYN4-IYjvRDVzwE3K408XuI07g6g4,10724
|
|
56
69
|
wayfinder_paths/core/clients/__init__.py,sha256=oNq6fQW8hUnpkuIZxdbOTLPayJRLA6S-k8e7wqsH_7c,1581
|
|
57
|
-
wayfinder_paths/core/clients/protocols.py,sha256=
|
|
70
|
+
wayfinder_paths/core/clients/protocols.py,sha256=3TYdOdvz9en72_xA6sMHgahB21ZQFP5w86qE6pwo7YA,10117
|
|
58
71
|
wayfinder_paths/core/clients/sdk_example.py,sha256=Y6mSyHfsWcOje6E-geNI0C4CQ6uyZaD3V9Q8kPM53eo,2969
|
|
59
72
|
wayfinder_paths/core/config.py,sha256=A--KQp_EDLXhtituvk3WXPUP2SJv45IcNcm4G_nFMc0,16890
|
|
60
73
|
wayfinder_paths/core/constants/__init__.py,sha256=KH-TtfNBJgp0WfKIxvHnvS521odH8RS3Qhl8cQhr4Ys,663
|
|
@@ -92,20 +105,30 @@ wayfinder_paths/policies/util.py,sha256=r8xQLPvE3kU21_LG6VbkFI9sUSYltcsKunryZdHO
|
|
|
92
105
|
wayfinder_paths/run_strategy.py,sha256=HRj5iY2AFWaxRKXukKUKPxaXcz4YN-fb6anSLHJaeDg,14502
|
|
93
106
|
wayfinder_paths/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
94
107
|
wayfinder_paths/scripts/create_strategy.py,sha256=rp2kkGXsmcAbOt1eZthV1iZ2yM6wAbjn4R10IATulOw,6275
|
|
95
|
-
wayfinder_paths/scripts/make_wallets.py,sha256=
|
|
108
|
+
wayfinder_paths/scripts/make_wallets.py,sha256=_diYY5FzpLC5mFVIzZsQUBhlBCUQpvhxL5CtQW0qaT8,6298
|
|
109
|
+
wayfinder_paths/scripts/run_strategy.py,sha256=EQDsE59mLHXR0HO7vzmzNsqSj-YpsuObC9tg2ZYVztA,3633
|
|
96
110
|
wayfinder_paths/scripts/validate_manifests.py,sha256=sTJhCVTb8X0SFYozArVbX4AMAEv-0R1Imp4dpHfAuHE,7075
|
|
97
111
|
wayfinder_paths/strategies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
112
|
+
wayfinder_paths/strategies/basis_trading_strategy/README.md,sha256=rTUXQ2owEoPmXlfHcJfRFCwcQxlU3a4hOJGN5kaWWQ0,7176
|
|
113
|
+
wayfinder_paths/strategies/basis_trading_strategy/__init__.py,sha256=kVcehFjBUtoi5xzSHI56jtDghsy0nYl6XIE6BI1l6aI,79
|
|
114
|
+
wayfinder_paths/strategies/basis_trading_strategy/constants.py,sha256=PJ1WtSALxiuW1FXx-BF30ciFISEhO5VBfrSZyfhPuz0,45
|
|
115
|
+
wayfinder_paths/strategies/basis_trading_strategy/examples.json,sha256=q2wlAH8Gr-LUJeamKzWL1EtChL3TBWe0HQ4_P-VCdqQ,429
|
|
116
|
+
wayfinder_paths/strategies/basis_trading_strategy/manifest.yaml,sha256=cmvAizwBP_SoXvypal8CEHLNh4Du5M_RBKy37ScUjL0,1078
|
|
117
|
+
wayfinder_paths/strategies/basis_trading_strategy/snapshot_mixin.py,sha256=pkYJ3Ax7quuJUZT_AjB6PFNPM3iDmEE6xpXGthXa5UY,38748
|
|
118
|
+
wayfinder_paths/strategies/basis_trading_strategy/strategy.py,sha256=pA11cJXTVuvwBiSc_BYsapshtKBK5FI_Xm-hKxJ9bhg,173962
|
|
119
|
+
wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py,sha256=cFw191y1ud-dtb8jBMTvEbmvhZAXJmLkHaQ3BQBxlXg,28964
|
|
120
|
+
wayfinder_paths/strategies/basis_trading_strategy/types.py,sha256=rlbouTUOVPLfGPzMbsf-fUmMcn0R_OsG-IdfiBJmmqI,845
|
|
98
121
|
wayfinder_paths/strategies/config.py,sha256=5dv-8tWwoxH3Sxd9jtiw90shrLipEe3UlU-IYUBfciM,2762
|
|
99
122
|
wayfinder_paths/strategies/hyperlend_stable_yield_strategy/README.md,sha256=8mjDUBkBEYp_GWkM0knbFIbJ2Nmb-63pNR09ztZ67qo,4596
|
|
100
|
-
wayfinder_paths/strategies/hyperlend_stable_yield_strategy/examples.json,sha256=
|
|
123
|
+
wayfinder_paths/strategies/hyperlend_stable_yield_strategy/examples.json,sha256=72lu80KAzPG2Bqu_ct1I0qsnEFVs-lurwCXuHZrefck,95
|
|
101
124
|
wayfinder_paths/strategies/hyperlend_stable_yield_strategy/manifest.yaml,sha256=__YWl6MEeTBLbNWwUyZjQky0ok1T8B1m8dHPQWtW454,240
|
|
102
125
|
wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py,sha256=VqHuuULeXZ5bA8g7cK9oD1kgXrK87N8Hxu8bnDBR1Cc,88820
|
|
103
|
-
wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py,sha256=
|
|
126
|
+
wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py,sha256=xXPYV45EivXvKPuq-3sJP4Ce5m9GWfGzG40miOtwmxI,13371
|
|
104
127
|
wayfinder_paths/strategies/stablecoin_yield_strategy/README.md,sha256=Qj1b2bU5606pbZXsPf1WOtsx0erfBaXpRygxIDGVIgE,5211
|
|
105
128
|
wayfinder_paths/strategies/stablecoin_yield_strategy/examples.json,sha256=pL1DNFEvYvXKK7xXD5oQYFPQj3Cm1ocKnk6r_iZk0IY,423
|
|
106
129
|
wayfinder_paths/strategies/stablecoin_yield_strategy/manifest.yaml,sha256=rBb7-Fmub8twfKJgbBIiCWbwI2nLnuqBNyAJs36WhIg,750
|
|
107
|
-
wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py,sha256=
|
|
108
|
-
wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py,sha256=
|
|
130
|
+
wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py,sha256=6Ug2_cFx3nqw4Of5Oo1e9h1tQL1G3JXk2XcxNoq2Q0g,75607
|
|
131
|
+
wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py,sha256=StGLLqDwthmqYDKLo-Qo0XCUU0pEFD_H65smdxgpBGc,20125
|
|
109
132
|
wayfinder_paths/templates/adapter/README.md,sha256=QcJ0cwXqqtj1VRK1wAs-unUphTPHdJwoIrIoSU4hTmA,3550
|
|
110
133
|
wayfinder_paths/templates/adapter/adapter.py,sha256=8wdqcEwqb7XGUxl2gQvGnbFwhPi1h15ZJhB2lgtZieI,814
|
|
111
134
|
wayfinder_paths/templates/adapter/examples.json,sha256=KLHy3AgPIplAaZN0qY2A-HBMa1xXkMhIyusORovTD9w,79
|
|
@@ -120,7 +143,7 @@ wayfinder_paths/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
|
|
|
120
143
|
wayfinder_paths/tests/test_smoke_manifest.py,sha256=YjVzHTWys5o6Ae2cUuuJPhk-QgKxT1InDFHLjpouRiY,1267
|
|
121
144
|
wayfinder_paths/tests/test_test_coverage.py,sha256=9NrZeVmP02D4W7Qc0XjciC05bhvdTCVibYjTGfa_GQk,7893
|
|
122
145
|
wayfinder_paths/tests/test_utils.py,sha256=pxHT0QKFlyJeJo8bFnKXzWcOdi6t8rbJ0JFCBaFCBRQ,2112
|
|
123
|
-
wayfinder_paths-0.1.
|
|
124
|
-
wayfinder_paths-0.1.
|
|
125
|
-
wayfinder_paths-0.1.
|
|
126
|
-
wayfinder_paths-0.1.
|
|
146
|
+
wayfinder_paths-0.1.8.dist-info/LICENSE,sha256=dYKnlkC_xosBAEQNUvB6cHMuhFgcUtN0oBR7E8_aR2Y,1066
|
|
147
|
+
wayfinder_paths-0.1.8.dist-info/METADATA,sha256=xHD03utEsSU9sZijwc-UwDmK0kXBiUNUIcQgD0eDfXA,31404
|
|
148
|
+
wayfinder_paths-0.1.8.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
149
|
+
wayfinder_paths-0.1.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|