wayfinder-paths 0.1.21__tar.gz → 0.1.23__tar.gz

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 (144) hide show
  1. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/PKG-INFO +3 -4
  2. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/README.md +1 -1
  3. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/pyproject.toml +2 -2
  4. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/__init__.py +0 -4
  5. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/balance_adapter/README.md +0 -1
  6. wayfinder_paths-0.1.23/wayfinder_paths/adapters/balance_adapter/adapter.py +179 -0
  7. wayfinder_paths-0.1.23/wayfinder_paths/adapters/balance_adapter/test_adapter.py +90 -0
  8. wayfinder_paths-0.1.23/wayfinder_paths/adapters/brap_adapter/README.md +71 -0
  9. wayfinder_paths-0.1.23/wayfinder_paths/adapters/brap_adapter/adapter.py +305 -0
  10. wayfinder_paths-0.1.23/wayfinder_paths/adapters/brap_adapter/examples.json +67 -0
  11. wayfinder_paths-0.1.23/wayfinder_paths/adapters/brap_adapter/test_adapter.py +87 -0
  12. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/hyperlend_adapter/adapter.py +39 -86
  13. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py +5 -1
  14. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/hyperliquid_adapter/adapter.py +6 -5
  15. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/ledger_adapter/README.md +4 -1
  16. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/ledger_adapter/adapter.py +3 -3
  17. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/moonwell_adapter/adapter.py +108 -198
  18. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/moonwell_adapter/test_adapter.py +37 -23
  19. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/token_adapter/adapter.py +14 -0
  20. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/__init__.py +0 -3
  21. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/clients/BRAPClient.py +3 -0
  22. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/clients/ClientManager.py +0 -7
  23. wayfinder_paths-0.1.23/wayfinder_paths/core/clients/LedgerClient.py +344 -0
  24. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/clients/WayfinderClient.py +0 -1
  25. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/clients/__init__.py +0 -5
  26. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/clients/protocols.py +0 -13
  27. wayfinder_paths-0.1.23/wayfinder_paths/core/config.py +39 -0
  28. wayfinder_paths-0.1.23/wayfinder_paths/core/constants/__init__.py +73 -0
  29. wayfinder_paths-0.1.23/wayfinder_paths/core/constants/base.py +24 -0
  30. wayfinder_paths-0.1.23/wayfinder_paths/core/constants/chains.py +36 -0
  31. wayfinder_paths-0.1.23/wayfinder_paths/core/constants/contracts.py +39 -0
  32. wayfinder_paths-0.1.23/wayfinder_paths/core/constants/tokens.py +9 -0
  33. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/strategies/Strategy.py +0 -10
  34. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/utils/evm_helpers.py +5 -15
  35. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/utils/tokens.py +28 -0
  36. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/utils/transaction.py +13 -7
  37. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/utils/web3.py +5 -3
  38. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/policies/enso.py +1 -2
  39. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/policies/hyper_evm.py +6 -3
  40. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/policies/hyperlend.py +1 -2
  41. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/policies/moonwell.py +12 -7
  42. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/policies/prjx.py +1 -3
  43. wayfinder_paths-0.1.23/wayfinder_paths/run_strategy.py +146 -0
  44. wayfinder_paths-0.1.23/wayfinder_paths/strategies/basis_trading_strategy/constants.py +3 -0
  45. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/strategies/basis_trading_strategy/strategy.py +19 -14
  46. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +12 -11
  47. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +20 -33
  48. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py +21 -18
  49. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +69 -130
  50. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +32 -42
  51. wayfinder_paths-0.1.21/wayfinder_paths/adapters/balance_adapter/adapter.py +0 -283
  52. wayfinder_paths-0.1.21/wayfinder_paths/adapters/balance_adapter/test_adapter.py +0 -162
  53. wayfinder_paths-0.1.21/wayfinder_paths/adapters/brap_adapter/README.md +0 -124
  54. wayfinder_paths-0.1.21/wayfinder_paths/adapters/brap_adapter/adapter.py +0 -694
  55. wayfinder_paths-0.1.21/wayfinder_paths/adapters/brap_adapter/examples.json +0 -186
  56. wayfinder_paths-0.1.21/wayfinder_paths/adapters/brap_adapter/test_adapter.py +0 -315
  57. wayfinder_paths-0.1.21/wayfinder_paths/core/clients/LedgerClient.py +0 -320
  58. wayfinder_paths-0.1.21/wayfinder_paths/core/clients/WalletClient.py +0 -41
  59. wayfinder_paths-0.1.21/wayfinder_paths/core/config.py +0 -203
  60. wayfinder_paths-0.1.21/wayfinder_paths/core/constants/__init__.py +0 -17
  61. wayfinder_paths-0.1.21/wayfinder_paths/core/constants/base.py +0 -38
  62. wayfinder_paths-0.1.21/wayfinder_paths/core/engine/StrategyJob.py +0 -110
  63. wayfinder_paths-0.1.21/wayfinder_paths/core/services/test_local_evm_txn.py +0 -145
  64. wayfinder_paths-0.1.21/wayfinder_paths/run_strategy.py +0 -349
  65. wayfinder_paths-0.1.21/wayfinder_paths/strategies/basis_trading_strategy/constants.py +0 -1
  66. wayfinder_paths-0.1.21/wayfinder_paths/templates/adapter/README.md +0 -150
  67. wayfinder_paths-0.1.21/wayfinder_paths/templates/adapter/adapter.py +0 -16
  68. wayfinder_paths-0.1.21/wayfinder_paths/templates/adapter/examples.json +0 -8
  69. wayfinder_paths-0.1.21/wayfinder_paths/templates/adapter/test_adapter.py +0 -30
  70. wayfinder_paths-0.1.21/wayfinder_paths/templates/strategy/README.md +0 -186
  71. wayfinder_paths-0.1.21/wayfinder_paths/templates/strategy/examples.json +0 -11
  72. wayfinder_paths-0.1.21/wayfinder_paths/templates/strategy/strategy.py +0 -35
  73. wayfinder_paths-0.1.21/wayfinder_paths/templates/strategy/test_strategy.py +0 -166
  74. wayfinder_paths-0.1.21/wayfinder_paths/tests/test_smoke_manifest.py +0 -63
  75. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/LICENSE +0 -0
  76. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/__init__.py +0 -0
  77. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/balance_adapter/examples.json +0 -0
  78. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/brap_adapter/__init__.py +0 -0
  79. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/hyperlend_adapter/__init__.py +0 -0
  80. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/hyperliquid_adapter/__init__.py +0 -0
  81. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/hyperliquid_adapter/executor.py +0 -0
  82. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/hyperliquid_adapter/paired_filler.py +0 -0
  83. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/hyperliquid_adapter/test_adapter.py +0 -0
  84. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/hyperliquid_adapter/test_adapter_live.py +0 -0
  85. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/hyperliquid_adapter/test_executor.py +0 -0
  86. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/hyperliquid_adapter/test_utils.py +0 -0
  87. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/hyperliquid_adapter/utils.py +0 -0
  88. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/ledger_adapter/__init__.py +0 -0
  89. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/ledger_adapter/examples.json +0 -0
  90. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/ledger_adapter/test_adapter.py +0 -0
  91. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/moonwell_adapter/README.md +0 -0
  92. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/moonwell_adapter/__init__.py +0 -0
  93. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/pool_adapter/README.md +0 -0
  94. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/pool_adapter/__init__.py +0 -0
  95. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/pool_adapter/adapter.py +0 -0
  96. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/pool_adapter/examples.json +0 -0
  97. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/pool_adapter/test_adapter.py +0 -0
  98. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/token_adapter/README.md +0 -0
  99. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/token_adapter/__init__.py +0 -0
  100. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/token_adapter/examples.json +0 -0
  101. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/adapters/token_adapter/test_adapter.py +0 -0
  102. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/conftest.py +0 -0
  103. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/adapters/BaseAdapter.py +0 -0
  104. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/adapters/__init__.py +0 -0
  105. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/adapters/models.py +0 -0
  106. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/analytics/__init__.py +0 -0
  107. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/analytics/bootstrap.py +0 -0
  108. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/analytics/stats.py +0 -0
  109. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/analytics/test_analytics.py +0 -0
  110. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/clients/HyperlendClient.py +0 -0
  111. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/clients/PoolClient.py +0 -0
  112. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/clients/TokenClient.py +0 -0
  113. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/constants/erc20_abi.py +0 -0
  114. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/constants/hyperlend_abi.py +0 -0
  115. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/constants/moonwell_abi.py +0 -0
  116. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/strategies/__init__.py +0 -0
  117. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/strategies/base.py +0 -0
  118. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/strategies/descriptors.py +0 -0
  119. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/utils/__init__.py +0 -0
  120. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/core/utils/wallets.py +0 -0
  121. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/policies/erc20.py +0 -0
  122. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/policies/evm.py +0 -0
  123. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/policies/hyperliquid.py +0 -0
  124. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/policies/util.py +0 -0
  125. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/scripts/__init__.py +0 -0
  126. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/scripts/create_strategy.py +0 -0
  127. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/scripts/make_wallets.py +0 -0
  128. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/strategies/__init__.py +0 -0
  129. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/strategies/basis_trading_strategy/README.md +0 -0
  130. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/strategies/basis_trading_strategy/__init__.py +0 -0
  131. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/strategies/basis_trading_strategy/examples.json +0 -0
  132. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/strategies/basis_trading_strategy/snapshot_mixin.py +0 -0
  133. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py +0 -0
  134. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/strategies/basis_trading_strategy/types.py +0 -0
  135. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/strategies/hyperlend_stable_yield_strategy/README.md +0 -0
  136. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/strategies/hyperlend_stable_yield_strategy/examples.json +0 -0
  137. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/README.md +0 -0
  138. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/examples.json +0 -0
  139. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/test_strategy.py +0 -0
  140. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/strategies/stablecoin_yield_strategy/README.md +0 -0
  141. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/strategies/stablecoin_yield_strategy/examples.json +0 -0
  142. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/tests/__init__.py +0 -0
  143. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/tests/test_test_coverage.py +0 -0
  144. {wayfinder_paths-0.1.21 → wayfinder_paths-0.1.23}/wayfinder_paths/tests/test_utils.py +0 -0
