From 04efa25b4d44e7e4c3bc4441954bf6837ed465cb Mon Sep 17 00:00:00 2001 From: Philip London Date: Fri, 17 Jul 2020 12:41:39 +0200 Subject: [PATCH] feat(sb): display raw tx data to fiat tx --- package.json | 2 +- .../src/assets/locales/index.d.ts | 1 + .../Transactions/TransactionList/index.tsx | 17 +++-- .../TransactionList/template.fiattx.tsx | 16 +++++ ...ate.simplebuy.tsx => template.sborder.tsx} | 23 ++----- .../scenes/Transactions/components/index.tsx | 14 ++++ .../src/scenes/Transactions/index.tsx | 14 +++- .../{selectors.js => selectors.ts} | 11 ++- .../Transactions/template.headerexplainer.tsx | 49 +++++++------- .../src/network/api/simpleBuy/index.ts | 30 ++++++++- .../src/network/api/simpleBuy/types.ts | 27 ++++++++ .../src/redux/data/actionTypes.ts | 3 +- .../src/redux/data/actions.ts | 3 +- .../src/redux/data/fiat/actionTypes.ts | 9 +++ .../src/redux/data/fiat/actions.ts | 41 ++++++++++++ .../src/redux/data/fiat/reducers.ts | 67 +++++++++++++++++++ .../src/redux/data/fiat/sagaRegister.ts | 14 ++++ .../src/redux/data/fiat/sagas.ts | 40 +++++++++++ .../src/redux/data/fiat/selectors.ts | 10 +++ .../src/redux/data/fiat/types.ts | 35 ++++++++++ .../src/redux/data/reducers.ts | 2 + .../src/redux/data/sagaRegister.ts | 2 + .../src/redux/data/sagas.ts | 2 + .../src/redux/data/selectors.ts | 3 +- .../src/redux/data/simpleBuy/sagas.ts | 5 +- .../src/redux/walletOptions/types.ts | 2 +- 26 files changed, 382 insertions(+), 60 deletions(-) create mode 100644 packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/TransactionList/template.fiattx.tsx rename packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/TransactionList/{template.simplebuy.tsx => template.sborder.tsx} (91%) create mode 100644 packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/components/index.tsx rename packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/{selectors.js => selectors.ts} (87%) create mode 100644 packages/blockchain-wallet-v4/src/redux/data/fiat/actionTypes.ts create mode 100644 packages/blockchain-wallet-v4/src/redux/data/fiat/actions.ts create mode 100644 packages/blockchain-wallet-v4/src/redux/data/fiat/reducers.ts create mode 100644 packages/blockchain-wallet-v4/src/redux/data/fiat/sagaRegister.ts create mode 100644 packages/blockchain-wallet-v4/src/redux/data/fiat/sagas.ts create mode 100644 packages/blockchain-wallet-v4/src/redux/data/fiat/selectors.ts create mode 100644 packages/blockchain-wallet-v4/src/redux/data/fiat/types.ts diff --git a/package.json b/package.json index eecefad432a..c501358ea3c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blockchain-wallet-v4", - "version": "4.37.13", + "version": "4.37.14", "license": "AGPL-3.0-or-later", "private": true, "author": { diff --git a/packages/blockchain-wallet-v4-frontend/src/assets/locales/index.d.ts b/packages/blockchain-wallet-v4-frontend/src/assets/locales/index.d.ts index a23572046f4..3a4b6a5f193 100644 --- a/packages/blockchain-wallet-v4-frontend/src/assets/locales/index.d.ts +++ b/packages/blockchain-wallet-v4-frontend/src/assets/locales/index.d.ts @@ -2014,6 +2014,7 @@ type MessagesType = { 'scenes.transaction.headertext.explainer.bch': 'Bitcoin Cash (BCH) is a fork of Bitcoin built for everday transactions.' 'scenes.transaction.headertext.explainer.btc1': 'Bitcoin (BTC) is the original crypto and the internet’s digital currency.' 'scenes.transaction.headertext.explainer.eth': 'Ethereum (ETH) is a currency and computing platform. Built for developers and apps.' + 'scenes.transaction.headertext.explainer.fiat': 'Store {currency} on your wallet and use it to Buy Crypto.' 'scenes.transaction.headertext.explainer.usdd': 'The USD Digital coin (USD-D) is backed by the US Dollar, making it a Stablecoin.' 'scenes.transaction.headertext.explainer.usdt': 'The Tether coin (USDT) is backed by the US Dollar, making it a Stablecoin.' 'scenes.transaction.headertext.explainer.xlm': 'The Stellar Lumen (XLM) connects banks, payments and you to the Stellar Payment network.' diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/TransactionList/index.tsx b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/TransactionList/index.tsx index e426f606676..f54c9046f8a 100644 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/TransactionList/index.tsx +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/TransactionList/index.tsx @@ -3,13 +3,16 @@ import { FiatType, ProcessedTxType, RemoteDataType, - SBOrderType + SBOrderType, + SBTransactionType } from 'core/types' import DataError from 'components/DataError' -import Loading from './template.loading' import React, { PureComponent } from 'react' -import SimpleBuyListItem from './template.simplebuy' import styled from 'styled-components' + +import FiatTxListItem from './template.fiattx' +import Loading from './template.loading' +import SimpleBuyListItem from './template.sborder' import TransactionListItem from 'components/TransactionListItem' const TransactionsWrapper = styled.div` @@ -30,7 +33,9 @@ class TransactionList extends PureComponent { const { coin, coinTicker, currency, data } = this.props return data.cata({ - Success: (transactions: Array) => ( + Success: ( + transactions: Array + ) => ( {transactions.map(tx => { return 'hash' in tx ? ( @@ -41,8 +46,10 @@ class TransactionList extends PureComponent { coinTicker={coinTicker} currency={currency} /> - ) : ( + ) : 'pair' in tx ? ( + ) : ( + ) })} diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/TransactionList/template.fiattx.tsx b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/TransactionList/template.fiattx.tsx new file mode 100644 index 00000000000..c3791420326 --- /dev/null +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/TransactionList/template.fiattx.tsx @@ -0,0 +1,16 @@ +import media from 'services/ResponsiveService' +import React from 'react' +import styled from 'styled-components' + +import { SBTransactionType } from 'core/types' +import { TransactionRow } from '../components' + +const FiatTxListItem: React.FC = props => { + return {JSON.stringify(props.tx)} +} + +type Props = { + tx: SBTransactionType +} + +export default FiatTxListItem diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/TransactionList/template.simplebuy.tsx b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/TransactionList/template.sborder.tsx similarity index 91% rename from packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/TransactionList/template.simplebuy.tsx rename to packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/TransactionList/template.sborder.tsx index 508efb9a19f..ac2a45a5e58 100644 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/TransactionList/template.simplebuy.tsx +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/TransactionList/template.sborder.tsx @@ -1,29 +1,20 @@ -import { actions } from 'data' import { bindActionCreators, Dispatch } from 'redux' import { Button, Text } from 'blockchain-info-components' import { connect, ConnectedProps } from 'react-redux' -import { convertBaseToStandard } from 'data/components/exchange/services' import { fiatToString } from 'core/exchange/currency' import { FiatType, SBOrderType } from 'core/types' import { FormattedMessage } from 'react-intl' -import { getOrderType } from 'data/components/simpleBuy/model' -import { Status } from './model' import media from 'services/ResponsiveService' import React, { PureComponent } from 'react' import styled from 'styled-components' -const TransactionRow = styled.div` - width: 100%; - display: flex; - cursor: pointer; - align-items: center; - justify-content: space-between; - border-bottom: 1px solid ${props => props.theme.grey000} !important; - box-sizing: border-box; - padding: 14px; - padding-left: 0px; - margin-left: 14px; -` +import { actions } from 'data' + +import { convertBaseToStandard } from 'data/components/exchange/services' +import { getOrderType } from 'data/components/simpleBuy/model' +import { Status } from './model' +import { TransactionRow } from '../components' + const StatusColumn = styled.div` display: flex; flex-direction: column; diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/components/index.tsx b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/components/index.tsx new file mode 100644 index 00000000000..7abe3f8c2ff --- /dev/null +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/components/index.tsx @@ -0,0 +1,14 @@ +import styled from 'styled-components' + +export const TransactionRow = styled.div` + width: 100%; + display: flex; + cursor: pointer; + align-items: center; + justify-content: space-between; + border-bottom: 1px solid ${props => props.theme.grey000} !important; + box-sizing: border-box; + padding: 14px; + padding-left: 0px; + margin-left: 14px; +` \ No newline at end of file diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/index.tsx b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/index.tsx index ec8fcdbed27..6ba9514dc6e 100644 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/index.tsx +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/index.tsx @@ -1,5 +1,5 @@ import { actions, model } from 'data' -import { CoinType, FiatType, SupportedCoinType } from 'core/types' +import { CoinType, FiatType, FiatTypeEnum, SupportedCoinType } from 'core/types' import { compose, Dispatch } from 'redux' import { connect, ConnectedProps } from 'react-redux' import { getData } from './selectors' @@ -119,12 +119,12 @@ class TransactionsContainer extends React.PureComponent { {getHeaderExplainer(coinModel)} - - + */} {(hasTxResults || isSearchEntered) && ( @@ -177,6 +177,14 @@ const mapDispatchToProps = (dispatch: Dispatch, ownProps) => { dispatch(actions.components.ethTransactions.loadMoreErc20(coin)) } } + if (coin in FiatTypeEnum) { + return { + fetchData: () => {}, + loadMoreTxs: () => + dispatch(actions.core.data.fiat.fetchTransactions(coin)), + initTxs: () => dispatch(actions.core.data.fiat.fetchTransactions(coin)) + } + } return { fetchData: () => dispatch(actions.core.data[toLower(coin)].fetchData()), initTxs: () => diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/selectors.js b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/selectors.ts similarity index 87% rename from packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/selectors.js rename to packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/selectors.ts index 931d80ba0cc..4301c89ecf1 100644 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/selectors.js +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/selectors.ts @@ -23,6 +23,7 @@ const { WALLET_TX_SEARCH } = model.form const filterTransactions = curry((status, criteria, transactions) => { const isOfType = curry((filter, tx) => propSatisfies( + // @ts-ignore x => filter === '' || (x && toUpper(x) === toUpper(filter)), 'type', tx @@ -51,7 +52,12 @@ const coinSelectorMap = (state, coin, isCoinErc20) => { return state => selectors.core.common.eth.getErc20WalletTransactions(state, coin) } - return selectors.core.common[toLower(coin)].getWalletTransactions + if (selectors.core.common[toLower(coin)]) { + return selectors.core.common[toLower(coin)].getWalletTransactions + } + + // default to fiat + return state => selectors.core.data.fiat.getTransactions(coin, state) } export const getData = (state, coin, isCoinErc20) => @@ -62,7 +68,7 @@ export const getData = (state, coin, isCoinErc20) => selectors.core.settings.getCurrency, () => selectors.core.walletOptions.getCoinModel(state, coin) ], - (userSearch, pages, currencyR, coinModelR) => { + (userSearch, pages: any, currencyR, coinModelR) => { const empty = page => isEmpty(page.data) const search = propOr('', 'search', userSearch) const status = propOr('', 'status', userSearch) @@ -76,6 +82,7 @@ export const getData = (state, coin, isCoinErc20) => coinModel: coinModelR.getOrElse({}), currency: currencyR.getOrElse(''), hasTxResults: !all(empty)(filteredPages), + // @ts-ignore isSearchEntered: search.length > 0 || status !== '', pages: filteredPages, sourceType diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/template.headerexplainer.tsx b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/template.headerexplainer.tsx index bdeae1d0e89..8b6a5fbc73c 100644 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/template.headerexplainer.tsx +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Transactions/template.headerexplainer.tsx @@ -1,5 +1,6 @@ import { FormattedMessage } from 'react-intl' import { Link, Text } from 'blockchain-info-components' +import { SupportedCoinType, SupportedFiatType } from 'core/types' import React from 'react' import styled from 'styled-components' @@ -19,7 +20,9 @@ const LearnMoreText = styled(Text)` color: ${props => props.theme.blue600}; ` -export const getHeaderExplainer = coinModel => { +export const getHeaderExplainer = ( + coinModel: SupportedCoinType | SupportedFiatType +) => { switch (coinModel.coinTicker) { case 'BTC': { return ( @@ -28,10 +31,7 @@ export const getHeaderExplainer = coinModel => { id='scenes.transaction.headertext.explainer.btc1' defaultMessage='Bitcoin (BTC) is the original crypto and the internet’s digital currency.' /> - + { id='scenes.transaction.headertext.explainer.eth' defaultMessage='Ethereum (ETH) is a currency and computing platform. Built for developers and apps.' /> - + { id='scenes.transaction.headertext.explainer.bch' defaultMessage='Bitcoin Cash (BCH) is a fork of Bitcoin built for everday transactions.' /> - + { ) } + // @ts-ignore case 'USD-D': { return ( @@ -91,10 +86,7 @@ export const getHeaderExplainer = coinModel => { id='scenes.transaction.headertext.explainer.usdd' defaultMessage='The USD Digital coin (USD-D) is backed by the US Dollar, making it a Stablecoin.' /> - + { id='scenes.transaction.headertext.explainer.usdt' defaultMessage='The Tether coin (USDT) is backed by the US Dollar, making it a Stablecoin.' /> - + { id='scenes.transaction.headertext.explainer.xlm' defaultMessage='The Stellar Lumen (XLM) connects banks, payments and you to the Stellar Payment network.' /> - + { ) } + case 'GBP': + case 'EUR': + return ( + + + + ) default: { return } diff --git a/packages/blockchain-wallet-v4/src/network/api/simpleBuy/index.ts b/packages/blockchain-wallet-v4/src/network/api/simpleBuy/index.ts index bc0f3243dbd..c297ec28894 100644 --- a/packages/blockchain-wallet-v4/src/network/api/simpleBuy/index.ts +++ b/packages/blockchain-wallet-v4/src/network/api/simpleBuy/index.ts @@ -13,7 +13,9 @@ import { SBPaymentMethodType, SBProviderAttributesType, SBQuoteType, - SBSuggestedAmountType + SBSuggestedAmountType, + SBTransactionStateType, + SBTransactionsType } from './types' import { Moment } from 'moment' import { UserDataType } from 'data/types' @@ -233,6 +235,31 @@ export default ({ } }) + const getSBTransactions = ( + currency: FiatType, + next?: string, + limit?: string, + type?: 'DEPOSIT' | 'WITHDRAWAL', + state?: SBTransactionStateType + ): SBTransactionsType => + next + ? authorizedGet({ + url: nabuUrl, + endPoint: next, + ignoreQueryParams: true, + }) + : authorizedGet({ + url: nabuUrl, + ignoreQueryParams: true, + endPoint: '/payments/transactions?product=SIMPLEBUY', + data: { + currency, + limit, + type, + state + } + }) + const submitSBCardDetailsToEverypay = ({ accessToken, apiUserName, @@ -310,6 +337,7 @@ export default ({ getSBFiatEligible, getSBQuote, getSBSuggestedAmounts, + getSBTransactions, submitSBCardDetailsToEverypay, withdrawSBFunds } diff --git a/packages/blockchain-wallet-v4/src/network/api/simpleBuy/types.ts b/packages/blockchain-wallet-v4/src/network/api/simpleBuy/types.ts index 1e6e952d4b5..d0ec13cab2a 100644 --- a/packages/blockchain-wallet-v4/src/network/api/simpleBuy/types.ts +++ b/packages/blockchain-wallet-v4/src/network/api/simpleBuy/types.ts @@ -193,6 +193,33 @@ export type SBQuoteType = { time: string } +export type SBTransactionType = { + amount: { symbol: FiatType; value: string } + extraAttributes: null + id: string + insertedAt: string + state: SBTransactionStateType + type: 'DEPOSIT' | 'WITHDRAWAL' +} + +export type SBTransactionsType = { + items: Array + next: string | null + prev: string | null +} + +export type SBTransactionStateType = + | 'CREATED' + | 'PENDING' + | 'UNIDENTIFIED' + | 'FAILED' + | 'FRAUD_REVIEW' + | 'MANUAL_REVIEW' + | 'REJECTED' + | 'CLEARED' + | 'COMPLETE' + | 'REFUNDED' + export type FiatEligibleType = { eligible: boolean paymentAccountEligible: boolean diff --git a/packages/blockchain-wallet-v4/src/redux/data/actionTypes.ts b/packages/blockchain-wallet-v4/src/redux/data/actionTypes.ts index a81c9ddcec8..3306ed71d41 100755 --- a/packages/blockchain-wallet-v4/src/redux/data/actionTypes.ts +++ b/packages/blockchain-wallet-v4/src/redux/data/actionTypes.ts @@ -2,8 +2,9 @@ import * as algo from './algo/actionTypes' import * as bch from './bch/actionTypes' import * as btc from './btc/actionTypes' import * as eth from './eth/actionTypes' +import * as fiat from './fiat/actionTypes' import * as misc from './misc/actionTypes' import * as stx from './stx/actionTypes' import * as xlm from './xlm/actionTypes' -export { algo, bch, btc, eth, misc, stx, xlm } +export { algo, bch, btc, eth, fiat, misc, stx, xlm } diff --git a/packages/blockchain-wallet-v4/src/redux/data/actions.ts b/packages/blockchain-wallet-v4/src/redux/data/actions.ts index e0b5e5eebf9..9c69a713d05 100755 --- a/packages/blockchain-wallet-v4/src/redux/data/actions.ts +++ b/packages/blockchain-wallet-v4/src/redux/data/actions.ts @@ -2,8 +2,9 @@ import * as algo from './algo/actions' import * as bch from './bch/actions' import * as btc from './btc/actions' import * as eth from './eth/actions' +import * as fiat from './fiat/actions' import * as misc from './misc/actions' import * as stx from './stx/actions' import * as xlm from './xlm/actions' -export { algo, bch, btc, eth, misc, stx, xlm } +export { algo, bch, btc, eth, fiat, misc, stx, xlm } diff --git a/packages/blockchain-wallet-v4/src/redux/data/fiat/actionTypes.ts b/packages/blockchain-wallet-v4/src/redux/data/fiat/actionTypes.ts new file mode 100644 index 00000000000..5959df195e5 --- /dev/null +++ b/packages/blockchain-wallet-v4/src/redux/data/fiat/actionTypes.ts @@ -0,0 +1,9 @@ +// FETCH_FIAT_TRANSACTIONS +export const FETCH_FIAT_TRANSACTIONS = '@CORE.FETCH_FIAT_TRANSACTIONS' +export const FETCH_FIAT_TRANSACTIONS_LOADING = + '@CORE.FETCH_FIAT_TRANSACTIONS_LOADING' +export const FETCH_FIAT_TRANSACTIONS_SUCCESS = + '@CORE.FETCH_FIAT_TRANSACTIONS_SUCCESS' +export const FETCH_FIAT_TRANSACTIONS_FAILURE = + '@CORE.FETCH_FIAT_TRANSACTIONS_FAILURE' +export const FIAT_TRANSACTIONS_AT_BOUND = '@CORE.FIAT_TRANSACTIONS_AT_BOUND' diff --git a/packages/blockchain-wallet-v4/src/redux/data/fiat/actions.ts b/packages/blockchain-wallet-v4/src/redux/data/fiat/actions.ts new file mode 100644 index 00000000000..01a4488f80e --- /dev/null +++ b/packages/blockchain-wallet-v4/src/redux/data/fiat/actions.ts @@ -0,0 +1,41 @@ +import * as AT from './actionTypes' +import { FiatActionTypes } from './types' +import { FiatType, SBTransactionsType } from 'core/types' + +// FETCH_FIAT_TRANSACTIONS +export const fetchTransactions = (currency: FiatType, reset?: boolean) => ({ + type: AT.FETCH_FIAT_TRANSACTIONS, + payload: { currency, reset } +}) +export const fetchTransactionsFailure = ( + currency: FiatType, + error +): FiatActionTypes => ({ + type: AT.FETCH_FIAT_TRANSACTIONS_FAILURE, + payload: { currency, error } +}) +export const fetchTransactionsLoading = ( + currency: FiatType, + reset: boolean +): FiatActionTypes => ({ + type: AT.FETCH_FIAT_TRANSACTIONS_LOADING, + payload: { currency, reset } +}) +export const fetchTransactionsSuccess = ( + currency: FiatType, + response: SBTransactionsType, + reset?: boolean +): FiatActionTypes => ({ + type: AT.FETCH_FIAT_TRANSACTIONS_SUCCESS, + payload: { currency, response, reset } +}) +export const transactionsAtBound = ( + currency: FiatType, + isAtBound: boolean +) => ({ + type: AT.FIAT_TRANSACTIONS_AT_BOUND, + payload: { + currency, + isAtBound + } +}) diff --git a/packages/blockchain-wallet-v4/src/redux/data/fiat/reducers.ts b/packages/blockchain-wallet-v4/src/redux/data/fiat/reducers.ts new file mode 100644 index 00000000000..b55ef82a3c8 --- /dev/null +++ b/packages/blockchain-wallet-v4/src/redux/data/fiat/reducers.ts @@ -0,0 +1,67 @@ +import Remote from 'blockchain-wallet-v4/src/remote/remote' + +import * as AT from './actionTypes' +import { FiatActionTypes, FiatStateType } from './types' +import { RemoteDataType, SBTransactionsType } from 'core/types' + +const DEFAULT_STATE = { + transactions: [], + next: Remote.NotAsked, + prev: Remote.NotAsked +} + +const INITIAL_STATE: FiatStateType = { + EUR: DEFAULT_STATE, + GBP: DEFAULT_STATE +} + +let txs: Array> + +export const fiatReducer = ( + state = INITIAL_STATE, + action: FiatActionTypes +): FiatStateType => { + switch (action.type) { + case AT.FETCH_FIAT_TRANSACTIONS_FAILURE: + return { + ...state, + [action.payload.currency]: { + transactions: [Remote.Failure(action.payload.error)], + next: Remote.Failure(action.payload.error), + prev: Remote.Failure(action.payload.error) + } + } + case AT.FETCH_FIAT_TRANSACTIONS_LOADING: + txs = state[action.payload.currency]?.transactions || [] + return { + ...state, + [action.payload.currency]: { + transactions: action.payload.reset + ? [Remote.Loading] + : txs + ? [...txs, Remote.Loading] + : [Remote.Loading], + next: Remote.Loading, + prev: Remote.Loading + } + } + case AT.FETCH_FIAT_TRANSACTIONS_SUCCESS: + txs = state[action.payload.currency]?.transactions || [] + return { + ...state, + [action.payload.currency]: { + transactions: [ + Remote.Success(action.payload.response.items), + ...txs.filter((tx, i) => i !== txs.length - 1) + ], + next: Remote.Success(action.payload.response.next), + prev: Remote.Success(action.payload.response.prev) + } + } + default: { + return state + } + } +} + +export default fiatReducer diff --git a/packages/blockchain-wallet-v4/src/redux/data/fiat/sagaRegister.ts b/packages/blockchain-wallet-v4/src/redux/data/fiat/sagaRegister.ts new file mode 100644 index 00000000000..75d913ac19e --- /dev/null +++ b/packages/blockchain-wallet-v4/src/redux/data/fiat/sagaRegister.ts @@ -0,0 +1,14 @@ +import * as AT from './actionTypes' +import { takeLatest } from 'redux-saga/effects' +import sagas from './sagas' + +export default ({ api }) => { + const dataFiatSagas = sagas({ api }) + + return function * coreDataFiatSaga () { + yield takeLatest( + AT.FETCH_FIAT_TRANSACTIONS, + dataFiatSagas.fetchTransactions + ) + } +} diff --git a/packages/blockchain-wallet-v4/src/redux/data/fiat/sagas.ts b/packages/blockchain-wallet-v4/src/redux/data/fiat/sagas.ts new file mode 100644 index 00000000000..66f20990def --- /dev/null +++ b/packages/blockchain-wallet-v4/src/redux/data/fiat/sagas.ts @@ -0,0 +1,40 @@ +import { call, put, select } from 'redux-saga/effects' +import { last } from 'ramda' + +import { APIType } from 'core/network/api' +import Remote from '../../../remote' + +import * as A from './actions' +import * as S from './selectors' +import { errorHandler } from 'blockchain-wallet-v4/src/utils' + +export default ({ api }: { api: APIType }) => { + const fetchTransactions = function * ( + action: ReturnType + ) { + try { + const { payload } = action + const { reset } = payload + const data = S.getFiatData(action.payload.currency, yield select()) + if (data && Remote.Loading.is(last(data.transactions))) return + const next = data && data.next.getOrElse(undefined) + if (!next && !reset && data?.transactions.length) return + yield put(A.fetchTransactionsLoading(action.payload.currency, !!reset)) + const response: ReturnType = yield call( + api.getSBTransactions, + action.payload.currency, + next + ) + yield put( + A.fetchTransactionsSuccess(action.payload.currency, response, reset) + ) + } catch (e) { + const error = errorHandler(e) + yield put(A.fetchTransactionsFailure(action.payload.currency, error)) + } + } + + return { + fetchTransactions + } +} diff --git a/packages/blockchain-wallet-v4/src/redux/data/fiat/selectors.ts b/packages/blockchain-wallet-v4/src/redux/data/fiat/selectors.ts new file mode 100644 index 00000000000..169de0432b5 --- /dev/null +++ b/packages/blockchain-wallet-v4/src/redux/data/fiat/selectors.ts @@ -0,0 +1,10 @@ +import { FiatType } from 'core/types' +import { RootState } from 'data/rootReducer' + +export const getFiatData = (currency: FiatType, state: RootState) => { + return state.dataPath.fiat[currency] +} + +export const getTransactions = (currency: FiatType, state: RootState) => { + return state.dataPath.fiat[currency]?.transactions || [] +} diff --git a/packages/blockchain-wallet-v4/src/redux/data/fiat/types.ts b/packages/blockchain-wallet-v4/src/redux/data/fiat/types.ts new file mode 100644 index 00000000000..5406fd6406c --- /dev/null +++ b/packages/blockchain-wallet-v4/src/redux/data/fiat/types.ts @@ -0,0 +1,35 @@ +import { FiatType, RemoteDataType, SBTransactionsType } from 'core/types' + +import * as AT from './actionTypes' + +// state +export type FiatStateType = { + [key in FiatType]?: { + next: RemoteDataType + prev: RemoteDataType + transactions: Array> + } +} + +// actions +interface FetchTransactionsFailureActionType { + payload: { currency: FiatType; error: string } + type: typeof AT.FETCH_FIAT_TRANSACTIONS_FAILURE +} +interface FetchTransactionsLoadingActionType { + payload: { currency: FiatType; reset: boolean } + type: typeof AT.FETCH_FIAT_TRANSACTIONS_LOADING +} +interface FetchTransactionsSuccessActionType { + payload: { + currency: FiatType + reset?: boolean + response: SBTransactionsType + } + type: typeof AT.FETCH_FIAT_TRANSACTIONS_SUCCESS +} + +export type FiatActionTypes = + | FetchTransactionsFailureActionType + | FetchTransactionsLoadingActionType + | FetchTransactionsSuccessActionType diff --git a/packages/blockchain-wallet-v4/src/redux/data/reducers.ts b/packages/blockchain-wallet-v4/src/redux/data/reducers.ts index 8dad7b16c30..535f3157aef 100755 --- a/packages/blockchain-wallet-v4/src/redux/data/reducers.ts +++ b/packages/blockchain-wallet-v4/src/redux/data/reducers.ts @@ -1,5 +1,6 @@ import { algoReducer } from './algo/reducers' import { combineReducers } from 'redux' +import { fiatReducer } from './fiat/reducers' import { miscReducer } from './misc/reducers' import bch from './bch/reducers' import btc from './btc/reducers' @@ -11,6 +12,7 @@ const dataReducer = combineReducers({ bch, btc, eth, + fiat: fiatReducer, misc: miscReducer, xlm }) diff --git a/packages/blockchain-wallet-v4/src/redux/data/sagaRegister.ts b/packages/blockchain-wallet-v4/src/redux/data/sagaRegister.ts index da30abe65f2..c160711698c 100755 --- a/packages/blockchain-wallet-v4/src/redux/data/sagaRegister.ts +++ b/packages/blockchain-wallet-v4/src/redux/data/sagaRegister.ts @@ -3,6 +3,7 @@ import algo from './algo/sagaRegister' import bch from './bch/sagaRegister' import btc from './btc/sagaRegister' import eth from './eth/sagaRegister' +import fiat from './fiat/sagaRegister' import misc from './misc/sagaRegister' import stx from './stx/sagaRegister' import xlm from './xlm/sagaRegister' @@ -13,6 +14,7 @@ export default ({ api, networks }) => yield fork(bch({ api })) yield fork(btc({ api })) yield fork(eth({ api })) + yield fork(fiat({ api })) yield fork(misc({ api })) yield fork(stx()) yield fork(xlm({ api, networks })) diff --git a/packages/blockchain-wallet-v4/src/redux/data/sagas.ts b/packages/blockchain-wallet-v4/src/redux/data/sagas.ts index 6109c130d58..bddd47c0a45 100755 --- a/packages/blockchain-wallet-v4/src/redux/data/sagas.ts +++ b/packages/blockchain-wallet-v4/src/redux/data/sagas.ts @@ -2,6 +2,7 @@ import algo from './algo/sagas' import bch from './bch/sagas' import btc from './btc/sagas' import eth from './eth/sagas' +import fiat from './fiat/sagas' import stx from './stx/sagas' import xlm from './xlm/sagas' @@ -10,6 +11,7 @@ export default ({ api, networks }) => ({ bch: bch({ api }), btc: btc({ api }), eth: eth({ api }), + fiat: fiat({ api }), stx: stx(), xlm: xlm({ api, networks }) }) diff --git a/packages/blockchain-wallet-v4/src/redux/data/selectors.ts b/packages/blockchain-wallet-v4/src/redux/data/selectors.ts index f5d3d8e698a..51b90f0fbd6 100755 --- a/packages/blockchain-wallet-v4/src/redux/data/selectors.ts +++ b/packages/blockchain-wallet-v4/src/redux/data/selectors.ts @@ -2,7 +2,8 @@ import * as algo from './algo/selectors' import * as bch from './bch/selectors' import * as btc from './btc/selectors' import * as eth from './eth/selectors' +import * as fiat from './fiat/selectors' import * as misc from './misc/selectors' import * as xlm from './xlm/selectors' -export { algo, bch, btc, eth, xlm, misc } +export { algo, bch, btc, eth, fiat, xlm, misc } diff --git a/packages/blockchain-wallet-v4/src/redux/data/simpleBuy/sagas.ts b/packages/blockchain-wallet-v4/src/redux/data/simpleBuy/sagas.ts index 8bc0916dd89..c4aa29fd80a 100644 --- a/packages/blockchain-wallet-v4/src/redux/data/simpleBuy/sagas.ts +++ b/packages/blockchain-wallet-v4/src/redux/data/simpleBuy/sagas.ts @@ -1,16 +1,15 @@ import { APIType } from 'core/network/api' import { call } from 'redux-saga/effects' -import { CoinType, SBOrderType } from 'core/types' +import { CoinType, FiatType, SBOrderType } from 'core/types' import { ProcessedTxType } from 'core/transactions/types' import moment from 'moment' export default ({ api }: { api: APIType }) => { - // TODO - filter orders by coin const fetchSBOrders = function * ( page: Array, offset: number, transactionsAtBound: boolean, - currency: CoinType + currency: CoinType | FiatType ) { try { const latestTx = page[0] diff --git a/packages/blockchain-wallet-v4/src/redux/walletOptions/types.ts b/packages/blockchain-wallet-v4/src/redux/walletOptions/types.ts index a73a3d3539d..3bd6036ed1c 100644 --- a/packages/blockchain-wallet-v4/src/redux/walletOptions/types.ts +++ b/packages/blockchain-wallet-v4/src/redux/walletOptions/types.ts @@ -14,7 +14,7 @@ export type SupportedCoinType = { syncToPit: boolean } coinCode: CoinType - coinTicker: string + coinTicker: CoinType colorCode: 'btc' | 'bch' | 'eth' | 'xlm' | 'pax' | 'stx' | 'usdt' config: { network: string