wayfinder-paths 0.1.22__py3-none-any.whl → 0.1.23__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 (63) hide show
  1. wayfinder_paths/__init__.py +0 -4
  2. wayfinder_paths/adapters/balance_adapter/README.md +0 -1
  3. wayfinder_paths/adapters/balance_adapter/adapter.py +65 -169
  4. wayfinder_paths/adapters/balance_adapter/test_adapter.py +41 -113
  5. wayfinder_paths/adapters/brap_adapter/README.md +22 -75
  6. wayfinder_paths/adapters/brap_adapter/adapter.py +187 -576
  7. wayfinder_paths/adapters/brap_adapter/examples.json +21 -140
  8. wayfinder_paths/adapters/brap_adapter/test_adapter.py +6 -234
  9. wayfinder_paths/adapters/hyperlend_adapter/adapter.py +39 -86
  10. wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py +5 -1
  11. wayfinder_paths/adapters/hyperliquid_adapter/adapter.py +6 -5
  12. wayfinder_paths/adapters/ledger_adapter/README.md +4 -1
  13. wayfinder_paths/adapters/ledger_adapter/adapter.py +3 -3
  14. wayfinder_paths/adapters/moonwell_adapter/adapter.py +108 -198
  15. wayfinder_paths/adapters/moonwell_adapter/test_adapter.py +37 -23
  16. wayfinder_paths/adapters/token_adapter/adapter.py +14 -0
  17. wayfinder_paths/core/__init__.py +0 -3
  18. wayfinder_paths/core/clients/BRAPClient.py +3 -0
  19. wayfinder_paths/core/clients/ClientManager.py +0 -7
  20. wayfinder_paths/core/clients/LedgerClient.py +196 -172
  21. wayfinder_paths/core/clients/WayfinderClient.py +0 -1
  22. wayfinder_paths/core/clients/__init__.py +0 -5
  23. wayfinder_paths/core/clients/protocols.py +0 -13
  24. wayfinder_paths/core/config.py +0 -164
  25. wayfinder_paths/core/constants/__init__.py +58 -2
  26. wayfinder_paths/core/constants/base.py +8 -22
  27. wayfinder_paths/core/constants/chains.py +36 -0
  28. wayfinder_paths/core/constants/contracts.py +39 -0
  29. wayfinder_paths/core/constants/tokens.py +9 -0
  30. wayfinder_paths/core/strategies/Strategy.py +0 -10
  31. wayfinder_paths/core/utils/evm_helpers.py +5 -15
  32. wayfinder_paths/core/utils/tokens.py +28 -0
  33. wayfinder_paths/core/utils/transaction.py +13 -7
  34. wayfinder_paths/core/utils/web3.py +5 -3
  35. wayfinder_paths/policies/enso.py +1 -2
  36. wayfinder_paths/policies/hyper_evm.py +6 -3
  37. wayfinder_paths/policies/hyperlend.py +1 -2
  38. wayfinder_paths/policies/moonwell.py +12 -7
  39. wayfinder_paths/policies/prjx.py +1 -3
  40. wayfinder_paths/run_strategy.py +97 -300
  41. wayfinder_paths/strategies/basis_trading_strategy/constants.py +3 -1
  42. wayfinder_paths/strategies/basis_trading_strategy/strategy.py +19 -14
  43. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +12 -11
  44. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +20 -33
  45. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py +21 -18
  46. wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +69 -130
  47. wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +32 -42
  48. {wayfinder_paths-0.1.22.dist-info → wayfinder_paths-0.1.23.dist-info}/METADATA +2 -3
  49. {wayfinder_paths-0.1.22.dist-info → wayfinder_paths-0.1.23.dist-info}/RECORD +51 -60
  50. {wayfinder_paths-0.1.22.dist-info → wayfinder_paths-0.1.23.dist-info}/WHEEL +1 -1
  51. wayfinder_paths/core/clients/WalletClient.py +0 -41
  52. wayfinder_paths/core/engine/StrategyJob.py +0 -110
  53. wayfinder_paths/core/services/test_local_evm_txn.py +0 -145
  54. wayfinder_paths/templates/adapter/README.md +0 -150
  55. wayfinder_paths/templates/adapter/adapter.py +0 -16
  56. wayfinder_paths/templates/adapter/examples.json +0 -8
  57. wayfinder_paths/templates/adapter/test_adapter.py +0 -30
  58. wayfinder_paths/templates/strategy/README.md +0 -186
  59. wayfinder_paths/templates/strategy/examples.json +0 -11
  60. wayfinder_paths/templates/strategy/strategy.py +0 -35
  61. wayfinder_paths/templates/strategy/test_strategy.py +0 -166
  62. wayfinder_paths/tests/test_smoke_manifest.py +0 -63
  63. {wayfinder_paths-0.1.22.dist-info → wayfinder_paths-0.1.23.dist-info}/LICENSE +0 -0
