diff --git a/src/actions/ethereum/SendFormActions.js b/src/actions/ethereum/SendFormActions.js index 8743ff18..417513b7 100644 --- a/src/actions/ethereum/SendFormActions.js +++ b/src/actions/ethereum/SendFormActions.js @@ -251,6 +251,7 @@ export const onAmountChange = ( shouldUpdateLocalAmount: boolean = true ): ThunkAction => (dispatch: Dispatch, getState: GetState): void => { const state = getState().sendFormEthereum; + dispatch({ type: SEND.CHANGE, networkType: 'ethereum', @@ -265,7 +266,7 @@ export const onAmountChange = ( if (shouldUpdateLocalAmount) { const { localCurrency } = getState().sendFormEthereum; - const fiatRates = getState().fiat.find(f => f.network === state.networkName); + const fiatRates = getState().fiat.find(f => f.network === state.currency.toLowerCase()); const localAmount = toFiatCurrency(amount, localCurrency, fiatRates); dispatch(onLocalAmountChange(localAmount, false)); } @@ -280,7 +281,6 @@ export const onLocalAmountChange = ( ): ThunkAction => (dispatch: Dispatch, getState: GetState): void => { const state = getState().sendFormEthereum; const { localCurrency } = getState().sendFormEthereum; - const fiatRates = getState().fiat.find(f => f.network === state.networkName); const { network } = getState().selectedAccount; // updates localAmount @@ -300,6 +300,7 @@ export const onLocalAmountChange = ( if (shouldUpdateAmount) { if (!network) return; // converts amount in local currency to crypto currency that will be sent + const fiatRates = getState().fiat.find(f => f.network === state.currency.toLowerCase()); const amount = fromFiatCurrency(localAmount, localCurrency, fiatRates, network.decimals); dispatch(onAmountChange(amount, false)); } @@ -364,6 +365,9 @@ export const onCurrencyChange = (currency: { value: string, label: string }): Th gasLimit, }, }); + + // Recalculates local amount with new currency rates + dispatch(onAmountChange(state.amount, true)); }; /* diff --git a/src/services/CoingeckoService.js b/src/services/CoingeckoService.js index f39bd0a7..5bdd1097 100644 --- a/src/services/CoingeckoService.js +++ b/src/services/CoingeckoService.js @@ -3,6 +3,8 @@ import { httpRequest } from 'utils/networkUtils'; import { resolveAfter } from 'utils/promiseUtils'; import { READY } from 'actions/constants/localStorage'; +import * as TOKEN from 'actions/constants/token'; +import type { Token } from 'reducers/TokensReducer'; import type { Middleware, @@ -14,8 +16,15 @@ import type { GetState, } from 'flowtype'; +const BASE_URL = 'https://api.coingecko.com/'; + export const RATE_UPDATE: 'rate__update' = 'rate__update'; +export type NetworkRate = { + network: string, + rates: { [string]: number }, +}; + export type FiatRateAction = { type: typeof RATE_UPDATE, network: string, @@ -58,6 +67,49 @@ const loadRateAction = (): AsyncAction => async ( await resolveAfter(50000); }; +const fetchCoinRate = async (id: string): Promise => { + const url = new URL(`/api/v3/coins/${id}`, BASE_URL); + url.searchParams.set('tickers', 'false'); + url.searchParams.set('market_data', 'true'); + url.searchParams.set('community_data', 'false'); + url.searchParams.set('developer_data', 'false'); + url.searchParams.set('sparkline', 'false'); + + const response = await fetch(url.toString()); + const rates = await response.json(); + return rates; +}; + +const fetchCoinList = async (): Promise => { + const url = new URL('/api/v3/coins/list', BASE_URL); + + const response = await fetch(url.toString()); + const tokens = await response.json(); + return tokens; +}; + +const loadTokenRateAction = (token: Token): AsyncAction => async ( + dispatch: Dispatch +): Promise => { + const { symbol } = token; + try { + const tokens = await fetchCoinList(); + const tokenData = tokens.find(t => t.symbol === symbol.toLowerCase()); + if (!tokenData) return; + + const res = await fetchCoinRate(tokenData.id); + if (res) { + dispatch({ + type: RATE_UPDATE, + network: res.symbol, + rates: res.market_data.current_price, + }); + } + } catch (err) { + console.log(err); + } +}; + /** * Middleware */ @@ -70,6 +122,10 @@ const CoingeckoService: Middleware = (api: MiddlewareAPI) => (next: MiddlewareDi api.dispatch(loadRateAction()); } + if (action.type === TOKEN.ADD) { + api.dispatch(loadTokenRateAction(action.payload)); + } + return action; };