-
Notifications
You must be signed in to change notification settings - Fork 20
fix: add fallback price sources for wallet tokens #94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@Hebx is attempting to deploy a commit to the dark Team on Vercel. A member of the Team first needs to authorize it. |
|
Deployment failed with the following error: |
|
this is a good enhancement, because birdeye data is definitely expensive. the mallory wallet does support arbitrary spl tokens though, so we shouldn't just rely on fetching SOL and USDC/T prices. i'm not 100% sure off hand how robust coingecko's API is. can we refactor to do something like this:
and operate under the assumption that the user will have arbitrary SPL tokens in their wallet? |
Related Feature PRThis fix PR is now followed by a feature PR that builds on top of it: Feature PR: The feature PR adds:
Once this fix PR is merged, the feature PR can be reviewed and merged. |
- Add CoinGecko API as fallback for SOL price (free, no API key needed) - Improve Jupiter API error handling with timeouts - Add multi-tier fallback system: Birdeye -> Jupiter -> CoinGecko - Handle rate limits (429) gracefully with fallback sources - Add better logging for price fetching - Support multiple Birdeye response formats - Use fallback prices only for stablecoins (USDC/USDT) Fixes issue where wallet prices showed --.00 when Birdeye API was rate-limited or Jupiter had connection issues.
- Add tests for Jupiter API integration (endpoint selection, timeout handling) - Add tests for CoinGecko fallback mechanism - Add tests for fallback chain order and stablecoin prices - Add tests for error handling (ECONNREFUSED, rate limits) - Verify NaN validation for Jupiter API responses
256a355 to
1a0d8a9
Compare
…allback chain - Integrate Jupiter Price API V3 for efficient batch price fetching - Implement prioritized fallback chain: Jupiter → CoinGecko → Birdeye - Add support for arbitrary token price fetching (not just SOL) - Fix response parsing to handle Jupiter API V3 format (usdPrice field) - Add comprehensive logging for debugging price fetch failures - Improve error handling and fallback logic This ensures we get the most accurate real-time prices from Jupiter first, with reliable fallbacks for tokens Jupiter doesn't have prices for.
- Add tests for batch price fetching with Jupiter Price API V3 - Add tests for prioritized fallback chain (Jupiter -> CoinGecko -> Birdeye) - Add tests for arbitrary token price fetching from CoinGecko - Add tests for response format validation (usdPrice field) - Add tests for error handling and performance optimizations - Verify batch request efficiency vs individual requests
apps/server/src/routes/wallet/__tests__/holdings-price-fallback.test.ts
Outdated
Show resolved
Hide resolved
- Fix hasApiKey check from !process.env.JUPITER_API_KEY to !!process.env.JUPITER_API_KEY - Update test to conditionally check for correct endpoint based on API key presence - Test now correctly verifies lite-api.jup.ag when no key, api.jup.ag when key is set Fixes test failure where inverted logic caused wrong endpoint to be tested
- Fix hasApiKey check from !process.env.JUPITER_API_KEY to !!process.env.JUPITER_API_KEY - Update test to conditionally check for correct endpoint based on API key presence - Test now correctly verifies lite-api.jup.ag when no key, api.jup.ag when key is set Fixes test failure where inverted logic caused wrong endpoint to be tested
- Add GRID_ENV: production to both integration and E2E test jobs - Add debug step to verify environment variables are set before server starts - Improve error messages with better logging when server fails to start - This should fix backend server startup failures in GitHub Actions The debug step will help identify if secrets are missing or empty, which was causing the server to crash immediately on startup.
- Fix: Call fetchTokenPricesWithFallbacks instead of fetchMarketDataWithFallbacks This ensures Jupiter Price API V3 is prioritized as intended (Jupiter -> CoinGecko -> Birdeye) - Fix: Add isFinite check to price validation to prevent Infinity values This matches the test expectations and prevents calculation errors downstream Fixes the bug where the new Jupiter-first implementation was never called, and ensures price validation properly rejects Infinity values.
- Add CI-aware error messages in supabase.ts that detect GitHub Actions context - Configure dotenv to not override existing env vars (respects GitHub Actions secrets) - Add early validation checks in workflow before starting server - Improve error messages to help debug missing environment variables
The test was validating Jupiter's old swap/v1 endpoint, but the implementation now uses the price/v3 endpoint. Updated all endpoint references and validation logic to match the actual implementation: - Changed endpoint URLs from swap/v1 to price/v3 - Updated test descriptions to reference Price API V3 - Replaced outAmount validation with usdPrice validation - Added test for batch request URL construction with ids parameter - Updated fallback chain description to mention Price API V3 This ensures the test validates the actual production code and will catch regressions in the Jupiter Price API V3 integration.
Add isFinite() validation to prevent Infinity and -Infinity values from passing price validation checks. This fixes calculation errors downstream when computing token values. Fixed validation points: - CoinGecko SOL price validation - CoinGecko token price validation - Jupiter prices in result map - CoinGecko prices in result map - Birdeye prices in fallback chain - Birdeye prices in market data fetch - SOL price from fallbacks All price validations now follow the pattern: typeof price === 'number' && isFinite(price) && price > 0 This matches the test expectations in holdings-price-fallback.test.ts which explicitly tests for isFinite validation (line 71, 80).
- Add 'Validate required secrets' step in integration-tests and e2e-tests jobs - Check if GitHub secrets exist before attempting to start server - Provide clear error messages with instructions when secrets are missing - Fail fast with helpful guidance instead of generic environment variable errors This prevents the server from attempting to start with missing credentials and provides actionable error messages pointing to where secrets should be configured in GitHub Actions.
…ck-sources - Integrated Jupiter Price API V3 as primary price source - Added comprehensive test coverage for price fallback system - Updated CI workflow with secret validation - Improved error handling and validation for price data - Resolved merge conflicts in holdings-price-fallback.test.ts
fa719d1 to
28772e2
Compare
- Wrap fetch calls in try-finally blocks to ensure clearTimeout always executes - Fixes resource leaks when fetch() throws errors before timeout cleanup - Matches pattern used in birdeye client service
414f84e to
b81c86d
Compare
Problem
Wallet token prices were showing as $0.00 when:
This resulted in inaccurate wallet balance calculations and poor user experience.
Solution
Implemented a comprehensive multi-tier fallback system for fetching token prices with robust error handling and resource management.
Price Fetching Priority Chain
Key Features
🚀 Jupiter Price API V3 Integration
idsparameter with comma-separated mint addressesusdPricefield validation🔄 CoinGecko Fallback
🛡️ Robust Error Handling
clearTimeout()always executes✅ Data Validation
isFinite()checks prevent Infinity/NaN values🧪 Comprehensive Testing
🔧 CI/CD Improvements
Changes Made
Core Functionality
isFinite()checksCode Quality
Infrastructure
GRID_ENVconfiguration for productionTechnical Details
API Endpoints Used
Jupiter Price API V3:
https://lite-api.jup.ag/price/v3?ids=<comma-separated-addresses>https://api.jup.ag/price/v3?ids=<comma-separated-addresses>(with API key)CoinGecko:
https://api.coingecko.com/api/v3/simple/price?ids=solana&vs_currencies=usdhttps://api.coingecko.com/api/v3/simple/token_price/solana?contract_addresses=<address>&vs_currencies=usdPerformance Optimizations
Resource Management
Testing
Before & After
Before ❌
After ✅
Files Changed
apps/server/src/routes/wallet/holdings.ts- Core price fetching logicapps/server/src/routes/wallet/__tests__/holdings-price-fallback.test.ts- Test suiteapps/server/src/routes/wallet/__tests__/jupiter-price-api-v3.test.ts- Jupiter API tests.github/workflows/test.yml- CI improvementsapps/server/src/lib/supabase.ts- CI-aware error handlingapps/server/src/server.ts- Environment variable handlingRelated Issues
Fixes #93 - Real Token Holdings Not Displayed in Wallet & Grid Wallet Balance Not Triggered in Chat
Checklist