wayfinder-paths 0.1.19__py3-none-any.whl → 0.1.21__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.

Files changed (98) hide show
  1. wayfinder_paths/__init__.py +0 -2
  2. wayfinder_paths/adapters/balance_adapter/README.md +59 -45
  3. wayfinder_paths/adapters/balance_adapter/adapter.py +1 -22
  4. wayfinder_paths/adapters/balance_adapter/test_adapter.py +0 -14
  5. wayfinder_paths/adapters/brap_adapter/README.md +61 -184
  6. wayfinder_paths/adapters/brap_adapter/__init__.py +0 -4
  7. wayfinder_paths/adapters/brap_adapter/adapter.py +1 -148
  8. wayfinder_paths/adapters/brap_adapter/test_adapter.py +0 -15
  9. wayfinder_paths/adapters/hyperlend_adapter/__init__.py +0 -4
  10. wayfinder_paths/adapters/hyperlend_adapter/adapter.py +1 -10
  11. wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py +0 -17
  12. wayfinder_paths/adapters/hyperliquid_adapter/adapter.py +3 -312
  13. wayfinder_paths/adapters/hyperliquid_adapter/executor.py +1 -71
  14. wayfinder_paths/adapters/hyperliquid_adapter/paired_filler.py +0 -57
  15. wayfinder_paths/adapters/hyperliquid_adapter/test_adapter.py +0 -17
  16. wayfinder_paths/adapters/hyperliquid_adapter/test_adapter_live.py +2 -42
  17. wayfinder_paths/adapters/hyperliquid_adapter/test_executor.py +1 -9
  18. wayfinder_paths/adapters/hyperliquid_adapter/test_utils.py +15 -47
  19. wayfinder_paths/adapters/hyperliquid_adapter/utils.py +0 -7
  20. wayfinder_paths/adapters/ledger_adapter/README.md +54 -74
  21. wayfinder_paths/adapters/ledger_adapter/__init__.py +0 -4
  22. wayfinder_paths/adapters/ledger_adapter/adapter.py +0 -106
  23. wayfinder_paths/adapters/ledger_adapter/test_adapter.py +0 -12
  24. wayfinder_paths/adapters/moonwell_adapter/README.md +67 -106
  25. wayfinder_paths/adapters/moonwell_adapter/__init__.py +0 -4
  26. wayfinder_paths/adapters/moonwell_adapter/adapter.py +10 -122
  27. wayfinder_paths/adapters/moonwell_adapter/test_adapter.py +84 -83
  28. wayfinder_paths/adapters/pool_adapter/README.md +30 -51
  29. wayfinder_paths/adapters/pool_adapter/__init__.py +0 -4
  30. wayfinder_paths/adapters/pool_adapter/adapter.py +0 -19
  31. wayfinder_paths/adapters/pool_adapter/test_adapter.py +0 -8
  32. wayfinder_paths/adapters/token_adapter/README.md +41 -49
  33. wayfinder_paths/adapters/token_adapter/adapter.py +0 -32
  34. wayfinder_paths/adapters/token_adapter/test_adapter.py +1 -12
  35. wayfinder_paths/conftest.py +0 -8
  36. wayfinder_paths/core/__init__.py +0 -2
  37. wayfinder_paths/core/adapters/BaseAdapter.py +0 -22
  38. wayfinder_paths/core/adapters/__init__.py +0 -5
  39. wayfinder_paths/core/adapters/models.py +0 -5
  40. wayfinder_paths/core/analytics/__init__.py +0 -2
  41. wayfinder_paths/core/analytics/bootstrap.py +0 -16
  42. wayfinder_paths/core/analytics/stats.py +0 -7
  43. wayfinder_paths/core/analytics/test_analytics.py +5 -34
  44. wayfinder_paths/core/clients/BRAPClient.py +0 -35
  45. wayfinder_paths/core/clients/ClientManager.py +0 -51
  46. wayfinder_paths/core/clients/HyperlendClient.py +0 -77
  47. wayfinder_paths/core/clients/LedgerClient.py +2 -122
  48. wayfinder_paths/core/clients/PoolClient.py +0 -2
  49. wayfinder_paths/core/clients/TokenClient.py +0 -39
  50. wayfinder_paths/core/clients/WalletClient.py +0 -15
  51. wayfinder_paths/core/clients/WayfinderClient.py +0 -24
  52. wayfinder_paths/core/clients/__init__.py +0 -4
  53. wayfinder_paths/core/clients/protocols.py +25 -98
  54. wayfinder_paths/core/config.py +0 -24
  55. wayfinder_paths/core/constants/__init__.py +0 -7
  56. wayfinder_paths/core/constants/base.py +2 -9
  57. wayfinder_paths/core/constants/erc20_abi.py +0 -5
  58. wayfinder_paths/core/constants/hyperlend_abi.py +0 -7
  59. wayfinder_paths/core/constants/moonwell_abi.py +0 -35
  60. wayfinder_paths/core/engine/StrategyJob.py +0 -32
  61. wayfinder_paths/core/strategies/Strategy.py +0 -99
  62. wayfinder_paths/core/strategies/__init__.py +0 -2
  63. wayfinder_paths/core/utils/__init__.py +0 -1
  64. wayfinder_paths/core/utils/evm_helpers.py +0 -50
  65. wayfinder_paths/core/utils/{erc20_service.py → tokens.py} +25 -21
  66. wayfinder_paths/core/utils/transaction.py +0 -1
  67. wayfinder_paths/run_strategy.py +0 -46
  68. wayfinder_paths/scripts/create_strategy.py +0 -17
  69. wayfinder_paths/scripts/make_wallets.py +1 -4
  70. wayfinder_paths/strategies/basis_trading_strategy/README.md +71 -163
  71. wayfinder_paths/strategies/basis_trading_strategy/snapshot_mixin.py +0 -24
  72. wayfinder_paths/strategies/basis_trading_strategy/strategy.py +36 -400
  73. wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py +15 -64
  74. wayfinder_paths/strategies/basis_trading_strategy/types.py +0 -4
  75. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/README.md +65 -56
  76. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +4 -27
  77. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +0 -10
  78. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/README.md +71 -72
  79. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py +23 -227
  80. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/test_strategy.py +120 -113
  81. wayfinder_paths/strategies/stablecoin_yield_strategy/README.md +64 -59
  82. wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +4 -44
  83. wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +2 -35
  84. wayfinder_paths/templates/adapter/README.md +107 -46
  85. wayfinder_paths/templates/adapter/adapter.py +0 -9
  86. wayfinder_paths/templates/adapter/test_adapter.py +0 -19
  87. wayfinder_paths/templates/strategy/README.md +113 -59
  88. wayfinder_paths/templates/strategy/strategy.py +0 -22
  89. wayfinder_paths/templates/strategy/test_strategy.py +0 -28
  90. wayfinder_paths/tests/test_test_coverage.py +2 -12
  91. wayfinder_paths/tests/test_utils.py +1 -31
  92. wayfinder_paths-0.1.21.dist-info/METADATA +355 -0
  93. wayfinder_paths-0.1.21.dist-info/RECORD +129 -0
  94. {wayfinder_paths-0.1.19.dist-info → wayfinder_paths-0.1.21.dist-info}/WHEEL +1 -1
  95. wayfinder_paths/core/adapters/base.py +0 -5
  96. wayfinder_paths-0.1.19.dist-info/METADATA +0 -592
  97. wayfinder_paths-0.1.19.dist-info/RECORD +0 -130
  98. {wayfinder_paths-0.1.19.dist-info → wayfinder_paths-0.1.21.dist-info}/LICENSE +0 -0
