Browse Source

Merge pull request #9 from LN-Zap/fix/refactor-ticker

Refactor hard-coded tickers to currentTicker
renovate/lint-staged-8.x
jackmallers 7 years ago
committed by GitHub
parent
commit
f3cbb58a25
  1. 9
      app/api/index.js
  2. 5
      app/lnd/methods/index.js
  3. 4
      app/reducers/ipc.js
  4. 76
      app/reducers/ticker.js
  5. 8
      app/routes/activity/components/Activity.js
  6. 10
      app/routes/activity/components/components/Invoices.js
  7. 12
      app/routes/activity/components/components/Payments.js
  8. 5
      app/routes/activity/containers/ActivityContainer.js
  9. 10
      app/routes/app/components/App.js
  10. 12
      app/routes/app/components/components/Form/Form.js
  11. 11
      app/routes/app/components/components/Nav.js
  12. 6
      app/routes/app/containers/AppContainer.js
  13. 11
      app/routes/wallet/components/Wallet.js
  14. 23
      app/routes/wallet/components/components/Channels/Channels.js
  15. 11
      app/routes/wallet/components/components/Channels/components/Channel/Channel.js
  16. 9
      app/routes/wallet/components/components/Channels/components/ChannelForm/ChannelForm.js
  17. 11
      app/routes/wallet/components/components/Channels/components/ClosedPendingChannel/ClosedPendingChannel.js
  18. 11
      app/routes/wallet/components/components/Channels/components/OpenPendingChannel/OpenPendingChannel.js
  19. 8
      app/routes/wallet/containers/WalletContainer.js
  20. 30
      test/reducers/__snapshots__/ticker.spec.js.snap
  21. 21
      test/reducers/ticker.spec.js

9
app/api/index.js

