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
|
@@ -45,16 +45,6 @@ success, amount = await balance.get_pool_balance(
|
|
|
45
45
|
)
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
### `get_all_balances(wallet_address: str, enrich=True, from_cache=False, add_llama=True)`
|
|
49
|
-
Returns the enriched token balance payload Wayfinder exposes (including USD value, metadata, and optional DeFi Llama overlays).
|
|
50
|
-
|
|
51
|
-
```python
|
|
52
|
-
success, snapshot = await balance.get_all_balances(
|
|
53
|
-
wallet_address=config["strategy_wallet"]["address"],
|
|
54
|
-
enrich=True,
|
|
55
|
-
)
|
|
56
|
-
```
|
|
57
|
-
|
|
58
48
|
### `move_from_main_wallet_to_strategy_wallet(token_id: str, amount: float, strategy_name="unknown", skip_ledger=False)`
|
|
59
49
|
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.
|
|
60
50
|
|
|
@@ -236,23 +236,3 @@ class BalanceAdapter(BaseAdapter):
|
|
|
236
236
|
return (True, self._parse_balance(raw))
|
|
237
237
|
except Exception as e:
|
|
238
238
|
return (False, str(e))
|
|
239
|
-
|
|
240
|
-
async def get_all_balances(
|
|
241
|
-
self,
|
|
242
|
-
*,
|
|
243
|
-
wallet_address: str,
|
|
244
|
-
enrich: bool = True,
|
|
245
|
-
from_cache: bool = False,
|
|
246
|
-
add_llama: bool = True,
|
|
247
|
-
) -> tuple[bool, Any]:
|
|
248
|
-
"""Get all enriched token balances for a wallet."""
|
|
249
|
-
try:
|
|
250
|
-
data = await self.wallet_client.get_all_enriched_token_balances_for_wallet(
|
|
251
|
-
wallet_address=wallet_address,
|
|
252
|
-
enrich=enrich,
|
|
253
|
-
from_cache=from_cache,
|
|
254
|
-
add_llama=add_llama,
|
|
255
|
-
)
|
|
256
|
-
return (True, data)
|
|
257
|
-
except Exception as e:
|
|
258
|
-
return (False, str(e))
|
|
@@ -54,36 +54,6 @@ class TestBalanceAdapter:
|
|
|
54
54
|
ok = await adapter.connect()
|
|
55
55
|
assert isinstance(ok, bool)
|
|
56
56
|
|
|
57
|
-
@pytest.mark.asyncio
|
|
58
|
-
async def test_get_all_enriched_token_balances_for_wallet_success(
|
|
59
|
-
self, adapter, mock_wallet_client
|
|
60
|
-
):
|
|
61
|
-
"""Test successful retrieval of enriched token balances"""
|
|
62
|
-
mock_response = {
|
|
63
|
-
"balances": [
|
|
64
|
-
{
|
|
65
|
-
"token_id": "usd-coin-base",
|
|
66
|
-
"symbol": "USDC",
|
|
67
|
-
"balance": "1000000000",
|
|
68
|
-
"usd_value": 1000.0,
|
|
69
|
-
}
|
|
70
|
-
],
|
|
71
|
-
"total_usd_value": 1000.0,
|
|
72
|
-
}
|
|
73
|
-
mock_wallet_client.get_all_enriched_token_balances_for_wallet = AsyncMock(
|
|
74
|
-
return_value=(True, mock_response)
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
success, data = await adapter.get_all_balances(
|
|
78
|
-
wallet_address="0x1234567890123456789012345678901234567890",
|
|
79
|
-
enrich=True,
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
assert success is True
|
|
83
|
-
assert isinstance(data, (dict, tuple))
|
|
84
|
-
if isinstance(data, dict):
|
|
85
|
-
assert "balances" in data
|
|
86
|
-
|
|
87
57
|
def test_adapter_type(self, adapter):
|
|
88
58
|
"""Test adapter has adapter_type"""
|
|
89
59
|
assert adapter.adapter_type == "BALANCE"
|
|
@@ -147,8 +147,7 @@ class BRAPAdapter(BaseAdapter):
|
|
|
147
147
|
)
|
|
148
148
|
|
|
149
149
|
# Extract best quote from response
|
|
150
|
-
|
|
151
|
-
best_quote = quotes.get("best_quote")
|
|
150
|
+
best_quote = data["best_route"]
|
|
152
151
|
|
|
153
152
|
if not best_quote:
|
|
154
153
|
return (False, "No quotes available")
|
|
@@ -631,6 +630,7 @@ class BRAPAdapter(BaseAdapter):
|
|
|
631
630
|
|
|
632
631
|
response = broadcast_response if isinstance(broadcast_response, dict) else {}
|
|
633
632
|
operation_data = SWAP(
|
|
633
|
+
adapter=self.adapter_type,
|
|
634
634
|
from_token_id=from_token.get("id"),
|
|
635
635
|
to_token_id=to_token.get("id"),
|
|
636
636
|
from_amount=quote.get("input_amount"),
|
|
@@ -638,6 +638,7 @@ class BRAPAdapter(BaseAdapter):
|
|
|
638
638
|
from_amount_usd=from_amount_usd or 0,
|
|
639
639
|
to_amount_usd=to_amount_usd or 0,
|
|
640
640
|
transaction_hash=response.get("transaction_hash"),
|
|
641
|
+
transaction_chain_id=from_token.get("chain_id"),
|
|
641
642
|
transaction_status=response.get("transaction_status"),
|
|
642
643
|
transaction_receipt=response.get("transaction_receipt"),
|
|
643
644
|
)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from types import SimpleNamespace
|
|
2
|
-
from unittest.mock import AsyncMock
|
|
2
|
+
from unittest.mock import AsyncMock
|
|
3
3
|
|
|
4
4
|
import pytest
|
|
5
5
|
|
|
@@ -33,11 +33,9 @@ class TestBRAPAdapter:
|
|
|
33
33
|
@pytest.fixture
|
|
34
34
|
def adapter(self, mock_brap_client, mock_web3_service):
|
|
35
35
|
"""Create a BRAPAdapter instance with mocked client for testing"""
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
):
|
|
40
|
-
return BRAPAdapter(web3_service=mock_web3_service)
|
|
36
|
+
adapter = BRAPAdapter(web3_service=mock_web3_service)
|
|
37
|
+
adapter.brap_client = mock_brap_client
|
|
38
|
+
return adapter
|
|
41
39
|
|
|
42
40
|
@pytest.mark.asyncio
|
|
43
41
|
async def test_get_swap_quote_success(self, adapter, mock_brap_client):
|
|
@@ -83,12 +81,10 @@ class TestBRAPAdapter:
|
|
|
83
81
|
async def test_get_best_quote_success(self, adapter, mock_brap_client):
|
|
84
82
|
"""Test successful best quote retrieval"""
|
|
85
83
|
mock_response = {
|
|
86
|
-
"
|
|
87
|
-
"
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
"total_fee": "8000000000000000",
|
|
91
|
-
}
|
|
84
|
+
"best_route": {
|
|
85
|
+
"input_amount": "1000000000000000000",
|
|
86
|
+
"output_amount": "995000000000000000",
|
|
87
|
+
"total_fee": "8000000000000000",
|
|
92
88
|
}
|
|
93
89
|
}
|
|
94
90
|
mock_brap_client.get_quote = AsyncMock(return_value=mock_response)
|
|
@@ -110,7 +106,7 @@ class TestBRAPAdapter:
|
|
|
110
106
|
@pytest.mark.asyncio
|
|
111
107
|
async def test_get_best_quote_no_quotes(self, adapter, mock_brap_client):
|
|
112
108
|
"""Test best quote retrieval when no quotes available"""
|
|
113
|
-
mock_response = {"
|
|
109
|
+
mock_response = {"best_route": None}
|
|
114
110
|
mock_brap_client.get_quote = AsyncMock(return_value=mock_response)
|
|
115
111
|
|
|
116
112
|
success, data = await adapter.get_best_quote(
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
from
|
|
1
|
+
from types import SimpleNamespace
|
|
2
|
+
from unittest.mock import AsyncMock
|
|
2
3
|
|
|
3
4
|
import pytest
|
|
4
5
|
|
|
@@ -15,13 +16,19 @@ class TestHyperlendAdapter:
|
|
|
15
16
|
return mock_client
|
|
16
17
|
|
|
17
18
|
@pytest.fixture
|
|
18
|
-
def
|
|
19
|
+
def mock_web3_service(self):
|
|
20
|
+
"""Minimal Web3Service stub for adapter construction."""
|
|
21
|
+
return SimpleNamespace(token_transactions=SimpleNamespace())
|
|
22
|
+
|
|
23
|
+
@pytest.fixture
|
|
24
|
+
def adapter(self, mock_hyperlend_client, mock_web3_service):
|
|
19
25
|
"""Create a HyperlendAdapter instance with mocked client for testing"""
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
)
|
|
24
|
-
|
|
26
|
+
adapter = HyperlendAdapter(
|
|
27
|
+
config={},
|
|
28
|
+
web3_service=mock_web3_service,
|
|
29
|
+
)
|
|
30
|
+
adapter.hyperlend_client = mock_hyperlend_client
|
|
31
|
+
return adapter
|
|
25
32
|
|
|
26
33
|
@pytest.mark.asyncio
|
|
27
34
|
async def test_get_stable_markets_success(self, adapter, mock_hyperlend_client):
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from .adapter import (
|
|
2
|
+
ARBITRUM_USDC_ADDRESS,
|
|
3
|
+
HYPERLIQUID_BRIDGE_ADDRESS,
|
|
4
|
+
HyperliquidAdapter,
|
|
5
|
+
)
|
|
6
|
+
from .executor import HyperliquidExecutor, LocalHyperliquidExecutor
|
|
7
|
+
from .paired_filler import FillConfig, FillConfirmCfg, PairedFiller
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"HyperliquidAdapter",
|
|
11
|
+
"HyperliquidExecutor",
|
|
12
|
+
"LocalHyperliquidExecutor",
|
|
13
|
+
"PairedFiller",
|
|
14
|
+
"FillConfig",
|
|
15
|
+
"FillConfirmCfg",
|
|
16
|
+
"HYPERLIQUID_BRIDGE_ADDRESS",
|
|
17
|
+
"ARBITRUM_USDC_ADDRESS",
|
|
18
|
+
]
|