@@ -1,8 +1,3 @@
1
- """
2
- Client Manager
3
- Consolidated client management for all API interactions
4
- """
5
-
6
1
  from typing import Any
7
2
 
8
3
  from wayfinder_paths.core.clients.BRAPClient import BRAPClient
@@ -22,28 +17,11 @@ from wayfinder_paths.core.clients.WalletClient import WalletClient
22
17
 
23
18
 
24
19
  class ClientManager:
25
- """
26
- Manages all API client instances for a strategy job.
27
-
28
- Args:
29
- clients: Optional dict of pre-instantiated clients to inject directly.
30
- Keys: 'token', 'hyperlend', 'ledger', 'wallet', 'transaction', 'pool', 'brap'.
31
- If not provided, defaults to HTTP-based clients.
32
- skip_auth: If True, skips authentication (for SDK usage).
33
- """
34
-
35
20
  def __init__(
36
21
  self,
37
22
  clients: dict[str, Any] | None = None,
38
23
  skip_auth: bool = False,
39
24
  ):
40
- """
41
- Initialize ClientManager.
42
-
43
- Args:
44
- clients: Optional dict of pre-instantiated clients to inject directly.
45
- skip_auth: If True, skips authentication (for SDK usage).
46
- """
47
25
  self._injected_clients = clients or {}
