Skip to content

Commit 90fc710

Browse files
codebydivineclaude
andcommitted
feat: optimize SOL price API and integrate through main TokenAPI
- Optimize SOL price calculation with smart caching and auto-tuning - Add volatility-based TTL (1min volatile, 5min stable markets) - Implement progressive retry with parameter auto-adjustment - Add IQR outlier filtering and confidence scoring - Consolidate from 4 methods to 1 smart method - Remove direct SVMTokenAPI exposure, integrate via main TokenAPI - Add comprehensive examples demonstrating optimized functionality - Update all tests for new optimized API (250 tests passing, 96% coverage) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent e3695e6 commit 90fc710

File tree

5 files changed

+633
-3
lines changed

5 files changed

+633
-3
lines changed

examples/endpoints/svm/sol_price.py

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
"""
2+
Example: Optimized SOL price calculation with smart SVM API.
3+
4+
This example demonstrates the new optimized SOL price functionality:
5+
1. Super simple price retrieval with smart defaults
6+
2. Detailed statistics with confidence scoring
7+
3. Automatic caching with volatility-based TTL
8+
4. Zero-config usage - just works!
9+
"""
10+
11+
import asyncio
12+
import os
13+
import sys
14+
import time
15+
from datetime import datetime
16+
17+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
18+
19+
from dotenv import load_dotenv
20+
21+
from thegraph_token_api import SwapPrograms, TokenAPI
22+
23+
# Load environment variables
24+
load_dotenv()
25+
26+
27+
async def example_simple_usage():
28+
"""Example: Super simple SOL price - just one line!"""
29+
print("\n=== ✨ Optimized Simple Usage ===")
30+
31+
api_key = os.getenv("THEGRAPH_API_KEY")
32+
if not api_key:
33+
print("Error: THEGRAPH_API_KEY not found in environment")
34+
return
35+
36+
api = TokenAPI(api_key=api_key)
37+
# One line to get SOL price - that's it!
38+
price = await api.svm.get_sol_price()
39+
40+
if price:
41+
print(f"💰 Current SOL price: ${price:.2f}")
42+
print("✅ Auto-cached with smart TTL based on volatility")
43+
print("⚡ Smart retry logic with progressive sampling")
44+
print("🎯 Automatic outlier filtering using IQR method")
45+
else:
46+
print("❌ Failed to get SOL price")
47+
48+
49+
async def example_with_confidence():
50+
"""Example: Get SOL price with confidence and stats."""
51+
print("\n=== 📊 Price with Intelligence ===")
52+
53+
api_key = os.getenv("THEGRAPH_API_KEY")
54+
if not api_key:
55+
print("Error: THEGRAPH_API_KEY not found in environment")
56+
return
57+
58+
api = TokenAPI(api_key=api_key)
59+
# Get detailed stats with one parameter
60+
stats = await api.svm.get_sol_price(include_stats=True)
61+
62+
if stats and stats.get("price"):
63+
print(f"💰 Price: ${stats['price']:.2f}")
64+
print(f"📈 Confidence: {stats['confidence']:.0%}")
65+
print(f"📊 Trades analyzed: {stats['trades_analyzed']}")
66+
print(f"📉 Volatility: {stats['std_deviation']:.2f}")
67+
print(f"⏰ Data age: {datetime.now().timestamp() - stats['timestamp']:.0f}s")
68+
69+
# Show confidence interpretation
70+
conf = stats["confidence"]
71+
if conf >= 0.8:
72+
print("🟢 High confidence - excellent data quality")
73+
elif conf >= 0.5:
74+
print("🟡 Medium confidence - good data quality")
75+
else:
76+
print("🟠 Low confidence - limited data available")
77+
else:
78+
print("❌ No price data available")
79+
80+
81+
async def example_cached_performance():
82+
"""Example: Show smart caching in action."""
83+
print("\n=== ⚡ Smart Caching Demo ===")
84+
85+
api_key = os.getenv("THEGRAPH_API_KEY")
86+
if not api_key:
87+
print("Error: THEGRAPH_API_KEY not found in environment")
88+
return
89+
90+
api = TokenAPI(api_key=api_key)
91+
92+
# First call - fetches from API
93+
start = time.time()
94+
price1 = await api.svm.get_sol_price()
95+
time1 = time.time() - start
96+
97+
# Second call - uses smart cache
98+
start = time.time()
99+
price2 = await api.svm.get_sol_price()
100+
time2 = time.time() - start
101+
102+
print(f"🌐 First call (API): ${price1:.2f} - took {time1:.2f}s")
103+
print(f"⚡ Second call (cache): ${price2:.2f} - took {time2:.3f}s")
104+
print(f"🚀 Speedup: {time1 / time2:.0f}x faster!")
105+
106+
# Show cache intelligence
107+
stats = await api.svm.get_sol_price(include_stats=True)
108+
if stats:
109+
volatility = stats["std_deviation"] / stats["price"]
110+
ttl = 60 if volatility > 0.05 else 300
111+
print(f"🧠 Smart TTL: {ttl}s (based on {volatility:.1%} volatility)")
112+
113+
114+
async def example_integration():
115+
"""Example: Show how it integrates seamlessly with other SVM functions."""
116+
print("\n=== 🔗 Seamless Integration ===")
117+
118+
api_key = os.getenv("THEGRAPH_API_KEY")
119+
if not api_key:
120+
print("Error: THEGRAPH_API_KEY not found in environment")
121+
return
122+
123+
api = TokenAPI(api_key=api_key)
124+
# All in one API session - share connections efficiently
125+
126+
# Get current SOL price
127+
sol_price = await api.svm.get_sol_price()
128+
129+
# Get recent Jupiter swaps
130+
swaps = await api.svm.swaps(program_id=SwapPrograms.JUPITER_V6, limit=3)
131+
132+
# Get SOL balance example (if you have a token account)
133+
# balances = await api.svm.balances(mint="So11111111111111111111111111111111111111112")
134+
135+
if sol_price:
136+
print(f"💰 Current SOL price: ${sol_price:.2f}")
137+
138+
if swaps:
139+
print(f"📋 Recent Jupiter swaps: {len(swaps)}")
140+
if len(swaps) > 0:
141+
latest = swaps[0]
142+
print(f" Latest: {getattr(latest, 'datetime', 'N/A')}")
143+
144+
print("🎯 All data fetched in same session with optimized connections!")
145+
146+
147+
async def main():
148+
"""Run all examples."""
149+
await example_simple_usage()
150+
await example_with_confidence()
151+
await example_cached_performance()
152+
await example_integration()
153+
154+
155+
if __name__ == "__main__":
156+
asyncio.run(main())