@@ -59,20 +59,24 @@ class TestMoonwellAdapter:
59
59
  async def test_lend(self, adapter):
60
60
  mock_tx_hash = {"tx_hash": "0xabc123", "status": "success"}
61
61
  with (
62
- patch.object(
63
- adapter, "_ensure_allowance", new_callable=AsyncMock
62
+ patch(
63
+ "wayfinder_paths.adapters.moonwell_adapter.adapter.ensure_allowance",
64
+ new_callable=AsyncMock,
64
65
  ) as mock_allowance,
65
66
  patch.object(
66
67
  adapter, "_encode_call", new_callable=AsyncMock
67
68
  ) as mock_encode,
68
- patch.object(adapter, "_send_tx", new_callable=AsyncMock) as mock_send,
69
+ patch(
70
+ "wayfinder_paths.adapters.moonwell_adapter.adapter.send_transaction",
71
+ new_callable=AsyncMock,
72
+ ) as mock_send,
69
73
  ):
70
74
  mock_allowance.return_value = (True, {})
71
75
  mock_encode.return_value = {
72
76
  "data": "0x1234",
73
77
  "to": MOONWELL_DEFAULTS["m_usdc"],
74
78
  }
75
- mock_send.return_value = (True, mock_tx_hash)
79
+ mock_send.return_value = mock_tx_hash
76
80
 
77
81
  success, result = await adapter.lend(
78
82
  mtoken=MOONWELL_DEFAULTS["m_usdc"],
@@ -117,9 +121,12 @@ class TestMoonwellAdapter:
117
121
  "wayfinder_paths.adapters.moonwell_adapter.adapter.web3_from_chain_id",
118
122
  mock_web3_ctx,
119
123
  ),
120
- patch.object(adapter, "_send_tx", new_callable=AsyncMock) as mock_send,
124
+ patch(
125
+ "wayfinder_paths.adapters.moonwell_adapter.adapter.send_transaction",
126
+ new_callable=AsyncMock,
127
+ ) as mock_send,
121
128
  ):
122
- mock_send.return_value = (True, mock_tx_hash)
129
+ mock_send.return_value = mock_tx_hash
123
130
  success, result = await adapter.unlend(
124
131
  mtoken=MOONWELL_DEFAULTS["m_usdc"],
125
132
  amount=10**8,
@@ -176,9 +183,12 @@ class TestMoonwellAdapter:
176
183
  "wayfinder_paths.adapters.moonwell_adapter.adapter.web3_from_chain_id",
177
184
  mock_web3_ctx,
178
185
  ),
179
- patch.object(adapter, "_send_tx", new_callable=AsyncMock) as mock_send,
186
+ patch(
187
+ "wayfinder_paths.adapters.moonwell_adapter.adapter.send_transaction",
188
+ new_callable=AsyncMock,
189
+ ) as mock_send,
180
190
  ):
