diff --git a/packages/blockchain-wallet-v4-frontend/src/data/components/activityList/sagas.js b/packages/blockchain-wallet-v4-frontend/src/data/components/activityList/sagas.js index 05324c8bc43..23f57338210 100644 --- a/packages/blockchain-wallet-v4-frontend/src/data/components/activityList/sagas.js +++ b/packages/blockchain-wallet-v4-frontend/src/data/components/activityList/sagas.js @@ -11,9 +11,9 @@ export default ({ coreSagas }) => { const bchTransactions = yield select(selectors.core.data.bch.getTransactions) const ethTransactions = yield select(selectors.core.data.ethereum.getTransactions) if (!Remote.Success.is(logsR)) yield put(actions.core.data.misc.fetchLogs()) - if (isEmpty(btcTransactions)) yield put(actions.core.data.bitcoin.fetchData('', true)) - if (isEmpty(bchTransactions)) yield put(actions.core.data.bch.fetchData('', true)) - if (isEmpty(ethTransactions)) yield put(actions.core.data.ethereum.fetchData()) + if (isEmpty(btcTransactions)) yield put(actions.core.data.bitcoin.fetchTransactions('', true)) + if (isEmpty(bchTransactions)) yield put(actions.core.data.bch.fetchTransactions('', true)) + if (isEmpty(ethTransactions)) yield put(actions.core.data.ethereum.fetchTransactions()) } catch (e) { yield put(actions.logs.logErrorMessage('components/activityList/sagas', 'initialized', e)) } diff --git a/packages/blockchain-wallet-v4-frontend/src/data/components/bchTransactions/sagas.js b/packages/blockchain-wallet-v4-frontend/src/data/components/bchTransactions/sagas.js index f13250c1f39..63c6082efc7 100644 --- a/packages/blockchain-wallet-v4-frontend/src/data/components/bchTransactions/sagas.js +++ b/packages/blockchain-wallet-v4-frontend/src/data/components/bchTransactions/sagas.js @@ -1,6 +1,5 @@ import { select, put } from 'redux-saga/effects' import { equals, path, prop } from 'ramda' -import { Remote } from 'blockchain-wallet-v4/src' import { actions, selectors } from 'data' export default ({ coreSagas }) => { @@ -14,8 +13,7 @@ export default ({ coreSagas }) => { search: '' } yield put(actions.form.initialize('bchTransactions', initialValues)) - const bchTransactionsR = yield select(selectors.core.data.bch.getTransactions) - if (!Remote.Success.is(bchTransactionsR)) yield put(actions.core.data.bch.fetchData(defaultSource, true)) + yield put(actions.core.data.bch.fetchTransactions(defaultSource, true)) } catch (e) { yield put(actions.logs.logErrorMessage(logLocation, 'initialized', e)) } @@ -38,7 +36,7 @@ export default ({ coreSagas }) => { const threshold = 250 const { yMax, yOffset } = action.payload if (yMax - yOffset < threshold) { - yield put(actions.core.data.bch.fetchData(source, false)) + yield put(actions.core.data.bch.fetchTransactions(source, false)) } } catch (e) { yield put(actions.logs.logErrorMessage(logLocation, 'scrollUpdated', e)) @@ -55,7 +53,7 @@ export default ({ coreSagas }) => { switch (field) { case 'source': const onlyShow = equals(payload, 'all') ? '' : (payload.xpub || payload.address) - yield put(actions.core.data.bch.fetchData(onlyShow, true)) + yield put(actions.core.data.bch.fetchTransactions(onlyShow, true)) } } catch (e) { yield put(actions.logs.logErrorMessage(logLocation, 'formChanged', e)) diff --git a/packages/blockchain-wallet-v4-frontend/src/data/components/btcTransactions/sagas.js b/packages/blockchain-wallet-v4-frontend/src/data/components/btcTransactions/sagas.js index a939955e925..6304b9f8c80 100644 --- a/packages/blockchain-wallet-v4-frontend/src/data/components/btcTransactions/sagas.js +++ b/packages/blockchain-wallet-v4-frontend/src/data/components/btcTransactions/sagas.js @@ -8,15 +8,13 @@ export default ({ coreSagas }) => { const initialized = function * () { try { - const defaultSource = '' const initialValues = { - source: defaultSource, + source: '', status: '', search: '' } yield put(actions.form.initialize('btcTransactions', initialValues)) - const btcTransactionsR = yield select(selectors.core.data.bitcoin.getTransactions) - if (!Remote.Success.is(btcTransactionsR)) yield put(actions.core.data.bitcoin.fetchData(defaultSource, true)) + yield put(actions.core.data.bitcoin.fetchTransactions(initialValues.source)) } catch (e) { yield put(actions.logs.logErrorMessage(logLocation, 'initialized', e)) } @@ -40,7 +38,7 @@ export default ({ coreSagas }) => { const { yMax, yOffset } = action.payload if (yMax - yOffset < threshold) { - yield put(actions.core.data.bitcoin.fetchData(source, false)) + yield put(actions.core.data.bitcoin.fetchTransactions(source, false)) } } catch (e) { yield put(actions.logs.logErrorMessage(logLocation, 'scrollUpdated', e)) @@ -57,7 +55,7 @@ export default ({ coreSagas }) => { switch (field) { case 'source': const onlyShow = equals(payload, 'all') ? '' : (payload.xpub || payload.address) - yield put(actions.core.data.bitcoin.fetchData(onlyShow, true)) + yield put(actions.core.data.bitcoin.fetchTransactions(onlyShow, true)) } } catch (e) { yield put(actions.logs.logErrorMessage(logLocation, 'formChanged', e)) diff --git a/packages/blockchain-wallet-v4-frontend/src/data/components/ethTransactions/sagas.js b/packages/blockchain-wallet-v4-frontend/src/data/components/ethTransactions/sagas.js index 0560a27d6e7..a1a4d963864 100644 --- a/packages/blockchain-wallet-v4-frontend/src/data/components/ethTransactions/sagas.js +++ b/packages/blockchain-wallet-v4-frontend/src/data/components/ethTransactions/sagas.js @@ -1,7 +1,6 @@ import { select, put } from 'redux-saga/effects' import { equals, path } from 'ramda' import { actions, selectors } from 'data' -import { Remote } from 'blockchain-wallet-v4/src' export default ({ coreSagas }) => { const logLocation = 'components/ethTransactions/sagas' @@ -12,8 +11,7 @@ export default ({ coreSagas }) => { search: '' } yield put(actions.form.initialize('ethTransactions', initialValues)) - const ethTransactionsR = yield select(selectors.core.data.ethereum.getTransactions) - if (!Remote.Success.is(ethTransactionsR)) yield put(actions.core.data.ethereum.fetchData(true)) + yield put(actions.core.data.ethereum.fetchTransactions()) } catch (e) { yield put(actions.logs.logErrorMessage(logLocation, 'initialized', e)) } @@ -27,7 +25,7 @@ export default ({ coreSagas }) => { const { yMax, yOffset } = action.payload if (yMax - yOffset < threshold) { - yield put(actions.core.data.ethereum.fetchData()) + yield put(actions.core.data.ethereum.fetchTransactions()) } } catch (e) { yield put(actions.logs.logErrorMessage(logLocation, 'scrollUpdated', e)) @@ -41,7 +39,7 @@ export default ({ coreSagas }) => { if (!equals('ethTransactions', form)) return switch (field) { case 'source': - yield put(actions.core.data.ethereum.fetchData()) + yield put(actions.core.data.ethereum.fetchTransactions()) } } catch (e) { yield put(actions.logs.logErrorMessage(logLocation, 'formChanged', e)) diff --git a/packages/blockchain-wallet-v4-frontend/src/data/components/sendBch/sagas.js b/packages/blockchain-wallet-v4-frontend/src/data/components/sendBch/sagas.js index 505123e451f..1a642c9cd37 100644 --- a/packages/blockchain-wallet-v4-frontend/src/data/components/sendBch/sagas.js +++ b/packages/blockchain-wallet-v4-frontend/src/data/components/sendBch/sagas.js @@ -139,7 +139,7 @@ export default ({ coreSagas }) => { if (path(['description', 'length'], payment.value())) { yield put(actions.core.kvStore.bch.setTxNotesBch(payment.value().txId, payment.value().description)) } - yield put(actions.core.data.bch.fetchData('', true)) + yield put(actions.core.data.bch.fetchData()) yield put(actions.router.push('/bch/transactions')) yield put(actions.alerts.displaySuccess(C.SEND_BCH_SUCCESS)) } catch (e) { diff --git a/packages/blockchain-wallet-v4-frontend/src/data/components/sendBtc/sagas.js b/packages/blockchain-wallet-v4-frontend/src/data/components/sendBtc/sagas.js index 36ca6a39b98..80acd33bcbc 100644 --- a/packages/blockchain-wallet-v4-frontend/src/data/components/sendBtc/sagas.js +++ b/packages/blockchain-wallet-v4-frontend/src/data/components/sendBtc/sagas.js @@ -214,7 +214,7 @@ export default ({ coreSagas }) => { payment = yield payment.sign(password) payment = yield payment.publish() yield put(A.sendBtcPaymentUpdated(Remote.of(payment.value()))) - yield put(actions.core.data.bitcoin.fetchData('', true)) + yield put(actions.core.data.bitcoin.fetchData()) if (path(['description', 'length'], payment.value())) { yield put(actions.core.wallet.setTransactionNote(payment.value().txId, payment.value().description)) } diff --git a/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BchBalance/index.js b/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BchBalance/index.js index 4e3aca0ecbb..3e0bc254dbf 100644 --- a/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BchBalance/index.js +++ b/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BchBalance/index.js @@ -2,7 +2,6 @@ import React from 'react' import { connect } from 'react-redux' import { bindActionCreators } from 'redux' -import { Remote } from 'blockchain-wallet-v4/src' import { actions } from 'data' import { getData } from './selectors' import Error from './template.error' @@ -16,13 +15,11 @@ class BchBalance extends React.PureComponent { } componentWillMount () { - if (Remote.NotAsked.is(this.props.data)) { - this.props.actions.fetchSpendableBalance() - } + this.props.actions.fetchData() } handleRefresh () { - this.props.actions.fetchSpendableBalance() + this.props.actions.fetchData() } render () { diff --git a/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BchBalance/selectors.js b/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BchBalance/selectors.js index 32b23fe0aea..12dc8a0e2da 100644 --- a/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BchBalance/selectors.js +++ b/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BchBalance/selectors.js @@ -1,3 +1,15 @@ import { selectors } from 'data' +import { createDeepEqualSelector } from 'services/ReselectHelper' +import { add, traverse, reduce } from 'ramda' +import { Remote } from 'blockchain-wallet-v4/src' -export const getData = selectors.core.data.bch.getSpendableBalance +export const getData = state => createDeepEqualSelector( + [ + selectors.core.kvStore.bch.getSpendableContext + ], + (context) => { + const getBalance = address => selectors.core.data.bch.getFinalBalance(address, state) + const balancesR = traverse(Remote.of, getBalance, context) + return balancesR.map(xs => reduce(add, 0, xs)) + } +)(state) diff --git a/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BchWatchOnlyBalance/index.js b/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BchWatchOnlyBalance/index.js index 02a39f97d7f..cf2fc088424 100644 --- a/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BchWatchOnlyBalance/index.js +++ b/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BchWatchOnlyBalance/index.js @@ -2,7 +2,6 @@ import React from 'react' import { connect } from 'react-redux' import { bindActionCreators } from 'redux' -import { Remote } from 'blockchain-wallet-v4/src' import { actions } from 'data' import { getData } from './selectors' import Error from './template.error' @@ -16,13 +15,11 @@ class BchWatchOnlyBalance extends React.PureComponent { } componentWillMount () { - if (Remote.NotAsked.is(this.props.data)) { - this.props.actions.fetchUnspendableBalance() - } + this.props.actions.fetchData() } handleRefresh () { - this.props.actions.fetchUnspendableBalance() + this.props.actions.fetchData() } render () { diff --git a/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BchWatchOnlyBalance/selectors.js b/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BchWatchOnlyBalance/selectors.js index ee431f53a90..62d84b8019a 100644 --- a/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BchWatchOnlyBalance/selectors.js +++ b/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BchWatchOnlyBalance/selectors.js @@ -1,3 +1,15 @@ import { selectors } from 'data' +import { createDeepEqualSelector } from 'services/ReselectHelper' +import { add, traverse, reduce } from 'ramda' +import { Remote } from 'blockchain-wallet-v4/src' -export const getData = selectors.core.data.bch.getUnspendableBalance +export const getData = state => createDeepEqualSelector( + [ + selectors.core.kvStore.bch.getUnspendableContext + ], + (context) => { + const getBalance = address => selectors.core.data.bch.getFinalBalance(address, state) + const balancesR = traverse(Remote.of, getBalance, context) + return balancesR.map(xs => reduce(add, 0, xs)) + } +)(state) diff --git a/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BtcBalance/index.js b/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BtcBalance/index.js index 915c17c6a9a..090ee438879 100644 --- a/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BtcBalance/index.js +++ b/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BtcBalance/index.js @@ -2,7 +2,6 @@ import React from 'react' import { connect } from 'react-redux' import { bindActionCreators } from 'redux' -import { Remote } from 'blockchain-wallet-v4/src' import { actions } from 'data' import { getData } from './selectors' import Error from './template.error' @@ -16,13 +15,11 @@ class BtcBalance extends React.PureComponent { } componentWillMount () { - if (Remote.NotAsked.is(this.props.data)) { - this.props.actions.fetchSpendableBalance() - } + this.props.actions.fetchData() } handleRefresh () { - this.props.actions.fetchSpendableBalance() + this.props.actions.fetchData() } render () { diff --git a/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BtcBalance/selectors.js b/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BtcBalance/selectors.js index a7390a93ba8..b2b5aa83489 100644 --- a/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BtcBalance/selectors.js +++ b/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BtcBalance/selectors.js @@ -1,3 +1,15 @@ import { selectors } from 'data' +import { createDeepEqualSelector } from 'services/ReselectHelper' +import { add, traverse, reduce } from 'ramda' +import { Remote } from 'blockchain-wallet-v4/src' -export const getData = selectors.core.data.bitcoin.getSpendableBalance +export const getData = state => createDeepEqualSelector( + [ + selectors.core.wallet.getSpendableContext + ], + (context) => { + const getBalance = address => selectors.core.data.bitcoin.getFinalBalance(address, state) + const balancesR = traverse(Remote.of, getBalance, context) + return balancesR.map(xs => reduce(add, 0, xs)) + } +)(state) diff --git a/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BtcWatchOnlyBalance/index.js b/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BtcWatchOnlyBalance/index.js index 88d43c7b964..7fe2aca96b1 100644 --- a/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BtcWatchOnlyBalance/index.js +++ b/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BtcWatchOnlyBalance/index.js @@ -2,7 +2,6 @@ import React from 'react' import { connect } from 'react-redux' import { bindActionCreators } from 'redux' -import { Remote } from 'blockchain-wallet-v4/src' import { actions } from 'data' import { getData } from './selectors' import Error from './template.error' @@ -16,13 +15,11 @@ class BtcWatchOnlyBalance extends React.PureComponent { } componentWillMount () { - if (Remote.NotAsked.is(this.props.data)) { - this.props.actions.fetchUnspendableBalance() - } + this.props.actions.fetchData() } handleRefresh () { - this.props.actions.fetchUnspendableBalance() + this.props.actions.fetchData() } render () { diff --git a/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BtcWatchOnlyBalance/selectors.js b/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BtcWatchOnlyBalance/selectors.js index cf1d1897a8e..293d7f0c68a 100644 --- a/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BtcWatchOnlyBalance/selectors.js +++ b/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/BtcWatchOnlyBalance/selectors.js @@ -1,3 +1,15 @@ import { selectors } from 'data' +import { createDeepEqualSelector } from 'services/ReselectHelper' +import { add, traverse, reduce } from 'ramda' +import { Remote } from 'blockchain-wallet-v4/src' -export const getData = selectors.core.data.bitcoin.getUnspendableBalance +export const getData = state => createDeepEqualSelector( + [ + selectors.core.wallet.getUnspendableContext + ], + (context) => { + const getBalance = address => selectors.core.data.bitcoin.getFinalBalance(address, state) + const balancesR = traverse(Remote.of, getBalance, context) + return balancesR.map(xs => reduce(add, 0, xs)) + } +)(state) diff --git a/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/EthBalance/index.js b/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/EthBalance/index.js index c83de8d710c..51ebb379e5b 100644 --- a/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/EthBalance/index.js +++ b/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/EthBalance/index.js @@ -2,7 +2,6 @@ import React from 'react' import { connect } from 'react-redux' import { bindActionCreators } from 'redux' -import { Remote } from 'blockchain-wallet-v4/src' import { actions } from 'data' import { getData } from './selectors' import Error from './template.error' @@ -16,9 +15,7 @@ class EthBalance extends React.PureComponent { } componentWillMount () { - if (Remote.NotAsked.is(this.props.data)) { - this.props.actions.fetchData() - } + this.props.actions.fetchData() } handleRefresh () { diff --git a/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/TotalBalance/selectors.js b/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/TotalBalance/selectors.js index e3b30d1e4c5..cd6a65ab92d 100644 --- a/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/TotalBalance/selectors.js +++ b/packages/blockchain-wallet-v4-frontend/src/layouts/Wallet/MenuTop/Balance/TotalBalance/selectors.js @@ -1,23 +1,32 @@ -import { lift } from 'ramda' +import { add, lift, reduce, traverse } from 'ramda' import { selectors } from 'data' import { Exchange, Remote } from 'blockchain-wallet-v4/src' import * as Currency from 'blockchain-wallet-v4/src/exchange/currency' import { createDeepEqualSelector } from 'services/ReselectHelper' -export const getBtcBalance = createDeepEqualSelector( - [selectors.core.data.bitcoin.getSpendableBalance], - (btcBalanceR) => Remote.of(btcBalanceR.getOrElse(0)) -) +export const getBtcBalance = state => createDeepEqualSelector( + [ + selectors.core.wallet.getSpendableContext + ], + (context) => { + const getBalance = address => selectors.core.data.bitcoin.getFinalBalance(address, state) + const balancesR = traverse(Remote.of, getBalance, context) + return balancesR.map(xs => reduce(add, 0, xs)) + } +)(state) -export const getBchBalance = createDeepEqualSelector( - [selectors.core.data.bch.getSpendableBalance], - (bchBalanceR) => Remote.of(bchBalanceR.getOrElse(0)) -) +export const getBchBalance = state => createDeepEqualSelector( + [ + selectors.core.kvStore.bch.getSpendableContext + ], + (context) => { + const getBalance = address => selectors.core.data.bch.getFinalBalance(address, state) + const balancesR = traverse(Remote.of, getBalance, context) + return balancesR.map(xs => reduce(add, 0, xs)) + } +)(state) -export const getEthBalance = createDeepEqualSelector( - [selectors.core.data.ethereum.getBalance], - (ethBalanceR) => Remote.of(ethBalanceR.getOrElse(0)) -) +export const getEthBalance = selectors.core.data.ethereum.getBalance export const getBtcBalanceInfo = createDeepEqualSelector( [ diff --git a/packages/blockchain-wallet-v4/src/redux/data/bch/actionTypes.js b/packages/blockchain-wallet-v4/src/redux/data/bch/actionTypes.js index e3e41781782..d7cad3249e5 100644 --- a/packages/blockchain-wallet-v4/src/redux/data/bch/actionTypes.js +++ b/packages/blockchain-wallet-v4/src/redux/data/bch/actionTypes.js @@ -30,15 +30,3 @@ export const FETCH_BCH_TRANSACTION_HISTORY_LOADING = '@CORE.FETCH_BCH_TRANSACTIO export const FETCH_BCH_TRANSACTION_HISTORY_SUCCESS = '@CORE.FETCH_BCH_TRANSACTION_HISTORY_SUCCESS' export const FETCH_BCH_TRANSACTION_HISTORY_FAILURE = '@CORE.FETCH_BCH_TRANSACTION_HISTORY_FAILURE' export const CLEAR_BCH_TRANSACTION_HISTORY = '@CORE.CLEAR_BCH_TRANSACTION_HISTORY' - -// FETCH_BCH_TRANSACTION_HISTORY -export const FETCH_BCH_SPENDABLE_BALANCE = '@CORE.FETCH_BCH_SPENDABLE_BALANCE' -export const FETCH_BCH_SPENDABLE_BALANCE_LOADING = '@CORE.FETCH_BCH_SPENDABLE_BALANCE_LOADING' -export const FETCH_BCH_SPENDABLE_BALANCE_SUCCESS = '@CORE.FETCH_BCH_SPENDABLE_BALANCE_SUCCESS' -export const FETCH_BCH_SPENDABLE_BALANCE_FAILURE = '@CORE.FETCH_BCH_SPENDABLE_BALANCE_FAILURE' - -// FETCH_BCH_TRANSACTION_HISTORY -export const FETCH_BCH_UNSPENDABLE_BALANCE = '@CORE.FETCH_BCH_UNSPENDABLE_BALANCE' -export const FETCH_BCH_UNSPENDABLE_BALANCE_LOADING = '@CORE.FETCH_BCH_UNSPENDABLE_BALANCE_LOADING' -export const FETCH_BCH_UNSPENDABLE_BALANCE_SUCCESS = '@CORE.FETCH_BCH_UNSPENDABLE_BALANCE_SUCCESS' -export const FETCH_BCH_UNSPENDABLE_BALANCE_FAILURE = '@CORE.FETCH_BCH_UNSPENDABLE_BALANCE_FAILURE' diff --git a/packages/blockchain-wallet-v4/src/redux/data/bch/actions.js b/packages/blockchain-wallet-v4/src/redux/data/bch/actions.js index b1ad49863e3..aa20257951c 100644 --- a/packages/blockchain-wallet-v4/src/redux/data/bch/actions.js +++ b/packages/blockchain-wallet-v4/src/redux/data/bch/actions.js @@ -3,7 +3,7 @@ import * as AT from './actionTypes' export const setBCHLatestBlock = (block_index, hash, height, time) => ({ type: AT.SET_BCH_LATEST_BLOCK, payload: { block_index, hash, height, time } }) // FETCH_BCH_DATA -export const fetchData = (address, reset) => ({ type: AT.FETCH_BCH_DATA, payload: { address, reset } }) +export const fetchData = () => ({ type: AT.FETCH_BCH_DATA }) export const fetchDataLoading = () => ({ type: AT.FETCH_BCH_DATA_LOADING }) export const fetchDataSuccess = (data) => ({ type: AT.FETCH_BCH_DATA_SUCCESS, payload: data }) export const fetchDataFailure = (error) => ({ type: AT.FETCH_BCH_DATA_FAILURE, payload: error }) @@ -21,6 +21,7 @@ export const fetchRatesSuccess = (data) => ({ type: AT.FETCH_BCH_RATES_SUCCESS, export const fetchRatesFailure = (error) => ({ type: AT.FETCH_BCH_RATES_FAILURE, payload: error }) // FETCH_BCH_TRANSACTIONS +export const fetchTransactions = (address, reset) => ({ type: AT.FETCH_BCH_TRANSACTIONS, payload: { address, reset } }) export const fetchTransactionsLoading = (reset) => ({ type: AT.FETCH_BCH_TRANSACTIONS_LOADING, payload: { reset } }) export const fetchTransactionsSuccess = (transactions, reset) => ({ type: AT.FETCH_BCH_TRANSACTIONS_SUCCESS, payload: { transactions, reset } }) export const fetchTransactionsFailure = (error) => ({ type: AT.FETCH_BCH_TRANSACTIONS_FAILURE, payload: error }) @@ -31,15 +32,3 @@ export const fetchTransactionHistoryLoading = () => ({ type: AT.FETCH_BCH_TRANSA export const fetchTransactionHistorySuccess = (data) => ({ type: AT.FETCH_BCH_TRANSACTION_HISTORY_SUCCESS, payload: data }) export const fetchTransactionHistoryFailure = (error) => ({ type: AT.FETCH_BCH_TRANSACTION_HISTORY_FAILURE, payload: error }) export const clearTransactionHistory = () => ({ type: AT.CLEAR_BCH_TRANSACTION_HISTORY }) - -// FETCH_BCH_SPENDABLE_BALANCE -export const fetchSpendableBalance = () => ({ type: AT.FETCH_BCH_SPENDABLE_BALANCE }) -export const fetchSpendableBalanceLoading = () => ({ type: AT.FETCH_BCH_SPENDABLE_BALANCE_LOADING }) -export const fetchSpendableBalanceSuccess = (data) => ({ type: AT.FETCH_BCH_SPENDABLE_BALANCE_SUCCESS, payload: data }) -export const fetchSpendableBalanceFailure = (error) => ({ type: AT.FETCH_BCH_SPENDABLE_BALANCE_FAILURE, payload: error }) - -// FETCH_BCH_UNSPENDABLE_BALANCE -export const fetchUnspendableBalance = () => ({ type: AT.FETCH_BCH_UNSPENDABLE_BALANCE }) -export const fetchUnspendableBalanceLoading = () => ({ type: AT.FETCH_BCH_UNSPENDABLE_BALANCE_LOADING }) -export const fetchUnspendableBalanceSuccess = (data) => ({ type: AT.FETCH_BCH_UNSPENDABLE_BALANCE_SUCCESS, payload: data }) -export const fetchUnspendableBalanceFailure = (error) => ({ type: AT.FETCH_BCH_UNSPENDABLE_BALANCE_FAILURE, payload: error }) diff --git a/packages/blockchain-wallet-v4/src/redux/data/bch/reducers.js b/packages/blockchain-wallet-v4/src/redux/data/bch/reducers.js index bb8d4d2f8b5..c8a48398aad 100644 --- a/packages/blockchain-wallet-v4/src/redux/data/bch/reducers.js +++ b/packages/blockchain-wallet-v4/src/redux/data/bch/reducers.js @@ -9,8 +9,6 @@ const INITIAL_STATE = { latest_block: Remote.NotAsked, rates: Remote.NotAsked, transactions: [], - spendable_balance: Remote.NotAsked, - unspendable_balance: Remote.NotAsked, transaction_history: Remote.NotAsked } @@ -92,24 +90,6 @@ const bchReducer = (state = INITIAL_STATE, action) => { case AT.CLEAR_BCH_TRANSACTION_HISTORY: { return assoc('transaction_history', Remote.NotAsked, state) } - case AT.FETCH_BCH_SPENDABLE_BALANCE_LOADING: { - return state - } - case AT.FETCH_BCH_SPENDABLE_BALANCE_SUCCESS: { - return assoc('spendable_balance', Remote.Success(payload), state) - } - case AT.FETCH_BCH_SPENDABLE_BALANCE_FAILURE: { - return assoc('spendable_balance', Remote.Failure(payload), state) - } - case AT.FETCH_BCH_UNSPENDABLE_BALANCE_LOADING: { - return state - } - case AT.FETCH_BCH_UNSPENDABLE_BALANCE_SUCCESS: { - return assoc('unspendable_balance', Remote.Success(payload), state) - } - case AT.FETCH_BCH_UNSPENDABLE_BALANCE_FAILURE: { - return assoc('unspendable_balance', Remote.Failure(payload), state) - } default: return state } diff --git a/packages/blockchain-wallet-v4/src/redux/data/bch/sagaRegister.js b/packages/blockchain-wallet-v4/src/redux/data/bch/sagaRegister.js index c485a31bdd7..b9134977db4 100644 --- a/packages/blockchain-wallet-v4/src/redux/data/bch/sagaRegister.js +++ b/packages/blockchain-wallet-v4/src/redux/data/bch/sagaRegister.js @@ -1,4 +1,4 @@ -import { takeLatest } from 'redux-saga/effects' +import { fork, takeLatest } from 'redux-saga/effects' import * as AT from './actionTypes' import sagas from './sagas' @@ -6,11 +6,10 @@ export default ({ api }) => { const dataBchSagas = sagas({ api }) return function * () { - yield takeLatest(AT.FETCH_BCH_FEE, dataBchSagas.fetchFee) yield takeLatest(AT.FETCH_BCH_DATA, dataBchSagas.fetchData) + yield takeLatest(AT.FETCH_BCH_FEE, dataBchSagas.fetchFee) yield takeLatest(AT.FETCH_BCH_RATES, dataBchSagas.fetchRates) - yield takeLatest(AT.FETCH_BCH_SPENDABLE_BALANCE, dataBchSagas.fetchSpendableBalance) - yield takeLatest(AT.FETCH_BCH_UNSPENDABLE_BALANCE, dataBchSagas.fetchUnspendableBalance) + yield fork(dataBchSagas.watchTransactions) yield takeLatest(AT.FETCH_BCH_TRANSACTION_HISTORY, dataBchSagas.fetchTransactionHistory) } } diff --git a/packages/blockchain-wallet-v4/src/redux/data/bch/sagas.js b/packages/blockchain-wallet-v4/src/redux/data/bch/sagas.js index bd681c5daf6..7928fb1adb2 100644 --- a/packages/blockchain-wallet-v4/src/redux/data/bch/sagas.js +++ b/packages/blockchain-wallet-v4/src/redux/data/bch/sagas.js @@ -1,10 +1,27 @@ -import { call, fork, put, select } from 'redux-saga/effects' -import { indexBy, length, path, prop, last } from 'ramda' +import { call, put, select, take } from 'redux-saga/effects' +import { indexBy, last, path, prop } from 'ramda' import * as A from './actions' +import * as AT from './actionTypes' import * as S from './selectors' import * as selectors from '../../selectors' export default ({ api }) => { + const fetchData = function * () { + try { + yield put(A.fetchDataLoading()) + const context = yield select(selectors.wallet.getContext) + const data = yield call(api.fetchBchData, context, { n: 1 }) + const bchData = { + addresses: indexBy(prop('address'), prop('addresses', data)), + info: path(['wallet'], data), + latest_block: path(['info', 'latest_block'], data) + } + yield put(A.fetchDataSuccess(bchData)) + } catch (e) { + yield put(A.fetchDataFailure(e.message)) + } + } + const fetchFee = function * () { try { yield put(A.fetchFeeLoading()) @@ -25,7 +42,14 @@ export default ({ api }) => { } } - const fetchData = function * ({ payload }) { + const watchTransactions = function * () { + while (true) { + const action = yield take(AT.FETCH_BCH_TRANSACTIONS) + yield call(fetchTransactions, action) + } + } + + const fetchTransactions = function * ({ type, payload }) { const { address, reset } = payload const TX_PER_PAGE = 10 const BCH_FORK_TIME = 1501590000 @@ -34,16 +58,11 @@ export default ({ api }) => { const lastPage = last(pages) if (!reset && lastPage && lastPage.map(length).getOrElse(0) === 0) { return } const offset = reset ? 0 : length(pages) * TX_PER_PAGE - yield put(A.fetchDataLoading()) yield put(A.fetchTransactionsLoading(reset)) - const context = yield select(selectors.kvStore.bch.getContext) + const context = yield select(selectors.wallet.getWalletContext) const data = yield call(api.fetchBchData, context, { n: TX_PER_PAGE, onlyShow: address, offset }) - yield call(multiaddrSaga, data) - yield fork(fetchSpendableBalance) - yield fork(fetchUnspendableBalance) yield put(A.fetchTransactionsSuccess(data.txs.filter(tx => tx.time > BCH_FORK_TIME), reset)) } catch (e) { - yield put(A.fetchDataFailure(e.message)) yield put(A.fetchTransactionsFailure(e.message)) } } @@ -67,59 +86,11 @@ export default ({ api }) => { } } - const fetchUnspent = function * (action) { - try { - // source can be the hd account index / or a legacy address - const { source } = action.payload - yield put(A.fetchUnspentLoading()) - const wrapper = yield select(selectors.wallet.getWrapper) - const data = yield call(api.getBCHWalletUnspents, wrapper, source) - yield put(A.fetchUnspentSuccess(data)) - } catch (e) { - yield put(A.fetchUnspentSuccess([])) - } - } - - const fetchSpendableBalance = function * (action) { - try { - const context = yield select(selectors.kvStore.bch.getSpendableContext) - yield put(A.fetchSpendableBalanceLoading()) - const data = yield call(api.fetchBchData, context) - const balance = data.wallet ? data.wallet.final_balance : 0 - yield put(A.fetchSpendableBalanceSuccess(balance)) - } catch (e) { - yield put(A.fetchSpendableBalanceFailure(e)) - } - } - - const fetchUnspendableBalance = function * (action) { - try { - const context = yield select(selectors.kvStore.bch.getUnspendableContext) - yield put(A.fetchUnspendableBalanceLoading()) - const data = yield call(api.fetchBchData, context) - const balance = data.wallet ? data.wallet.final_balance : 0 - yield put(A.fetchUnspendableBalanceSuccess(balance)) - } catch (e) { - yield put(A.fetchUnspendableBalanceFailure(e)) - } - } - - const multiaddrSaga = function * (data) { - const bchData = { - addresses: indexBy(prop('address'), prop('addresses', data)), - info: path(['wallet'], data), - latest_block: path(['info', 'latest_block'], data) - } - yield put(A.fetchDataSuccess(bchData)) - } - return { - fetchFee, fetchData, + fetchFee, fetchRates, - fetchUnspent, - fetchSpendableBalance, - fetchUnspendableBalance, - fetchTransactionHistory + fetchTransactionHistory, + watchTransactions } } diff --git a/packages/blockchain-wallet-v4/src/redux/data/bch/selectors.js b/packages/blockchain-wallet-v4/src/redux/data/bch/selectors.js index 97b7fee56ae..f5a6a937ad3 100644 --- a/packages/blockchain-wallet-v4/src/redux/data/bch/selectors.js +++ b/packages/blockchain-wallet-v4/src/redux/data/bch/selectors.js @@ -1,5 +1,6 @@ import { curry, path } from 'ramda' import { dataPath } from '../../paths' +import Remote from '../../../remote' export const getAddresses = path([dataPath, 'bch', 'addresses']) @@ -17,9 +18,9 @@ export const getTransactionHistory = path([dataPath, 'bch', 'transaction_history export const getCoins = path([dataPath, 'bch', 'payment', 'coins']) -export const getSpendableBalance = path([dataPath, 'bch', 'spendable_balance']) +export const getSpendableBalance = () => Remote.of(0) -export const getUnspendableBalance = path([dataPath, 'bch', 'unspendable_balance']) +export const getUnspendableBalance = () => Remote.of(0) // Specific export const getChangeIndex = curry((xpub, state) => getAddresses(state).map(path([xpub, 'change_index']))) @@ -28,6 +29,8 @@ export const getReceiveIndex = curry((xpub, state) => getAddresses(state).map(pa export const getTotalTxPerAccount = curry((xpubOrAddress, state) => getAddresses(state).map(path([xpubOrAddress, 'n_tx']))) +export const getFinalBalance = curry((address, state) => getAddresses(state).map(path([address, 'final_balance'])).map(x => x || 0)) + // TODO: Import fee from wallet-options // export const getFees = ... diff --git a/packages/blockchain-wallet-v4/src/redux/data/bitcoin/actionTypes.js b/packages/blockchain-wallet-v4/src/redux/data/bitcoin/actionTypes.js index 10cbf8d8c60..60714f42345 100644 --- a/packages/blockchain-wallet-v4/src/redux/data/bitcoin/actionTypes.js +++ b/packages/blockchain-wallet-v4/src/redux/data/bitcoin/actionTypes.js @@ -36,15 +36,3 @@ export const FETCH_BITCOIN_TRANSACTION_HISTORY_LOADING = '@CORE.FETCH_BITCOIN_TR export const FETCH_BITCOIN_TRANSACTION_HISTORY_SUCCESS = '@CORE.FETCH_BITCOIN_TRANSACTION_HISTORY_SUCCESS' export const FETCH_BITCOIN_TRANSACTION_HISTORY_FAILURE = '@CORE.FETCH_BITCOIN_TRANSACTION_HISTORY_FAILURE' export const CLEAR_BITCOIN_TRANSACTION_HISTORY = '@CORE.CLEAR_BITCOIN_TRANSACTION_HISTORY' - -// FETCH_BITCOIN_TRANSACTION_HISTORY -export const FETCH_BITCOIN_SPENDABLE_BALANCE = '@CORE.FETCH_BITCOIN_SPENDABLE_BALANCE' -export const FETCH_BITCOIN_SPENDABLE_BALANCE_LOADING = '@CORE.FETCH_BITCOIN_SPENDABLE_BALANCE_LOADING' -export const FETCH_BITCOIN_SPENDABLE_BALANCE_SUCCESS = '@CORE.FETCH_BITCOIN_SPENDABLE_BALANCE_SUCCESS' -export const FETCH_BITCOIN_SPENDABLE_BALANCE_FAILURE = '@CORE.FETCH_BITCOIN_SPENDABLE_BALANCE_FAILURE' - -// FETCH_BITCOIN_TRANSACTION_HISTORY -export const FETCH_BITCOIN_UNSPENDABLE_BALANCE = '@CORE.FETCH_BITCOIN_UNSPENDABLE_BALANCE' -export const FETCH_BITCOIN_UNSPENDABLE_BALANCE_LOADING = '@CORE.FETCH_BITCOIN_UNSPENDABLE_BALANCE_LOADING' -export const FETCH_BITCOIN_UNSPENDABLE_BALANCE_SUCCESS = '@CORE.FETCH_BITCOIN_UNSPENDABLE_BALANCE_SUCCESS' -export const FETCH_BITCOIN_UNSPENDABLE_BALANCE_FAILURE = '@CORE.FETCH_BITCOIN_UNSPENDABLE_BALANCE_FAILURE' diff --git a/packages/blockchain-wallet-v4/src/redux/data/bitcoin/actions.js b/packages/blockchain-wallet-v4/src/redux/data/bitcoin/actions.js index 2834555c1ef..e0c8f1309f1 100644 --- a/packages/blockchain-wallet-v4/src/redux/data/bitcoin/actions.js +++ b/packages/blockchain-wallet-v4/src/redux/data/bitcoin/actions.js @@ -3,7 +3,7 @@ import * as AT from './actionTypes' export const setBitcoinLatestBlock = (block_index, hash, height, time) => ({ type: AT.SET_BITCOIN_LATEST_BLOCK, payload: { block_index, hash, height, time } }) // FETCH_BITCOIN_DATA -export const fetchData = (address, reset) => ({ type: AT.FETCH_BITCOIN_DATA, payload: { address, reset } }) +export const fetchData = () => ({ type: AT.FETCH_BITCOIN_DATA }) export const fetchDataLoading = () => ({ type: AT.FETCH_BITCOIN_DATA_LOADING }) export const fetchDataSuccess = (data) => ({ type: AT.FETCH_BITCOIN_DATA_SUCCESS, payload: data }) export const fetchDataFailure = (error) => ({ type: AT.FETCH_BITCOIN_DATA_FAILURE, payload: error }) @@ -27,6 +27,7 @@ export const fetchRatesSuccess = (data) => ({ type: AT.FETCH_BITCOIN_RATES_SUCCE export const fetchRatesFailure = (error) => ({ type: AT.FETCH_BITCOIN_RATES_FAILURE, payload: error }) // FETCH_BITCOIN_TRANSACTIONS +export const fetchTransactions = (address, reset) => ({ type: AT.FETCH_BITCOIN_TRANSACTIONS, payload: { address, reset } }) export const fetchTransactionsLoading = (reset) => ({ type: AT.FETCH_BITCOIN_TRANSACTIONS_LOADING, payload: { reset } }) export const fetchTransactionsSuccess = (transactions, reset) => ({ type: AT.FETCH_BITCOIN_TRANSACTIONS_SUCCESS, payload: {transactions, reset} }) export const fetchTransactionsFailure = (error) => ({ type: AT.FETCH_BITCOIN_TRANSACTIONS_FAILURE, payload: error }) @@ -37,15 +38,3 @@ export const fetchTransactionHistoryLoading = () => ({ type: AT.FETCH_BITCOIN_TR export const fetchTransactionHistorySuccess = (data) => ({ type: AT.FETCH_BITCOIN_TRANSACTION_HISTORY_SUCCESS, payload: data }) export const fetchTransactionHistoryFailure = (error) => ({ type: AT.FETCH_BITCOIN_TRANSACTION_HISTORY_FAILURE, payload: error }) export const clearTransactionHistory = () => ({ type: AT.CLEAR_BITCOIN_TRANSACTION_HISTORY }) - -// FETCH_BITCOIN_SPENDABLE_BALANCE -export const fetchSpendableBalance = () => ({ type: AT.FETCH_BITCOIN_SPENDABLE_BALANCE }) -export const fetchSpendableBalanceLoading = () => ({ type: AT.FETCH_BITCOIN_SPENDABLE_BALANCE_LOADING }) -export const fetchSpendableBalanceSuccess = (data) => ({ type: AT.FETCH_BITCOIN_SPENDABLE_BALANCE_SUCCESS, payload: data }) -export const fetchSpendableBalanceFailure = (error) => ({ type: AT.FETCH_BITCOIN_SPENDABLE_BALANCE_FAILURE, payload: error }) - -// FETCH_BITCOIN_UNSPENDABLE_BALANCE -export const fetchUnspendableBalance = () => ({ type: AT.FETCH_BITCOIN_UNSPENDABLE_BALANCE }) -export const fetchUnspendableBalanceLoading = () => ({ type: AT.FETCH_BITCOIN_UNSPENDABLE_BALANCE_LOADING }) -export const fetchUnspendableBalanceSuccess = (data) => ({ type: AT.FETCH_BITCOIN_UNSPENDABLE_BALANCE_SUCCESS, payload: data }) -export const fetchUnspendableBalanceFailure = (error) => ({ type: AT.FETCH_BITCOIN_UNSPENDABLE_BALANCE_FAILURE, payload: error }) diff --git a/packages/blockchain-wallet-v4/src/redux/data/bitcoin/reducers.js b/packages/blockchain-wallet-v4/src/redux/data/bitcoin/reducers.js index 1c605431ae8..43df8067335 100644 --- a/packages/blockchain-wallet-v4/src/redux/data/bitcoin/reducers.js +++ b/packages/blockchain-wallet-v4/src/redux/data/bitcoin/reducers.js @@ -10,7 +10,6 @@ const INITIAL_STATE = { rates: Remote.NotAsked, transactions: [], transactions_fiat: {}, - spendable_balance: Remote.NotAsked, unspendable_balance: Remote.NotAsked, transaction_history: Remote.NotAsked } @@ -104,15 +103,6 @@ const bitcoinReducer = (state = INITIAL_STATE, action) => { case AT.CLEAR_BITCOIN_TRANSACTION_HISTORY: { return assoc('transaction_history', Remote.NotAsked, state) } - case AT.FETCH_BITCOIN_SPENDABLE_BALANCE_LOADING: { - return state - } - case AT.FETCH_BITCOIN_SPENDABLE_BALANCE_SUCCESS: { - return assoc('spendable_balance', Remote.Success(payload), state) - } - case AT.FETCH_BITCOIN_SPENDABLE_BALANCE_FAILURE: { - return assoc('spendable_balance', Remote.Failure(payload), state) - } case AT.FETCH_BITCOIN_UNSPENDABLE_BALANCE_LOADING: { return state } diff --git a/packages/blockchain-wallet-v4/src/redux/data/bitcoin/sagaRegister.js b/packages/blockchain-wallet-v4/src/redux/data/bitcoin/sagaRegister.js index 3d8d8c0703e..258866764ed 100644 --- a/packages/blockchain-wallet-v4/src/redux/data/bitcoin/sagaRegister.js +++ b/packages/blockchain-wallet-v4/src/redux/data/bitcoin/sagaRegister.js @@ -1,4 +1,4 @@ -import { takeLatest, takeEvery } from 'redux-saga/effects' +import { fork, takeLatest, takeEvery } from 'redux-saga/effects' import * as AT from './actionTypes' import sagas from './sagas' @@ -6,12 +6,11 @@ export default ({ api }) => { const dataBtcSagas = sagas({ api }) return function * () { - yield takeLatest(AT.FETCH_BITCOIN_FEE, dataBtcSagas.fetchFee) yield takeLatest(AT.FETCH_BITCOIN_DATA, dataBtcSagas.fetchData) + yield takeLatest(AT.FETCH_BITCOIN_FEE, dataBtcSagas.fetchFee) yield takeLatest(AT.FETCH_BITCOIN_RATES, dataBtcSagas.fetchRates) + yield fork(dataBtcSagas.watchTransactions) yield takeEvery(AT.FETCH_BITCOIN_FIAT_AT_TIME, dataBtcSagas.fetchFiatAtTime) - yield takeLatest(AT.FETCH_BITCOIN_SPENDABLE_BALANCE, dataBtcSagas.fetchSpendableBalance) - yield takeLatest(AT.FETCH_BITCOIN_UNSPENDABLE_BALANCE, dataBtcSagas.fetchUnspendableBalance) yield takeLatest(AT.FETCH_BITCOIN_TRANSACTION_HISTORY, dataBtcSagas.fetchTransactionHistory) } } diff --git a/packages/blockchain-wallet-v4/src/redux/data/bitcoin/sagas.js b/packages/blockchain-wallet-v4/src/redux/data/bitcoin/sagas.js index 60e1f031d55..173850b6797 100644 --- a/packages/blockchain-wallet-v4/src/redux/data/bitcoin/sagas.js +++ b/packages/blockchain-wallet-v4/src/redux/data/bitcoin/sagas.js @@ -1,10 +1,27 @@ -import { call, fork, put, select } from 'redux-saga/effects' -import { indexBy, length, path, prop, last } from 'ramda' +import { call, put, select, take } from 'redux-saga/effects' +import { indexBy, length, last, path, prop } from 'ramda' import * as A from './actions' +import * as AT from './actionTypes' import * as S from './selectors' import * as selectors from '../../selectors' export default ({ api }) => { + const fetchData = function * () { + try { + yield put(A.fetchDataLoading()) + const context = yield select(selectors.wallet.getContext) + const data = yield call(api.fetchBlockchainData, context, { n: 1 }) + const bitcoinData = { + addresses: indexBy(prop('address'), prop('addresses', data)), + info: path(['wallet'], data), + latest_block: path(['info', 'latest_block'], data) + } + yield put(A.fetchDataSuccess(bitcoinData)) + } catch (e) { + yield put(A.fetchDataFailure(e.message)) + } + } + const fetchFee = function * () { try { yield put(A.fetchFeeLoading()) @@ -25,25 +42,27 @@ export default ({ api }) => { } } - const fetchData = function * (action) { - const { payload } = action - const { address, reset } = payload - const TX_PER_PAGE = 10 + const watchTransactions = function * () { + while (true) { + const action = yield take(AT.FETCH_BITCOIN_TRANSACTIONS) + yield call(fetchTransactions, action) + } + } + + const fetchTransactions = function * (action) { try { + const { payload } = action + const { address, reset } = payload + const TX_PER_PAGE = 10 const pages = yield select(S.getTransactions) const lastPage = last(pages) if (!reset && lastPage && lastPage.map(length).getOrElse(0) === 0) { return } const offset = reset ? 0 : length(pages) * TX_PER_PAGE - yield put(A.fetchDataLoading(reset)) yield put(A.fetchTransactionsLoading(reset)) const context = yield select(selectors.wallet.getWalletContext) const data = yield call(api.fetchBlockchainData, context, { n: TX_PER_PAGE, onlyShow: address, offset }) - yield call(multiaddrSaga, data) - yield fork(fetchSpendableBalance) - yield fork(fetchUnspendableBalance) yield put(A.fetchTransactionsSuccess(data.txs, reset)) } catch (e) { - yield put(A.fetchDataFailure(e.message)) yield put(A.fetchTransactionsFailure(e.message)) } } @@ -78,60 +97,12 @@ export default ({ api }) => { } } - const fetchUnspent = function * (action) { - try { - // source can be the hd account index / or a legacy address - const { source } = action.payload - yield put(A.fetchUnspentLoading()) - const wrapper = yield select(selectors.wallet.getWrapper) - const data = yield call(api.getBTCWalletUnspents, wrapper, source) - yield put(A.fetchUnspentSuccess(data)) - } catch (e) { - yield put(A.fetchUnspentSuccess([])) - } - } - - const fetchSpendableBalance = function * () { - try { - const context = yield select(selectors.wallet.getSpendableContext) - yield put(A.fetchSpendableBalanceLoading()) - const data = yield call(api.fetchBlockchainData, context) - const balance = data.wallet ? data.wallet.final_balance : 0 - yield put(A.fetchSpendableBalanceSuccess(balance)) - } catch (e) { - yield put(A.fetchSpendableBalanceFailure(e)) - } - } - - const fetchUnspendableBalance = function * () { - try { - const context = yield select(selectors.wallet.getUnspendableContext) - yield put(A.fetchUnspendableBalanceLoading()) - const data = yield call(api.fetchBlockchainData, context) - const balance = data.wallet ? data.wallet.final_balance : 0 - yield put(A.fetchUnspendableBalanceSuccess(balance)) - } catch (e) { - yield put(A.fetchUnspendableBalanceFailure(e)) - } - } - - const multiaddrSaga = function * (data) { - const btcData = { - addresses: indexBy(prop('address'), prop('addresses', data)), - info: path(['wallet'], data), - latest_block: path(['info', 'latest_block'], data) - } - yield put(A.fetchDataSuccess(btcData)) - } - return { fetchFee, fetchData, fetchRates, - fetchUnspent, fetchFiatAtTime, - fetchSpendableBalance, - fetchUnspendableBalance, - fetchTransactionHistory + fetchTransactionHistory, + watchTransactions } } diff --git a/packages/blockchain-wallet-v4/src/redux/data/bitcoin/selectors.js b/packages/blockchain-wallet-v4/src/redux/data/bitcoin/selectors.js index c0fbc19e385..3846904b0c3 100644 --- a/packages/blockchain-wallet-v4/src/redux/data/bitcoin/selectors.js +++ b/packages/blockchain-wallet-v4/src/redux/data/bitcoin/selectors.js @@ -1,5 +1,6 @@ import { curry, path } from 'ramda' import { dataPath } from '../../paths' +import Remote from '../../../remote' export const getAddresses = path([dataPath, 'bitcoin', 'addresses']) @@ -17,9 +18,9 @@ export const getTransactionHistory = path([dataPath, 'bitcoin', 'transaction_his export const getCoins = path([dataPath, 'bitcoin', 'payment', 'coins']) -export const getSpendableBalance = path([dataPath, 'bitcoin', 'spendable_balance']) +export const getSpendableBalance = () => Remote.of(0) -export const getUnspendableBalance = path([dataPath, 'bitcoin', 'unspendable_balance']) +export const getUnspendableBalance = () => Remote.of(0) // Specific export const getChangeIndex = curry((xpub, state) => getAddresses(state).map(path([xpub, 'change_index']))) @@ -28,6 +29,8 @@ export const getReceiveIndex = curry((xpub, state) => getAddresses(state).map(pa export const getTotalTxPerAccount = curry((xpubOrAddress, state) => getAddresses(state).map(path([xpubOrAddress, 'n_tx']))) +export const getFinalBalance = curry((address, state) => getAddresses(state).map(path([address, 'final_balance'])).map(x => x || 0)) + export const getFeeRegular = state => getFee(state).map(path(['regular'])) export const getFeePriority = state => getFee(state).map(path(['priority'])) diff --git a/packages/blockchain-wallet-v4/src/redux/data/ethereum/actions.js b/packages/blockchain-wallet-v4/src/redux/data/ethereum/actions.js index 5cc22124197..3078807b489 100644 --- a/packages/blockchain-wallet-v4/src/redux/data/ethereum/actions.js +++ b/packages/blockchain-wallet-v4/src/redux/data/ethereum/actions.js @@ -3,7 +3,7 @@ import * as AT from './actionTypes' // export const setEthereumTransactions = (address, txs) => ({ type: AT.SET_ETHEREUM_TRANSACTIONS, payload: { address, txs } }) // FETCH_ETHEREUM_DATA -export const fetchData = (reset) => ({ type: AT.FETCH_ETHEREUM_DATA, payload: { reset } }) +export const fetchData = () => ({ type: AT.FETCH_ETHEREUM_DATA }) export const fetchDataLoading = () => ({ type: AT.FETCH_ETHEREUM_DATA_LOADING }) export const fetchDataSuccess = (data) => ({ type: AT.FETCH_ETHEREUM_DATA_SUCCESS, payload: data }) export const fetchDataFailure = (error) => ({ type: AT.FETCH_ETHEREUM_DATA_FAILURE, payload: error }) @@ -33,6 +33,7 @@ export const fetchRatesSuccess = (data) => ({ type: AT.FETCH_ETHEREUM_RATES_SUCC export const fetchRatesFailure = (error) => ({ type: AT.FETCH_ETHEREUM_RATES_FAILURE, payload: error }) // FETCH_ETHEREUM_TRANSACTIONS +export const fetchTransactions = () => ({ type: AT.FETCH_ETHEREUM_TRANSACTIONS }) export const fetchTransactionsLoading = (reset) => ({ type: AT.FETCH_ETHEREUM_TRANSACTIONS_LOADING, payload: { reset } }) export const fetchTransactionsSuccess = (transactions, reset) => ({ type: AT.FETCH_ETHEREUM_TRANSACTIONS_SUCCESS, payload: { transactions, reset } }) export const fetchTransactionsFailure = (error) => ({ type: AT.FETCH_ETHEREUM_TRANSACTIONS_FAILURE, payload: error }) diff --git a/packages/blockchain-wallet-v4/src/redux/data/ethereum/sagaRegister.js b/packages/blockchain-wallet-v4/src/redux/data/ethereum/sagaRegister.js index 644f8b6d7c2..bfdf4b663f1 100644 --- a/packages/blockchain-wallet-v4/src/redux/data/ethereum/sagaRegister.js +++ b/packages/blockchain-wallet-v4/src/redux/data/ethereum/sagaRegister.js @@ -1,5 +1,5 @@ -import { takeLatest } from 'redux-saga/effects' +import { fork, takeLatest } from 'redux-saga/effects' import * as AT from './actionTypes' import sagas from './sagas' @@ -7,10 +7,11 @@ export default ({ api }) => { const dataEthereumSagas = sagas({ api }) return function * () { - yield takeLatest(AT.FETCH_ETHEREUM_FEE, dataEthereumSagas.fetchFee) yield takeLatest(AT.FETCH_ETHEREUM_DATA, dataEthereumSagas.fetchData) - yield takeLatest(AT.FETCH_ETHEREUM_LEGACY_BALANCE, dataEthereumSagas.fetchLegacyBalance) + yield takeLatest(AT.FETCH_ETHEREUM_FEE, dataEthereumSagas.fetchFee) yield takeLatest(AT.FETCH_ETHEREUM_RATES, dataEthereumSagas.fetchRates) + yield fork(dataEthereumSagas.watchTransactions) + yield takeLatest(AT.FETCH_ETHEREUM_LEGACY_BALANCE, dataEthereumSagas.fetchLegacyBalance) yield takeLatest(AT.FETCH_ETHEREUM_LATEST_BLOCK, dataEthereumSagas.fetchLatestBlock) } } diff --git a/packages/blockchain-wallet-v4/src/redux/data/ethereum/sagas.js b/packages/blockchain-wallet-v4/src/redux/data/ethereum/sagas.js index cdb756147ce..6702f2a8451 100644 --- a/packages/blockchain-wallet-v4/src/redux/data/ethereum/sagas.js +++ b/packages/blockchain-wallet-v4/src/redux/data/ethereum/sagas.js @@ -1,12 +1,43 @@ -import { call, put, select } from 'redux-saga/effects' +import { call, put, select, take } from 'redux-saga/effects' import { dissoc, isNil, length, mapObjIndexed, path, sum, values } from 'ramda' import { convertFeeToWei } from '../../../utils/ethereum' import * as A from './actions' +import * as AT from './actionTypes' import * as S from './selectors' import * as selectors from '../../selectors' import * as kvStoreSelectors from '../../kvStore/ethereum/selectors' export default ({ api }) => { + const fetchData = function * (action) { + try { + yield put(A.fetchDataLoading()) + const contextR = yield select(kvStoreSelectors.getContext) + const context = contextR.getOrFail('ethereum_context') + const data = yield call(api.getEthereumData, context) + const latestBlock = yield call(api.getEthereumLatestBlock) + // Accounts treatments + const finalBalance = sum(values(data).map(obj => obj.balance)) + const totalReceived = sum(values(data).map(obj => obj.totalReceived)) + const totalSent = sum(values(data).map(obj => obj.totalSent)) + const nTx = sum(values(data).map(obj => obj.txn_count)) + const addresses = mapObjIndexed((num, key, obj) => dissoc('txns', num), data) + + const ethereumData = { + addresses, + info: { + n_tx: nTx, + total_received: totalReceived, + total_sent: totalSent, + final_balance: finalBalance + }, + latest_block: latestBlock + } + yield put(A.fetchDataSuccess(ethereumData)) + } catch (e) { + yield put(A.fetchDataFailure(e.message)) + } + } + const fetchFee = function * () { try { yield put(A.fetchFeeLoading()) @@ -38,24 +69,25 @@ export default ({ api }) => { } } - const fetchData = function * (action) { - const { payload } = action - const { reset } = payload + const watchTransactions = function * () { + while (true) { + const action = yield take(AT.FETCH_ETHEREUM_TRANSACTIONS) + yield call(fetchTransactions, action) + } + } + + const fetchTransactions = function * ({ type, payload }) { try { const defaultAccountR = yield select(selectors.kvStore.ethereum.getContext) const address = defaultAccountR.getOrFail('Could not get ethereum context.') - const pages = reset ? [] : yield select(S.getTransactions) + const pages = yield select(S.getTransactions) const nextPage = length(pages) - yield put(A.fetchDataLoading()) - yield put(A.fetchTransactionsLoading(reset)) + yield put(A.fetchTransactionsLoading()) const data = yield call(api.getEthereumTransactions, address, nextPage) - const latestBlock = yield call(api.getEthereumLatestBlock) - yield call(accountSaga, data, latestBlock) const txs = path([address, 'txns'], data) if (isNil(txs)) return - yield put(A.fetchTransactionsSuccess(txs, reset)) + yield put(A.fetchTransactionsSuccess(txs)) } catch (e) { - yield put(A.fetchDataFailure(e)) yield put(A.fetchTransactionsFailure(e.message)) } } @@ -72,35 +104,12 @@ export default ({ api }) => { yield put(A.fetchLegacyBalanceFailure()) } } - - const accountSaga = function * (data, latestBlock) { - // Accounts treatments - const finalBalance = sum(values(data).map(obj => obj.balance)) - const totalReceived = sum(values(data).map(obj => obj.totalReceived)) - const totalSent = sum(values(data).map(obj => obj.totalSent)) - const nTx = sum(values(data).map(obj => obj.txn_count)) - const addresses = mapObjIndexed((num, key, obj) => dissoc('txns', num), data) - // const transactions = mapObjIndexed((num, key, obj) => sortBy(compose(negate, prop('timeStamp')), prop('txns', num)), data) - - const ethereumData = { - addresses, - info: { - n_tx: nTx, - total_received: totalReceived, - total_sent: totalSent, - final_balance: finalBalance - }, - latest_block: latestBlock - // transactions - } - yield put(A.fetchDataSuccess(ethereumData)) - } - return { fetchFee, fetchData, fetchLegacyBalance, fetchRates, - fetchLatestBlock + fetchLatestBlock, + watchTransactions } } diff --git a/packages/blockchain-wallet-v4/src/redux/refresh/sagas.js b/packages/blockchain-wallet-v4/src/redux/refresh/sagas.js index b019b044984..b6a42e54508 100644 --- a/packages/blockchain-wallet-v4/src/redux/refresh/sagas.js +++ b/packages/blockchain-wallet-v4/src/redux/refresh/sagas.js @@ -5,9 +5,9 @@ import * as ethActions from '../data/ethereum/actions' export default () => { const refresh = function * () { - yield put(btcActions.fetchData('', true)) - yield put(bchActions.fetchData('', true)) - yield put(ethActions.fetchData(true)) + yield put(btcActions.fetchData()) + yield put(bchActions.fetchData()) + yield put(ethActions.fetchData()) yield put(btcActions.fetchRates()) yield put(bchActions.fetchRates()) yield put(ethActions.fetchRates()) diff --git a/packages/blockchain-wallet-v4/src/redux/wallet/sagas.js b/packages/blockchain-wallet-v4/src/redux/wallet/sagas.js index 26743a9ef51..de65494676c 100644 --- a/packages/blockchain-wallet-v4/src/redux/wallet/sagas.js +++ b/packages/blockchain-wallet-v4/src/redux/wallet/sagas.js @@ -136,7 +136,7 @@ export default ({ api }) => { } const refetchContextData = function * () { - yield put(fetchData('', true)) + yield put(fetchData()) } return { diff --git a/packages/blockchain-wallet-v4/src/redux/wallet/selectors.js b/packages/blockchain-wallet-v4/src/redux/wallet/selectors.js index 7a118f5c809..a67db678aa4 100644 --- a/packages/blockchain-wallet-v4/src/redux/wallet/selectors.js +++ b/packages/blockchain-wallet-v4/src/redux/wallet/selectors.js @@ -15,6 +15,7 @@ export const getWrapper = prop(walletPath) export const getWallet = compose(Wrapper.selectWallet, getWrapper) export const getDefaultHDWallet = compose(HDWalletList.selectHDWallet, Wallet.selectHdWallets, getWallet) export const getWalletContext = compose(ImtoJS, Wallet.selectContext, getWallet) +export const getContext = compose(ImtoJS, Wallet.selectContext, getWallet) export const getSpendableContext = compose(ImtoJS, Wallet.selectSpendableContext, getWallet) export const getUnspendableContext = compose(ImtoJS, Wallet.selectUnspendableContext, getWallet) export const getAddressContext = compose(ImtoJS, Wallet.selectAddrContext, getWallet) diff --git a/packages/blockchain-wallet-v4/src/redux/webSocket/bch/sagas.js b/packages/blockchain-wallet-v4/src/redux/webSocket/bch/sagas.js index cac13178599..885feb91188 100644 --- a/packages/blockchain-wallet-v4/src/redux/webSocket/bch/sagas.js +++ b/packages/blockchain-wallet-v4/src/redux/webSocket/bch/sagas.js @@ -20,7 +20,7 @@ export default ({ api, bchSocket }) => { switch (message.op) { case 'utx': - yield put(bchActions.fetchData('', true)) + yield put(bchActions.fetchTransactions('', true)) const transactions = yield take(bchAT.FETCH_BCH_TRANSACTIONS_SUCCESS) for (let i in transactions.payload.transactions) { const tx = transactions.payload.transactions[i] diff --git a/packages/blockchain-wallet-v4/src/redux/webSocket/bitcoin/sagas.js b/packages/blockchain-wallet-v4/src/redux/webSocket/bitcoin/sagas.js index 1577b4212eb..663d900891a 100644 --- a/packages/blockchain-wallet-v4/src/redux/webSocket/bitcoin/sagas.js +++ b/packages/blockchain-wallet-v4/src/redux/webSocket/bitcoin/sagas.js @@ -34,7 +34,7 @@ export default ({ api, btcSocket }) => { } break case 'utx': - yield put(btcActions.fetchData('', true)) + yield put(btcActions.fetchTransactions('', true)) const transactions = yield take(btcAT.FETCH_BITCOIN_TRANSACTIONS_SUCCESS) for (let i in transactions.payload.transactions) { const tx = transactions.payload.transactions[i]