src/thegraph_token_api/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ async def main():
2222
# SVM (Solana)
2323
sol_balances = await api.svm.balances(mint="So11111111111111111111111111111111111111112")
2424
sol_swaps = await api.svm.swaps(program_id=SwapPrograms.RAYDIUM, limit=5)
25+
sol_price = await api.svm.get_sol_price() # Get current SOL price with smart caching
2526
2627
# Utility
2728
health = await api.health()

src/thegraph_token_api/simple.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,40 @@ async def transfers(
322322
)
323323
return convert_list_to_models(data, SolanaTransfer)
324324

325+
async def get_sol_price(
326+
self, *, include_stats: bool = False, network: SolanaNetworkId | str = SolanaNetworkId.SOLANA
327+
) -> float | dict[str, Any] | None:
328+
"""
329+
Get current SOL price in USD with smart caching and auto-optimization.
330+
331+
This method automatically:
332+
- Uses optimal trade sampling based on market conditions
333+
- Caches results with volatility-based TTL
334+
- Handles retries and outlier filtering
335+
- Adapts parameters based on data availability
336+
337+
Args:
338+
include_stats: If True, returns detailed statistics instead of just price
339+
network: Solana network to use (default: mainnet)
340+
341+
Returns:
342+
float: Current SOL price in USD (if include_stats=False)
343+
dict: Price with statistics (if include_stats=True)
344+
None: If no valid price data available
345+
346+
Example:
347+
```python
348+
# Simple usage
349+
price = await api.svm.get_sol_price()
350+
print(f"SOL price: ${price:.2f}")
351+
352+
# With detailed stats
353+
stats = await api.svm.get_sol_price(include_stats=True)
354+
print(f"Price: ${stats['price']:.2f} (confidence: {stats['confidence']:.0%})")
355+
```
356+
"""
357+
return await self._api._svm_get_sol_price(include_stats=include_stats, network=network) # type: ignore[no-any-return]
358+
325359

326360
class TokenAPI:
327361
"""
@@ -350,6 +384,7 @@ class TokenAPI:
350384
sol_balances = await api.svm.balances(mint="So11111111111111111111111111111111111111112")
351385
sol_swaps = await api.svm.swaps(program_id=SwapPrograms.RAYDIUM, limit=10)
352386
sol_transfers = await api.svm.transfers(mint="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v") # pragma: allowlist secret
387+
sol_price = await api.svm.get_sol_price() # Get current SOL price
353388
354389
# Utility
355390
health = await api.health()
@@ -684,6 +719,15 @@ async def _svm_swaps(
684719
)
685720
return self._extract_data(response)
686721

722+
async def _svm_get_sol_price(
723+
self,
724+
include_stats: bool = False,
725+
network: SolanaNetworkId | str = SolanaNetworkId.SOLANA,
726+
) -> float | dict[str, Any] | None:
727+
"""Internal SVM SOL price implementation."""
728+
async with self._api.svm(str(network)) as client:
729+
return await client.get_sol_price(include_stats=include_stats) # type: ignore[no-any-return]
730+
687731
# ===== Utility Methods =====
688732

689733
async def version(self) -> list[dict[Any, Any]]:

0 commit comments

Comments
 (0)