wayfinder-paths 0.1.3__py3-none-any.whl → 0.1.5__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 (109) hide show
  1. wayfinder_paths/CONFIG_GUIDE.md +37 -32
  2. wayfinder_paths/__init__.py +3 -3
  3. wayfinder_paths/{vaults/adapters → adapters}/balance_adapter/README.md +12 -12
  4. wayfinder_paths/{vaults/adapters → adapters}/balance_adapter/adapter.py +12 -11
  5. wayfinder_paths/{vaults/adapters → adapters}/balance_adapter/examples.json +1 -1
  6. wayfinder_paths/{vaults/adapters → adapters}/balance_adapter/manifest.yaml +1 -1
  7. wayfinder_paths/{vaults/adapters → adapters}/balance_adapter/test_adapter.py +12 -6
  8. wayfinder_paths/{vaults/adapters → adapters}/brap_adapter/README.md +2 -2
  9. wayfinder_paths/{vaults/adapters → adapters}/brap_adapter/adapter.py +30 -23
  10. wayfinder_paths/{vaults/adapters → adapters}/brap_adapter/manifest.yaml +1 -1
  11. wayfinder_paths/{vaults/adapters → adapters}/brap_adapter/test_adapter.py +2 -2
  12. wayfinder_paths/adapters/hyperlend_adapter/__init__.py +7 -0
  13. wayfinder_paths/{vaults/adapters → adapters}/hyperlend_adapter/adapter.py +33 -26
  14. wayfinder_paths/{vaults/adapters → adapters}/hyperlend_adapter/manifest.yaml +1 -1
  15. wayfinder_paths/{vaults/adapters → adapters}/hyperlend_adapter/test_adapter.py +2 -2
  16. wayfinder_paths/{vaults/adapters → adapters}/ledger_adapter/README.md +27 -40
  17. wayfinder_paths/{vaults/adapters → adapters}/ledger_adapter/adapter.py +78 -75
  18. wayfinder_paths/{vaults/adapters → adapters}/ledger_adapter/examples.json +10 -4
  19. wayfinder_paths/adapters/ledger_adapter/manifest.yaml +11 -0
  20. wayfinder_paths/{vaults/adapters → adapters}/ledger_adapter/test_adapter.py +33 -28
  21. wayfinder_paths/{vaults/adapters → adapters}/pool_adapter/README.md +2 -14
  22. wayfinder_paths/{vaults/adapters → adapters}/pool_adapter/adapter.py +12 -19
  23. wayfinder_paths/{vaults/adapters → adapters}/pool_adapter/manifest.yaml +1 -1
  24. wayfinder_paths/{vaults/adapters → adapters}/pool_adapter/test_adapter.py +2 -2
  25. wayfinder_paths/{vaults/adapters → adapters}/token_adapter/README.md +1 -1
  26. wayfinder_paths/{vaults/adapters → adapters}/token_adapter/adapter.py +8 -4
  27. wayfinder_paths/adapters/token_adapter/examples.json +26 -0
  28. wayfinder_paths/{vaults/adapters → adapters}/token_adapter/manifest.yaml +1 -1
  29. wayfinder_paths/{vaults/adapters → adapters}/token_adapter/test_adapter.py +1 -1
  30. wayfinder_paths/config.example.json +3 -1
  31. wayfinder_paths/core/__init__.py +3 -3
  32. wayfinder_paths/core/adapters/BaseAdapter.py +20 -3
  33. wayfinder_paths/core/adapters/models.py +41 -0
  34. wayfinder_paths/core/clients/BRAPClient.py +21 -2
  35. wayfinder_paths/core/clients/ClientManager.py +42 -63
  36. wayfinder_paths/core/clients/HyperlendClient.py +46 -5
  37. wayfinder_paths/core/clients/LedgerClient.py +350 -124
  38. wayfinder_paths/core/clients/PoolClient.py +51 -19
  39. wayfinder_paths/core/clients/SimulationClient.py +16 -4
  40. wayfinder_paths/core/clients/TokenClient.py +34 -18
  41. wayfinder_paths/core/clients/TransactionClient.py +18 -2
  42. wayfinder_paths/core/clients/WalletClient.py +35 -4
  43. wayfinder_paths/core/clients/WayfinderClient.py +16 -5
  44. wayfinder_paths/core/clients/protocols.py +69 -62
  45. wayfinder_paths/core/clients/sdk_example.py +0 -5
  46. wayfinder_paths/core/config.py +192 -103
  47. wayfinder_paths/core/constants/base.py +17 -0
  48. wayfinder_paths/core/engine/{VaultJob.py → StrategyJob.py} +25 -19
  49. wayfinder_paths/core/engine/__init__.py +2 -2
  50. wayfinder_paths/core/engine/manifest.py +1 -1
  51. wayfinder_paths/core/services/base.py +6 -4
  52. wayfinder_paths/core/services/local_evm_txn.py +3 -2
  53. wayfinder_paths/core/settings.py +2 -2
  54. wayfinder_paths/core/strategies/Strategy.py +123 -37
  55. wayfinder_paths/core/utils/evm_helpers.py +12 -10
  56. wayfinder_paths/core/wallets/README.md +3 -3
  57. wayfinder_paths/core/wallets/WalletManager.py +3 -3
  58. wayfinder_paths/{vaults/policies → policies}/enso.py +1 -1
  59. wayfinder_paths/{vaults/policies → policies}/hyper_evm.py +2 -2
  60. wayfinder_paths/{vaults/policies → policies}/hyperlend.py +1 -1
  61. wayfinder_paths/{vaults/policies → policies}/moonwell.py +1 -1
  62. wayfinder_paths/{vaults/policies → policies}/prjx.py +1 -1
  63. wayfinder_paths/run_strategy.py +29 -27
  64. wayfinder_paths/scripts/create_strategy.py +3 -3
  65. wayfinder_paths/scripts/make_wallets.py +6 -6
  66. wayfinder_paths/scripts/validate_manifests.py +2 -2
  67. wayfinder_paths/{vaults/strategies → strategies}/hyperlend_stable_yield_strategy/README.md +10 -9
  68. wayfinder_paths/{vaults/strategies → strategies}/hyperlend_stable_yield_strategy/manifest.yaml +1 -1
  69. wayfinder_paths/{vaults/strategies → strategies}/hyperlend_stable_yield_strategy/strategy.py +47 -167
  70. wayfinder_paths/{vaults/strategies → strategies}/hyperlend_stable_yield_strategy/test_strategy.py +10 -8
  71. wayfinder_paths/{vaults/strategies → strategies}/stablecoin_yield_strategy/README.md +15 -14
  72. wayfinder_paths/{vaults/strategies → strategies}/stablecoin_yield_strategy/manifest.yaml +2 -2
  73. wayfinder_paths/{vaults/strategies → strategies}/stablecoin_yield_strategy/strategy.py +97 -97
  74. wayfinder_paths/{vaults/strategies → strategies}/stablecoin_yield_strategy/test_strategy.py +8 -8
  75. wayfinder_paths/{vaults/templates → templates}/adapter/README.md +5 -5
  76. wayfinder_paths/{vaults/templates → templates}/adapter/manifest.yaml +1 -1
  77. wayfinder_paths/{vaults/templates → templates}/adapter/test_adapter.py +1 -1
  78. wayfinder_paths/{vaults/templates → templates}/strategy/README.md +10 -9
  79. wayfinder_paths/{vaults/templates → templates}/strategy/manifest.yaml +1 -1
  80. wayfinder_paths/{vaults/templates → templates}/strategy/test_strategy.py +8 -8
  81. wayfinder_paths/tests/test_test_coverage.py +5 -5
  82. {wayfinder_paths-0.1.3.dist-info → wayfinder_paths-0.1.5.dist-info}/METADATA +146 -69
  83. wayfinder_paths-0.1.5.dist-info/RECORD +126 -0
  84. wayfinder_paths/vaults/adapters/hyperlend_adapter/__init__.py +0 -7
  85. wayfinder_paths/vaults/adapters/ledger_adapter/manifest.yaml +0 -11
  86. wayfinder_paths/vaults/adapters/token_adapter/examples.json +0 -26
  87. wayfinder_paths/vaults/strategies/__init__.py +0 -0
  88. wayfinder_paths-0.1.3.dist-info/RECORD +0 -126
  89. /wayfinder_paths/{vaults → adapters}/__init__.py +0 -0
  90. /wayfinder_paths/{vaults/adapters → adapters}/brap_adapter/__init__.py +0 -0
  91. /wayfinder_paths/{vaults/adapters → adapters}/brap_adapter/examples.json +0 -0
  92. /wayfinder_paths/{vaults/adapters → adapters}/ledger_adapter/__init__.py +0 -0
  93. /wayfinder_paths/{vaults/adapters → adapters}/pool_adapter/__init__.py +0 -0
  94. /wayfinder_paths/{vaults/adapters → adapters}/pool_adapter/examples.json +0 -0
  95. /wayfinder_paths/{vaults/adapters → adapters}/token_adapter/__init__.py +0 -0
  96. /wayfinder_paths/{vaults/policies → policies}/erc20.py +0 -0
  97. /wayfinder_paths/{vaults/policies → policies}/evm.py +0 -0
  98. /wayfinder_paths/{vaults/policies → policies}/hyperliquid.py +0 -0
  99. /wayfinder_paths/{vaults/policies → policies}/util.py +0 -0
  100. /wayfinder_paths/{vaults/adapters → strategies}/__init__.py +0 -0
  101. /wayfinder_paths/{vaults/strategies → strategies}/config.py +0 -0
  102. /wayfinder_paths/{vaults/strategies → strategies}/hyperlend_stable_yield_strategy/examples.json +0 -0
  103. /wayfinder_paths/{vaults/strategies → strategies}/stablecoin_yield_strategy/examples.json +0 -0
  104. /wayfinder_paths/{vaults/templates → templates}/adapter/adapter.py +0 -0
  105. /wayfinder_paths/{vaults/templates → templates}/adapter/examples.json +0 -0
  106. /wayfinder_paths/{vaults/templates → templates}/strategy/examples.json +0 -0
  107. /wayfinder_paths/{vaults/templates → templates}/strategy/strategy.py +0 -0
  108. {wayfinder_paths-0.1.3.dist-info → wayfinder_paths-0.1.5.dist-info}/LICENSE +0 -0
  109. {wayfinder_paths-0.1.3.dist-info → wayfinder_paths-0.1.5.dist-info}/WHEEL +0 -0
