diff --git a/package.json b/package.json index 1c97f64..43382ae 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,8 @@ "ethereum-blockies": "github:MyEtherWallet/blockies", "ethjs": "^0.4.0", "ms": "^2.1.2", - "shortid": "^2.2.15" + "shortid": "^2.2.15", + "swr": "^0.1.18" }, "devDependencies": { "@babel/core": "^7.9.0", diff --git a/src/renderer/store/AppProvider.jsx b/src/renderer/store/AppProvider.jsx index 658a650..3f9aabd 100644 --- a/src/renderer/store/AppProvider.jsx +++ b/src/renderer/store/AppProvider.jsx @@ -25,9 +25,12 @@ export default function AppProvider({ children }) { }, []) useEffect(() => { + if (!prices) return + async function init() { try { await setBalances() + console.log('Updated balance') setIsLoading(false) } catch (error) { console.error(error.message) diff --git a/src/renderer/store/PriceProvider.jsx b/src/renderer/store/PriceProvider.jsx index 0998675..02fcbaf 100644 --- a/src/renderer/store/PriceProvider.jsx +++ b/src/renderer/store/PriceProvider.jsx @@ -1,9 +1,11 @@ -import React, { useEffect, useState } from 'react' +import React, { useState, useEffect } from 'react' import PropTypes from 'prop-types' -import ms from 'ms' import { PriceContext } from './createContext' import { refreshInterval, conversions } from '../../config' -import { fetchAndSetPrices } from './helpers' +import { fetchData } from '../../utils' +import { convertPrices } from './helpers' +import useSWR from 'swr' +import ms from 'ms' export default function PriceProvider({ children }) { // construct initial prices Map to get consistent @@ -21,25 +23,32 @@ export default function PriceProvider({ children }) { ) ) + // Fetch new prices periodically with swr + const currencies = conversions.join(',') + const url = `https://api.coingecko.com/api/v3/simple/price?ids=ocean-protocol&vs_currencies=${currencies}&include_24hr_change=true` + + const { data } = useSWR(url, fetchData, { + refreshInterval: ms(refreshInterval), + onSuccess + }) + + async function onSuccess() { + if (!data) return + + console.log('Got new prices.') + const { newPrices, newPriceChanges } = await convertPrices(data, prices) + + setPrices(newPrices) + setPriceChanges(newPriceChanges) + global.ipcRenderer.send('prices-updated', Array.from(newPrices)) // convert Map to array, ipc messages seem to kill it + } + useEffect(() => { async function init() { - try { - const { newPrices, newPriceChanges } = await fetchAndSetPrices(prices) - setPrices(newPrices) - setPriceChanges(newPriceChanges) - global.ipcRenderer.send('prices-updated', Array.from(newPrices)) // convert Map to array, ipc messages seem to kill it - } catch (error) { - console.error(error.message) - } + await onSuccess() } - init() - setInterval(init, ms(refreshInterval)) - - return () => { - clearInterval(init) - } - }, []) + }, [data]) return ( diff --git a/src/renderer/store/helpers.js b/src/renderer/store/helpers.js index 878b9e8..dfd59b0 100644 --- a/src/renderer/store/helpers.js +++ b/src/renderer/store/helpers.js @@ -1,21 +1,15 @@ import Store from 'electron-store' import Eth from 'ethjs' -import { fetchData } from '../../utils' import { oceanTokenContract, conversions } from '../../config' import { abi } from '@oceanprotocol/keeper-contracts/artifacts/OceanToken.pacific.json' -export async function fetchAndSetPrices(prices) { - const currencies = conversions.join(',') - const json = await fetchData( - `https://api.coingecko.com/api/v3/simple/price?ids=ocean-protocol&vs_currencies=${currencies}&include_24hr_change=true` - ) - +export async function convertPrices(data, prices) { let newPrices = new Map(prices) // make a shallow copy of the Map - conversions.map((key) => newPrices.set(key, json['ocean-protocol'][key])) // modify the copy + conversions.map((key) => newPrices.set(key, data['ocean-protocol'][key])) // modify the copy const newPriceChanges = await Object.assign( ...conversions.map((key) => ({ - [key]: json['ocean-protocol'][key + '_24h_change'] + [key]: data['ocean-protocol'][key + '_24h_change'] })) )