wayfinder-paths 0.1.1__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 (115) hide show
  1. wayfinder_paths/CONFIG_GUIDE.md +394 -0
  2. wayfinder_paths/__init__.py +21 -0
  3. wayfinder_paths/config.example.json +20 -0
  4. wayfinder_paths/conftest.py +31 -0
  5. wayfinder_paths/core/__init__.py +13 -0
  6. wayfinder_paths/core/adapters/BaseAdapter.py +48 -0
  7. wayfinder_paths/core/adapters/__init__.py +5 -0
  8. wayfinder_paths/core/adapters/base.py +5 -0
  9. wayfinder_paths/core/clients/AuthClient.py +83 -0
  10. wayfinder_paths/core/clients/BRAPClient.py +90 -0
  11. wayfinder_paths/core/clients/ClientManager.py +231 -0
  12. wayfinder_paths/core/clients/HyperlendClient.py +151 -0
  13. wayfinder_paths/core/clients/LedgerClient.py +222 -0
  14. wayfinder_paths/core/clients/PoolClient.py +96 -0
  15. wayfinder_paths/core/clients/SimulationClient.py +180 -0
  16. wayfinder_paths/core/clients/TokenClient.py +73 -0
  17. wayfinder_paths/core/clients/TransactionClient.py +47 -0
  18. wayfinder_paths/core/clients/WalletClient.py +90 -0
  19. wayfinder_paths/core/clients/WayfinderClient.py +258 -0
  20. wayfinder_paths/core/clients/__init__.py +48 -0
  21. wayfinder_paths/core/clients/protocols.py +295 -0
  22. wayfinder_paths/core/clients/sdk_example.py +115 -0
  23. wayfinder_paths/core/config.py +369 -0
  24. wayfinder_paths/core/constants/__init__.py +26 -0
  25. wayfinder_paths/core/constants/base.py +25 -0
  26. wayfinder_paths/core/constants/erc20_abi.py +118 -0
  27. wayfinder_paths/core/constants/hyperlend_abi.py +152 -0
  28. wayfinder_paths/core/engine/VaultJob.py +182 -0
  29. wayfinder_paths/core/engine/__init__.py +5 -0
  30. wayfinder_paths/core/engine/manifest.py +97 -0
  31. wayfinder_paths/core/services/__init__.py +0 -0
  32. wayfinder_paths/core/services/base.py +177 -0
  33. wayfinder_paths/core/services/local_evm_txn.py +429 -0
  34. wayfinder_paths/core/services/local_token_txn.py +231 -0
  35. wayfinder_paths/core/services/web3_service.py +45 -0
  36. wayfinder_paths/core/settings.py +61 -0
  37. wayfinder_paths/core/strategies/Strategy.py +183 -0
  38. wayfinder_paths/core/strategies/__init__.py +5 -0
  39. wayfinder_paths/core/strategies/base.py +7 -0
  40. wayfinder_paths/core/utils/__init__.py +1 -0
  41. wayfinder_paths/core/utils/evm_helpers.py +165 -0
  42. wayfinder_paths/core/utils/wallets.py +77 -0
  43. wayfinder_paths/core/wallets/README.md +91 -0
  44. wayfinder_paths/core/wallets/WalletManager.py +56 -0
  45. wayfinder_paths/core/wallets/__init__.py +7 -0
  46. wayfinder_paths/run_strategy.py +409 -0
  47. wayfinder_paths/scripts/__init__.py +0 -0
  48. wayfinder_paths/scripts/create_strategy.py +181 -0
  49. wayfinder_paths/scripts/make_wallets.py +160 -0
  50. wayfinder_paths/scripts/validate_manifests.py +213 -0
  51. wayfinder_paths/tests/__init__.py +0 -0
  52. wayfinder_paths/tests/test_smoke_manifest.py +48 -0
  53. wayfinder_paths/tests/test_test_coverage.py +212 -0
  54. wayfinder_paths/tests/test_utils.py +64 -0
  55. wayfinder_paths/vaults/__init__.py +0 -0
  56. wayfinder_paths/vaults/adapters/__init__.py +0 -0
  57. wayfinder_paths/vaults/adapters/balance_adapter/README.md +104 -0
  58. wayfinder_paths/vaults/adapters/balance_adapter/adapter.py +257 -0
  59. wayfinder_paths/vaults/adapters/balance_adapter/examples.json +6 -0
  60. wayfinder_paths/vaults/adapters/balance_adapter/manifest.yaml +8 -0
  61. wayfinder_paths/vaults/adapters/balance_adapter/test_adapter.py +83 -0
  62. wayfinder_paths/vaults/adapters/brap_adapter/README.md +249 -0
  63. wayfinder_paths/vaults/adapters/brap_adapter/__init__.py +7 -0
  64. wayfinder_paths/vaults/adapters/brap_adapter/adapter.py +717 -0
  65. wayfinder_paths/vaults/adapters/brap_adapter/examples.json +175 -0
  66. wayfinder_paths/vaults/adapters/brap_adapter/manifest.yaml +11 -0
  67. wayfinder_paths/vaults/adapters/brap_adapter/test_adapter.py +288 -0
  68. wayfinder_paths/vaults/adapters/hyperlend_adapter/__init__.py +7 -0
  69. wayfinder_paths/vaults/adapters/hyperlend_adapter/adapter.py +298 -0
  70. wayfinder_paths/vaults/adapters/hyperlend_adapter/manifest.yaml +10 -0
  71. wayfinder_paths/vaults/adapters/hyperlend_adapter/test_adapter.py +267 -0
  72. wayfinder_paths/vaults/adapters/ledger_adapter/README.md +158 -0
  73. wayfinder_paths/vaults/adapters/ledger_adapter/__init__.py +7 -0
  74. wayfinder_paths/vaults/adapters/ledger_adapter/adapter.py +286 -0
  75. wayfinder_paths/vaults/adapters/ledger_adapter/examples.json +131 -0
  76. wayfinder_paths/vaults/adapters/ledger_adapter/manifest.yaml +11 -0
  77. wayfinder_paths/vaults/adapters/ledger_adapter/test_adapter.py +202 -0
  78. wayfinder_paths/vaults/adapters/pool_adapter/README.md +218 -0
  79. wayfinder_paths/vaults/adapters/pool_adapter/__init__.py +7 -0
  80. wayfinder_paths/vaults/adapters/pool_adapter/adapter.py +289 -0
  81. wayfinder_paths/vaults/adapters/pool_adapter/examples.json +143 -0
  82. wayfinder_paths/vaults/adapters/pool_adapter/manifest.yaml +10 -0
  83. wayfinder_paths/vaults/adapters/pool_adapter/test_adapter.py +222 -0
  84. wayfinder_paths/vaults/adapters/token_adapter/README.md +101 -0
  85. wayfinder_paths/vaults/adapters/token_adapter/__init__.py +3 -0
  86. wayfinder_paths/vaults/adapters/token_adapter/adapter.py +92 -0
  87. wayfinder_paths/vaults/adapters/token_adapter/examples.json +26 -0
  88. wayfinder_paths/vaults/adapters/token_adapter/manifest.yaml +6 -0
  89. wayfinder_paths/vaults/adapters/token_adapter/test_adapter.py +135 -0
  90. wayfinder_paths/vaults/strategies/__init__.py +0 -0
  91. wayfinder_paths/vaults/strategies/config.py +85 -0
  92. wayfinder_paths/vaults/strategies/hyperlend_stable_yield_strategy/README.md +99 -0
  93. wayfinder_paths/vaults/strategies/hyperlend_stable_yield_strategy/examples.json +16 -0
  94. wayfinder_paths/vaults/strategies/hyperlend_stable_yield_strategy/manifest.yaml +7 -0
  95. wayfinder_paths/vaults/strategies/hyperlend_stable_yield_strategy/strategy.py +2328 -0
  96. wayfinder_paths/vaults/strategies/hyperlend_stable_yield_strategy/test_strategy.py +319 -0
  97. wayfinder_paths/vaults/strategies/stablecoin_yield_strategy/README.md +95 -0
  98. wayfinder_paths/vaults/strategies/stablecoin_yield_strategy/examples.json +17 -0
  99. wayfinder_paths/vaults/strategies/stablecoin_yield_strategy/manifest.yaml +17 -0
  100. wayfinder_paths/vaults/strategies/stablecoin_yield_strategy/strategy.py +1684 -0
  101. wayfinder_paths/vaults/strategies/stablecoin_yield_strategy/test_strategy.py +350 -0
  102. wayfinder_paths/vaults/templates/adapter/README.md +105 -0
  103. wayfinder_paths/vaults/templates/adapter/adapter.py +26 -0
  104. wayfinder_paths/vaults/templates/adapter/examples.json +8 -0
  105. wayfinder_paths/vaults/templates/adapter/manifest.yaml +6 -0
  106. wayfinder_paths/vaults/templates/adapter/test_adapter.py +49 -0
  107. wayfinder_paths/vaults/templates/strategy/README.md +152 -0
  108. wayfinder_paths/vaults/templates/strategy/examples.json +11 -0
  109. wayfinder_paths/vaults/templates/strategy/manifest.yaml +8 -0
  110. wayfinder_paths/vaults/templates/strategy/strategy.py +57 -0
  111. wayfinder_paths/vaults/templates/strategy/test_strategy.py +197 -0
  112. wayfinder_paths-0.1.1.dist-info/LICENSE +21 -0
  113. wayfinder_paths-0.1.1.dist-info/METADATA +727 -0
  114. wayfinder_paths-0.1.1.dist-info/RECORD +115 -0
  115. wayfinder_paths-0.1.1.dist-info/WHEEL +4 -0
