diff --git a/react/src/actions/actionCreators.js b/react/src/actions/actionCreators.js index 71c1dbe..266050d 100644 --- a/react/src/actions/actionCreators.js +++ b/react/src/actions/actionCreators.js @@ -332,7 +332,7 @@ export function addCoin(coin, mode) { } export function iguanaAddCoin(coin, mode, acData) { - return dispatch => { + function _iguanaAddCoin(dispatch) { return fetch('http://127.0.0.1:' + Config.iguanaCorePort, { method: 'POST', body: JSON.stringify(acData), @@ -344,6 +344,20 @@ export function iguanaAddCoin(coin, mode, acData) { .then(response => response.json()) .then(json => dispatch(addCoinResult(coin, mode, acData))); } + + if (mode === 0) { + return dispatch => { + return _iguanaAddCoin(dispatch); + /*startIguanaInstance('basilisk', 'basilisk') + .then(function(json) { + _iguanaAddCoin(dispatch); + });*/ + } + } else { + return dispatch => { + return _iguanaAddCoin(dispatch); + } + } } export function shepherdHerd(coin, mode, path) { @@ -653,6 +667,7 @@ export function getPeersListState(json) { } } +export function getFullTransactionsList(coin) { /*params = { 'userpass': tmpIguanaRPCAuth, 'agent': 'dex', @@ -662,8 +677,6 @@ export function getPeersListState(json) { 'skip': 0, 'symbol': coin };*/ - -export function getFullTransactionsList(coin) { const payload = { 'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'), 'coin': coin, @@ -700,17 +713,41 @@ export function getBasiliskTransactionsList(coin, address) { 'symbol': coin }; - return dispatch => { - return fetch('http://127.0.0.1:' + Config.iguanaCorePort, { - method: 'POST', - body: JSON.stringify(payload), - }) - .catch(function(error) { - console.log(error); - dispatch(triggerToaster(true, 'getBasiliskTransactionsList', 'Error', 'error')); - }) - .then(response => response.json()) - .then(json => dispatch(getNativeTxHistoryState(json))) + if (sessionStorage.getItem('useCache')) { + const pubkey = JSON.parse(sessionStorage.getItem('IguanaActiveAccount')).pubkey; + + return dispatch => { + return fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/cache?pubkey=' + pubkey, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }) + .catch(function(error) { + console.log(error); + dispatch(triggerToaster(true, 'getBasiliskTransactionsList+cache', 'Error', 'error')); + }) + .then(response => response.json()) + .then(function(json) { + json = json.result.basilisk; + if (json[coin][address].listtransactions) { + dispatch(getNativeTxHistoryState({ 'result': json[coin][address].listtransactions.data })); + } + }) + } + } else { + return dispatch => { + return fetch('http://127.0.0.1:' + (Config.useBasiliskInstance ? Config.basiliskPort : Config.iguanaCorePort), { + method: 'POST', + body: JSON.stringify(payload), + }) + .catch(function(error) { + console.log(error); + dispatch(triggerToaster(true, 'getBasiliskTransactionsList', 'Error', 'error')); + }) + .then(response => response.json()) + .then(json => dispatch(getNativeTxHistoryState(json))) + } } } @@ -932,7 +969,7 @@ export function getKMDAddressesNative(coin, mode, currentAddress) { }; } - if (mode !== 'native' || mode !== 'basilisk') { + if (mode === 'native' || mode === 'basilisk') { payload = { 'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'), 'coin': coin, @@ -941,17 +978,40 @@ export function getKMDAddressesNative(coin, mode, currentAddress) { 'account': '*' }; } - - fetch('http://127.0.0.1:' + Config.iguanaCorePort, { - method: 'POST', - body: JSON.stringify(payload), - }) - .catch(function(error) { - console.log(error); - dispatch(triggerToaster(true, 'getKMDAddressesNative', 'Error', 'error')); - }) - .then(response => response.json()) - .then(json => resolve(json)) + console.log('pl', payload); + + if (sessionStorage.getItem('useCache') && mode === 'basilisk') { + const pubkey = JSON.parse(sessionStorage.getItem('IguanaActiveAccount')).pubkey; + + fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/cache?pubkey=' + pubkey, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }) + .catch(function(error) { + console.log(error); + dispatch(triggerToaster(true, 'getKMDAddressesNative+addresslist+cache', 'Error', 'error')); + }) + .then(response => response.json()) + .then(function(json) { + json = json.result.basilisk; + if (json[coin].addresses) { + resolve({ 'result': json[coin].addresses }); + } + }) + } else { + fetch('http://127.0.0.1:' + Config.iguanaCorePort, { + method: 'POST', + body: JSON.stringify(payload), + }) + .catch(function(error) { + console.log(error); + dispatch(triggerToaster(true, 'getKMDAddressesNative', 'Error', 'error')); + }) + .then(response => response.json()) + .then(json => resolve(json)) + } }); })) .then(result => { @@ -1002,20 +1062,18 @@ export function getKMDAddressesNative(coin, mode, currentAddress) { }; } - fetch('http://127.0.0.1:' + Config.iguanaCorePort, { - method: 'POST', - body: JSON.stringify(payload), - }) - .catch(function(error) { - console.log(error); - dispatch(triggerToaster(true, 'getKMDAddressesNative+Balance', 'Error', 'error')); - }) - .then(response => response.json()) - .then(function(json) { + function calcBalance(result, json, dispatch, mode) { + console.log('result', result); if (mode === 'full' || mode === 'basilisk') { result[0] = result[0].result; + } else { + result[0] = result[0].result; + result[1] = result[1].result; } + console.log('calc result', result); + console.log('calc json', json); + if (mode !== 'basilisk') { const allAddrArray = json.map(res => res.address).filter((x, i, a) => a.indexOf(x) == i); for (let a=0; a < allAddrArray.length; a++) { @@ -1054,6 +1112,8 @@ export function getKMDAddressesNative(coin, mode, currentAddress) { } else { filteredArray = json.filter(res => res.address === result[a][b]).map(res => res.amount); } + console.log('filteredArray', filteredArray); + console.log('addr', result[a][b]); let sum = 0; @@ -1072,11 +1132,87 @@ export function getKMDAddressesNative(coin, mode, currentAddress) { 'public': newAddressArray[0], 'private': newAddressArray[1] })); - }) + } + + if (sessionStorage.getItem('useCache') && mode === 'basilisk') { + const pubkey = JSON.parse(sessionStorage.getItem('IguanaActiveAccount')).pubkey; + + fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/cache?pubkey=' + pubkey, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }) + .catch(function(error) { + console.log(error); + dispatch(triggerToaster(true, 'getKMDAddressesNative+addresslist+cache', 'Error', 'error')); + }) + .then(response => response.json()) + .then(function(json) { + json = json.result.basilisk; + // if listunspent is not in cache file retrieve new copy + // otherwise read from cache data + // TODO: save listunspent to cache file(?) + if (json[coin][currentAddress].listunspent) { + calcBalance(result, json[coin][currentAddress].listunspent, dispatch, mode); + } else { + fetch('http://127.0.0.1:' + (Config.useBasiliskInstance && mode === 'basilisk' ? Config.basiliskPort : Config.iguanaCorePort), { + method: 'POST', + body: JSON.stringify(payload), + }) + .catch(function(error) { + console.log(error); + dispatch(triggerToaster(true, 'getKMDAddressesNative+Balance', 'Error', 'error')); + }) + .then(response => response.json()) + .then(function(json) { + calcBalance(result, json, dispatch, mode); + }) + } + }) + } else { + fetch('http://127.0.0.1:' + (Config.useBasiliskInstance && mode === 'basilisk' ? Config.basiliskPort : Config.iguanaCorePort), { + method: 'POST', + body: JSON.stringify(payload), + }) + .catch(function(error) { + console.log(error); + dispatch(triggerToaster(true, 'getKMDAddressesNative+Balance', 'Error', 'error')); + }) + .then(response => response.json()) + .then(function(json) { + calcBalance(result, json, dispatch, mode); + }) + } }) } } +export function fetchUtxoCache(_payload) { + const _userpass = '?userpass=tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'), + _pubkey = '&pubkey=' + _payload.pubkey, + _route = _payload.allcoins ? 'cache-all' : 'cache-one', + _coin = '&coin=' + _payload.coin, + _calls = '&calls=' + _payload.calls, + _address = '&address' + _payload.address, + _iguanaInstancePort = Config.useBasiliskInstance ? '&port=' + Config.basiliskPort : ''; + + return dispatch => { + return fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/' + _route + _userpass + _pubkey + _coin + _calls + _address + _iguanaInstancePort, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }) + .catch(function(error) { + console.log(error); + dispatch(triggerToaster(true, 'fetchNewCacheData', 'Error', 'error')); + }) + .then(response => response.json()) + .then(json => dispatch(getShepherdCache(_pubkey))) + } +} + function getShepherdCacheState(json) { return { type: DASHBOARD_ACTIVE_COIN_GET_CACHE, @@ -1272,7 +1408,7 @@ export function getDexBalance(coin, addr) { }; console.log('addr', _addr); return new Promise((resolve, reject) => { - fetch('http://127.0.0.1:' + Config.iguanaCorePort, { + fetch('http://127.0.0.1:' + (Config.useBasiliskInstance ? Config.basiliskPort : Config.iguanaCorePort), { method: 'POST', body: JSON.stringify(payload), }) @@ -1640,7 +1776,7 @@ export function checkAddressBasilisk(coin, address) { }; return dispatch => { - return fetch('http://127.0.0.1:' + Config.iguanaCorePort, { + return fetch('http://127.0.0.1:' + (Config.useBasiliskInstance ? Config.basiliskPort : Config.iguanaCorePort), { method: 'POST', body: JSON.stringify(payload), }) @@ -1680,7 +1816,7 @@ export function validateAddressBasilisk(coin, address) { }; return dispatch => { - return fetch('http://127.0.0.1:' + Config.iguanaCorePort, { + return fetch('http://127.0.0.1:' + (Config.useBasiliskInstance ? Config.basiliskPort : Config.iguanaCorePort), { method: 'POST', body: JSON.stringify(payload), }) @@ -1715,7 +1851,7 @@ export function getDexNotaries(coin) { }; return dispatch => { - return fetch('http://127.0.0.1:' + Config.iguanaCorePort, { + return fetch('http://127.0.0.1:' + (Config.useBasiliskInstance ? Config.basiliskPort : Config.iguanaCorePort), { method: 'POST', body: JSON.stringify(payload), }) @@ -1785,10 +1921,11 @@ export function fetchNewCacheData(_payload) { _pubkey = '&pubkey=' + _payload.pubkey, _route = _payload.allcoins ? 'cache-all' : 'cache-one', _coin = '&coin=' + _payload.coin, - _calls = '&calls=' + _payload.calls; + _calls = '&calls=' + _payload.calls, + _iguanaInstancePort = Config.useBasiliskInstance ? '&port=' + Config.basiliskPort : ''; return dispatch => { - return fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/' + _route + _userpass + _pubkey + _coin + _calls, { + return fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/' + _route + _userpass + _pubkey + _coin + _calls + _iguanaInstancePort, { method: 'GET', headers: { 'Content-Type': 'application/json', @@ -1814,7 +1951,7 @@ function initNotaryNodesConSequence(nodes) { }; return new Promise((resolve, reject) => { - fetch('http://127.0.0.1:' + Config.iguanaCorePort, { + fetch('http://127.0.0.1:' + Config.useBasiliskInstance ? Config.basiliskPort : Config.iguanaCorePort, { method: 'POST', body: JSON.stringify(payload), }) @@ -1867,6 +2004,65 @@ function connectAllNotaryNodes(json, dispatch) { } } +export function startIguanaInstance(mode, coin) { + return new Promise((resolve, reject) => { + fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/forks', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + mode, + coin + }), + }) + .catch(function(error) { + console.log(error); + dispatch(triggerToaster(true, 'startIguanaInstance', 'Error', 'error')); + }) + .then(response => response.json()) + .then(json => resolve(json)) + }); +} + +export function getIguanaInstancesList() { + return new Promise((resolve, reject) => { + fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/forks', { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }) + .catch(function(error) { + console.log(error); + dispatch(triggerToaster(true, 'getIguanaInstanceList', 'Error', 'error')); + }) + .then(response => response.json()) + .then(json => resolve(json)) + }); +} + +export function restartIguanaInstance(pmid) { + return new Promise((resolve, reject) => { + fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/forks/restart?pmid=' + pmid, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + /*body: JSON.stringify({ + mode, + coin + }),*/ + }) + .catch(function(error) { + console.log(error); + dispatch(triggerToaster(true, 'restartIguanaInstance', 'Error', 'error')); + }) + .then(response => response.json()) + .then(json => resolve(json)) + }); +} + export function connectNotaries() { const payload = { 'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'), diff --git a/react/src/components/dashboard/coinTileItem.js b/react/src/components/dashboard/coinTileItem.js index 9e551c7..3b6d051 100644 --- a/react/src/components/dashboard/coinTileItem.js +++ b/react/src/components/dashboard/coinTileItem.js @@ -15,7 +15,8 @@ import { getKMDOPID, getFullTransactionsList, getBasiliskTransactionsList, - getShepherdCache + getShepherdCache, + fetchNewCacheData } from '../../actions/actionCreators'; import Store from '../../store'; @@ -31,48 +32,76 @@ class CoinTileItem extends React.Component { // 3) limit req in basilisk as much as possible incl. activehandle // 4) add pending requests store + dispatchCoinActions(coin, mode) { + if (mode === 'native') { + Store.dispatch(iguanaActiveHandle(true)); + Store.dispatch(getSyncInfoNative(coin)); + Store.dispatch(getKMDBalanceTotal(coin)); + Store.dispatch(getNativeTxHistory(coin)); + Store.dispatch(getKMDAddressesNative(coin, mode)); + Store.dispatch(getKMDOPID(null, coin)); + } + if (mode === 'full') { + Store.dispatch(iguanaActiveHandle(true)); + Store.dispatch(getSyncInfo(coin)); + Store.dispatch(iguanaEdexBalance(coin, mode)); + Store.dispatch(getKMDAddressesNative(coin, mode)); //getAddressesByAccount(coin)); + Store.dispatch(getFullTransactionsList(coin)); + } + if (mode === 'basilisk') { + console.log('dispatchCoinActions', mode); + const useAddress = this.props.ActiveCoin.mainBasiliskAddress ? this.props.ActiveCoin.mainBasiliskAddress : this.props.Dashboard.activeHandle[coin]; + Store.dispatch(iguanaActiveHandle(true)); + + if (this.props && this.props.Dashboard && this.props.Dashboard.activeHandle && this.props.Dashboard.activeHandle[coin]) { + Store.dispatch(getShepherdCache(this.props.Dashboard.activeHandle.pubkey)); + Store.dispatch(getBasiliskTransactionsList(coin, useAddress)); + Store.dispatch(getKMDAddressesNative(coin, mode, useAddress)); + Store.dispatch(iguanaEdexBalance(coin, mode)); + } + } + } + dashboardChangeActiveCoin(coin, mode) { if (coin !== this.props.ActiveCoin.coin) { Store.dispatch(stopInterval('sync', this.props.Interval.interval)); + Store.dispatch(stopInterval('basilisk', this.props.Interval.interval)); Store.dispatch(dashboardChangeActiveCoin(coin, mode)); + this.dispatchCoinActions(coin, mode); if (mode === 'full') { var _iguanaActiveHandle = setInterval(function() { - Store.dispatch(getSyncInfo(coin)); - Store.dispatch(iguanaEdexBalance(coin, mode)); - Store.dispatch(getKMDAddressesNative(coin, mode)); //getAddressesByAccount(coin)); - Store.dispatch(getFullTransactionsList(coin)); - }, 3000); + this.dispatchCoinActions(coin, mode); + }.bind(this), 3000); Store.dispatch(startInterval('sync', _iguanaActiveHandle)); } if (mode === 'native') { // TODO: add conditions to skip txhistory, balances, addresses while "activating best chain" var _iguanaActiveHandle = setInterval(function() { - Store.dispatch(getSyncInfoNative(coin)); - Store.dispatch(getKMDBalanceTotal(coin)); - Store.dispatch(getNativeTxHistory(coin)); - Store.dispatch(getKMDAddressesNative(coin)); - Store.dispatch(getKMDOPID(null, coin)); - }, coin === 'KMD' ? 15000 : 3000); + this.dispatchCoinActions(coin, mode); + }.bind(this), coin === 'KMD' ? 15000 : 3000); Store.dispatch(startInterval('sync', _iguanaActiveHandle)); } if (mode === 'basilisk') { var _iguanaActiveHandle = setInterval(function() { - const useAddress = this.props.ActiveCoin.mainBasiliskAddress ? this.props.ActiveCoin.mainBasiliskAddress : this.props.Dashboard.activeHandle[coin]; + this.dispatchCoinActions(coin, mode); + }.bind(this), 3000); - if (this.props && this.props.Dashboard && this.props.Dashboard.activeHandle && this.props.Dashboard.activeHandle[coin]) { - Store.dispatch(getBasiliskTransactionsList(coin, useAddress)); - Store.dispatch(getKMDAddressesNative(coin, mode, useAddress)); - Store.dispatch(getShepherdCache(this.props.Dashboard.activeHandle.pubkey)); - Store.dispatch(iguanaEdexBalance(coin, mode)); + var _basiliskCache = setInterval(function() { + if (sessionStorage.getItem('useCache')) { + Store.dispatch(fetchNewCacheData({ + 'pubkey': this.props.Dashboard.activeHandle.pubkey, + 'allcoins': false, + 'coin': this.props.ActiveCoin.coin, + 'calls': 'listtransactions:getbalance', + })); } - }.bind(this), 3000); + }.bind(this), 60000); Store.dispatch(startInterval('sync', _iguanaActiveHandle)); + Store.dispatch(startInterval('basilisk', _basiliskCache)); // basilisk } } - - Store.dispatch(iguanaActiveHandle(true)); } render() { diff --git a/react/src/components/dashboard/dashboard.js b/react/src/components/dashboard/dashboard.js index 1e89a36..2362f8b 100644 --- a/react/src/components/dashboard/dashboard.js +++ b/react/src/components/dashboard/dashboard.js @@ -36,7 +36,7 @@ class Dashboard extends React.Component { - + diff --git a/react/src/components/dashboard/walletsCacheData.js b/react/src/components/dashboard/walletsCacheData.js index 887367f..5f3cf42 100644 --- a/react/src/components/dashboard/walletsCacheData.js +++ b/react/src/components/dashboard/walletsCacheData.js @@ -39,7 +39,7 @@ class WalletsCacheData extends React.Component { {this.renderArrayNode(`${pre}-array-${value}`, key)} ); } else { - return Object.keys(_sourceObj.data).map((key, value) => this.renderKeyValue(pre, key, value)); + return Object.keys(_sourceObj.data).map((key, value) => this.renderKeyValue(pre, key, _sourceObj.data[key])); } } diff --git a/react/src/components/dashboard/walletsData.js b/react/src/components/dashboard/walletsData.js index 2c32ee9..7337ef6 100644 --- a/react/src/components/dashboard/walletsData.js +++ b/react/src/components/dashboard/walletsData.js @@ -12,7 +12,11 @@ import { displayNotariesModal, deleteCacheFile, connectNotaries, - toggleViewCacheModal + toggleViewCacheModal, + fetchNewCacheData, + fetchUtxoCache, + getIguanaInstancesList, + restartIguanaInstance } from '../../actions/actionCreators'; import Store from '../../store'; @@ -38,6 +42,7 @@ class WalletsData extends React.Component { addressSelectorOpen: false, currentStackLength: 0, totalStackLength: 0, + useCache: sessionStorage.getItem('useCache') ? true : false, }; this.updateInput = this.updateInput.bind(this); this.toggleBasiliskActionsMenu = this.toggleBasiliskActionsMenu.bind(this); @@ -48,9 +53,25 @@ class WalletsData extends React.Component { this.refreshTxList = this.refreshTxList.bind(this); this.removeAndFetchNewCache = this.removeAndFetchNewCache.bind(this); this._toggleViewCacheModal = this._toggleViewCacheModal.bind(this); + this.toggleCacheApi = this.toggleCacheApi.bind(this); + this._fetchUtxoCache = this._fetchUtxoCache.bind(this); + this.restartBasiliskInstance = this.restartBasiliskInstance.bind(this); socket.on('messages', msg => this.updateSocketsData(msg)); } + componentDidMount() { + console.log('use cache = ', this.state.useCache); + } + + toggleCacheApi() { + const _useCache = !this.state.useCache; + console.log('useCache is set to', _useCache); + sessionStorage.setItem('useCache', _useCache); + this.setState(Object.assign({}, this.state, { + useCache: _useCache, + })); + } + _toggleViewCacheModal() { Store.dispatch(toggleViewCacheModal(!this.props.Dashboard.displayViewCacheModal)); } @@ -75,6 +96,18 @@ class WalletsData extends React.Component { } } + restartBasiliskInstance() { + getIguanaInstancesList().then(function(json) { + for (let port in json.result) { + if (json.result[port].mode === 'basilisk') { + restartIguanaInstance(json.result[port].pmid).then(function(json) { + console.log('restartBasiliskInstance', json); + }); + } + } + }); + } + removeAndFetchNewCache() { Store.dispatch(deleteCacheFile({ 'pubkey': this.props.Dashboard.activeHandle.pubkey, @@ -84,6 +117,16 @@ class WalletsData extends React.Component { })); } + _fetchUtxoCache() { + Store.dispatch(fetchUtxoCache({ + 'pubkey': this.props.Dashboard.activeHandle.pubkey, + 'allcoins': false, + 'coin': this.props.ActiveCoin.coin, + 'calls': 'refresh', + 'address': this.state.currentAddress, + })); + } + toggleBasiliskActionsMenu() { this.setState(Object.assign({}, this.state, { basiliskActionsMenu: !this.state.basiliskActionsMenu, @@ -91,9 +134,15 @@ class WalletsData extends React.Component { } basiliskRefreshAction() { - if (this.props.Dashboard) { + /*if (this.props.Dashboard) { Store.dispatch(basiliskRefresh(!this.props.Dashboard.basiliskRefresh)); - } + }*/ + Store.dispatch(fetchNewCacheData({ + 'pubkey': this.props.Dashboard.activeHandle.pubkey, + 'allcoins': false, + 'coin': this.props.ActiveCoin.coin, + 'calls': 'listtransactions:getbalance', + })); } basiliskConnectionAction() { @@ -390,17 +439,27 @@ class WalletsData extends React.Component { {translate('INDEX.REFRESH_BASILISK_CONNECTIONS')} -
  • +
  • {translate('INDEX.FETCH_WALLET_DATA')}
  • -
  • +
  • - {translate('INDEX.REFETCH_WALLET_DATA')} + {translate('INDEX.REFETCH_WALLET_DATA')}
  • -
  • +
  • + + Update UTXO + +
  • +
  • + + Restart Basilisk Instance + +
  • +
  • {translate('INDEX.VIEW_CACHE_DATA')} @@ -415,8 +474,14 @@ class WalletsData extends React.Component {
    {this.renderAddressList()}
    +
    +
    + +
    + +
    -
    +
    {this.renderPaginationItemsPerPageSelector()}
    diff --git a/react/src/components/dashboard/walletsNativeTxHistory.js b/react/src/components/dashboard/walletsNativeTxHistory.js index 860827e..f90e2a6 100644 --- a/react/src/components/dashboard/walletsNativeTxHistory.js +++ b/react/src/components/dashboard/walletsNativeTxHistory.js @@ -80,12 +80,14 @@ class WalletsNativeTxHistory extends React.Component { componentWillReceiveProps(props) { if (!this.state.itemsList || (this.state.itemsList && !this.state.itemsList.length) || (props.ActiveCoin.txhistory !== this.props.ActiveCoin.txhistory)) { - let historyToSplit = this.props.ActiveCoin.txhistory; - historyToSplit = historyToSplit.slice((this.state.activePage - 1) * this.state.itemsPerPage, this.state.activePage * this.state.itemsPerPage); + if (this.props.ActiveCoin.txhistory) { + let historyToSplit = this.props.ActiveCoin.txhistory; + historyToSplit = historyToSplit.slice((this.state.activePage - 1) * this.state.itemsPerPage, this.state.activePage * this.state.itemsPerPage); - this.setState(Object.assign({}, this.state, { - itemsList: historyToSplit, - })); + this.setState(Object.assign({}, this.state, { + itemsList: historyToSplit, + })); + } } } @@ -114,7 +116,7 @@ class WalletsNativeTxHistory extends React.Component { } renderPaginationItemsPerPageSelector() { - if (this.props.ActiveCoin.txhistory.length > 10) { + if (this.props.ActiveCoin.txhistory && this.props.ActiveCoin.txhistory.length > 10) { return (