From 9498a4effa886b9f304c1fecc33eb1e2b8b9a488 Mon Sep 17 00:00:00 2001 From: Vladimir Volek Date: Wed, 7 Nov 2018 14:31:42 +0100 Subject: [PATCH 1/6] Added coingecko api --- public/data/appConfig.json | 4 +- src/flowtype/index.js | 2 +- src/reducers/FiatRateReducer.js | 18 ++++----- src/services/CoinmarketcapService.js | 1 + src/services/TickerService.js | 60 ++++++++++++++++++++++++++++ src/services/index.js | 4 +- 6 files changed, 73 insertions(+), 16 deletions(-) create mode 100644 src/services/TickerService.js diff --git a/public/data/appConfig.json b/public/data/appConfig.json index 08460609..ecce7034 100644 --- a/public/data/appConfig.json +++ b/public/data/appConfig.json @@ -59,11 +59,11 @@ "fiatValueTickers": [ { "network": "eth", - "url": "https://api.coinmarketcap.com/v1/ticker/ethereum/" + "url": "https://api.coingecko.com/api/v3/coins/ethereum" }, { "network": "etc", - "url": "https://api.coinmarketcap.com/v1/ticker/ethereum-classic/" + "url": "https://api.coingecko.com/api/v3/coins/ethereum-classic" } ], diff --git a/src/flowtype/index.js b/src/flowtype/index.js index f262aa49..e3eef1b7 100644 --- a/src/flowtype/index.js +++ b/src/flowtype/index.js @@ -31,7 +31,7 @@ import type { TokenAction } from 'actions/TokenActions'; import type { TrezorConnectAction } from 'actions/TrezorConnectActions'; import type { WalletAction } from 'actions/WalletActions'; import type { Web3Action } from 'actions/Web3Actions'; -import type { FiatRateAction } from 'services/CoinmarketcapService'; // this service has no action file, all is written inside one file +import type { FiatRateAction } from 'services/TickerService'; // this service has no action file, all is written inside one file import type { Device, diff --git a/src/reducers/FiatRateReducer.js b/src/reducers/FiatRateReducer.js index af190d11..2f63a69d 100644 --- a/src/reducers/FiatRateReducer.js +++ b/src/reducers/FiatRateReducer.js @@ -1,9 +1,9 @@ /* @flow */ -import { RATE_UPDATE } from 'services/CoinmarketcapService'; +import { RATE_UPDATE } from 'services/TickerService'; import type { Action } from 'flowtype'; -import type { FiatRateAction } from 'services/CoinmarketcapService'; +import type { FiatRateAction } from 'services/TickerService'; export type Fiat = { +network: string; @@ -14,15 +14,11 @@ export const initialState: Array = []; const update = (state: Array, action: FiatRateAction): Array => { const newState: Array = [...state]; - const exists: ?Fiat = newState.find(f => f.network === action.network); - if (exists) { - exists.value = action.rate.price_usd; - } else { - newState.push({ - network: action.network, - value: action.rate.price_usd, - }); - } + newState.push({ + network: action.network, + value: action.rate.current_price.usd, + }); + console.log('newState', newState); return newState; }; diff --git a/src/services/CoinmarketcapService.js b/src/services/CoinmarketcapService.js index d6c0e9ea..a35b50b7 100644 --- a/src/services/CoinmarketcapService.js +++ b/src/services/CoinmarketcapService.js @@ -30,6 +30,7 @@ const loadRateAction = (): AsyncAction => async (dispatch: Dispatch, getState: G config.fiatValueTickers.forEach(async (ticker) => { // const rate: ?Array = await JSONRequest(`${ticker.url}?convert=USD`, 'json'); const rate: ?Array = await httpRequest(`${ticker.url}?convert=USD`, 'json'); + console.log('rate'); if (rate) { dispatch({ type: RATE_UPDATE, diff --git a/src/services/TickerService.js b/src/services/TickerService.js new file mode 100644 index 00000000..42a71dd7 --- /dev/null +++ b/src/services/TickerService.js @@ -0,0 +1,60 @@ +/* @flow */ + +import { httpRequest } from 'utils/networkUtils'; +import { resolveAfter } from 'utils/promiseUtils'; +import { READY } from 'actions/constants/localStorage'; + +import type { + Middleware, + MiddlewareAPI, + MiddlewareDispatch, + Dispatch, + Action, + AsyncAction, + GetState, +} from 'flowtype'; + +export const RATE_UPDATE: 'rate__update' = 'rate__update'; + +export type FiatRateAction = { + type: typeof RATE_UPDATE; + network: string; + rate: any; +} + +const loadRateAction = (): AsyncAction => async (dispatch: Dispatch, getState: GetState): Promise => { + const { config } = getState().localStorage; + if (!config) return; + + try { + config.fiatValueTickers.forEach(async (ticker) => { + const response: ?Array = await httpRequest(`${ticker.url}?tickers=false&market_data=true&community_data=false&developer_data=false&sparkline=false`, 'json'); + if (response) { + console.log({ + type: RATE_UPDATE, + network: response.symbol, + rate: response.market_data, + }); + } + }); + } catch (error) { + // ignore error + } + + await resolveAfter(50000); +}; + +/** + * Middleware + */ +const TickerService: Middleware = (api: MiddlewareAPI) => (next: MiddlewareDispatch) => (action: Action): Action => { + next(action); + + if (action.type === READY) { + api.dispatch(loadRateAction()); + } + + return action; +}; + +export default TickerService; \ No newline at end of file diff --git a/src/services/index.js b/src/services/index.js index b2ed5a5b..c7b51c8f 100644 --- a/src/services/index.js +++ b/src/services/index.js @@ -2,7 +2,7 @@ import WalletService from './WalletService'; import LogService from './LogService'; import RouterService from './RouterService'; import LocalStorageService from './LocalStorageService'; -import CoinmarketcapService from './CoinmarketcapService'; +import TickerService from './TickerService'; import TrezorConnectService from './TrezorConnectService'; export default [ @@ -11,5 +11,5 @@ export default [ RouterService, LocalStorageService, TrezorConnectService, - CoinmarketcapService, + TickerService, ]; \ No newline at end of file From eaede07068005589bf4d4eb40f516505b6c58f87 Mon Sep 17 00:00:00 2001 From: Vladimir Volek Date: Wed, 7 Nov 2018 17:14:06 +0100 Subject: [PATCH 2/6] Propagate rate to ui --- src/reducers/FiatRateReducer.js | 3 +- src/services/CoinmarketcapService.js | 62 ------------------- src/services/TickerService.js | 2 +- .../components/AccountMenu/index.js | 2 +- .../Summary/components/Balance/index.js | 5 +- 5 files changed, 5 insertions(+), 69 deletions(-) delete mode 100644 src/services/CoinmarketcapService.js diff --git a/src/reducers/FiatRateReducer.js b/src/reducers/FiatRateReducer.js index 2f63a69d..ccc3e793 100644 --- a/src/reducers/FiatRateReducer.js +++ b/src/reducers/FiatRateReducer.js @@ -8,7 +8,7 @@ import type { FiatRateAction } from 'services/TickerService'; export type Fiat = { +network: string; value: string; -} +}; export const initialState: Array = []; @@ -18,7 +18,6 @@ const update = (state: Array, action: FiatRateAction): Array => { network: action.network, value: action.rate.current_price.usd, }); - console.log('newState', newState); return newState; }; diff --git a/src/services/CoinmarketcapService.js b/src/services/CoinmarketcapService.js deleted file mode 100644 index a35b50b7..00000000 --- a/src/services/CoinmarketcapService.js +++ /dev/null @@ -1,62 +0,0 @@ -/* @flow */ - -import { httpRequest } from 'utils/networkUtils'; -import { resolveAfter } from 'utils/promiseUtils'; -import { READY } from 'actions/constants/localStorage'; - -import type { - Middleware, - MiddlewareAPI, - MiddlewareDispatch, - Dispatch, - Action, - AsyncAction, - GetState, -} from 'flowtype'; - -export const RATE_UPDATE: 'rate__update' = 'rate__update'; - -export type FiatRateAction = { - type: typeof RATE_UPDATE; - network: string; - rate: any; -} - -const loadRateAction = (): AsyncAction => async (dispatch: Dispatch, getState: GetState): Promise => { - const { config } = getState().localStorage; - if (!config) return; - - try { - config.fiatValueTickers.forEach(async (ticker) => { - // const rate: ?Array = await JSONRequest(`${ticker.url}?convert=USD`, 'json'); - const rate: ?Array = await httpRequest(`${ticker.url}?convert=USD`, 'json'); - console.log('rate'); - if (rate) { - dispatch({ - type: RATE_UPDATE, - network: ticker.network, - rate: rate[0], - }); - } - }); - } catch (error) { - // ignore error - } - - await resolveAfter(50000); -}; - -/** - * Middleware - */ -const CoinmarketcapService: Middleware = (api: MiddlewareAPI) => (next: MiddlewareDispatch) => (action: Action): Action => { - next(action); - - if (action.type === READY) { - api.dispatch(loadRateAction()); - } - - return action; -}; - -export default CoinmarketcapService; \ No newline at end of file diff --git a/src/services/TickerService.js b/src/services/TickerService.js index 42a71dd7..a6f7d2ce 100644 --- a/src/services/TickerService.js +++ b/src/services/TickerService.js @@ -30,7 +30,7 @@ const loadRateAction = (): AsyncAction => async (dispatch: Dispatch, getState: G config.fiatValueTickers.forEach(async (ticker) => { const response: ?Array = await httpRequest(`${ticker.url}?tickers=false&market_data=true&community_data=false&developer_data=false&sparkline=false`, 'json'); if (response) { - console.log({ + dispatch({ type: RATE_UPDATE, network: response.symbol, rate: response.market_data, diff --git a/src/views/Wallet/components/LeftNavigation/components/AccountMenu/index.js b/src/views/Wallet/components/LeftNavigation/components/AccountMenu/index.js index f41efa2a..e137f0ae 100644 --- a/src/views/Wallet/components/LeftNavigation/components/AccountMenu/index.js +++ b/src/views/Wallet/components/LeftNavigation/components/AccountMenu/index.js @@ -136,7 +136,7 @@ const AccountMenu = (props: Props) => { balance = `${availableBalance} ${network.symbol}`; if (fiatRate) { const accountBalance = new BigNumber(availableBalance); - const fiat = accountBalance.times(fiatRate.value).toFixed(2); + const fiat = accountBalance.times(parseInt(fiatRate.value, 10)).toFixed(2); balance = `${availableBalance} ${network.symbol} / $${fiat}`; } } diff --git a/src/views/Wallet/views/Account/Summary/components/Balance/index.js b/src/views/Wallet/views/Account/Summary/components/Balance/index.js index 1968abe1..d0614f40 100644 --- a/src/views/Wallet/views/Account/Summary/components/Balance/index.js +++ b/src/views/Wallet/views/Account/Summary/components/Balance/index.js @@ -107,17 +107,16 @@ class AccountBalance extends PureComponent { render() { const { network } = this.props; const fiatRate: any = this.props.fiat.find(f => f.network === network.shortcut); - let accountBalance = ''; let fiatRateValue = ''; let fiat = ''; if (fiatRate) { + const fiatValue = Math.round(fiatRate.value * 100) / 100; accountBalance = new BigNumber(this.props.balance); - fiatRateValue = new BigNumber(fiatRate.value).toFixed(2); + fiatRateValue = new BigNumber(fiatValue).toFixed(2); fiat = accountBalance.times(fiatRateValue).toFixed(2); } - return ( Date: Wed, 7 Nov 2018 17:43:18 +0100 Subject: [PATCH 3/6] Fix flow --- src/services/TickerService.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/TickerService.js b/src/services/TickerService.js index a6f7d2ce..951d61d2 100644 --- a/src/services/TickerService.js +++ b/src/services/TickerService.js @@ -28,7 +28,7 @@ const loadRateAction = (): AsyncAction => async (dispatch: Dispatch, getState: G try { config.fiatValueTickers.forEach(async (ticker) => { - const response: ?Array = await httpRequest(`${ticker.url}?tickers=false&market_data=true&community_data=false&developer_data=false&sparkline=false`, 'json'); + const response = await httpRequest(`${ticker.url}?tickers=false&market_data=true&community_data=false&developer_data=false&sparkline=false`, 'json'); if (response) { dispatch({ type: RATE_UPDATE, From 9844983e0903d1d169dc92f63649a9ca4325eab0 Mon Sep 17 00:00:00 2001 From: Vladimir Volek Date: Wed, 7 Nov 2018 17:44:57 +0100 Subject: [PATCH 4/6] renamed service --- src/flowtype/index.js | 2 +- src/reducers/FiatRateReducer.js | 4 ++-- src/services/{TickerService.js => CoingeckoService.js} | 4 ++-- src/services/index.js | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) rename src/services/{TickerService.js => CoingeckoService.js} (89%) diff --git a/src/flowtype/index.js b/src/flowtype/index.js index e3eef1b7..72623205 100644 --- a/src/flowtype/index.js +++ b/src/flowtype/index.js @@ -31,7 +31,7 @@ import type { TokenAction } from 'actions/TokenActions'; import type { TrezorConnectAction } from 'actions/TrezorConnectActions'; import type { WalletAction } from 'actions/WalletActions'; import type { Web3Action } from 'actions/Web3Actions'; -import type { FiatRateAction } from 'services/TickerService'; // this service has no action file, all is written inside one file +import type { FiatRateAction } from 'services/CoingeckoService'; // this service has no action file, all is written inside one file import type { Device, diff --git a/src/reducers/FiatRateReducer.js b/src/reducers/FiatRateReducer.js index ccc3e793..6492fcec 100644 --- a/src/reducers/FiatRateReducer.js +++ b/src/reducers/FiatRateReducer.js @@ -1,9 +1,9 @@ /* @flow */ -import { RATE_UPDATE } from 'services/TickerService'; +import { RATE_UPDATE } from 'services/CoingeckoService'; import type { Action } from 'flowtype'; -import type { FiatRateAction } from 'services/TickerService'; +import type { FiatRateAction } from 'services/CoingeckoService'; export type Fiat = { +network: string; diff --git a/src/services/TickerService.js b/src/services/CoingeckoService.js similarity index 89% rename from src/services/TickerService.js rename to src/services/CoingeckoService.js index 951d61d2..b8fc96a4 100644 --- a/src/services/TickerService.js +++ b/src/services/CoingeckoService.js @@ -47,7 +47,7 @@ const loadRateAction = (): AsyncAction => async (dispatch: Dispatch, getState: G /** * Middleware */ -const TickerService: Middleware = (api: MiddlewareAPI) => (next: MiddlewareDispatch) => (action: Action): Action => { +const CoingeckoService: Middleware = (api: MiddlewareAPI) => (next: MiddlewareDispatch) => (action: Action): Action => { next(action); if (action.type === READY) { @@ -57,4 +57,4 @@ const TickerService: Middleware = (api: MiddlewareAPI) => (next: MiddlewareDispa return action; }; -export default TickerService; \ No newline at end of file +export default CoingeckoService; \ No newline at end of file diff --git a/src/services/index.js b/src/services/index.js index c7b51c8f..58a6e636 100644 --- a/src/services/index.js +++ b/src/services/index.js @@ -2,7 +2,7 @@ import WalletService from './WalletService'; import LogService from './LogService'; import RouterService from './RouterService'; import LocalStorageService from './LocalStorageService'; -import TickerService from './TickerService'; +import CoingeckoService from './CoingeckoService'; import TrezorConnectService from './TrezorConnectService'; export default [ @@ -11,5 +11,5 @@ export default [ RouterService, LocalStorageService, TrezorConnectService, - TickerService, + CoingeckoService, ]; \ No newline at end of file From 8e13b49d2e4aca684cb90726ca3df844253badc3 Mon Sep 17 00:00:00 2001 From: Vladimir Volek Date: Mon, 12 Nov 2018 10:36:40 +0100 Subject: [PATCH 5/6] Review implemented --- src/reducers/FiatRateReducer.js | 19 +++++++++++++++---- src/services/CoingeckoService.js | 2 +- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/reducers/FiatRateReducer.js b/src/reducers/FiatRateReducer.js index 6492fcec..a0b21603 100644 --- a/src/reducers/FiatRateReducer.js +++ b/src/reducers/FiatRateReducer.js @@ -14,10 +14,21 @@ export const initialState: Array = []; const update = (state: Array, action: FiatRateAction): Array => { const newState: Array = [...state]; - newState.push({ - network: action.network, - value: action.rate.current_price.usd, - }); + let exists: ?Fiat = newState.find(f => f.network === action.network); + const { network, rate } = action; + + if (exists) { + exists = { + network, + value: rate, + }; + } else { + newState.push({ + network, + value: rate, + }); + } + return newState; }; diff --git a/src/services/CoingeckoService.js b/src/services/CoingeckoService.js index b8fc96a4..c6607840 100644 --- a/src/services/CoingeckoService.js +++ b/src/services/CoingeckoService.js @@ -33,7 +33,7 @@ const loadRateAction = (): AsyncAction => async (dispatch: Dispatch, getState: G dispatch({ type: RATE_UPDATE, network: response.symbol, - rate: response.market_data, + rate: response.market_data.current_price.usd, }); } }); From d3093313d6626ffd06fe9b804aaba39cc129516d Mon Sep 17 00:00:00 2001 From: Szymon Lesisz Date: Mon, 12 Nov 2018 12:39:24 +0100 Subject: [PATCH 6/6] fix fiat rate value in reducer --- src/reducers/FiatRateReducer.js | 21 ++++++------------- src/services/CoingeckoService.js | 2 +- .../components/AccountMenu/index.js | 2 +- .../Summary/components/Balance/index.js | 5 ++--- 4 files changed, 10 insertions(+), 20 deletions(-) diff --git a/src/reducers/FiatRateReducer.js b/src/reducers/FiatRateReducer.js index a0b21603..1b5164f6 100644 --- a/src/reducers/FiatRateReducer.js +++ b/src/reducers/FiatRateReducer.js @@ -13,23 +13,14 @@ export type Fiat = { export const initialState: Array = []; const update = (state: Array, action: FiatRateAction): Array => { - const newState: Array = [...state]; - let exists: ?Fiat = newState.find(f => f.network === action.network); + const affected = state.find(f => f.network === action.network); + const otherRates = state.filter(d => d !== affected); const { network, rate } = action; - if (exists) { - exists = { - network, - value: rate, - }; - } else { - newState.push({ - network, - value: rate, - }); - } - - return newState; + return otherRates.concat([{ + network, + value: rate.toFixed(2), + }]); }; export default (state: Array = initialState, action: Action): Array => { diff --git a/src/services/CoingeckoService.js b/src/services/CoingeckoService.js index c6607840..612af829 100644 --- a/src/services/CoingeckoService.js +++ b/src/services/CoingeckoService.js @@ -19,7 +19,7 @@ export const RATE_UPDATE: 'rate__update' = 'rate__update'; export type FiatRateAction = { type: typeof RATE_UPDATE; network: string; - rate: any; + rate: number; } const loadRateAction = (): AsyncAction => async (dispatch: Dispatch, getState: GetState): Promise => { diff --git a/src/views/Wallet/components/LeftNavigation/components/AccountMenu/index.js b/src/views/Wallet/components/LeftNavigation/components/AccountMenu/index.js index e137f0ae..f41efa2a 100644 --- a/src/views/Wallet/components/LeftNavigation/components/AccountMenu/index.js +++ b/src/views/Wallet/components/LeftNavigation/components/AccountMenu/index.js @@ -136,7 +136,7 @@ const AccountMenu = (props: Props) => { balance = `${availableBalance} ${network.symbol}`; if (fiatRate) { const accountBalance = new BigNumber(availableBalance); - const fiat = accountBalance.times(parseInt(fiatRate.value, 10)).toFixed(2); + const fiat = accountBalance.times(fiatRate.value).toFixed(2); balance = `${availableBalance} ${network.symbol} / $${fiat}`; } } diff --git a/src/views/Wallet/views/Account/Summary/components/Balance/index.js b/src/views/Wallet/views/Account/Summary/components/Balance/index.js index d0614f40..c7c978fc 100644 --- a/src/views/Wallet/views/Account/Summary/components/Balance/index.js +++ b/src/views/Wallet/views/Account/Summary/components/Balance/index.js @@ -106,14 +106,13 @@ class AccountBalance extends PureComponent { render() { const { network } = this.props; - const fiatRate: any = this.props.fiat.find(f => f.network === network.shortcut); + const fiatRate = this.props.fiat.find(f => f.network === network.shortcut); let accountBalance = ''; let fiatRateValue = ''; let fiat = ''; if (fiatRate) { - const fiatValue = Math.round(fiatRate.value * 100) / 100; accountBalance = new BigNumber(this.props.balance); - fiatRateValue = new BigNumber(fiatValue).toFixed(2); + fiatRateValue = new BigNumber(fiatRate.value).toFixed(2); fiat = accountBalance.times(fiatRateValue).toFixed(2); }