@@ -0,0 +1,202 @@
1
+ from unittest.mock import AsyncMock, patch
2
+
3
+ import pytest
4
+
5
+ from wayfinder_paths.vaults.adapters.ledger_adapter.adapter import LedgerAdapter
6
+
7
+
8
+ class TestLedgerAdapter:
9
+ """Test cases for LedgerAdapter"""
10
+
11
+ @pytest.fixture
12
+ def mock_ledger_client(self):
13
+ """Mock LedgerClient for testing"""
14
+ mock_client = AsyncMock()
15
+ return mock_client
16
+
17
+ @pytest.fixture
18
+ def adapter(self, mock_ledger_client):
19
+ """Create a LedgerAdapter instance with mocked client for testing"""
20
+ with patch(
21
+ "vaults.adapters.ledger_adapter.adapter.LedgerClient",
22
+ return_value=mock_ledger_client,
23
+ ):
24
+ return LedgerAdapter()
25
+
26
+ @pytest.mark.asyncio
27
+ async def test_get_vault_transactions_success(self, adapter, mock_ledger_client):
28
+ """Test successful vault transaction retrieval"""
29
+ mock_response = {
30
+ "transactions": [
31
+ {
32
+ "id": "tx_123",
33
+ "operation": "DEPOSIT",
34
+ "amount": "1000000000000000000",
35
+ "usd_value": "1000.00",
36
+ }
37
+ ],
38
+ "total": 1,
39
+ }
40
+ mock_ledger_client.get_vault_transactions = AsyncMock(
41
+ return_value=mock_response
42
+ )
43
+
44
+ success, data = await adapter.get_vault_transactions(
45
+ wallet_address="0x1234567890123456789012345678901234567890",
46
+ limit=10,
47
+ offset=0,
48
+ )
49
+
50
+ assert success is True
51
+ assert data == mock_response
52
+ mock_ledger_client.get_vault_transactions.assert_called_once_with(
53
+ wallet_address="0x1234567890123456789012345678901234567890",
54
+ limit=10,
55
+ offset=0,
56
+ )
57
+
58
+ @pytest.mark.asyncio
59
+ async def test_get_vault_transactions_failure(self, adapter, mock_ledger_client):
60
+ """Test vault transaction retrieval failure"""
61
+ mock_ledger_client.get_vault_transactions = AsyncMock(
62
+ side_effect=Exception("API Error")
63
+ )
64
+
65
+ success, data = await adapter.get_vault_transactions(
66
+ wallet_address="0x1234567890123456789012345678901234567890"
67
+ )
68
+
69
+ assert success is False
70
+ assert "API Error" in data
71
+
72
+ @pytest.mark.asyncio
73
+ async def test_get_vault_net_deposit_success(self, adapter, mock_ledger_client):
74
+ """Test successful vault net deposit retrieval"""
75
+ mock_response = {
76
+ "net_deposit": "1000.00",
77
+ "total_deposits": "1500.00",
78
+ "total_withdrawals": "500.00",
79
+ }
80
+ mock_ledger_client.get_vault_net_deposit = AsyncMock(return_value=mock_response)
81
+
82
+ # Test
83
+ success, data = await adapter.get_vault_net_deposit(
84
+ wallet_address="0x1234567890123456789012345678901234567890"
85
+ )
86
+
87
+ assert success is True
88
+ assert data == mock_response
89
+ mock_ledger_client.get_vault_net_deposit.assert_called_once_with(
90
+ wallet_address="0x1234567890123456789012345678901234567890"
91
+ )
92
+
93
+ @pytest.mark.asyncio
94
+ async def test_record_deposit_success(self, adapter, mock_ledger_client):
95
+ """Test successful deposit recording"""
96
+ mock_response = {
97
+ "transaction_id": "tx_456",
98
+ "status": "recorded",
99
+ "timestamp": "2024-01-15T10:30:00Z",
100
+ }
101
+ mock_ledger_client.add_vault_deposit.return_value = mock_response
102
+
103
+ # Test
104
+ success, data = await adapter.record_deposit(
105
+ wallet_address="0x1234567890123456789012345678901234567890",
106
+ chain_id=8453,
107
+ token_address="0xA0b86a33E6441c8C06DdD4D4c4c4c4c4c4c4c4c4c",
108
+ token_amount="1000000000000000000",
109
+ usd_value="1000.00",
110
+ strategy_name="TestStrategy",
111
+ )
112
+
113
+ assert success is True
114
+ assert data == mock_response
115
+ mock_ledger_client.add_vault_deposit.assert_called_once_with(
116
+ wallet_address="0x1234567890123456789012345678901234567890",
117
+ chain_id=8453,
118
+ token_address="0xA0b86a33E6441c8C06DdD4D4c4c4c4c4c4c4c4c4c",
119
+ token_amount="1000000000000000000",
120
+ usd_value="1000.00",
121
+ data=None,
122
+ strategy_name="TestStrategy",
123
+ )
124
+
125
+ @pytest.mark.asyncio
126
+ async def test_record_withdrawal_success(self, adapter, mock_ledger_client):
127
+ """Test successful withdrawal recording"""
128
+ mock_response = {
129
+ "transaction_id": "tx_789",
130
+ "status": "recorded",
131
+ "timestamp": "2024-01-15T11:00:00Z",
132
+ }
133
+ mock_ledger_client.add_vault_withdraw.return_value = mock_response
134
+
135
+ # Test
136
+ success, data = await adapter.record_withdrawal(
137
+ wallet_address="0x1234567890123456789012345678901234567890",
138
+ chain_id=8453,
139
+ token_address="0xA0b86a33E6441c8C06DdD4D4c4c4c4c4c4c4c4c4c",
140
+ token_amount="500000000000000000",
141
+ usd_value="500.00",
142
+ strategy_name="TestStrategy",
143
+ )
144
+
145
+ assert success is True
146
+ assert data == mock_response
147
+
148
+ @pytest.mark.asyncio
149
+ async def test_record_operation_success(self, adapter, mock_ledger_client):
150
+ """Test successful operation recording"""
151
+ mock_response = {
152
+ "operation_id": "op_123",
153
+ "status": "recorded",
154
+ "timestamp": "2024-01-15T10:45:00Z",
155
+ }
156
+ mock_ledger_client.add_vault_operation.return_value = mock_response
157
+
158
+ # Test
159
+ operation_data = {
160
+ "type": "SWAP",
161
+ "from_token": "0xA0b86a33E6441c8C06DdD4D4c4c4c4c4c4c4c4c4c",
162
+ "to_token": "0xB1c97a44F7552d9Dd5e5e5e5e5e5e5e5e5e5e5e5e5e",
163
+ "amount_in": "1000000000000000000",
164
+ "amount_out": "995000000000000000",
165
+ }
166
+
167
+ success, data = await adapter.record_operation(
168
+ wallet_address="0x1234567890123456789012345678901234567890",
169
+ operation_data=operation_data,
170
+ usd_value="1000.00",
171
+ strategy_name="TestStrategy",
172
+ )
173
+
174
+ assert success is True
175
+ assert data == mock_response
176
+
177
+ @pytest.mark.asyncio
178
+ async def test_get_transaction_summary_success(self, adapter, mock_ledger_client):
179
+ """Test successful transaction summary generation"""
180
+ mock_transactions = {
181
+ "transactions": [
182
+ {"operation": "DEPOSIT", "amount": "1000000000000000000"},
183
+ {"operation": "WITHDRAW", "amount": "500000000000000000"},
184
+ {"operation": "SWAP", "amount": "200000000000000000"},
185
+ ]
186
+ }
187
+ mock_ledger_client.get_vault_transactions.return_value = mock_transactions
188
+
189
+ # Test
190
+ success, data = await adapter.get_transaction_summary(
191
+ wallet_address="0x1234567890123456789012345678901234567890", limit=10
192
+ )
193
+
194
+ assert success is True
195
+ assert data["total_transactions"] == 3
196
+ assert data["operations"]["deposits"] == 1
197
+ assert data["operations"]["withdrawals"] == 1
198
+ assert data["operations"]["operations"] == 1
199
+
200
+ def test_adapter_type(self, adapter):
201
+ """Test adapter has adapter_type"""
202
+ assert adapter.adapter_type == "LEDGER"
@@ -0,0 +1,218 @@
1
+ # Pool Adapter
2
+
3
+ A Wayfinder adapter that provides high-level operations for DeFi pool data and analytics. This adapter wraps the `PoolClient` to offer strategy-friendly methods for discovering, analyzing, and filtering yield opportunities.
4
+
5
+ ## Capabilities
6
+
7
+ - `pool.read`: Read pool information and metadata
8
+ - `pool.analytics`: Get comprehensive pool analytics
9
+ - `pool.discovery`: Find and search pools
10
+ - `llama.data`: Access Llama protocol data
11
+ - `pool.reports`: Get pool reports and analytics
12
+
13
+ ## Configuration
14
+
15
+ The adapter uses the PoolClient which automatically handles authentication and API configuration through the Wayfinder settings. No additional configuration is required.
16
+
17
+ The PoolClient will automatically:
18
+ - Use the WAYFINDER_API_URL from settings
19
+ - Handle authentication via environment variables or config.json
20
+ - Manage token refresh and retry logic
21
+
22
+ ## Usage
23
+
24
+ ### Initialize the Adapter
25
+
26
+ ```python
27
+ from wayfinder_paths.vaults.adapters.pool_adapter.adapter import PoolAdapter
28
+
29
+ # No configuration needed - uses PoolClient with automatic settings
30
+ adapter = PoolAdapter()
31
+ ```
32
+
33
+ ### Get Pools by IDs
34
+
35
+ ```python
36
+ success, data = await adapter.get_pools_by_ids(
37
+ pool_ids=["pool-123", "pool-456"],
38
+ merge_external=True
39
+ )
40
+ if success:
41
+ pools = data.get("pools", [])
42
+ print(f"Found {len(pools)} pools")
43
+ else:
44
+ print(f"Error: {data}")
45
+ ```
46
+
47
+ ### Get All Pools
48
+
49
+ ```python
50
+ success, data = await adapter.get_all_pools(merge_external=False)
51
+ if success:
52
+ pools = data.get("pools", [])
53
+ print(f"Total pools available: {len(pools)}")
54
+ else:
55
+ print(f"Error: {data}")
56
+ ```
57
+
58
+ ### Get Combined Pool Reports
59
+
60
+ ```python
61
+ success, data = await adapter.get_combined_pool_reports()
62
+ if success:
63
+ reports = data.get("reports", [])
64
+ print(f"Received {len(reports)} combined reports")
65
+ else:
66
+ print(f"Error: {data}")
67
+ ```
68
+
69
+ ### Find High Yield Pools
70
+
71
+ ```python
72
+ success, data = await adapter.find_high_yield_pools(
73
+ min_apy=0.03, # 3% minimum APY
74
+ min_tvl=500000, # $500k minimum TVL
75
+ stablecoin_only=True,
76
+ network_codes=["base", "ethereum"]
77
+ )
78
+ if success:
79
+ pools = data.get("pools", [])
80
+ print(f"Found {len(pools)} high-yield pools")
81
+ for pool in pools:
82
+ print(f"Pool: {pool.get('id')} - APY: {pool.get('llama_apy_pct')}%")
83
+ else:
84
+ print(f"Error: {data}")
85
+ ```
86
+
87
+ ### Get Pool Analytics
88
+
89
+ ```python
90
+ success, data = await adapter.get_pool_analytics(
91
+ pool_ids=["pool-123", "pool-456"]
92
+ )
93
+ if success:
94
+ analytics = data.get("analytics", [])
95
+ for pool_analytics in analytics:
96
+ pool = pool_analytics.get("pool", {})
97
+ combined_apy = pool_analytics.get("combined_apy", 0)
98
+ tvl_usd = pool_analytics.get("tvl_usd", 0)
99
+ print(f"Pool: {pool.get('name')} - APY: {combined_apy:.2%} - TVL: ${tvl_usd:,.0f}")
100
+ else:
101
+ print(f"Error: {data}")
102
+ ```
103
+
104
+ ### Search Pools
105
+
106
+ ```python
107
+ success, data = await adapter.search_pools(
108
+ query="USDC",
109
+ limit=10
110
+ )
111
+ if success:
112
+ pools = data.get("pools", [])
113
+ print(f"Found {len(pools)} pools matching 'USDC'")
114
+ for pool in pools:
115
+ print(f"Pool: {pool.get('name')} - {pool.get('symbol')}")
116
+ else:
117
+ print(f"Error: {data}")
118
+ ```
119
+
120
+ ### Get Llama Matches
121
+
122
+ ```python
123
+ success, data = await adapter.get_llama_matches()
124
+ if success:
125
+ matches = data.get("matches", [])
126
+ print(f"Found {len(matches)} Llama matches")
127
+ for match in matches:
128
+ if match.get("llama_stablecoin"):
129
+ print(f"Stablecoin pool: {match.get('id')} - APY: {match.get('llama_apy_pct')}%")
130
+ else:
131
+ print(f"Error: {data}")
132
+ ```
133
+
134
+ ### Get Llama Reports
135
+
136
+ ```python
137
+ success, data = await adapter.get_llama_reports(
138
+ identifiers=["pool-123", "usd-coin-base", "base_0x1234..."]
139
+ )
140
+ if success:
141
+ reports = data
142
+ for identifier, report in reports.items():
143
+ print(f"Report for {identifier}: APY {report.get('llama_apy_pct', 0)}%")
144
+ else:
145
+ print(f"Error: {data}")
146
+ ```
147
+
148
+ ## Advanced Usage
149
+
150
+ ### Filtering High Yield Pools
151
+
152
+ The `find_high_yield_pools` method provides powerful filtering capabilities:
153
+
154
+ ```python
155
+ # Find stablecoin pools with high yield on specific networks
156
+ success, data = await adapter.find_high_yield_pools(
157
+ min_apy=0.05, # 5% minimum APY
158
+ min_tvl=1000000, # $1M minimum TVL
159
+ stablecoin_only=True, # Only stablecoin pools
160
+ network_codes=["base", "arbitrum"] # Specific networks
161
+ )
162
+
163
+ if success:
164
+ pools = data.get("pools", [])
165
+ # Pools are automatically sorted by APY (highest first)
166
+ best_pool = pools[0] if pools else None
167
+ if best_pool:
168
+ print(f"Best pool: {best_pool.get('id')} - APY: {best_pool.get('llama_apy_pct')}%")
169
+ ```
170
+
171
+ ### Comprehensive Pool Analysis
172
+
173
+ ```python
174
+ # Get detailed analytics for specific pools
175
+ success, data = await adapter.get_pool_analytics(["pool-123"])
176
+
177
+ if success:
178
+ analytics = data.get("analytics", [])
179
+ for pool_analytics in analytics:
180
+ pool = pool_analytics.get("pool", {})
181
+ llama_data = pool_analytics.get("llama_data", {})
182
+
183
+ print(f"Pool: {pool.get('name')}")
184
+ print(f" Combined APY: {pool_analytics.get('combined_apy', 0):.2%}")
185
+ print(f" TVL: ${pool_analytics.get('tvl_usd', 0):,.0f}")
186
+ print(f" Llama APY: {llama_data.get('llama_apy_pct', 0)}%")
187
+ print(f" Stablecoin: {llama_data.get('llama_stablecoin', False)}")
188
+ print(f" IL Risk: {llama_data.get('llama_il_risk', 'unknown')}")
189
+ ```
190
+
191
+ ## API Endpoints
192
+
193
+ The adapter uses the following Wayfinder API endpoints:
194
+
195
+ - `GET /api/v1/public/pools/?pool_ids=X` - Get pools by IDs
196
+ - `GET /api/v1/public/pools/` - Get all pools
197
+ - `GET /api/v1/public/pools/combined/` - Get combined pool reports
198
+ - `GET /api/v1/public/pools/llama/matches/` - Get Llama matches
199
+ - `GET /api/v1/public/pools/llama/reports/` - Get Llama reports
200
+
201
+ ## Error Handling
202
+
203
+ All methods return a tuple of `(success: bool, data: Any)` where:
204
+ - `success` is `True` if the operation succeeded
205
+ - `data` contains the response data on success or error message on failure
206
+
207
+ ## Testing
208
+
209
+ Run the adapter tests:
210
+
211
+ ```bash
212
+ pytest wayfinder_paths/vaults/adapters/pool_adapter/test_adapter.py -v
213
+ ```
214
+
215
+ ## Dependencies
216
+
217
+ - `PoolClient` - Low-level API client for pool operations
218
+ - `BaseAdapter` - Base adapter class with common functionality
@@ -0,0 +1,7 @@
1
+ """
2
+ Pool Adapter Package
3
+ """
4
+
5
+ from .adapter import PoolAdapter
6
+
7
+ __all__ = ["PoolAdapter"]