ACINQ / phoenix

Phoenix is a self-custodial Bitcoin wallet using Lightning to send/receive payments.
https://phoenix.acinq.co
Apache License 2.0
644 stars 97 forks source link

Only auto-refresh the currencies needed by the app #352

Closed robbiehanson closed 1 year ago

robbiehanson commented 1 year ago

The CurrencyManager is currently fetching data from 5 different sources. This is largely unnecessary work for most users. For example, if you're only using the Euro or the US Dollar, then you only really need to fetch from 1 source.

This PR optimizes the auto-refresh task to only fetch the currencies needed by the app. For example, if the user is only using COP (Colombian Pesos), then the currency manager will only fetch:

and we'll see something like this in the logs:

[CurrencyManager] API(blockchain.info): Next refresh: 0s
[CurrencyManager] Fetching 1 exchange rate(s) from blockchain.info
[CurrencyManager] API(coinbase): Next refresh: 0s
[CurrencyManager] Fetching 1 exchange rate(s) from coinbase
[CurrencyManager] API(coindesk): Nothing to refresh
[CurrencyManager] API(bluelytics): Nothing to refresh
[CurrencyManager] API(yadio): Nothing to refresh

The key to this optimization is the existing AppConfigurationManager.preferredFiatCurrencies:

data class PreferredFiatCurrencies(
   val primary: FiatCurrency,
   val others: Set<FiatCurrency>
) { /* ... */ }

val preferredFiatCurrencies: StateFlow<PreferredFiatCurrencies?>

(Where primary is the user's configured fiat currency, and others includes those in the Currency Converter)

So as long as the UI code properly updates AppConfigurationManager.preferredFiatCurrencies, then the CurrencyManager can optimize the auto-refresh logic, and perform much less work.