@ -1,7 +1,7 @@
import axios from 'axios' import axios from 'axios'
export default function requestTicker() { export function requestTicker(id) {
const BASE_URL = 'https://api.coinmarketcap.com/v1/ticker/bitcoin/' const BASE_URL = `https://api.coinmarketcap.com/v1/ticker/${id}/`
return axios({ return axios({
method: 'get', method: 'get',
url: BASE_URL url: BASE_URL
@ -9,3 +9,8 @@ export default function requestTicker() {
.then(response => response.data) .then(response => response.data)
.catch(error => error) .catch(error => error)
} }
export function requestTickers(ids) {
return axios.all(ids.map(id => requestTicker(id)))
.then(axios.spread((btcTicker, ltcTicker) => ({ btcTicker: btcTicker[0], ltcTicker: ltcTicker[0] })))
}

5
app/lnd/methods/index.js

@ -20,7 +20,10 @@ export default function (lnd, event, msg, data) {
switch (msg) { switch (msg) {
case 'info': case 'info':
info(lnd) info(lnd)
.then(infoData => event.sender.send('receiveInfo', infoData)) .then((infoData) => {
event.sender.send('receiveInfo', infoData)
event.sender.send('receiveCryptocurrency', infoData.chains[0])
})
.catch(error => console.log('info error: ', error)) .catch(error => console.log('info error: ', error))
break break
case 'newaddress': case 'newaddress':

4
app/reducers/ipc.js

@ -1,6 +1,7 @@
import createIpc from 'redux-electron-ipc' import createIpc from 'redux-electron-ipc'
import { receiveInfo } from './info' import { receiveInfo } from './info'
import { receiveAddress } from './address' import { receiveAddress } from './address'
import { receiveCryptocurrency } from './ticker'
import { receivePeers, connectSuccess, disconnectSuccess } from './peers' import { receivePeers, connectSuccess, disconnectSuccess } from './peers'
import { import {
receiveChannels, receiveChannels,
@ -32,7 +33,8 @@ const ipc = createIpc({
pushchannelstatus, pushchannelstatus,
connectSuccess, connectSuccess,
disconnectSuccess, disconnectSuccess,
receiveAddress receiveAddress,
receiveCryptocurrency
}) })
export default ipc export default ipc

76
app/reducers/ticker.js

@ -1,10 +1,18 @@
import requestTicker from '../api' import { createSelector } from 'reselect'
import { requestTickers } from '../api'
// ------------------------------------ // ------------------------------------
// Constants // Constants
// ------------------------------------ // ------------------------------------
export const SET_CURRENCY = 'SET_CURRENCY' export const SET_CURRENCY = 'SET_CURRENCY'
export const GET_TICKER = 'GET_TICKER' export const SET_CRYPTO = 'SET_CRYPTO'
export const RECIEVE_TICKER = 'RECIEVE_TICKER' export const GET_TICKERS = 'GET_TICKERS'
export const RECIEVE_TICKERS = 'RECIEVE_TICKERS'
// Map for crypto names to crypto tickers
const cryptoTickers = {
bitcoin: 'btc',
litecoin: 'ltc'
}
// ------------------------------------ // ------------------------------------
// Actions // Actions
@ -16,46 +24,78 @@ export function setCurrency(currency) {
} }
} }
export function getTicker() { export function setCrypto(crypto) {
return { return {
type: GET_TICKER type: SET_CRYPTO,
crypto
} }
} }
export function recieveTicker(ticker) { export function getTickers() {
return { return {
type: RECIEVE_TICKER, type: GET_TICKERS
ticker }
}
export function recieveTickers({ btcTicker, ltcTicker }) {
return {
type: RECIEVE_TICKERS,
btcTicker,
ltcTicker
} }
} }
export const fetchTicker = () => async (dispatch) => { export const fetchTicker = () => async (dispatch) => {
dispatch(getTicker()) dispatch(getTickers())
const ticker = await requestTicker() const tickers = await requestTickers(['bitcoin', 'litecoin'])
dispatch(recieveTicker(ticker)) dispatch(recieveTickers(tickers))
return ticker return tickers
} }
// Receive IPC event for receiveCryptocurrency
export const receiveCryptocurrency = (event, currency) => (dispatch) => {
dispatch({ type: SET_CURRENCY, currency: cryptoTickers[currency] })
dispatch({ type: SET_CRYPTO, crypto: cryptoTickers[currency] })
}
// ------------------------------------ // ------------------------------------
// Action Handlers // Action Handlers
// ------------------------------------ // ------------------------------------
const ACTION_HANDLERS = { const ACTION_HANDLERS = {
[SET_CURRENCY]: (state, { currency }) => ({ ...state, currency }), [SET_CURRENCY]: (state, { currency }) => ({ ...state, currency }),
[GET_TICKER]: state => ({ ...state, tickerLoading: true }), [SET_CRYPTO]: (state, { crypto }) => ({ ...state, crypto }),
[RECIEVE_TICKER]: (state, { ticker }) => ( [GET_TICKERS]: state => ({ ...state, tickerLoading: true }),
{ ...state, tickerLoading: false, btcTicker: ticker[0] } [RECIEVE_TICKERS]: (state, { btcTicker, ltcTicker }) => (
{ ...state, tickerLoading: false, btcTicker, ltcTicker }
) )
} }
// Selectors
const tickerSelectors = {}
const cryptoSelector = state => state.ticker.crypto
const bitcoinTickerSelector = state => state.ticker.btcTicker
const litecoinTickerSelector = state => state.ticker.ltcTicker
tickerSelectors.currentTicker = createSelector(
cryptoSelector,
bitcoinTickerSelector,
litecoinTickerSelector,
(crypto, btcTicker, ltcTicker) => (crypto === 'btc' ? btcTicker : ltcTicker)
)
export { tickerSelectors }
// ------------------------------------ // ------------------------------------
// Reducer // Reducer
// ------------------------------------ // ------------------------------------
const initialState = { const initialState = {
tickerLoading: false, tickerLoading: false,
currency: 'btc', currency: '',
crypto: 'btc', crypto: '',
btcTicker: null btcTicker: null,
ltcTicker: null
} }
export default function tickerReducer(state = initialState, action) { export default function tickerReducer(state = initialState, action) {

8
app/routes/activity/components/Activity.js

@ -31,7 +31,8 @@ class Activity extends Component {
setPayment, setPayment,
setInvoice, setInvoice,
paymentModalOpen, paymentModalOpen,
invoiceModalOpen invoiceModalOpen,
currentTicker
} = this.props } = this.props
if (invoiceLoading || paymentLoading) { return <div>Loading...</div> } if (invoiceLoading || paymentLoading) { return <div>Loading...</div> }
@ -75,6 +76,7 @@ class Activity extends Component {
ticker={ticker} ticker={ticker}
setPayment={setPayment} setPayment={setPayment}
paymentModalOpen={paymentModalOpen} paymentModalOpen={paymentModalOpen}
currentTicker={currentTicker}
/> />
: :
<Invoices <Invoices
@ -83,6 +85,7 @@ class Activity extends Component {
ticker={ticker} ticker={ticker}
setInvoice={setInvoice} setInvoice={setInvoice}
invoiceModalOpen={invoiceModalOpen} invoiceModalOpen={invoiceModalOpen}
currentTicker={currentTicker}
/> />
} }
</div> </div>
@ -103,7 +106,8 @@ Activity.propTypes = {
setPayment: PropTypes.func.isRequired, setPayment: PropTypes.func.isRequired,
setInvoice: PropTypes.func.isRequired, setInvoice: PropTypes.func.isRequired,
paymentModalOpen: PropTypes.bool.isRequired, paymentModalOpen: PropTypes.bool.isRequired,
invoiceModalOpen: PropTypes.bool.isRequired invoiceModalOpen: PropTypes.bool.isRequired,
currentTicker: PropTypes.object.isRequired
} }
export default Activity export default Activity

10
app/routes/activity/components/components/Invoices.js

@ -14,7 +14,8 @@ const Invoices = ({
invoices, invoices,
ticker, ticker,
setInvoice, setInvoice,
invoiceModalOpen invoiceModalOpen,
currentTicker
}) => ( }) => (
<div> <div>
<Modal isOpen={invoiceModalOpen} resetObject={setInvoice}> <Modal isOpen={invoiceModalOpen} resetObject={setInvoice}>
@ -34,7 +35,7 @@ const Invoices = ({
ticker.currency === 'btc' ? ticker.currency === 'btc' ?
btc.satoshisToBtc(invoice.value) btc.satoshisToBtc(invoice.value)
: :
btc.satoshisToUsd(invoice.value, ticker.btcTicker.price_usd) btc.satoshisToUsd(invoice.value, currentTicker.price_usd)
} }
</span> </span>
</h1> </h1>
@ -91,7 +92,7 @@ const Invoices = ({
ticker.currency === 'btc' ? ticker.currency === 'btc' ?
btc.satoshisToBtc(invoiceItem.value) btc.satoshisToBtc(invoiceItem.value)
: :
btc.satoshisToUsd(invoiceItem.value, ticker.btcTicker.price_usd) btc.satoshisToUsd(invoiceItem.value, currentTicker.price_usd)
} }
</div> </div>
</div> </div>
@ -107,7 +108,8 @@ Invoices.propTypes = {
invoices: PropTypes.array.isRequired, invoices: PropTypes.array.isRequired,
ticker: PropTypes.object.isRequired, ticker: PropTypes.object.isRequired,
setInvoice: PropTypes.func.isRequired, setInvoice: PropTypes.func.isRequired,
invoiceModalOpen: PropTypes.bool.isRequired invoiceModalOpen: PropTypes.bool.isRequired,
currentTicker: PropTypes.object.isRequired
} }
export default Invoices export default Invoices

12
app/routes/activity/components/components/Payments.js

@ -12,7 +12,8 @@ const Payments = ({
payments, payments,
ticker, ticker,
setPayment, setPayment,
paymentModalOpen paymentModalOpen,
currentTicker
}) => ( }) => (
<div> <div>
<Modal isOpen={paymentModalOpen} resetObject={setPayment}> <Modal isOpen={paymentModalOpen} resetObject={setPayment}>
@ -32,7 +33,7 @@ const Payments = ({
ticker.currency === 'btc' ? ticker.currency === 'btc' ?
btc.satoshisToBtc(payment.value) btc.satoshisToBtc(payment.value)
: :
btc.satoshisToUsd(payment.value, ticker.btcTicker.price_usd) btc.satoshisToUsd(payment.value, currentTicker.price_usd)
} }
</span> </span>
</h1> </h1>
@ -81,7 +82,7 @@ const Payments = ({
ticker.currency === 'btc' ? ticker.currency === 'btc' ?
btc.satoshisToBtc(paymentItem.fee) btc.satoshisToBtc(paymentItem.fee)
: :
btc.satoshisToUsd(paymentItem.fee, ticker.btcTicker.price_usd) btc.satoshisToUsd(paymentItem.fee, currentTicker.price_usd)
} }
</span> </span>
</div> </div>
@ -91,7 +92,7 @@ const Payments = ({
ticker.currency === 'btc' ? ticker.currency === 'btc' ?
btc.satoshisToBtc(paymentItem.value) btc.satoshisToBtc(paymentItem.value)
: :
btc.satoshisToUsd(paymentItem.value, ticker.btcTicker.price_usd) btc.satoshisToUsd(paymentItem.value, currentTicker.price_usd)
} }
</span> </span>
</div> </div>
@ -107,7 +108,8 @@ Payments.propTypes = {
payments: PropTypes.array.isRequired, payments: PropTypes.array.isRequired,
ticker: PropTypes.object.isRequired, ticker: PropTypes.object.isRequired,
setPayment: PropTypes.func.isRequired, setPayment: PropTypes.func.isRequired,
paymentModalOpen: PropTypes.bool.isRequired paymentModalOpen: PropTypes.bool.isRequired,
currentTicker: PropTypes.object.isRequired
} }
export default Payments export default Payments

5
app/routes/activity/containers/ActivityContainer.js

@ -1,4 +1,5 @@
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { tickerSelectors } from '../../../reducers/ticker'
import { import {
fetchInvoices, fetchInvoices,
searchInvoices, searchInvoices,
@ -31,7 +32,9 @@ const mapStateToProps = state => ({
ticker: state.ticker, ticker: state.ticker,
paymentModalOpen: paymentSelectors.paymentModalOpen(state), paymentModalOpen: paymentSelectors.paymentModalOpen(state),
invoiceModalOpen: invoiceSelectors.invoiceModalOpen(state) invoiceModalOpen: invoiceSelectors.invoiceModalOpen(state),
currentTicker: tickerSelectors.currentTicker(state)
}) })
export default connect(mapStateToProps, mapDispatchToProps)(Activity) export default connect(mapStateToProps, mapDispatchToProps)(Activity)

10
app/routes/app/components/App.js

@ -6,10 +6,11 @@ import styles from './App.scss'
class App extends Component { class App extends Component {
componentWillMount() { componentWillMount() {
const { fetchTicker, fetchBalance } = this.props const { fetchTicker, fetchBalance, fetchInfo } = this.props
fetchTicker() fetchTicker()
fetchBalance() fetchBalance()
fetchInfo()
} }
render() { render() {
@ -29,9 +30,12 @@ class App extends Component {
createInvoice, createInvoice,
payInvoice, payInvoice,
fetchInvoice, fetchInvoice,
currentTicker,
children children
} = this.props } = this.props
if (!currentTicker) { return <div>Loading...</div> }
return ( return (
<div> <div>
<Form <Form
@ -49,12 +53,14 @@ class App extends Component {
payInvoice={payInvoice} payInvoice={payInvoice}
fetchInvoice={fetchInvoice} fetchInvoice={fetchInvoice}
formInvoice={formInvoice} formInvoice={formInvoice}
currentTicker={currentTicker}
/> />
<Nav <Nav
ticker={ticker} ticker={ticker}
balance={balance} balance={balance}
setCurrency={setCurrency} setCurrency={setCurrency}
formClicked={formType => setForm({ modalOpen: true, formType })} formClicked={formType => setForm({ modalOpen: true, formType })}
currentTicker={currentTicker}
/> />
<div className={styles.content}> <div className={styles.content}>
{children} {children}
@ -82,6 +88,8 @@ App.propTypes = {
createInvoice: PropTypes.func.isRequired, createInvoice: PropTypes.func.isRequired,
payInvoice: PropTypes.func.isRequired, payInvoice: PropTypes.func.isRequired,
fetchInvoice: PropTypes.func.isRequired, fetchInvoice: PropTypes.func.isRequired,
fetchInfo: PropTypes.func.isRequired,
currentTicker: PropTypes.object,
children: PropTypes.object.isRequired children: PropTypes.object.isRequired
} }

12
app/routes/app/components/components/Form/Form.js

@ -10,16 +10,17 @@ const Form = ({
setAmount, setAmount,
setMessage, setMessage,
setPaymentRequest, setPaymentRequest,
ticker: { currency, btcTicker }, ticker: { currency },
isOpen, isOpen,
close, close,
createInvoice, createInvoice,
payInvoice, payInvoice,
fetchInvoice, fetchInvoice,
formInvoice formInvoice,
currentTicker
}) => { }) => {
const requestClicked = () => { const requestClicked = () => {
createInvoice(amount, message, currency, btcTicker.price_usd) createInvoice(amount, message, currency, currentTicker.price_usd)
close() close()
} }
@ -33,7 +34,7 @@ const Form = ({
if (payreq.length === 124) { fetchInvoice(payreq) } if (payreq.length === 124) { fetchInvoice(payreq) }
} }
const calculateAmount = value => (currency === 'btc' ? btc.satoshisToBtc(value) : btc.satoshisToUsd(value, btcTicker.price_usd)) const calculateAmount = value => (currency === 'btc' ? btc.satoshisToBtc(value) : btc.satoshisToUsd(value, currentTicker.price_usd))
return ( return (
<div className={`${styles.formContainer} ${isOpen ? styles.open : ''}`}> <div className={`${styles.formContainer} ${isOpen ? styles.open : ''}`}>
@ -121,7 +122,8 @@ Form.propTypes = {
createInvoice: PropTypes.func.isRequired, createInvoice: PropTypes.func.isRequired,
payInvoice: PropTypes.func.isRequired, payInvoice: PropTypes.func.isRequired,
fetchInvoice: PropTypes.func.isRequired, fetchInvoice: PropTypes.func.isRequired,
formInvoice: PropTypes.object.isRequired formInvoice: PropTypes.object.isRequired,
currentTicker: PropTypes.object.isRequired
} }
export default Form export default Form

11
app/routes/app/components/components/Nav.js

@ -7,12 +7,12 @@ import { FaClockO, FaBitcoin, FaDollar } from 'react-icons/lib/fa'
import { btc } from '../../../../utils' import { btc } from '../../../../utils'
import styles from './Nav.scss' import styles from './Nav.scss'
const Nav = ({ ticker, balance, setCurrency, formClicked }) => ( const Nav = ({ ticker, balance, setCurrency, formClicked, currentTicker }) => (
<nav className={styles.nav}> <nav className={styles.nav}>
<ul className={styles.info}> <ul className={styles.info}>
<li className={`${styles.currencies} ${styles.link}`}> <li className={`${styles.currencies} ${styles.link}`}>
<span <span
data-hint={ticker.btcTicker ? ticker.btcTicker.price_usd : null} data-hint={currentTicker ? currentTicker.price_usd : null}
className={`${styles.currency} ${ticker.currency === 'btc' ? styles.active : ''} hint--bottom`} className={`${styles.currency} ${ticker.currency === 'btc' ? styles.active : ''} hint--bottom`}
onClick={() => setCurrency('btc')} onClick={() => setCurrency('btc')}
> >
@ -33,7 +33,7 @@ const Nav = ({ ticker, balance, setCurrency, formClicked }) => (
ticker.currency === 'btc' ? ticker.currency === 'btc' ?
btc.satoshisToBtc(balance.walletBalance) btc.satoshisToBtc(balance.walletBalance)
: :
btc.satoshisToUsd(balance.walletBalance, ticker.btcTicker.price_usd) btc.satoshisToUsd(balance.walletBalance, currentTicker.price_usd)
} }
</span> </span>
</p> </p>
@ -46,7 +46,7 @@ const Nav = ({ ticker, balance, setCurrency, formClicked }) => (
ticker.currency === 'btc' ? ticker.currency === 'btc' ?
btc.satoshisToBtc(balance.channelBalance) btc.satoshisToBtc(balance.channelBalance)
: :
btc.satoshisToUsd(balance.channelBalance, ticker.btcTicker.price_usd) btc.satoshisToUsd(balance.channelBalance, currentTicker.price_usd)
} }
</span> </span>
</p> </p>
@ -92,7 +92,8 @@ Nav.propTypes = {
ticker: PropTypes.object.isRequired, ticker: PropTypes.object.isRequired,
balance: PropTypes.object.isRequired, balance: PropTypes.object.isRequired,
setCurrency: PropTypes.func.isRequired, setCurrency: PropTypes.func.isRequired,
formClicked: PropTypes.func.isRequired formClicked: PropTypes.func.isRequired,
currentTicker: PropTypes.object.isRequired
} }
export default Nav export default Nav

6
app/routes/app/containers/AppContainer.js

@ -1,6 +1,6 @@
import { connect } from 'react-redux' import { connect } from 'react-redux'
import App from '../components/App' import App from '../components/App'
import { fetchTicker, setCurrency } from '../../../reducers/ticker' import { fetchTicker, setCurrency, tickerSelectors } from '../../../reducers/ticker'
import { fetchBalance } from '../../../reducers/balance' import { fetchBalance } from '../../../reducers/balance'
import { fetchInfo } from '../../../reducers/info' import { fetchInfo } from '../../../reducers/info'
import { createInvoice, fetchInvoice } from '../../../reducers/invoice' import { createInvoice, fetchInvoice } from '../../../reducers/invoice'
@ -35,7 +35,9 @@ const mapStateToProps = state => ({
balance: state.balance, balance: state.balance,
payment: state.payment, payment: state.payment,
form: state.form, form: state.form,
invoice: state.invoice invoice: state.invoice,
currentTicker: tickerSelectors.currentTicker(state)
}) })
export default connect(mapStateToProps, mapDispatchToProps)(App) export default connect(mapStateToProps, mapDispatchToProps)(App)

11
app/routes/wallet/components/Wallet.js

@ -7,9 +7,8 @@ import styles from './Wallet.scss'
class Wallet extends Component { class Wallet extends Component {
componentWillMount() { componentWillMount() {
const { fetchInfo, fetchPeers, fetchChannels, newAddress } = this.props const { fetchPeers, fetchChannels, newAddress } = this.props
fetchInfo()
fetchPeers() fetchPeers()
fetchChannels() fetchChannels()
newAddress('p2pkh') newAddress('p2pkh')
@ -31,7 +30,8 @@ class Wallet extends Component {
connectRequest, connectRequest,
disconnectRequest, disconnectRequest,
allChannels, allChannels,
openChannel openChannel,
currentTicker
} = this.props } = this.props
return ( return (
@ -74,6 +74,7 @@ class Wallet extends Component {
channelForm={channelForm} channelForm={channelForm}
setChannelForm={setChannelForm} setChannelForm={setChannelForm}
openChannel={openChannel} openChannel={openChannel}
currentTicker={currentTicker}
/> />
</section> </section>
</div> </div>
@ -82,7 +83,6 @@ class Wallet extends Component {
} }
Wallet.propTypes = { Wallet.propTypes = {
fetchInfo: PropTypes.func.isRequired,
fetchPeers: PropTypes.func.isRequired, fetchPeers: PropTypes.func.isRequired,
fetchChannels: PropTypes.func.isRequired, fetchChannels: PropTypes.func.isRequired,
info: PropTypes.object.isRequired, info: PropTypes.object.isRequired,
@ -100,7 +100,8 @@ Wallet.propTypes = {
allChannels: PropTypes.array.isRequired, allChannels: PropTypes.array.isRequired,
openChannel: PropTypes.func.isRequired, openChannel: PropTypes.func.isRequired,
newAddress: PropTypes.func.isRequired, newAddress: PropTypes.func.isRequired,
address: PropTypes.string.isRequired address: PropTypes.object.isRequired,
currentTicker: PropTypes.object.isRequired
} }

23
app/routes/wallet/components/components/Channels/Channels.js

@ -18,11 +18,12 @@ const Channels = ({
channelForm, channelForm,
setChannelForm, setChannelForm,
allChannels, allChannels,
openChannel openChannel,
currentTicker
}) => ( }) => (
<div className={styles.channels}> <div className={styles.channels}>
<ChannelModal isOpen={channelModalOpen} resetChannel={setChannel} channel={modalChannel} /> <ChannelModal isOpen={channelModalOpen} resetChannel={setChannel} channel={modalChannel} />
<ChannelForm form={channelForm} setForm={setChannelForm} ticker={ticker} peers={peers} openChannel={openChannel} /> <ChannelForm form={channelForm} setForm={setChannelForm} ticker={ticker} peers={peers} openChannel={openChannel} currentTicker={currentTicker} />
<div className={styles.header}> <div className={styles.header}>
<h3>Channels</h3> <h3>Channels</h3>
<div <div
@ -39,11 +40,21 @@ const Channels = ({
allChannels.map((channel, index) => { allChannels.map((channel, index) => {
if (Object.prototype.hasOwnProperty.call(channel, 'blocks_till_open')) { if (Object.prototype.hasOwnProperty.call(channel, 'blocks_till_open')) {
return ( return (
<OpenPendingChannel key={index} channel={channel} ticker={ticker} /> <OpenPendingChannel
key={index}
channel={channel}
ticker={ticker}
currentTicker={currentTicker}
/>
) )
} else if (Object.prototype.hasOwnProperty.call(channel, 'closing_txid')) { } else if (Object.prototype.hasOwnProperty.call(channel, 'closing_txid')) {
return ( return (
<ClosedPendingChannel key={index} channel={channel} ticker={ticker} /> <ClosedPendingChannel
key={index}
channel={channel}
ticker={ticker}
currentTicker={currentTicker}
/>
) )
} }
return ( return (
@ -52,6 +63,7 @@ const Channels = ({
ticker={ticker} ticker={ticker}
channel={channel} channel={channel}
setChannel={setChannel} setChannel={setChannel}
currentTicker={currentTicker}
/> />
) )
}) })
@ -72,7 +84,8 @@ Channels.propTypes = {
channelForm: PropTypes.object.isRequired, channelForm: PropTypes.object.isRequired,
setChannelForm: PropTypes.func.isRequired, setChannelForm: PropTypes.func.isRequired,
allChannels: PropTypes.array.isRequired, allChannels: PropTypes.array.isRequired,
openChannel: PropTypes.func.isRequired openChannel: PropTypes.func.isRequired,
currentTicker: PropTypes.object.isRequired
} }
export default Channels export default Channels

11
app/routes/wallet/components/components/Channels/components/Channel/Channel.js

@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
import { btc } from '../../../../../../../utils' import { btc } from '../../../../../../../utils'
import styles from './Channel.scss' import styles from './Channel.scss'
const Channel = ({ ticker, channel, setChannel }) => ( const Channel = ({ ticker, channel, setChannel, currentTicker }) => (
<li className={styles.channel} onClick={() => setChannel(channel)}> <li className={styles.channel} onClick={() => setChannel(channel)}>
<h1 className={styles.status}>Status: Open</h1> <h1 className={styles.status}>Status: Open</h1>
<div className={styles.left}> <div className={styles.left}>
@ -24,7 +24,7 @@ const Channel = ({ ticker, channel, setChannel }) => (
ticker.currency === 'btc' ? ticker.currency === 'btc' ?
btc.satoshisToBtc(channel.capacity) btc.satoshisToBtc(channel.capacity)
: :
btc.satoshisToUsd(channel.capacity, ticker.btcTicker.price_usd) btc.satoshisToUsd(channel.capacity, currentTicker.price_usd)
} }
</h2> </h2>
</section> </section>
@ -35,7 +35,7 @@ const Channel = ({ ticker, channel, setChannel }) => (
ticker.currency === 'btc' ? ticker.currency === 'btc' ?
btc.satoshisToBtc(channel.local_balance) btc.satoshisToBtc(channel.local_balance)
: :
btc.satoshisToUsd(channel.local_balance, ticker.btcTicker.price_usd) btc.satoshisToUsd(channel.local_balance, currentTicker.price_usd)
} }
</h4> </h4>
<span>Local</span> <span>Local</span>
@ -46,7 +46,7 @@ const Channel = ({ ticker, channel, setChannel }) => (
ticker.currency === 'btc' ? ticker.currency === 'btc' ?
btc.satoshisToBtc(channel.remote_balance) btc.satoshisToBtc(channel.remote_balance)
: :
btc.satoshisToUsd(channel.remote_balance, ticker.btcTicker.price_usd) btc.satoshisToUsd(channel.remote_balance, currentTicker.price_usd)
} }
</h4> </h4>
<span>Remote</span> <span>Remote</span>
@ -59,7 +59,8 @@ const Channel = ({ ticker, channel, setChannel }) => (
Channel.propTypes = { Channel.propTypes = {
ticker: PropTypes.object.isRequired, ticker: PropTypes.object.isRequired,
channel: PropTypes.object.isRequired, channel: PropTypes.object.isRequired,
setChannel: PropTypes.func.isRequired setChannel: PropTypes.func.isRequired,
currentTicker: PropTypes.object.isRequired
} }
export default Channel export default Channel

9
app/routes/wallet/components/components/Channels/components/ChannelForm/ChannelForm.js

@ -5,12 +5,12 @@ import { FaUser, FaBitcoin, FaDollar } from 'react-icons/lib/fa'
import { usd, btc } from '../../../../../../../utils' import { usd, btc } from '../../../../../../../utils'
import styles from './ChannelForm.scss' import styles from './ChannelForm.scss'
const ChannelForm = ({ form, setForm, ticker, peers, openChannel }) => { const ChannelForm = ({ form, setForm, ticker, peers, openChannel, currentTicker }) => {
const submitClicked = () => { const submitClicked = () => {
const { node_key, local_amt, push_amt } = form const { node_key, local_amt, push_amt } = form
const localamt = ticker.currency === 'btc' ? btc.btcToSatoshis(local_amt) : btc.btcToSatoshis(usd.usdToBtc(local_amt, ticker.btcTicker.price_usd)) const localamt = ticker.currency === 'btc' ? btc.btcToSatoshis(local_amt) : btc.btcToSatoshis(usd.usdToBtc(local_amt, currentTicker.price_usd))
const pushamt = ticker.currency === 'btc' ? btc.btcToSatoshis(push_amt) : btc.btcToSatoshis(usd.usdToBtc(push_amt, ticker.btcTicker.price_usd)) const pushamt = ticker.currency === 'btc' ? btc.btcToSatoshis(push_amt) : btc.btcToSatoshis(usd.usdToBtc(push_amt, currentTicker.price_usd))
openChannel({ pubkey: node_key, localamt, pushamt }) openChannel({ pubkey: node_key, localamt, pushamt })
setForm({ isOpen: false }) setForm({ isOpen: false })
@ -129,7 +129,8 @@ ChannelForm.propTypes = {
setForm: PropTypes.func.isRequired, setForm: PropTypes.func.isRequired,
ticker: PropTypes.object.isRequired, ticker: PropTypes.object.isRequired,
peers: PropTypes.array.isRequired, peers: PropTypes.array.isRequired,
openChannel: PropTypes.func.isRequired openChannel: PropTypes.func.isRequired,
currentTicker: PropTypes.object.isRequired
} }
export default ChannelForm export default ChannelForm

11
app/routes/wallet/components/components/Channels/components/ClosedPendingChannel/ClosedPendingChannel.js

@ -4,7 +4,7 @@ import PropTypes from 'prop-types'
import { btc } from '../../../../../../../utils' import { btc } from '../../../../../../../utils'
import styles from './ClosedPendingChannel.scss' import styles from './ClosedPendingChannel.scss'
const ClosedPendingChannel = ({ ticker, channel: { channel, closing_txid } }) => ( const ClosedPendingChannel = ({ ticker, channel: { channel, closing_txid }, currentTicker }) => (
<li className={styles.channel} onClick={() => shell.openExternal(`https://testnet.smartbit.com.au/tx/${closing_txid}`)}> <li className={styles.channel} onClick={() => shell.openExternal(`https://testnet.smartbit.com.au/tx/${closing_txid}`)}>
<h1 className={styles.closing}>Status: Closing</h1> <h1 className={styles.closing}>Status: Closing</h1>
<div className={styles.left}> <div className={styles.left}>
@ -25,7 +25,7 @@ const ClosedPendingChannel = ({ ticker, channel: { channel, closing_txid } }) =>
ticker.currency === 'btc' ? ticker.currency === 'btc' ?
btc.satoshisToBtc(channel.capacity) btc.satoshisToBtc(channel.capacity)
: :
btc.satoshisToUsd(channel.capacity, ticker.btcTicker.price_usd) btc.satoshisToUsd(channel.capacity, currentTicker.price_usd)
} }
</h2> </h2>
</section> </section>
@ -36,7 +36,7 @@ const ClosedPendingChannel = ({ ticker, channel: { channel, closing_txid } }) =>
ticker.currency === 'btc' ? ticker.currency === 'btc' ?
btc.satoshisToBtc(channel.local_balance) btc.satoshisToBtc(channel.local_balance)
: :
btc.satoshisToUsd(channel.local_balance, ticker.btcTicker.price_usd) btc.satoshisToUsd(channel.local_balance, currentTicker.price_usd)
} }
</h4> </h4>
<span>Local</span> <span>Local</span>
@ -47,7 +47,7 @@ const ClosedPendingChannel = ({ ticker, channel: { channel, closing_txid } }) =>
ticker.currency === 'btc' ? ticker.currency === 'btc' ?
btc.satoshisToBtc(channel.remote_balance) btc.satoshisToBtc(channel.remote_balance)
: :
btc.satoshisToUsd(channel.remote_balance, ticker.btcTicker.price_usd) btc.satoshisToUsd(channel.remote_balance, currentTicker.price_usd)
} }
</h4> </h4>
<span>Remote</span> <span>Remote</span>
@ -59,7 +59,8 @@ const ClosedPendingChannel = ({ ticker, channel: { channel, closing_txid } }) =>
ClosedPendingChannel.propTypes = { ClosedPendingChannel.propTypes = {
ticker: PropTypes.object.isRequired, ticker: PropTypes.object.isRequired,
channel: PropTypes.object.isRequired channel: PropTypes.object.isRequired,
currentTicker: PropTypes.object.isRequired
} }
export default ClosedPendingChannel export default ClosedPendingChannel

11
app/routes/wallet/components/components/Channels/components/OpenPendingChannel/OpenPendingChannel.js

@ -4,7 +4,7 @@ import PropTypes from 'prop-types'
import { btc } from '../../../../../../../utils' import { btc } from '../../../../../../../utils'
import styles from './OpenPendingChannel.scss' import styles from './OpenPendingChannel.scss'
const OpenPendingChannel = ({ ticker, channel: { channel } }) => ( const OpenPendingChannel = ({ ticker, channel: { channel }, currentTicker }) => (
<li className={styles.channel} onClick={() => shell.openExternal(`https://testnet.smartbit.com.au/tx/${channel.channel_point.split(':')[0]}`)}> <li className={styles.channel} onClick={() => shell.openExternal(`https://testnet.smartbit.com.au/tx/${channel.channel_point.split(':')[0]}`)}>
<h1 className={styles.pending}>Status: Pending</h1> <h1 className={styles.pending}>Status: Pending</h1>
<div className={styles.left}> <div className={styles.left}>
@ -25,7 +25,7 @@ const OpenPendingChannel = ({ ticker, channel: { channel } }) => (
ticker.currency === 'btc' ? ticker.currency === 'btc' ?
btc.satoshisToBtc(channel.capacity) btc.satoshisToBtc(channel.capacity)
: :
btc.satoshisToUsd(channel.capacity, ticker.btcTicker.price_usd) btc.satoshisToUsd(channel.capacity, currentTicker.price_usd)
} }
</h2> </h2>
</section> </section>
@ -36,7 +36,7 @@ const OpenPendingChannel = ({ ticker, channel: { channel } }) => (
ticker.currency === 'btc' ? ticker.currency === 'btc' ?
btc.satoshisToBtc(channel.local_balance) btc.satoshisToBtc(channel.local_balance)
: :
btc.satoshisToUsd(channel.local_balance, ticker.btcTicker.price_usd) btc.satoshisToUsd(channel.local_balance, currentTicker.price_usd)
} }
</h4> </h4>
<span>Local</span> <span>Local</span>
@ -47,7 +47,7 @@ const OpenPendingChannel = ({ ticker, channel: { channel } }) => (
ticker.currency === 'btc' ? ticker.currency === 'btc' ?
btc.satoshisToBtc(channel.remote_balance) btc.satoshisToBtc(channel.remote_balance)
: :
btc.satoshisToUsd(channel.remote_balance, ticker.btcTicker.price_usd) btc.satoshisToUsd(channel.remote_balance, currentTicker.price_usd)
} }
</h4> </h4>
<span>Remote</span> <span>Remote</span>
@ -59,7 +59,8 @@ const OpenPendingChannel = ({ ticker, channel: { channel } }) => (
OpenPendingChannel.propTypes = { OpenPendingChannel.propTypes = {
ticker: PropTypes.object.isRequired, ticker: PropTypes.object.isRequired,
channel: PropTypes.object.isRequired channel: PropTypes.object.isRequired,
currentTicker: PropTypes.object.isRequired
} }
export default OpenPendingChannel export default OpenPendingChannel

8
app/routes/wallet/containers/WalletContainer.js

@ -1,6 +1,6 @@
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { newAddress } from '../../../reducers/address' import { newAddress } from '../../../reducers/address'
import { fetchInfo } from '../../../reducers/info' import { tickerSelectors } from '../../../reducers/ticker'
import { import {
fetchPeers, fetchPeers,
setPeer, setPeer,
@ -22,8 +22,6 @@ import Wallet from '../components/Wallet'
const mapDispatchToProps = { const mapDispatchToProps = {
newAddress, newAddress,
fetchInfo,
fetchPeers, fetchPeers,
setPeer, setPeer,
connectRequest, connectRequest,
@ -49,7 +47,9 @@ const mapStateToProps = state => ({
allChannels: channelsSelectors.allChannels(state), allChannels: channelsSelectors.allChannels(state),
peerModalOpen: peersSelectors.peerModalOpen(state), peerModalOpen: peersSelectors.peerModalOpen(state),
channelModalOpen: channelsSelectors.channelModalOpen(state) channelModalOpen: channelsSelectors.channelModalOpen(state),
currentTicker: tickerSelectors.currentTicker(state)
}) })
export default connect(mapStateToProps, mapDispatchToProps)(Wallet) export default connect(mapStateToProps, mapDispatchToProps)(Wallet)

30
test/reducers/__snapshots__/ticker.spec.js.snap

@ -3,17 +3,29 @@
exports[`reducers tickerReducer should correctly getTicker 1`] = ` exports[`reducers tickerReducer should correctly getTicker 1`] = `
Object { Object {
"btcTicker": null, "btcTicker": null,
"crypto": "btc", "crypto": "",
"currency": "btc", "currency": "",
"ltcTicker": null,
"tickerLoading": true, "tickerLoading": true,
} }
`; `;
exports[`reducers tickerReducer should correctly receiveTicker 1`] = ` exports[`reducers tickerReducer should correctly receiveTicker 1`] = `
Object { Object {
"btcTicker": "f", "btcTicker": undefined,
"crypto": "btc", "crypto": "",
"currency": "btc", "currency": "",
"ltcTicker": undefined,
"tickerLoading": false,
}
`;
exports[`reducers tickerReducer should correctly setCrypto 1`] = `
Object {
"btcTicker": null,
"crypto": "foo",
"currency": "",
"ltcTicker": null,
"tickerLoading": false, "tickerLoading": false,
} }
`; `;
@ -21,8 +33,9 @@ Object {
exports[`reducers tickerReducer should correctly setCurrency 1`] = ` exports[`reducers tickerReducer should correctly setCurrency 1`] = `
Object { Object {
"btcTicker": null, "btcTicker": null,
"crypto": "btc", "crypto": "",
"currency": "foo", "currency": "foo",
"ltcTicker": null,
"tickerLoading": false, "tickerLoading": false,
} }
`; `;
@ -30,8 +43,9 @@ Object {
exports[`reducers tickerReducer should handle initial state 1`] = ` exports[`reducers tickerReducer should handle initial state 1`] = `
Object { Object {
"btcTicker": null, "btcTicker": null,
"crypto": "btc", "crypto": "",
"currency": "btc", "currency": "",
"ltcTicker": null,
"tickerLoading": false, "tickerLoading": false,
} }
`; `;

21
test/reducers/ticker.spec.js

@ -1,7 +1,8 @@
import tickerReducer, { import tickerReducer, {
SET_CURRENCY, SET_CURRENCY,
GET_TICKER, SET_CRYPTO,
RECIEVE_TICKER GET_TICKERS,
RECIEVE_TICKERS
} from '../../app/reducers/ticker' } from '../../app/reducers/ticker'
describe('reducers', () => { describe('reducers', () => {
@ -14,24 +15,32 @@ describe('reducers', () => {
expect(SET_CURRENCY).toEqual('SET_CURRENCY') expect(SET_CURRENCY).toEqual('SET_CURRENCY')
}) })
it('should have SET_CRYPTO', () => {
expect(SET_CRYPTO).toEqual('SET_CRYPTO')
})
it('should have GET_TICKER', () => { it('should have GET_TICKER', () => {
expect(GET_TICKER).toEqual('GET_TICKER') expect(GET_TICKERS).toEqual('GET_TICKERS')
}) })
it('should have RECIEVE_TICKER', () => { it('should have RECIEVE_TICKER', () => {
expect(RECIEVE_TICKER).toEqual('RECIEVE_TICKER') expect(RECIEVE_TICKERS).toEqual('RECIEVE_TICKERS')
}) })
it('should correctly setCurrency', () => { it('should correctly setCurrency', () => {
expect(tickerReducer(undefined, { type: SET_CURRENCY, currency: 'foo' })).toMatchSnapshot() expect(tickerReducer(undefined, { type: SET_CURRENCY, currency: 'foo' })).toMatchSnapshot()
}) })
it('should correctly setCrypto', () => {
expect(tickerReducer(undefined, { type: SET_CRYPTO, crypto: 'foo' })).toMatchSnapshot()
})
it('should correctly getTicker', () => { it('should correctly getTicker', () => {
expect(tickerReducer(undefined, { type: GET_TICKER })).toMatchSnapshot() expect(tickerReducer(undefined, { type: GET_TICKERS })).toMatchSnapshot()
}) })
it('should correctly receiveTicker', () => { it('should correctly receiveTicker', () => {
expect(tickerReducer(undefined, { type: RECIEVE_TICKER, ticker: 'foo' })).toMatchSnapshot() expect(tickerReducer(undefined, { type: RECIEVE_TICKERS, ticker: 'foo' })).toMatchSnapshot()
}) })
}) })
}) })

Loading…
Cancel
Save