@@ -5,8 +5,15 @@ from typing import Any
5
5
  from eth_utils import to_checksum_address
6
6
 
7
7
  from wayfinder_paths.core.adapters.BaseAdapter import BaseAdapter
8
- from wayfinder_paths.core.clients.HyperlendClient import HyperlendClient
8
+ from wayfinder_paths.core.clients.HyperlendClient import (
9
+ AssetsView,
10
+ HyperlendClient,
11
+ LendRateHistory,
12
+ MarketEntry,
13
+ StableMarket,
14
+ )
9
15
  from wayfinder_paths.core.clients.SimulationClient import SimulationClient
16
+ from wayfinder_paths.core.constants.base import DEFAULT_TRANSACTION_TIMEOUT
10
17
  from wayfinder_paths.core.constants.hyperlend_abi import (
11
18
  POOL_ABI,
12
19
  WRAPPED_TOKEN_GATEWAY_ABI,
@@ -43,7 +50,7 @@ class HyperlendAdapter(BaseAdapter):
43
50
  self.web3 = web3_service
44
51
  self.token_txn_service = web3_service.token_transactions
45
52
 
46
- self.vault_wallet = cfg.get("vault_wallet") or {}
53
+ self.strategy_wallet = cfg.get("strategy_wallet") or {}
47
54
  self.pool_address = self._checksum(
48
55
  adapter_cfg.get("pool_address") or HYPERLEND_DEFAULTS["pool"]
49
56
  )
@@ -70,7 +77,7 @@ class HyperlendAdapter(BaseAdapter):
70
77
  buffer_bps: int | None = None,
71
78
  min_buffer_tokens: float | None = None,
72
79
  is_stable_symbol: bool | None = None,
73
- ) -> tuple[bool, Any]:
80
+ ) -> tuple[bool, list[StableMarket] | str]:
74
81
  try:
75
82
  data = await self.hyperlend_client.get_stable_markets(
76
83
  chain_id=chain_id,
@@ -85,7 +92,7 @@ class HyperlendAdapter(BaseAdapter):
85
92
 
86
93
  async def get_assets_view(
87
94
  self, chain_id: int, user_address: str
88
- ) -> tuple[bool, Any]:
95
+ ) -> tuple[bool, AssetsView | str]:
89
96
  try:
90
97
  data = await self.hyperlend_client.get_assets_view(
91
98
  chain_id=chain_id, user_address=user_address
@@ -96,7 +103,7 @@ class HyperlendAdapter(BaseAdapter):
96
103
 
97
104
  async def get_market_entry(
98
105
  self, chain_id: int, underlying: str
99
- ) -> tuple[bool, Any]:
106
+ ) -> tuple[bool, MarketEntry | str]:
100
107
  try:
101
108
  data = await self.hyperlend_client.get_market_entry(chain_id, underlying)
102
109
  return True, data
@@ -108,7 +115,7 @@ class HyperlendAdapter(BaseAdapter):
108
115
  chain_id: int,
109
116
  token_address: str,
110
117
  lookback_hours: int,
111
- ) -> tuple[bool, Any]:
118
+ ) -> tuple[bool, LendRateHistory | str]:
112
119
  try:
113
120
  data = await self.hyperlend_client.get_lend_rate_history(
114
121
  chain_id=chain_id,
@@ -127,7 +134,7 @@ class HyperlendAdapter(BaseAdapter):
127
134
  chain_id: int,
128
135
  native: bool = False,
129
136
  ) -> tuple[bool, Any]:
130
- vault = self._vault_address()
137
+ strategy = self._strategy_address()
131
138
  qty = int(qty)
132
139
  if qty <= 0:
133
140
  return False, "qty must be positive"
@@ -138,8 +145,8 @@ class HyperlendAdapter(BaseAdapter):
138
145
  target=self.gateway_address,
139
146
  abi=WRAPPED_TOKEN_GATEWAY_ABI,
140
147
  fn_name="depositETH",
141
- args=[self._gateway_first_arg(underlying_token), vault, 0],
142
- from_address=vault,
148
+ args=[self._gateway_first_arg(underlying_token), strategy, 0],
149
+ from_address=strategy,
143
150
  chain_id=chain_id,
144
151
  value=qty,
145
152
  )
@@ -147,7 +154,7 @@ class HyperlendAdapter(BaseAdapter):
147
154
  token_addr = self._checksum(underlying_token)
148
155
  approved = await self._ensure_allowance(
149
156
  token_address=token_addr,
150
- owner=vault,
157
+ owner=strategy,
151
158
  spender=self.pool_address,
152
159
  amount=qty,
153
160
  chain_id=chain_id,
@@ -158,8 +165,8 @@ class HyperlendAdapter(BaseAdapter):
158
165
  target=self.pool_address,
159
166
  abi=POOL_ABI,
160
167
  fn_name="supply",
161
- args=[token_addr, qty, vault, 0],
162
- from_address=vault,
168
+ args=[token_addr, qty, strategy, 0],
169
+ from_address=strategy,
163
170
  chain_id=chain_id,
164
171
  )