48
26
  self._skip_auth = skip_auth
49
27
 
@@ -60,17 +38,6 @@ class ClientManager:
60
38
  injected_key: str,
61
39
  client_class: type[Any],
62
40
  ) -> Any:
63
- """
64
- Helper method to get or create a client instance.
65
-
66
- Args:
67
- client_attr: Name of the private attribute storing the client (e.g., "_token_client").
68
- injected_key: Key to look up in _injected_clients dict.
69
- client_class: Client class to instantiate if not injected.
70
-
71
- Returns:
72
- Client instance.
73
- """
74
41
  client = getattr(self, client_attr)
75
42
  if not client:
76
43
  client = self._injected_clients.get(injected_key) or client_class()
@@ -79,44 +46,26 @@ class ClientManager:
79
46
 
80
47
  @property
81
48
  def token(self) -> TokenClientProtocol:
82
- """Get or create token client"""
83
49
  return self._get_or_create_client("_token_client", "token", TokenClient)
84
50
 
85
51
  @property
86
52
  def ledger(self) -> LedgerClientProtocol:
87
- """Get or create ledger client"""
88
53
  return self._get_or_create_client("_ledger_client", "ledger", LedgerClient)
89
54
 
90
55
  @property
91
56
  def pool(self) -> PoolClientProtocol:
92
- """Get or create pool client"""
93
57
  return self._get_or_create_client("_pool_client", "pool", PoolClient)
94
58
 
95
59
  @property
96
60
  def hyperlend(self) -> HyperlendClientProtocol:
97
- """Get or create hyperlend client"""
98
61
  return self._get_or_create_client(
99
62
  "_hyperlend_client", "hyperlend", HyperlendClient
100
63
  )
101
64
 
102
65
  @property
103
66
  def wallet(self) -> WalletClientProtocol:
104
- """Get or create wallet client"""
105
67
  return self._get_or_create_client("_wallet_client", "wallet", WalletClient)
106
68
 
107
69
  @property
108
70
  def brap(self) -> BRAPClientProtocol:
109
- """Get or create BRAP client"""
110
71
  return self._get_or_create_client("_brap_client", "brap", BRAPClient)
111
-
112
- def get_all_clients(self) -> dict[str, Any]:
113
- """Get all initialized clients for direct access"""
114
- return {
115
- "token": self._token_client,
116
- "transaction": self._transaction_client,
117
- "ledger": self._ledger_client,
118
- "pool": self._pool_client,
119
- "wallet": self._wallet_client,
120
- "hyperlend": self._hyperlend_client,
121
- "brap": self._brap_client,
122
- }
@@ -1,8 +1,3 @@
1
- """
2
- Hyperlend Client
3
- Provides access to Hyperlend stable markets data via blockchain endpoints.
4
- """
5
-
6
1
  from __future__ import annotations
7
2
 
8
3
  from typing import Any, Required, TypedDict
@@ -12,8 +7,6 @@ from wayfinder_paths.core.config import get_api_base_url
12
7
 
13
8
 
14
9
  class AssetsView(TypedDict):
15
- """Assets view response structure"""
16
-
17
10
  block_number: Required[int]
18
11
  user: Required[str]
19
12
  native_balance_wei: Required[int]
@@ -24,8 +17,6 @@ class AssetsView(TypedDict):
24
17
 
25
18
 
26
19
  class MarketEntry(TypedDict):
27
- """Market entry data structure"""
28
-
29
20
  symbol: Required[str]
30
21
  symbol_canonical: Required[str]
31
22
  display_symbol: Required[str]
@@ -33,14 +24,10 @@ class MarketEntry(TypedDict):
33
24
 
34
25
 
35
26
  class LendRateHistory(TypedDict):
36
- """Lend rate history response structure"""
37
-
38
27
  history: Required[list[RateHistoryEntry]]
39
28
 
40
29
 
41
30
  class MarketHeadroom(TypedDict):
42
- """Market headroom data structure"""
43
-
44
31
  symbol: Required[str]
45
32
  symbol_canonical: Required[str]
46
33
  display_symbol: Required[str]
@@ -51,15 +38,11 @@ class MarketHeadroom(TypedDict):
51
38
 
52
39
 
53
40
  class StableMarketsHeadroomResponse(TypedDict):
