-
Notifications
You must be signed in to change notification settings - Fork 7
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
Show token prices #1382
Show token prices #1382
Conversation
✅ Deploy Preview for fractal-framework-dev ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
Not quite working. Went to Decent DAO on mainnet and it is showing only $9,708.66 |
Seeing that this implementation contained a CoinGecko API key surprised me, frankly. I suppose it's been a minute (~2 years) since I last implemented a CoinGecko powered pricing mechanism in a frontend app. Back then, the API was keyless -- totally open without any need for an API key, and rate limiting was simply enforced via IP address. Even still, those limits were quite generous. I believe they allowed something like up to 30 requests per minute. As long as I wrote some smart code to minimize API requests, there was no way any one user was going to hit those limits unless they refreshed the page over and over and over. I see that this isn't the case any longer, and I wonder if the implementation in this PR as it currently stands will work for us. Here are the problems I see:
So where does that leave us? I'm not sure.
|
Yeah, that's because I haven't added API key to the secrets yet. I was a bit concerned about same points that @adamgall raised, so just wanted to discuss approach first. I'm leaning towards proxying request through our own Netlify API function. |
After quick research - it seems like other popular pricing APIs either having pretty much same limitations (like https://pro.coinmarketcap.com/api/pricing ) or way less user friendly (like https://www.coinapi.io/market-data-api - here you need to execute 1 request per asset and their free plan is just 100 requests per day). I'm rather leaning towards implementing Netlify function and proxying call through it, hiding API key from FE. This request is executed primarily from Treasury page, which I wouldn't expect to be seen much. And for fetching the total for displaying on DAO Dashboard we could simply cache this value for some reasonable time (like 1h or even 1d and then adding a tooltip saying that this value updated once per day) on our side (not FE but function side), this will help reducing the cost. |
…oken prices through Netlify blob
…ing tokensStringParam once more, move const now down closer to the try...catch block of validating/setting cache
- Don't throw error when query param is not a valid address, just skip it. - Don't send "ethereum" string as a token to CG token API endpoint. - Return ethereum price in response if all data can be found in cache. - Fix expiration conditionals - Handle case when CoinGecko responds to an address but there's no usd price - Add entries to blob store (with long expiration) for token addresses that CoinGecko doesn't track, to avoid constantly asking about these tokens
I've just pushed up a pretty major refactor. Some things to note:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more thing I just thought of -- we should namespace these blob keys to include the network. That way when we start more seriously supporting other production networks we won't have token address conflicts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one thing that seems off to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm testing this locally, and it's not working. I have a value of "5" (minutes) set in my env var, but putting in a console.log right before the fetch to coingecko shows that it's making that request every time the frontend calls the API (every ~20 seconds).
netlify/functions/tokenPrices.mts
Outdated
|
||
// Let's pull out all of the expired addresses from our cache. | ||
const expiredCachedTokenAddresses = cachedTokenPrices | ||
.filter(tokenPrice => tokenPrice.metadata.fetched + config.cacheTime < config.now) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we should be converting this cacheTime
from "minutes" to "seconds" heh
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should just specify the env var value in miliseconds? config.now
gives milliseconds and I feel like it's more appropriate to not convert minutes to milliseconds here. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
config.now
gives seconds (https://github.com/decent-dao/fractal-interface/pull/1382/files#diff-284b3930e569c4259e85b685d36c139226ef2a210eaeb25f614b752fd1b2e910R197)
We did name the env var TOKEN_PRICE_CACHE_INTERVAL_MINUTES
, which specifies that the value should be MINUTES
. Minutes are a lot easier to reason about than milliseconds, when setting configs in an env var.
I think the cleaner solution is to convert the value to seconds when setting the config property here: https://github.com/decent-dao/fractal-interface/pull/1382/files#diff-284b3930e569c4259e85b685d36c139226ef2a210eaeb25f614b752fd1b2e910R198
const cacheTime = parseInt(process.env.TOKEN_PRICE_CACHE_INTERVAL_MINUTES) * 60
My TL;DR is that:
- I'd like the user-facing number to be denominated in "minutes" (because that seems like an appropriate resolution for setting things like a cache expiration).
- I'd like the code and data to be denominated in seconds (because we're using Unix timestamps here and those are in seconds).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mudrila i just pushed up the fix, no worries
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's go!
Description
This PR implements fetching coin prices from CoinGecko.
The implementation is as dumb as you could only imagine. Probably we could save some requests to putting returned value of
useFormatCoins
into global context - but that might lead us into unnecessary implementation over-engineering (given the fact that we could be migrating to the Safe API Kit once they'll release pricing service anyway).Notes
Issue
Closes #1362
Testing
Screenshots (if applicable)