165
172
  return await self._execute(tx)
@@ -172,7 +179,7 @@ class HyperlendAdapter(BaseAdapter):
172
179
  chain_id: int,
173
180
  native: bool = False,
174
181
  ) -> tuple[bool, Any]:
175
- vault = self._vault_address()
182
+ strategy = self._strategy_address()
176
183
  qty = int(qty)
177
184
  if qty <= 0:
178
185
  return False, "qty must be positive"
@@ -183,8 +190,8 @@ class HyperlendAdapter(BaseAdapter):
183
190
  target=self.gateway_address,
184
191
  abi=WRAPPED_TOKEN_GATEWAY_ABI,
185
192
  fn_name="withdrawETH",
186
- args=[self._gateway_first_arg(underlying_token), qty, vault],
187
- from_address=vault,
193
+ args=[self._gateway_first_arg(underlying_token), qty, strategy],
194
+ from_address=strategy,
188
195
  chain_id=chain_id,
189
196
  )
190
197
  else:
@@ -193,8 +200,8 @@ class HyperlendAdapter(BaseAdapter):
193
200
  target=self.pool_address,
194
201
  abi=POOL_ABI,
195
202
  fn_name="withdraw",
196
- args=[token_addr, qty, vault],
197
- from_address=vault,
203
+ args=[token_addr, qty, strategy],
204
+ from_address=strategy,
198
205
  chain_id=chain_id,
199
206
  )
200
207
  return await self._execute(tx)
@@ -233,14 +240,14 @@ class HyperlendAdapter(BaseAdapter):
233
240
  if self.simulation:
234
241
  return True, {"simulation": tx}
235
242
  return await self.web3.broadcast_transaction(
236
- tx, wait_for_receipt=True, timeout=120
243
+ tx, wait_for_receipt=True, timeout=DEFAULT_TRANSACTION_TIMEOUT
237
244
  )
238
245
 
239
246
  async def _broadcast_transaction(self, tx: dict[str, Any]) -> tuple[bool, Any]:
240
247
  if getattr(settings, "DRY_RUN", False):
241
248
  return True, {"dry_run": True, "transaction": tx}
242
249
  return await self.web3.evm_transactions.broadcast_transaction(
243
- tx, wait_for_receipt=True, timeout=120
250
+ tx, wait_for_receipt=True, timeout=DEFAULT_TRANSACTION_TIMEOUT
244
251
  )
245
252
 
246
253
  def _encode_call(
@@ -273,17 +280,17 @@ class HyperlendAdapter(BaseAdapter):
273
280
  }
274
281
  return tx
275
282
 
276
- def _vault_address(self) -> str:
283
+ def _strategy_address(self) -> str:
277
284
  addr = None