54
- """Stable markets headroom response structure"""
55
-
56
41
  markets: Required[dict[str, MarketHeadroom]]
57
42
  notes: Required[list[str]]
58
43
 
59
44
 
60
45
  class RateHistoryEntry(TypedDict):
61
- """Rate history entry data structure"""
62
-
63
46
  timestamp_ms: Required[int]
64
47
  timestamp: Required[float]
65
48
  supply_apr: Required[float]
@@ -72,8 +55,6 @@ class RateHistoryEntry(TypedDict):
72
55
 
73
56
 
74
57
  class AssetInfo(TypedDict):
75
- """Asset information structure"""
76
-
77
58
  underlying: Required[str]
78
59
  symbol: Required[str]
79
60
  symbol_canonical: Required[str]
@@ -102,8 +83,6 @@ class AssetInfo(TypedDict):
102
83
 
103
84
 
104
85
  class AccountData(TypedDict):
105
- """Account data structure"""
106
-
107
86
  total_collateral_base: Required[int | float]
108
87
  total_debt_base: Required[int | float]
109
88
  available_borrows_base: Required[int | float]
@@ -114,8 +93,6 @@ class AccountData(TypedDict):
114
93
 
115
94
 
116
95
  class BaseCurrencyInfo(TypedDict):
117
- """Base currency information structure"""
118
-
119
96
  marketReferenceCurrencyUnit: Required[int]
120
97
  marketReferenceCurrencyPriceInUsd: Required[int]
121
98
  networkBaseTokenPriceInUsd: Required[int]
@@ -123,8 +100,6 @@ class BaseCurrencyInfo(TypedDict):
123
100
 
124
101
 
125
102
  class HyperlendClient(WayfinderClient):
126
- """Client for Hyperlend-related operations"""
127
-
128
103
  def __init__(self):
129
104
  super().__init__()
130
105
  self.api_base_url = get_api_base_url()
@@ -136,20 +111,6 @@ class HyperlendClient(WayfinderClient):
136
111
  buffer_bps: int | None = None,
137
112
  min_buffer_tokens: float | None = None,
138
113
  ) -> StableMarketsHeadroomResponse:
139
- """
140
- Fetch stable markets headroom from Hyperlend.
141
-
142
- Args:
143
- required_underlying_tokens: Required underlying tokens amount
144
- buffer_bps: Buffer in basis points
145
- min_buffer_tokens: Minimum buffer in tokens
146
-
147
- Example:
148
- GET /api/v1/blockchain/hyperlend/stable_markets_headroom/?required_underlying_tokens=1000&buffer_bps=50&min_buffer_tokens=100
149
-
150
- Returns:
151
- Dictionary containing stable markets headroom data with markets and notes
152
- """
153
114
  url = f"{self.api_base_url}/v1/blockchain/hyperlend/stable_markets_headroom/"
154
115
  params: dict[str, Any] = {}
155
116
  if required_underlying_tokens is not None:
@@ -169,18 +130,6 @@ class HyperlendClient(WayfinderClient):
169
130
  *,
170
131
  user_address: str,
171
132
  ) -> AssetsView:
172
- """
173
- Fetch assets view for a user address from Hyperlend.
174
-
175
- Args:
176
- user_address: User wallet address to query assets for
177
-
178
- Example:
179
- GET /api/v1/blockchain/hyperlend/assets/?user_address=0x0c737cB5934afCb5B01965141F865F795B324080
180
-
181
- Returns:
182
- Dictionary containing assets view data with account information and base currency info
183
- """
184
133
  url = f"{self.api_base_url}/v1/blockchain/hyperlend/assets/"
185
134
  params: dict[str, Any] = {
186
135
  "user_address": user_address,
@@ -196,18 +145,6 @@ class HyperlendClient(WayfinderClient):
196
145
  *,
197
146
  token: str,
198
147
  ) -> MarketEntry:
199
- """
200
- Fetch market entry from Hyperlend.
201
-
202
- Args:
203
- token: Token address to query market for
204
-
205
- Example:
206
- GET /api/v1/blockchain/hyperlend/market_entry/?token=0x5555555555555555555555555555555555555555
207
-
208
- Returns:
209
- Dictionary containing market entry data with symbol and reserve information
210
- """
211
148
  url = f"{self.api_base_url}/v1/blockchain/hyperlend/market_entry/"