181
- mock_send.return_value = (True, mock_tx_hash)
191
+ mock_send.return_value = mock_tx_hash
182
192
  success, result = await adapter.borrow(
183
193
  mtoken=MOONWELL_DEFAULTS["m_usdc"],
184
194
  amount=10**6,
@@ -191,20 +201,24 @@ class TestMoonwellAdapter:
191
201
  async def test_repay(self, adapter):
192
202
  mock_tx_hash = {"tx_hash": "0xabc123", "status": "success"}
193
203
  with (
194
- patch.object(
195
- adapter, "_ensure_allowance", new_callable=AsyncMock
204
+ patch(
205
+ "wayfinder_paths.adapters.moonwell_adapter.adapter.ensure_allowance",
206
+ new_callable=AsyncMock,
196
207
  ) as mock_allowance,
197
208
  patch.object(
198
209
  adapter, "_encode_call", new_callable=AsyncMock
199
210
  ) as mock_encode,
200
- patch.object(adapter, "_send_tx", new_callable=AsyncMock) as mock_send,
211
+ patch(
212
+ "wayfinder_paths.adapters.moonwell_adapter.adapter.send_transaction",
213
+ new_callable=AsyncMock,
214
+ ) as mock_send,
201
215
  ):
202
216
  mock_allowance.return_value = (True, {})
203
217
  mock_encode.return_value = {
204
218
  "data": "0x1234",
205
219
  "to": MOONWELL_DEFAULTS["m_usdc"],
206
220
  }
207
- mock_send.return_value = (True, mock_tx_hash)
221
+ mock_send.return_value = mock_tx_hash
208
222
 
209
223
  success, result = await adapter.repay(
210
224
  mtoken=MOONWELL_DEFAULTS["m_usdc"],
@@ -243,9 +257,12 @@ class TestMoonwellAdapter:
243
257
  "wayfinder_paths.adapters.moonwell_adapter.adapter.web3_from_chain_id",
244
258
  mock_web3_ctx,
245
259
  ),
246
- patch.object(adapter, "_send_tx", new_callable=AsyncMock) as mock_send,
260
+ patch(
261
+ "wayfinder_paths.adapters.moonwell_adapter.adapter.send_transaction",
262
+ new_callable=AsyncMock,
263
+ ) as mock_send,
247
264
  ):
248
- mock_send.return_value = (True, mock_tx_hash)
265
+ mock_send.return_value = mock_tx_hash
249
266
  success, result = await adapter.set_collateral(
250
267
  mtoken=MOONWELL_DEFAULTS["m_wsteth"],
251
268
  )
@@ -652,23 +669,20 @@ class TestMoonwellAdapter:
652
669
  "wayfinder_paths.adapters.moonwell_adapter.adapter.web3_from_chain_id",
653
670
  mock_web3_ctx,
654
671
  ),
655
- patch.object(adapter, "_send_tx", new_callable=AsyncMock) as mock_send,
672
+ patch(
673
+ "wayfinder_paths.adapters.moonwell_adapter.adapter.send_transaction",
674
+ new_callable=AsyncMock,
675
+ ) as mock_send,
656
676
  ):
657
- mock_send.return_value = (True, mock_tx_hash)
677
+ mock_send.return_value = mock_tx_hash
658
678
  success, result = await adapter.wrap_eth(amount=10**18)
659
679
 
660
680
  assert success
661
681
  assert result == mock_tx_hash
662
682
 
663
683
  def test_strategy_address_missing(self):
664
- adapter = MoonwellAdapter(config={})
665
-
666
684
  with pytest.raises(ValueError, match="strategy_wallet"):
667
- adapter._strategy_address()
668
-
669
- def test_checksum_missing_address(self, adapter):
670
- with pytest.raises(ValueError, match="Missing required"):
671
- adapter._checksum(None)
685
+ MoonwellAdapter(config={})
672
686
 
673
687
  def test_config_override(self):