@@ -1,17 +1,16 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: wayfinder-paths
3
- Version: 0.1.21
3
+ Version: 0.1.23
4
4
  Summary: Wayfinder Path: strategies and adapters
5
5
  Author: Wayfinder
6
6
  Author-email: dev@wayfinder.ai
7
7
  Requires-Python: >=3.12,<4.0
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: Programming Language :: Python :: 3.12
10
- Classifier: Programming Language :: Python :: 3.13
11
10
  Requires-Dist: aiohttp (>=3.13.0,<4.0.0)
12
11
  Requires-Dist: eth-account (>=0.13.7,<0.14.0)
13
12
  Requires-Dist: httpx (>=0.28.1,<0.29.0)
14
- Requires-Dist: hyperliquid-python-sdk (>=0.21.0,<0.22.0)
13
+ Requires-Dist: hyperliquid-felix
15
14
  Requires-Dist: loguru (>=0.7.3,<0.8.0)
16
15
  Requires-Dist: numpy (>=1.26.0,<2.0.0)
17
16
  Requires-Dist: pandas (>=2.2.0,<3.0.0)
@@ -98,7 +97,7 @@ Strategy Layer - Trading logic (deposit, update, withdraw, exit)
98
97
 
99
98
  Adapter Layer - Protocol integrations (BalanceAdapter, PoolAdapter, etc.)