212
149
  params: dict[str, Any] = {
213
150
  "token": token,
@@ -225,20 +162,6 @@ class HyperlendClient(WayfinderClient):
225
162
  lookback_hours: int,
226
163
  force_refresh: bool | None = None,
227
164
  ) -> LendRateHistory:
228
- """
229
- Fetch lend rate history from Hyperlend.
230
-
231
- Args:
232
- token: Token address to query rate history for
233
- lookback_hours: Number of hours to look back for rate history
234
- force_refresh: Whether to force refresh the data (optional)
235
-
236
- Example:
237
- GET /api/v1/blockchain/hyperlend/lend_rate_history/?token=0x5555555555555555555555555555555555555555&lookback_hours=24&force_refresh=false
238
-
239
- Returns:
240
- Dictionary containing lend rate history data with history array
241
- """
242
165
  url = f"{self.api_base_url}/v1/blockchain/hyperlend/lend_rate_history/"
243
166
  params: dict[str, Any] = {
244
167
  "token": token,
@@ -11,8 +11,6 @@ from wayfinder_paths.core.adapters.models import Operation
11
11
 
12
12
 
13
13
  class StrategyTransaction(TypedDict):
14
- """Individual strategy transaction structure"""
15
-
16
14
  id: Required[str]
17
15
  operation: Required[str]
18
16
  timestamp: Required[str]
@@ -24,8 +22,6 @@ class StrategyTransaction(TypedDict):
24
22
 
25
23
 
26
24
  class StrategyTransactionList(TypedDict):
27
- """Vault transaction list response structure"""
28
-
29
25
  transactions: Required[list[StrategyTransaction]]
30
26
  total: Required[int]
31
27
  limit: Required[int]
@@ -33,8 +29,6 @@ class StrategyTransactionList(TypedDict):
33
29
 
34
30
 
35
31
  class NetDeposit(TypedDict):
36
- """Net deposit response structure"""
37
-
38
32
  net_deposit: Required[str]
39
33
  total_deposits: Required[str]
40
34
  total_withdrawals: Required[str]
@@ -42,34 +36,13 @@ class NetDeposit(TypedDict):
42
36
 
43
37
 
44
38
  class TransactionRecord(TypedDict):
45
- """Transaction record response structure"""
46
-
47
39
  transaction_id: Required[str]
48
40
  status: Required[str]
49
41
  timestamp: Required[str]
50
42
 
51
43
 
52
44
  class LedgerClient:
53
- """
54
- Client for strategy transaction history and bookkeeping operations using local JSON files.
55
-
56
- Supports:
57
- - GET strategy transactions
58
- - GET strategy net deposit
59
- - GET strategy latest transactions
60
- - POST add deposit
61
- - POST add withdraw
62
- - POST add operation
63
- - POST record snapshot
64
- """
65
-
66
45
  def __init__(self, ledger_dir: Path | str | None = None) -> None:
67
- """
68
- Initialize the ledger client.
69
-
70
- Args:
71
- ledger_dir: Directory to store ledger JSON files. Defaults to .ledger in project root
72
- """
73
46
  if ledger_dir is None:
74
47
  # Default to .ledger directory in project root
75
48
  project_root = Path(__file__).parent.parent.parent.parent
@@ -89,7 +62,6 @@ class LedgerClient:
89
62
  self._initialize_files()
90
63
 
91
64
  def _initialize_files(self) -> None:
92
- """Create initial JSON files if they don't exist."""
93
65
  if not self.transactions_file.exists():
94
66
  self.transactions_file.write_text(
95
67
  json.dumps({"transactions": []}, indent=2)
@@ -99,7 +71,6 @@ class LedgerClient:
99
71
  self.snapshots_file.write_text(json.dumps({"snapshots": []}, indent=2))
100
72
 
101
73
  async def _read_transactions(self) -> dict[str, Any]:
102
- """Read transactions from file with lock."""
103
74
  async with self._transactions_lock:
104
75
  if not self.transactions_file.exists():
105
76
  return {"transactions": []}
@@ -110,12 +81,10 @@ class LedgerClient:
110
81
  return {"transactions": []}
111
82
 
112
83
  async def _write_transactions(self, data: dict[str, Any]) -> None:
113
- """Write transactions to file with lock."""
114
84
  async with self._transactions_lock:
115
85
  self.transactions_file.write_text(json.dumps(data, indent=2))
116
86
 
117
87
  async def _read_snapshots(self) -> dict[str, Any]:
118
- """Read snapshots from file with lock."""
119
88
  async with self._snapshots_lock:
120
89
  if not self.snapshots_file.exists():
121
90
  return {"snapshots": []}
@@ -126,7 +95,6 @@ class LedgerClient:
126
95
  return {"snapshots": []}
127
96
 
128
97
  async def _write_snapshots(self, data: dict[str, Any]) -> None:
129
- """Write snapshots to file with lock."""
130
98
  async with self._snapshots_lock:
131
99
  self.snapshots_file.write_text(json.dumps(data, indent=2))
132
100
 
@@ -139,17 +107,6 @@ class LedgerClient:
139
107
  limit: int = 100,
140
108
  offset: int = 0,
141
109
  ) -> StrategyTransactionList:
142
- """
143
- Fetch a paginated list of transactions for a given strategy wallet address.
144
-
145
- Args:
146
- wallet_address: The strategy wallet address to filter by
147
- limit: Maximum number of transactions to return
148
- offset: Number of transactions to skip
149
-
150
- Returns:
151
- StrategyTransactionList with transactions, total, limit, and offset
152
- """
153
110
  data = await self._read_transactions()
154
111
  all_transactions = data.get("transactions", [])
155
112
 
@@ -174,15 +131,6 @@ class LedgerClient:
174
131
  }