278
- if isinstance(self.vault_wallet, dict):
279
- addr = self.vault_wallet.get("address") or (
280
- (self.vault_wallet.get("evm") or {}).get("address")
285
+ if isinstance(self.strategy_wallet, dict):
286
+ addr = self.strategy_wallet.get("address") or (
287
+ (self.strategy_wallet.get("evm") or {}).get("address")
281
288
  )
282
- elif isinstance(self.vault_wallet, str):
283
- addr = self.vault_wallet
289
+ elif isinstance(self.strategy_wallet, str):
290
+ addr = self.strategy_wallet
284
291
  if not addr:
285
292
  raise ValueError(
286
- "vault_wallet address is required for HyperLend operations"
293
+ "strategy_wallet address is required for HyperLend operations"
287
294
  )
288
295
  return to_checksum_address(addr)
289
296
 
@@ -1,5 +1,5 @@
1
1
  schema_version: "0.1"
2
- entrypoint: "vaults.adapters.hyperlend_adapter.adapter.HyperlendAdapter"
2
+ entrypoint: "adapters.hyperlend_adapter.adapter.HyperlendAdapter"
3
3
  capabilities:
4
4
  - "hyperlend.stable_markets.read"
5
5
  - "hyperlend.markets.query"
@@ -2,7 +2,7 @@ from unittest.mock import AsyncMock, patch
2
2
 
3
3
  import pytest
4
4
 
5
- from wayfinder_paths.vaults.adapters.hyperlend_adapter.adapter import HyperlendAdapter
5
+ from wayfinder_paths.adapters.hyperlend_adapter.adapter import HyperlendAdapter
6
6
 
7
7
 
8
8
  class TestHyperlendAdapter:
@@ -18,7 +18,7 @@ class TestHyperlendAdapter:
18
18
  def adapter(self, mock_hyperlend_client):
19
19
  """Create a HyperlendAdapter instance with mocked client for testing"""
20
20
  with patch(
21
- "wayfinder_paths.vaults.adapters.hyperlend_adapter.adapter.HyperlendClient",
21
+ "wayfinder_paths.adapters.hyperlend_adapter.adapter.HyperlendClient",
22
22
  return_value=mock_hyperlend_client,
23
23
  ):
24
24
  return HyperlendAdapter()
@@ -1,15 +1,15 @@
1
1
  # Ledger Adapter
2
2
 
3
- A Wayfinder adapter that provides high-level operations for vault transaction history and bookkeeping. This adapter wraps the `LedgerClient` to offer strategy-friendly methods for recording and retrieving vault operations.
3
+ A Wayfinder adapter that provides high-level operations for strategy transaction history and bookkeeping. This adapter wraps the `LedgerClient` to offer strategy-friendly methods for recording and retrieving strategy operations.
4
4
 
5
5
  ## Capabilities
6
6
 
7
- - `ledger.read`: Read vault transaction data and net deposits
7
+ - `ledger.read`: Read strategy transaction data and net deposits
8
8
  - `ledger.write`: Record deposits, withdrawals, and operations
9
- - `vault.transactions`: Access vault transaction history
10
- - `vault.deposits`: Record deposit transactions
11
- - `vault.withdrawals`: Record withdrawal transactions
12
- - `vault.operations`: Record vault operations (swaps, rebalances, etc.)
9
+ - `strategy.transactions`: Access strategy transaction history
10
+ - `strategy.deposits`: Record deposit transactions
11
+ - `strategy.withdrawals`: Record withdrawal transactions
12
+ - `strategy.operations`: Record strategy operations (swaps, rebalances, etc.)
13
13
 
14
14
  ## Configuration
15
15
 
@@ -25,16 +25,16 @@ The LedgerClient will automatically:
25
25
  ### Initialize the Adapter
26
26
 
27
27
  ```python
28
- from wayfinder_paths.vaults.adapters.ledger_adapter.adapter import LedgerAdapter
28
+ from wayfinder_paths.adapters.ledger_adapter.adapter import LedgerAdapter
29
29
 
30
30
  # No configuration needed - uses LedgerClient with automatic settings
31
31
  adapter = LedgerAdapter()
32
32
  ```
33
33
 
34
- ### Get Vault Transaction History
34
+ ### Get Strategy Transaction History
35
35
 
36
36
  ```python
37
- success, data = await adapter.get_vault_transactions(
37
+ success, data = await adapter.get_strategy_transactions(
38
38
  wallet_address="0x1234567890123456789012345678901234567890",
39
39
  limit=10,
40
40
  offset=0
@@ -49,7 +49,7 @@ else:
49
49
  ### Get Net Deposit Amount
50
50
 
51
51
  ```python
52
- success, data = await adapter.get_vault_net_deposit(
52
+ success, data = await adapter.get_strategy_net_deposit(
53
53
  wallet_address="0x1234567890123456789012345678901234567890"
54
54
  )
55
55
  if success:
@@ -93,51 +93,38 @@ else:
93
93
  print(f"Error: {data}")
94
94
  ```
95
95
 
96
- ### Record an Operation or Cashflow
96
+ ### Record an Operation
97
97
 
98
98
  ```python
99
+ from wayfinder_paths.adapters.ledger_adapter.models import SWAP
100
+
101
+ operation = SWAP(
102
+ from_token_id="0xA0b86...",
103
+ to_token_id="0xB1c97...",
104
+ from_amount="1000000000000000000",
105
+ to_amount="995000000000000000",
106
+ from_amount_usd=1000.0,
107
+ to_amount_usd=995.0,
108
+ )
109
+
99
110
  success, op = await adapter.record_operation(
100
- wallet_address=vault_address,
101
- operation_data={
102
- "type": "SWAP",
103
- "from_token": "...",
104
- "to_token": "...",
105
- "amount_in": "1000000000000000000",
106
- "amount_out": "995000000000000000",
107
- },
111
+ wallet_address=strategy_address,
112
+ operation_data=operation,
108
113
  usd_value="1000.00",
109
114
  strategy_name="StablecoinYieldStrategy",
110
115
  )
111
116
 
112
- success, cashflow = await adapter.record_cashflow(
113
- wallet_address=vault_address,
114
- block_timestamp=int(time.time()),
115
- token_addr="0x...",
116
- amount="250000000000000000",
117
- description="reward",
118
- strategy_name="StablecoinYieldStrategy",
119
- )
120
117
  ```
121
118
 
122
119
  ### Latest Transactions and Summaries
123
120
 
124
121
  ```python
125
- success, latest = await adapter.get_vault_latest_transactions(wallet_address=vault_address)
126
- success, summary = await adapter.get_transaction_summary(wallet_address=vault_address, limit=5)
122
+ success, latest = await adapter.get_strategy_latest_transactions(wallet_address=strategy_address)
123
+ success, summary = await adapter.get_transaction_summary(wallet_address=strategy_address, limit=5)
127
124
  if success:
128
125
  print(f"Total transactions: {summary.get('total_transactions')}")
129
126
  ```
130
127
 
131
- ## API Endpoints
132
-
133
- The adapter uses the following Wayfinder API endpoints:
134
-
135
- - `GET /api/v1/public/vaults/transactions/` - Get vault transactions
136
- - `GET /api/v1/public/vaults/net-deposit/` - Get net deposit amount
137
- - `POST /api/v1/public/vaults/deposits/` - Record a deposit
138
- - `POST /api/v1/public/vaults/withdrawals/` - Record a withdrawal
139
- - `POST /api/v1/public/vaults/operations/` - Record an operation
140
-
141
128
  ## Error Handling
142
129
 
143
130
  All methods return a tuple of `(success: bool, data: Any)` where:
@@ -149,7 +136,7 @@ All methods return a tuple of `(success: bool, data: Any)` where:
149
136
  Run the adapter tests:
150
137
 
151
138
  ```bash
152
- pytest wayfinder_paths/vaults/adapters/ledger_adapter/test_adapter.py -v
139
+ pytest wayfinder_paths/adapters/ledger_adapter/test_adapter.py -v
153
140
  ```
154
141
 
155
142
  ## Dependencies
@@ -1,18 +1,25 @@
1
1
  from typing import Any
2
2
 
3
3
  from wayfinder_paths.core.adapters.BaseAdapter import BaseAdapter
4
- from wayfinder_paths.core.clients.LedgerClient import LedgerClient
4
+ from wayfinder_paths.core.adapters.models import Operation
5
+ from wayfinder_paths.core.clients.LedgerClient import (
6
+ LedgerClient,
7
+ NetDeposit,
8
+ StrategyTransactionList,
9
+ TransactionRecord,
10
+ )
11
+ from wayfinder_paths.core.strategies.Strategy import StatusDict
5
12
 
6
13
 
7
14
  class LedgerAdapter(BaseAdapter):
8
15
  """
9
- Ledger adapter for vault transaction history and bookkeeping operations.
16
+ Ledger adapter for strategy transaction history and bookkeeping operations.
10
17
 
11
18
  Provides high-level operations for:
12
- - Fetching vault transaction history
19
+ - Fetching strategy transaction history
13
20
  - Getting net deposit amounts
14
21
  - Getting last rotation time
15
- - Recording deposits, withdrawals, operations, and cashflows
22
+ - Recording deposits, withdrawals, and operations
16
23
  """
17
24
 
18
25
  adapter_type: str = "LEDGER"
@@ -25,14 +32,14 @@ class LedgerAdapter(BaseAdapter):
25
32
  super().__init__("ledger_adapter", config)
26
33
  self.ledger_client = ledger_client or LedgerClient()
27
34
 
28
- async def get_vault_transactions(
35
+ async def get_strategy_transactions(
29
36
  self, wallet_address: str, limit: int = 50, offset: int = 0
30
- ) -> tuple[bool, Any]:
37
+ ) -> tuple[bool, StrategyTransactionList | str]:
31
38
  """
32
- Get paginated vault transaction history.
39
+ Get paginated strategy transaction history.
33
40
 
34
41
  Args:
35
- wallet_address: Vault wallet address
42
+ wallet_address: Strategy wallet address
36
43
  limit: Maximum number of transactions to return
37
44
  offset: Number of transactions to skip
38
45
 
@@ -40,52 +47,54 @@ class LedgerAdapter(BaseAdapter):
40
47
  Tuple of (success, data) where data is transaction list or error message
41
48
  """
42
49
  try:
43
- data = await self.ledger_client.get_vault_transactions(
50
+ data = await self.ledger_client.get_strategy_transactions(
44
51
  wallet_address=wallet_address, limit=limit, offset=offset
45
52
  )
46
53
  return (True, data)
47
54
  except Exception as e:
48
- self.logger.error(f"Error fetching vault transactions: {e}")
55
+ self.logger.error(f"Error fetching strategy transactions: {e}")
49
56
  return (False, str(e))
50
57
 
51
- async def get_vault_net_deposit(self, wallet_address: str) -> tuple[bool, Any]:
58
+ async def get_strategy_net_deposit(
59
+ self, wallet_address: str
60
+ ) -> tuple[bool, NetDeposit | str]:
52
61
  """
53
- Get net deposit amount (deposits - withdrawals) for a vault.
62
+ Get net deposit amount (deposits - withdrawals) for a strategy.
54
63
 
55
64
  Args:
56
- wallet_address: Vault wallet address
65
+ wallet_address: Strategy wallet address
57
66
 
58
67
  Returns:
59
68
  Tuple of (success, data) where data contains net_deposit or error message
60
69
  """
61
70
  try:
62
- data = await self.ledger_client.get_vault_net_deposit(
71
+ data = await self.ledger_client.get_strategy_net_deposit(
63
72
  wallet_address=wallet_address
64
73
  )
65
74
  return (True, data)
66
75
  except Exception as e:
67
- self.logger.error(f"Error fetching vault net deposit: {e}")
76
+ self.logger.error(f"Error fetching strategy net deposit: {e}")
68
77
  return (False, str(e))
69
78
 
70
- async def get_vault_latest_transactions(
79
+ async def get_strategy_latest_transactions(
71
80
  self, wallet_address: str
72
- ) -> tuple[bool, Any]:
81
+ ) -> tuple[bool, StrategyTransactionList | str]:
73
82
  """
74
- Get the latest transactions for a vault.
83
+ Get the latest transactions for a strategy.
75
84
 
76
85
  Args:
77
- wallet_address: Vault wallet address
86
+ wallet_address: Strategy wallet address
78
87
 
79
88
  Returns:
80
89
  Tuple of (success, data) where data contains latest transactions or error message
81
90
  """
82
91
  try:
83
- data = await self.ledger_client.get_vault_latest_transactions(
92
+ data = await self.ledger_client.get_strategy_latest_transactions(
84
93
  wallet_address=wallet_address
85
94
  )
86
95
  return (True, data)
87
96
  except Exception as e:
88
- self.logger.error(f"Error fetching vault last transactions: {e}")
97
+ self.logger.error(f"Error fetching strategy last transactions: {e}")
89
98
  return (False, str(e))
90
99
 
91
100
  async def record_deposit(
@@ -97,12 +106,12 @@ class LedgerAdapter(BaseAdapter):
97
106
  usd_value: str | float,
98
107
  data: dict[str, Any] | None = None,
99
108
  strategy_name: str | None = None,
100
- ) -> tuple[bool, Any]:
109
+ ) -> tuple[bool, TransactionRecord | str]:
101
110
  """
102
- Record a vault deposit transaction.
111
+ Record a strategy deposit transaction.
103
112
 
104
113
  Args:
105
- wallet_address: Vault wallet address
114
+ wallet_address: Strategy wallet address
106
115
  chain_id: Blockchain chain ID
107
116
  token_address: Token contract address
108
117
  token_amount: Amount deposited (in token units)
@@ -114,7 +123,7 @@ class LedgerAdapter(BaseAdapter):
114
123
  Tuple of (success, data) where data is transaction record or error message
115
124
  """
116
125
  try:
117
- result = await self.ledger_client.add_vault_deposit(
126
+ result = await self.ledger_client.add_strategy_deposit(
118
127
  wallet_address=wallet_address,
119
128
  chain_id=chain_id,
120
129
  token_address=token_address,
@@ -137,12 +146,12 @@ class LedgerAdapter(BaseAdapter):
137
146
  usd_value: str | float,
138
147
  data: dict[str, Any] | None = None,
139
148
  strategy_name: str | None = None,
140
- ) -> tuple[bool, Any]:
149
+ ) -> tuple[bool, TransactionRecord | str]:
141
150
  """
142
- Record a vault withdrawal transaction.
151
+ Record a strategy withdrawal transaction.
143
152
 
144
153
  Args:
145
- wallet_address: Vault wallet address
154
+ wallet_address: Strategy wallet address
146
155
  chain_id: Blockchain chain ID
147
156
  token_address: Token contract address
148
157
  token_amount: Amount withdrawn (in token units)
@@ -154,7 +163,7 @@ class LedgerAdapter(BaseAdapter):
154
163
  Tuple of (success, data) where data is transaction record or error message
155
164
  """
156
165
  try:
157
- result = await self.ledger_client.add_vault_withdraw(
166
+ result = await self.ledger_client.add_strategy_withdraw(
158
167
  wallet_address=wallet_address,
159
168
  chain_id=chain_id,
160
169
  token_address=token_address,
@@ -171,16 +180,16 @@ class LedgerAdapter(BaseAdapter):
171
180
  async def record_operation(
172
181
  self,
173
182
  wallet_address: str,
174
- operation_data: dict[str, Any],
183
+ operation_data: Operation,
175
184
  usd_value: str | float,
176
185
  strategy_name: str | None = None,
177
- ) -> tuple[bool, Any]:
186
+ ) -> tuple[bool, TransactionRecord | str]:
178
187
  """
179
- Record a vault operation (e.g., swaps, rebalances) for bookkeeping.
188
+ Record a strategy operation (e.g., swaps, rebalances) for bookkeeping.
180
189
 
181
190
  Args:
182
- wallet_address: Vault wallet address
183
- operation_data: Details of the operation performed
191
+ wallet_address: Strategy wallet address
192
+ operation_data: Operation model (SWAP, LEND, BORROW, etc.)
184
193
  usd_value: USD value of the operation
185
194
  strategy_name: Name of the strategy performing the operation
186
195
 
@@ -188,7 +197,7 @@ class LedgerAdapter(BaseAdapter):
188
197
  Tuple of (success, data) where data is operation record or error message
189
198
  """
190
199
  try:
191
- result = await self.ledger_client.add_vault_operation(
200
+ result = await self.ledger_client.add_strategy_operation(
192
201
  wallet_address=wallet_address,
193
202
  operation_data=operation_data,
194
203
  usd_value=usd_value,
@@ -199,58 +208,21 @@ class LedgerAdapter(BaseAdapter):
199
208
  self.logger.error(f"Error recording operation: {e}")
200
209
  return (False, str(e))
201
210
 
202
- async def record_cashflow(
203
- self,
204
- wallet_address: str,
205
- block_timestamp: int,
206
- token_addr: str,
207
- amount: str | int | float,
208
- description: str,
209
- strategy_name: str | None = None,
210
- ) -> tuple[bool, Any]:
211
- """
212
- Record a vault cashflow (interest, funding, reward, or fee).
213
-
214
- Args:
215
- wallet_address: Vault wallet address
216
- block_timestamp: Block timestamp (Unix timestamp)
217
- token_addr: Token contract address
218
- amount: Cashflow amount (in token units)
219
- description: Cashflow type - must be one of: "interest", "funding", "reward", "fee"
220
- strategy_name: Optional strategy name
221
-
222
- Returns:
223
- Tuple of (success, data) where data is cashflow record or error message
224
- """
225
- try:
226
- result = await self.ledger_client.add_vault_cashflow(
227
- wallet_address=wallet_address,
228
- block_timestamp=block_timestamp,
229
- token_addr=token_addr,
230
- amount=amount,
231
- description=description,
232
- strategy_name=strategy_name,
233
- )
234
- return (True, result)
235
- except Exception as e:
236
- self.logger.error(f"Error recording cashflow: {e}")
237
- return (False, str(e))
238
-
239
211
  async def get_transaction_summary(
240
212
  self, wallet_address: str, limit: int = 10
241
213
  ) -> tuple[bool, Any]:
242
214
  """
243
- Get a summary of recent vault transactions.
215
+ Get a summary of recent strategy transactions.
244
216
 
245
217
  Args:
246
- wallet_address: Vault wallet address
218
+ wallet_address: Strategy wallet address
247
219
  limit: Number of recent transactions to include
248
220
 
249
221
  Returns:
250
222
  Tuple of (success, data) where data is transaction summary or error message
251
223
  """
252
224
  try:
253
- success, transactions_data = await self.get_vault_transactions(
225
+ success, transactions_data = await self.get_strategy_transactions(
254
226
  wallet_address=wallet_address, limit=limit
255
227
  )
256
228
 
@@ -284,3 +256,34 @@ class LedgerAdapter(BaseAdapter):
284
256
  except Exception as e:
285
257
  self.logger.error(f"Error creating transaction summary: {e}")
286
258
  return (False, str(e))
259
+
260
+ async def record_strategy_snapshot(
261
+ self, wallet_address: str, strategy_status: StatusDict
262
+ ) -> tuple[bool, None | str]:
263
+ """
264
+ Record a strategy snapshot with current state.
265
+
266
+ Args:
267
+ wallet_address: Strategy wallet address
268
+ strat_portfolio_value: Current portfolio value
269
+ net_deposit: Net deposit amount
270
+ strategy_status: Current strategy status dictionary
271
+ gas_available: Available gas amount
272
+ gassed_up: Whether the strategy is gassed up
273
+
274
+ Returns:
275
+ Tuple of (success, None) on success or (False, error_message) on failure
276
+ """
277
+ try:
278
+ await self.ledger_client.strategy_snapshot(
279
+ wallet_address=wallet_address,
280
+ strat_portfolio_value=strategy_status["portfolio_value"],
281
+ net_deposit=strategy_status["net_deposit"],
282
+ strategy_status=strategy_status["strategy_status"],
283
+ gas_available=strategy_status["gas_available"],
284
+ gassed_up=strategy_status["gassed_up"],
285
+ )
286
+ return (True, None)
287
+ except Exception as e:
288
+ self.logger.error(f"Error recording strategy snapshot: {e}")
289
+ return (False, str(e))
@@ -80,14 +80,20 @@
80
80
  },
81
81
  "record_operation": {
82
82
  "description": "Record a vault operation (swap, rebalance, etc.)",
83
+ "note": "operation_data must be a Pydantic Operation model (currently only SWAP is implemented)",
83
84
  "input": {
84
85
  "wallet_address": "0x1234567890123456789012345678901234567890",
85
86
  "operation_data": {
86
87
  "type": "SWAP",
87
- "from_token": "0xA0b86a33E6441c8C06DdD4D4c4c4c4c4c4c4c4c4c",
88
- "to_token": "0xB1c97a44F7552d9Dd5e5e5e5e5e5e5e5e5e5e5e5e5e",
89
- "amount_in": "1000000000000000000",
90
- "amount_out": "995000000000000000"
88
+ "from_token_id": "0xA0b86a33E6441c8C06DdD4D4c4c4c4c4c4c4c4c4c",
89
+ "to_token_id": "0xB1c97a44F7552d9Dd5e5e5e5e5e5e5e5e5e5e5e5e5e",
90
+ "from_amount": "1000000000000000000",
91
+ "to_amount": "995000000000000000",
92
+ "from_amount_usd": 1000.0,
93
+ "to_amount_usd": 995.0,
94
+ "transaction_hash": "0xabcdef...",
95
+ "transaction_status": "success",
96
+ "transaction_receipt": null
91
97
  },
92
98
  "usd_value": "1000.00",
93
99
  "strategy_name": "StablecoinYieldStrategy"
@@ -0,0 +1,11 @@
1
+ schema_version: "0.1"
2
+ entrypoint: "adapters.ledger_adapter.adapter.LedgerAdapter"
3
+ capabilities:
4
+ - "ledger.read"
5
+ - "ledger.write"
6
+ - "strategy.transactions"
7
+ - "strategy.deposits"
8
+ - "strategy.withdrawals"
9
+ - "strategy.operations"
10
+ dependencies:
11
+ - "LedgerClient"