100
99
 
101
- Client Layer - API wrappers (TokenClient, WalletClient, PoolClient, etc.)
100
+ Client Layer - API wrappers (TokenClient, PoolClient, LedgerClient, etc.)
102
101
 
103
102
  Network - RPCs, Wayfinder API, external services
104
103
  ```
@@ -76,7 +76,7 @@ Strategy Layer - Trading logic (deposit, update, withdraw, exit)
76
76
 
77
77
  Adapter Layer - Protocol integrations (BalanceAdapter, PoolAdapter, etc.)
78
78
 
79
- Client Layer - API wrappers (TokenClient, WalletClient, PoolClient, etc.)
79
+ Client Layer - API wrappers (TokenClient, PoolClient, LedgerClient, etc.)
80
80
 
81
81
  Network - RPCs, Wayfinder API, external services
82
82
  ```
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "wayfinder-paths"
3
- version = "0.1.21"
3
+ version = "0.1.23"
4
4
  description = "Wayfinder Path: strategies and adapters"
5
5
  readme = "README.md"
6
6
  authors = ["Wayfinder <dev@wayfinder.ai>"]
@@ -19,7 +19,7 @@ eth-account = "^0.13.7"
19
19
  aiohttp = "^3.13.0"
20
20
  numpy = "^1.26.0"