175
132
 
176
133
  async def get_strategy_net_deposit(self, *, wallet_address: str) -> float:
177
- """
178
- Calculate the net deposit (deposits - withdrawals) for a strategy wallet.
179
-
180
- Args:
181
- wallet_address: The strategy wallet address
182
-
183
- Returns:
184
- NetDeposit with net_deposit, total_deposits, total_withdrawals
185
- """
186
134
  data = await self._read_transactions()
187
135
  all_transactions = data.get("transactions", [])
188
136
 
@@ -212,16 +160,6 @@ class LedgerClient:
212
160
  async def get_strategy_latest_transactions(
213
161
  self, *, wallet_address: str, limit: int = 10
214
162
  ) -> StrategyTransactionList:
215
- """
216
- Fetch the most recent transactions for a strategy wallet.
217
-
218
- Args:
219
- wallet_address: The strategy wallet address
220
- limit: Maximum number of transactions to return (default 10)
221
-
222
- Returns:
223
- StrategyTransactionList with the latest transactions
224
- """
225
163
  return await self.get_strategy_transactions(
226
164
  wallet_address=wallet_address,
227
165
  limit=limit,
@@ -241,21 +179,6 @@ class LedgerClient:
241
179
  data: dict[str, Any] | None = None,
242
180
  strategy_name: str | None = None,
243
181
  ) -> TransactionRecord:
244
- """
245
- Record a deposit for a strategy.
246
-
247
- Args:
248
- wallet_address: The strategy wallet address
249
- chain_id: The blockchain chain ID
250
- token_address: The token contract address
251
- token_amount: Amount of tokens deposited
252
- usd_value: USD value of the deposit
253
- data: Additional metadata
254
- strategy_name: Name of the strategy
255
-
256
- Returns:
257
- TransactionRecord with transaction_id, status, and timestamp
258
- """
259
182
  transaction_id = str(uuid.uuid4())
260
183
  timestamp = datetime.now(UTC).isoformat()
261
184
 
@@ -267,7 +190,7 @@ class LedgerClient:
267
190
  "chain_id": chain_id,
268
191
  "token_address": token_address,
269
192
  "token_amount": str(token_amount),
270
- "amount": str(token_amount), # For backward compatibility
193
+ "amount": str(token_amount),
271
194
  "usd_value": str(usd_value),
272
195
  "data": data or {},
273
196
  }
@@ -275,7 +198,6 @@ class LedgerClient:
275
198
  if strategy_name is not None:
276
199
  transaction["strategy_name"] = strategy_name
277
200
 
278
- # Add to transactions
279
201
  file_data = await self._read_transactions()
280
202
  file_data["transactions"].append(transaction)
281
203
  await self._write_transactions(file_data)
@@ -297,21 +219,6 @@ class LedgerClient:
297
219
  data: dict[str, Any] | None = None,
298
220
  strategy_name: str | None = None,
299
221
  ) -> TransactionRecord:
300
- """
301
- Record a withdrawal for a strategy.
302
-
303
- Args:
304
- wallet_address: The strategy wallet address
305
- chain_id: The blockchain chain ID
306
- token_address: The token contract address
307
- token_amount: Amount of tokens withdrawn
308
- usd_value: USD value of the withdrawal
309
- data: Additional metadata
310
- strategy_name: Name of the strategy
311
-
312
- Returns:
313
- TransactionRecord with transaction_id, status, and timestamp
314
- """
315
222
  transaction_id = str(uuid.uuid4())
316
223
  timestamp = datetime.now(UTC).isoformat()
317
224
 
@@ -323,7 +230,7 @@ class LedgerClient:
323
230
  "chain_id": chain_id,
324
231
  "token_address": token_address,
325
232
  "token_amount": str(token_amount),
326
- "amount": str(token_amount), # For backward compatibility
233
+ "amount": str(token_amount),
327
234
  "usd_value": str(usd_value),
328
235
  "data": data or {},
329
236
  }
@@ -331,7 +238,6 @@ class LedgerClient:
331
238
  if strategy_name is not None:
332
239
  transaction["strategy_name"] = strategy_name
333
240
 
334
- # Add to transactions
335
241
  file_data = await self._read_transactions()
336
242
  file_data["transactions"].append(transaction)
337
243
  await self._write_transactions(file_data)
@@ -350,18 +256,6 @@ class LedgerClient:
350
256
  usd_value: str | float,
351
257
  strategy_name: str | None = None,
352
258
  ) -> TransactionRecord:
353
- """
354
- Record a strategy operation (e.g., swaps, rebalances) for bookkeeping.
355
-
356
- Args:
357
- wallet_address: Strategy wallet address
358
- operation_data: Operation model (SWAP, LEND, UNLEND, etc.)
359
- usd_value: USD value of the operation
360
- strategy_name: Optional strategy name
361
-
362
- Returns:
363
- TransactionRecord with transaction_id, status, and timestamp
364
- """
365
259
  transaction_id = str(uuid.uuid4())
366
260
  timestamp = datetime.now(UTC).isoformat()
367
261
 
@@ -378,7 +272,6 @@ class LedgerClient:
378
272
  "data": {},
379
273
  }
380
274
 
381
- # Extract relevant fields from operation data for easier querying
382
275
  if operation_type == "SWAP":
383
276
  transaction["token_address"] = op_dict.get("to_token_id", "")
384
277
  transaction["amount"] = op_dict.get("to_amount", "0")
@@ -389,7 +282,6 @@ class LedgerClient:
389
282
  if strategy_name is not None:
390
283
  transaction["strategy_name"] = strategy_name
391
284
 
392
- # Add to transactions
393
285
  file_data = await self._read_transactions()
394
286
  file_data["transactions"].append(transaction)
395
287
  await self._write_transactions(file_data)
@@ -409,17 +301,6 @@ class LedgerClient:
409
301
  gas_available: float,
410
302
  gassed_up: bool,
411
303
  ) -> None:
412
- """
413
- Record a periodic snapshot of strategy state.
414
-
415
- Args:
416
- wallet_address: Strategy wallet address
417
- strat_portfolio_value: Total portfolio value in USD
418
- net_deposit: Net deposit amount in USD
419
- strategy_status: Arbitrary strategy status data
420
- gas_available: Available gas tokens
421
- gassed_up: Whether strategy has sufficient gas
422
- """
423
304
  snapshot_id = str(uuid.uuid4())
424
305
  timestamp = datetime.now(UTC).isoformat()
425
306
 
@@ -434,7 +315,6 @@ class LedgerClient:
434
315
  "strategy_status": strategy_status,
435
316
  }
436
317
 
437
- # Add to snapshots
438
318
  file_data = await self._read_snapshots()
439
319
  file_data["snapshots"].append(snapshot)
440
320
  await self._write_snapshots(file_data)
@@ -1,5 +1,3 @@
1
- """Read-only pool metadata and analytics via public endpoints."""
2
-
3
1
  from __future__ import annotations
4
2
 
5
3
  from typing import Any, Required, TypedDict
@@ -1,8 +1,3 @@
1
- """
2
- Token Adapter
3
- Handles token information, prices, and parsing
4
- """
5
-
6
1
  from __future__ import annotations
7
2
 
8
3
  from typing import NotRequired, Required, TypedDict
@@ -12,8 +7,6 @@ from wayfinder_paths.core.config import get_api_base_url
12
7
 
13
8
 
14
9
  class TokenLinks(TypedDict):
15
- """Token links structure"""
16
-
17
10
  github: NotRequired[list[str]]