674
688
  custom_comptroller = "0x1111111111111111111111111111111111111111"
@@ -59,6 +59,20 @@ class TokenAdapter(BaseAdapter):
59
59
  self.logger.error(f"Error getting token price for {token_id}: {e}")
60
60
  return (False, str(e))
61
61
 
62
+ async def get_amount_usd(
63
+ self,
64
+ token_id: str | None,
65
+ raw_amount: int | str | None,
66
+ decimals: int = 18,
67
+ ) -> float | None:
68
+ if raw_amount is None or token_id is None:
69
+ return None
70
+ success, price_data = await self.get_token_price(token_id)
71
+ if not success or not isinstance(price_data, dict):
72
+ return None
73
+ price = price_data.get("current_price", 0.0)
74
+ return price * float(raw_amount) / 10 ** int(decimals)
75
+
62
76
  async def get_gas_token(self, chain_code: str) -> tuple[bool, GasToken | str]:
63
77
  try:
64
78
  data = await self.token_client.get_gas_token(chain_code)
@@ -1,7 +1,5 @@
1
1
  from wayfinder_paths.core.adapters.BaseAdapter import BaseAdapter
2
- from wayfinder_paths.core.engine.StrategyJob import StrategyJob
3
2
  from wayfinder_paths.core.strategies.Strategy import (
4
- LiquidationResult,
5
3
  StatusDict,
6
4
  StatusTuple,
7
5
  Strategy,
@@ -12,5 +10,4 @@ __all__ = [
12
10
  "StatusDict",
13
11
  "StatusTuple",
14
12
  "BaseAdapter",
15
- "StrategyJob",
16
13
  ]
@@ -83,6 +83,7 @@ class BRAPClient(WayfinderClient):
83
83
  to_chain: int,
84
84
  from_wallet: str,
85
85
  from_amount: str,
86
+ slippage: float | None = None,
86
87
  ) -> BRAPQuoteResponse: # type: ignore # noqa: E501
87
88
  logger.info(
88
89
  f"Getting BRAP quote: {from_token} -> {to_token} (chain {from_chain} -> {to_chain})"
@@ -100,6 +101,8 @@ class BRAPClient(WayfinderClient):
100
101
  "from_wallet": from_wallet,
101
102
  "from_amount": from_amount,
102
103
  }
104
+ if slippage is not None:
105
+ params["slippage"] = slippage
103
106
 
104
107
  try:
105
108
  response = await self._authed_request("GET", url, params=params, headers={})
@@ -10,10 +10,8 @@ from wayfinder_paths.core.clients.protocols import (
10
10
  LedgerClientProtocol,
11
11
  PoolClientProtocol,
12
12
  TokenClientProtocol,
13
- WalletClientProtocol,
14
13
  )
15
14
  from wayfinder_paths.core.clients.TokenClient import TokenClient
16
- from wayfinder_paths.core.clients.WalletClient import WalletClient
17
15
 
18
16
 
19
17
  class ClientManager:
@@ -26,7 +24,6 @@ class ClientManager:
26
24
  self._skip_auth = skip_auth
27
25
 
28
26
  self._token_client: TokenClientProtocol | None = None
29
- self._wallet_client: WalletClientProtocol | None = None
30
27
  self._ledger_client: LedgerClientProtocol | None = None
31
28
  self._pool_client: PoolClientProtocol | None = None
32
29
  self._hyperlend_client: HyperlendClientProtocol | None = None
@@ -62,10 +59,6 @@ class ClientManager:
62
59
  "_hyperlend_client", "hyperlend", HyperlendClient
63
60
  )
64
61
 
65
- @property
66
- def wallet(self) -> WalletClientProtocol:
67
- return self._get_or_create_client("_wallet_client", "wallet", WalletClient)
68
-
69
62
  @property
70
63
  def brap(self) -> BRAPClientProtocol:
71
64
  return self._get_or_create_client("_brap_client", "brap", BRAPClient)