21
21
  pandas = "^2.2.0"
22
- hyperliquid-python-sdk = "^0.21.0"
22
+ hyperliquid-felix = "*"
23
23
 
24
24
  [tool.poetry.group.dev.dependencies]
25
25
  pytest = "^8.4.2"
@@ -1,13 +1,10 @@
1
1
  __version__ = "0.1.0"
2
2
 
3
- # Re-export commonly used items for convenience
4
3
  from wayfinder_paths.core import (
5
4
  BaseAdapter,
6
- LiquidationResult,
7
5
  StatusDict,
8
6
  StatusTuple,
9
7
  Strategy,
10
- StrategyJob,
11
8
  )
12
9
 
13
10
  __all__ = [
@@ -16,5 +13,4 @@ __all__ = [
16
13
  "Strategy",
17
14
  "StatusDict",
18
15
  "StatusTuple",
19
- "StrategyJob",
20
16
  ]
@@ -93,7 +93,6 @@ config = {
93
93
 
94
94
  ## Dependencies
95
95
 
96
- - `WalletClient` - For balance queries
97
96
  - `TokenClient` - For token metadata
98
97
  - `LedgerAdapter` - For transaction recording
99
98
  - `TokenAdapter` - For price lookups
@@ -0,0 +1,179 @@
1
+ from typing import Any
2
+
3
+ from wayfinder_paths.adapters.ledger_adapter.adapter import LedgerAdapter
4
+ from wayfinder_paths.adapters.token_adapter.adapter import TokenAdapter
5
+ from wayfinder_paths.core.adapters.BaseAdapter import BaseAdapter
6
+ from wayfinder_paths.core.clients.TokenClient import TokenClient
7
+ from wayfinder_paths.core.utils.evm_helpers import resolve_chain_id
8
+ from wayfinder_paths.core.utils.tokens import build_send_transaction, get_token_balance
9
+ from wayfinder_paths.core.utils.transaction import send_transaction
10
+
11
+
12
+ class BalanceAdapter(BaseAdapter):
13
+ adapter_type = "BALANCE"
14
+
15
+ def __init__(
16
+ self,
17
+ config: dict[str, Any],
18
+ main_wallet_signing_callback=None,
19
+ strategy_wallet_signing_callback=None,
20
+ ):
21
+ super().__init__("balance", config)
22
+ self.main_wallet_signing_callback = main_wallet_signing_callback
23
+ self.strategy_wallet_signing_callback = strategy_wallet_signing_callback
24
+ self.token_client = TokenClient()
25
+ self.token_adapter = TokenAdapter()
26
+ self.ledger_adapter = LedgerAdapter()
27
+
28
+ async def get_balance(
29
+ self,
30
+ *,
31
+ wallet_address: str,
32
+ token_id: str | None = None,
33
+ token_address: str | None = None,
34
+ chain_id: int | None = None,
35
+ ) -> tuple[bool, int | str]:
36
+ try:
37
+ if token_id and not token_address:
38
+ token_info = await self.token_client.get_token_details(token_id)
39
+ token_address = token_info["address"]
40
+ chain_id = chain_id or resolve_chain_id(token_info)
41
+ balance = await get_token_balance(token_address, chain_id, wallet_address)
42
+ return True, balance
43
+ except Exception as e:
44
+ return False, str(e)
45
+
46
+ async def move_from_main_wallet_to_strategy_wallet(
47
+ self,
48
+ token_id: str,
49
+ amount: float,
50
+ strategy_name: str = "unknown",
51
+ skip_ledger: bool = False,
52
+ ) -> tuple[bool, str]:
53
+ return await self._move_between_wallets(
54
+ token_id=token_id,
55
+ amount=amount,
56
+ from_wallet=self.config["main_wallet"],
57
+ to_wallet=self.config["strategy_wallet"],
58
+ ledger_method=self.ledger_adapter.record_deposit
59
+ if not skip_ledger
60
+ else None,
61
+ ledger_wallet="to",
62
+ strategy_name=strategy_name,
63
+ )
64
+
65
+ async def move_from_strategy_wallet_to_main_wallet(
66
+ self,
67
+ token_id: str,
68
+ amount: float,
69
+ strategy_name: str = "unknown",
70
+ skip_ledger: bool = False,
71
+ ) -> tuple[bool, str]:
72
+ return await self._move_between_wallets(
73
+ token_id=token_id,
74
+ amount=amount,
75
+ from_wallet=self.config["strategy_wallet"],
76
+ to_wallet=self.config["main_wallet"],
77
+ ledger_method=self.ledger_adapter.record_withdrawal
78
+ if not skip_ledger
79
+ else None,
80
+ ledger_wallet="from",
81
+ strategy_name=strategy_name,
82
+ )
83
+
84
+ async def send_to_address(
85
+ self,
86
+ token_id: str,
87
+ amount: int,
88
+ from_wallet: dict[str, Any],
89
+ to_address: str,
90
+ signing_callback,
91
+ ) -> tuple[bool, str]:
92
+ token_info = await self.token_client.get_token_details(token_id)
93
+ chain_id = resolve_chain_id(token_info)
94
+ tx = await build_send_transaction(
95
+ from_address=from_wallet["address"],
96
+ to_address=to_address,
97
+ token_address=token_info["address"],
98
+ chain_id=chain_id,
99
+ amount=amount,
100
+ )
101
+ tx_hash = await send_transaction(tx, signing_callback)
102
+ return True, tx_hash
103
+
104
+ async def _move_between_wallets(
105
+ self,
106
+ *,
107
+ token_id: str,
108
+ amount: float,
109
+ from_wallet: dict[str, Any],
110
+ to_wallet: dict[str, Any],
111
+ ledger_method,
112
+ ledger_wallet: str,
113
+ strategy_name: str,
114
+ ) -> tuple[bool, str]:
115
+ token_info = await self.token_client.get_token_details(token_id)
116
+ chain_id = resolve_chain_id(token_info)
117
+ decimals = token_info.get("decimals", 18)
118
+ raw_amount = int(amount * (10**decimals))
119
+
120
+ transaction = await build_send_transaction(
121
+ from_address=from_wallet["address"],
122
+ to_address=to_wallet["address"],
123
+ token_address=token_info["address"],
124
+ chain_id=chain_id,
125
+ amount=raw_amount,
126
+ )
127
+
128
+ main_address = self.config.get("main_wallet", {}).get("address", "").lower()
129
+ callback = (
130
+ self.main_wallet_signing_callback
131
+ if from_wallet["address"].lower() == main_address
132
+ else self.strategy_wallet_signing_callback
133
+ )
134
+ tx_hash = await send_transaction(transaction, callback)
135
+
136
+ if ledger_method:
137
+ wallet_for_ledger = (
138
+ from_wallet["address"]
139
+ if ledger_wallet == "from"
140
+ else to_wallet["address"]
141
+ )
142
+ await self._record_ledger_entry(
143
+ ledger_method, wallet_for_ledger, token_info, amount, strategy_name
144
+ )
145
+
146
+ return True, tx_hash
147
+
148
+ async def _record_ledger_entry(
149
+ self,
150
+ ledger_method,
151
+ wallet_address: str,
152
+ token_info: dict[str, Any],
153
+ amount: float,
154
+ strategy_name: str,
155
+ ) -> None:
156
+ try:
157
+ chain_id = resolve_chain_id(token_info)
158
+ token_id = token_info.get("token_id")
159
+ usd_value = (
160
+ await self.token_adapter.get_amount_usd(
161
+ token_info.get("token_id"), amount, decimals=0
162
+ )
163
+ or 0.0
164
+ )
165
+ await ledger_method(
166
+ wallet_address=wallet_address,
167
+ chain_id=chain_id,
168
+ token_address=token_info.get("address"),
169
+ token_amount=str(amount),
170
+ usd_value=usd_value,
171
+ data={
172
+ "token_id": token_id,
173
+ "amount": str(amount),
174
+ "usd_value": usd_value,
175
+ },
176
+ strategy_name=strategy_name,
177
+ )
178
+ except Exception as exc:
179
+ self.logger.warning(f"Ledger entry failed: {exc}", wallet=wallet_address)
@@ -0,0 +1,90 @@
1
+ from unittest.mock import AsyncMock, patch
2
+
3
+ import pytest
4
+
5
+ from wayfinder_paths.adapters.balance_adapter.adapter import BalanceAdapter
6
+
7
+
8
+ class TestBalanceAdapter:
9
+ @pytest.fixture
10
+ def mock_token_client(self):
11
+ return AsyncMock()
12
+
13
+ @pytest.fixture
14
+ def adapter(self, mock_token_client):
15
+ with patch(
16
+ "wayfinder_paths.adapters.balance_adapter.adapter.TokenClient",
17
+ return_value=mock_token_client,
18
+ ):
19
+ return BalanceAdapter(config={})
20
+
21
+ @pytest.mark.asyncio
22
+ async def test_health_check(self, adapter):
23
+ health = await adapter.health_check()
24
+ assert isinstance(health, dict)
25
+ assert health.get("status") in {"healthy", "unhealthy", "error"}
26
+
27
+ @pytest.mark.asyncio
28
+ async def test_connect(self, adapter):
29
+ ok = await adapter.connect()
30
+ assert isinstance(ok, bool)
31
+
32
+ def test_adapter_type(self, adapter):
33
+ assert adapter.adapter_type == "BALANCE"
34
+
35
+ @pytest.mark.asyncio
36
+ async def test_get_balance_with_token_id(self, adapter, mock_token_client):
37
+ mock_token_client.get_token_details = AsyncMock(
38
+ return_value={
39
+ "token_id": "usd-coin-base",
40
+ "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
41
+ "chain": {"id": 8453, "code": "base"},
42
+ }
43
+ )
44
+
45
+ with patch(
46
+ "wayfinder_paths.adapters.balance_adapter.adapter.get_token_balance",
47
+ new_callable=AsyncMock,
48
+ return_value=1000000,
49
+ ) as mock_get_balance:
50
+ success, balance = await adapter.get_balance(
51
+ token_id="usd-coin-base",
52
+ wallet_address="0xWallet",
53
+ )
54
+
55
+ assert success
56
+ assert balance == 1000000
57
+ mock_token_client.get_token_details.assert_called_once_with("usd-coin-base")
58
+ mock_get_balance.assert_called_once_with(
59
+ "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", 8453, "0xWallet"
60
+ )
61
+
62
+ @pytest.mark.asyncio
63
+ async def test_get_balance_with_token_address(self, adapter, mock_token_client):
64
+ with patch(
65
+ "wayfinder_paths.adapters.balance_adapter.adapter.get_token_balance",
66
+ new_callable=AsyncMock,
67
+ return_value=5000000,
68
+ ) as mock_get_balance:
69
+ success, balance = await adapter.get_balance(
70
+ token_address="0xTokenAddress",
71
+ wallet_address="0xWallet",
72
+ chain_id=8453,
73
+ )
74
+
75
+ assert success
76
+ assert balance == 5000000
77
+ mock_get_balance.assert_called_once_with("0xTokenAddress", 8453, "0xWallet")
78
+ mock_token_client.get_token_details.assert_not_called()
79
+
80
+ @pytest.mark.asyncio
81
+ async def test_get_balance_token_not_found(self, adapter, mock_token_client):
82
+ mock_token_client.get_token_details = AsyncMock(return_value=None)
83
+
84
+ success, error = await adapter.get_balance(
85
+ token_id="invalid-token",
86
+ wallet_address="0xWallet",
87
+ )
88
+
89
+ assert success is False
90
+ assert "NoneType" in error or "subscriptable" in error
@@ -0,0 +1,71 @@
1
+ # BRAP Adapter
2
+
3
+ Adapter for cross-chain swaps and bridges via the BRAP (Bridge/Router/Adapter Protocol).
4
+
5
+ - **Type**: `BRAP`
6
+ - **Module**: `wayfinder_paths.adapters.brap_adapter.adapter.BRAPAdapter`
7
+
8
+ ## Usage
9
+
10
+ ```python
11
+ from wayfinder_paths.adapters.brap_adapter.adapter import BRAPAdapter
12
+
13
+ adapter = BRAPAdapter(strategy_wallet_signing_callback=signing_callback)
14
+ ```
15
+
16
+ ## Methods
17
+
18
+ ### best_quote
19
+
20
+ Get the best quote for a swap.
21
+
22
+ ```python
23
+ success, quote = await adapter.best_quote(
24
+ from_token_address="0x...",
25
+ to_token_address="0x...",
26
+ from_chain_id=8453,
27
+ to_chain_id=1,
28
+ from_address="0x...",
29
+ amount="1000000000",
30
+ preferred_providers=["enso"], # optional
31
+ )
32
+ if success:
33
+ print(f"Output: {quote.get('output_amount')}")
34
+ ```
35
+
36
+ ### swap_from_token_ids
37
+
38
+ Execute a swap using token IDs.
39
+
40
+ ```python
41
+ success, result = await adapter.swap_from_token_ids(
42
+ from_token_id="usd-coin-base",
43
+ to_token_id="ethereum",
44
+ from_address="0x...",
45
+ amount="1000000000",
46
+ strategy_name="my_strategy",
47
+ preferred_providers=["enso"],
48
+ )
49
+ if success:
50
+ print(f"TX: {result.get('tx_hash')}")
51
+ ```
52
+
53
+ ### swap_from_quote
54
+
55
+ Execute a swap from a pre-fetched quote.
56
+
57
+ ```python
58
+ success, result = await adapter.swap_from_quote(
59
+ from_token=from_token_info,
60
+ to_token=to_token_info,
61
+ from_address="0x...",
62
+ quote=quote,
63
+ strategy_name="my_strategy",
64
+ )
65
+ ```
66
+
67
+ ## Testing
68
+
69
+ ```bash
70
+ poetry run pytest wayfinder_paths/adapters/brap_adapter/ -v
71
+ ```