18
11
  reddit: NotRequired[str]
19
12
  discord: NotRequired[str]
@@ -23,8 +16,6 @@ class TokenLinks(TypedDict):
23
16
 
24
17
 
25
18
  class ChainAddress(TypedDict):
26
- """Chain address structure"""
27
-
28
19
  address: Required[str]
29
20
  token_id: Required[str]
30
21
  is_contract: NotRequired[bool]
@@ -32,16 +23,12 @@ class ChainAddress(TypedDict):
32
23
 
33
24
 
34
25
  class ChainInfo(TypedDict):
35
- """Chain information structure"""
36
-
37
26
  id: Required[int]
38
27
  name: Required[str]
39
28
  code: Required[str]
40
29
 
41
30
 
42
31
  class TokenMetadata(TypedDict):
43
- """Token metadata structure"""
44
-
45
32
  query_processed: NotRequired[str]
46
33
  query_type: NotRequired[str]
47
34
  has_addresses: NotRequired[bool]
@@ -50,8 +37,6 @@ class TokenMetadata(TypedDict):
50
37
 
51
38
 
52
39
  class TokenDetails(TypedDict):
53
- """Token details response structure"""
54
-
55
40
  asset_id: NotRequired[str]
56
41
  token_ids: NotRequired[list[str]]
57
42
  name: Required[str]
@@ -81,8 +66,6 @@ class TokenDetails(TypedDict):
81
66
 
82
67
 
83
68
  class GasToken(TypedDict):
84
- """Gas token response structure"""
85
-
86
69
  id: Required[str]
87
70
  coingecko_id: NotRequired[str]
88
71
  token_id: Required[str]
@@ -94,8 +77,6 @@ class GasToken(TypedDict):
94
77
 
95
78
 
96
79
  class TokenClient(WayfinderClient):
97
- """Adapter for token-related operations"""
98
-
99
80
  def __init__(self):
100
81
  super().__init__()
101
82
  self.api_base_url = f"{get_api_base_url()}/v1/blockchain/tokens"
@@ -103,17 +84,6 @@ class TokenClient(WayfinderClient):
103
84
  async def get_token_details(
104
85
  self, query: str, market_data: bool = False, chain_id: int | None = None
105
86
  ) -> TokenDetails:
106
- """
107
- Get token data including price from the token-details endpoint.
108
-
109
- Args:
110
- query: Token identifier, address, or symbol to query
111
- market_data: Whether to include market data (default: True)
112
- chain_id: Optional chain ID
113
-
114
- Returns:
115
- Full token data including price information
116
- """
117
87
  url = f"{self.api_base_url}/detail/"
118
88
  params = {
119
89
  "query": query,
@@ -127,15 +97,6 @@ class TokenClient(WayfinderClient):
127
97
  return data.get("data", data)
128
98
 
129
99
  async def get_gas_token(self, query: str) -> GasToken:
130
- """
131
- Fetch the native gas token for a given chain code or query.
132
-
133
- Args:
134
- query: Chain code or query string
135
-
136
- Returns:
137
- Gas token information including chain details
138
- """
139
100
  url = f"{self.api_base_url}/gas/"
140
101
  params = {"query": query}
141
102
  response = await self._authed_request("GET", url, params=params)
@@ -1,8 +1,3 @@
1
- """
2
- Wallet Client
3
- Fetches wallet-related data such as aggregated balances for the authenticated user.
4
- """
5
-
6
1
  from __future__ import annotations
7
2
 
8
3
  from typing import NotRequired, Required, TypedDict
@@ -12,8 +7,6 @@ from wayfinder_paths.core.config import get_api_base_url
12
7
 
13
8
 
14
9
  class AddressBalance(TypedDict):
15
- """Balance response structure for address/query lookups."""
16
-
17
10
  balance: Required[int]
18
11
  balance_human: NotRequired[float | None]
19
12
  usd_value: NotRequired[float | None]
@@ -35,14 +28,6 @@ class WalletClient(WayfinderClient):
35
28
  query: str,
36
29
  chain_id: int | None = None,
37
30
  ) -> AddressBalance:
38
- """
39
- Fetch a balance for a wallet address + chain + query.
40
-
41
- Args:
42
- wallet_address: Wallet address
43
- query: Token address, pool address, or equivalent identifier
44
- chain_id: Chain ID (required)
45
- """
46
31
  if chain_id is None:
47
32
  raise ValueError("chain_id is required")
48
33