Skip to content

Commit

Permalink
feat(Transfer All): add transfer all to bch imported addrs
Browse files Browse the repository at this point in the history
  • Loading branch information
plondon committed Jan 9, 2019
1 parent 64ddffa commit b0ae36b
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 51 deletions.
Original file line number Diff line number Diff line change
@@ -1,29 +1,16 @@
import React from 'react'
import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import { prepend } from 'ramda'
import { getData } from './selectors'
import SelectBoxBCH from './template'

class SelectBoxBchAddresses extends React.PureComponent {
render () {
const { data, ...rest } = this.props
const allWallets = {
label: 'All',
options: [
{
label: 'All Bitcoin Cash Wallets',
value: 'all'
}
]
}

return data.cata({
Success: value => {
const elements = this.props.includeAll
? prepend(allWallets, value.data)
: value.data
return <SelectBoxBCH elements={elements} {...rest} />
return <SelectBoxBCH elements={value.data} {...rest} />
},
Failure: message => <div>{message}</div>,
Loading: () => <div />,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,43 @@ import {
not,
path,
prop,
prepend,
sequence,
reduce
} from 'ramda'
import { Exchange, Remote } from 'blockchain-wallet-v4/src'
import { selectors } from 'data'
import { ADDRESS_TYPES } from 'blockchain-wallet-v4/src/redux/payment/btc/utils'

const allWallets = {
label: 'All',
options: [
{
label: 'All Bitcoin Cash Wallets',
value: 'all'
}
]
}

const allImportedAddresses = {
label: 'Imported Addresses',
options: [
{
label: 'All Imported Bitcoin Cash Addresses',
value: 'allImportedAddresses'
}
]
}

export const getData = (state, ownProps) => {
const {
coin,
exclude = [],
excludeImported,
excludeHDWallets,
excludeWatchOnly,
excludeLockbox
excludeImported,
excludeLockbox,
includeAll = true
} = ownProps
const buildDisplay = wallet => {
if (has('balance', wallet)) {
Expand Down Expand Up @@ -93,7 +116,16 @@ export const getData = (state, ownProps) => {
.map(excluded)
.map(toDropdown)
.map(toGroup('Lockbox'))
]).map(([b1, b2, b3]) => ({ data: reduce(concat, [], [b1, b2, b3]) }))
]).map(([b1, b2, b3]) => {
const data = reduce(concat, [], [b1, b2, b3])
if (includeAll) {
return { data: prepend(allWallets, data) }
} else if (excludeHDWallets) {
return { data: [allImportedAddresses] }
} else {
return { data }
}
})
}

return getAddressesData()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import * as AT from './actionTypes'

export const initialized = () => ({ type: AT.SEND_BCH_INITIALIZED })
export const initialized = payload => ({
type: AT.SEND_BCH_INITIALIZED,
payload
})
export const destroyed = () => ({ type: AT.SEND_BCH_DESTROYED })
export const sendBchPaymentUpdated = payment => ({
type: AT.SEND_BCH_PAYMENT_UPDATED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,17 @@ import {
import * as C from 'services/AlertService'
import * as Lockbox from 'services/LockboxService'
import { promptForSecondPassword, promptForLockbox } from 'services/SagaService'
import { Exchange, Remote } from 'blockchain-wallet-v4/src'
import { Exchange, Remote, utils } from 'blockchain-wallet-v4/src'
import { ADDRESS_TYPES } from 'blockchain-wallet-v4/src/redux/payment/btc/utils'

export const logLocation = 'components/sendBch/sagas'
// TODO: Check how to retrieve Bitcoin cash default fee
export const bchDefaultFee = 4

export default ({ coreSagas, networks }) => {
const initialized = function*() {
const initialized = function*(action) {
try {
const { from } = action.payload
yield put(A.sendBchPaymentUpdated(Remote.Loading))
let payment = coreSagas.payment.bch.create({
network: networks.bch
Expand All @@ -38,11 +39,23 @@ export default ({ coreSagas, networks }) => {
)
const defaultIndex = defaultIndexR.getOrElse(0)
const defaultAccountR = accountsR.map(nth(defaultIndex))
payment = yield payment.from(defaultIndex, ADDRESS_TYPES.ACCOUNT)
if (from === 'allImportedAddresses') {
const addressesR = yield select(
selectors.core.common.bch.getActiveAddresses
)
const addresses = addressesR
.getOrElse([])
.filter(prop('priv'))
.map(prop('addr'))
.map(utils.bch.fromCashAddr)
payment = yield payment.from(addresses, ADDRESS_TYPES.LEGACY)
} else {
payment = yield payment.from(defaultIndex, ADDRESS_TYPES.ACCOUNT)
}
payment = yield payment.fee(bchDefaultFee)
const initialValues = {
coin: 'BCH',
from: defaultAccountR.getOrElse()
from: from || defaultAccountR.getOrElse()
}
yield put(initialize(FORM, initialValues))
yield put(A.sendBchPaymentUpdated(Remote.of(payment.value())))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class FirstStep extends React.Component {
onSubmit={actions.sendBchFirstStepSubmitClicked}
handleToToggle={this.handleToToggle}
excludeLockbox={value.excludeLockbox}
excludeHDWallets={this.props.excludeHDWallets}
/>
),
Failure: message => <Error>{message}</Error>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ const FirstStep = props => {
handleSubmit,
totalFee,
pristine,
excludeLockbox
excludeLockbox,
excludeHDWallets
} = props
const disableLockboxSend =
from &&
Expand Down Expand Up @@ -86,11 +87,12 @@ const FirstStep = props => {
<Field
name='from'
coin='BCH'
component={SelectBoxBchAddresses}
includeAll={false}
excludeWatchOnly
excludeLockbox={excludeLockbox}
validate={[required]}
component={SelectBoxBchAddresses}
excludeHDWallets={excludeHDWallets}
excludeLockbox={excludeLockbox}
excludeWatchOnly
/>
</FormItem>
</FormGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,22 @@ import SecondStep from './SecondStep'

class SendBchContainer extends React.PureComponent {
componentDidMount () {
this.props.actions.initialized()
const { from } = this.props
this.props.actions.initialized({
from
})
}

componentWillUnmount () {
this.props.actions.destroyed()
}

render () {
const { step, position, total, closeAll } = this.props
const { step, position, total, closeAll, excludeHDWallets } = this.props

return (
<SendBch position={position} total={total} closeAll={closeAll}>
{step === 1 && <FirstStep />}
{step === 1 && <FirstStep excludeHDWallets={excludeHDWallets} />}
{step === 2 && <SecondStep />}
</SendBch>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,23 @@ class ImportedAddressesContainer extends React.Component {
return !Remote.Loading.is(nextProps.data)
}

handleTransferAll = () => {
this.props.actions.showModal(model.components.sendBch.MODAL, {
from: 'allImportedAddresses',
excludeHDWallets: true
})
}

render () {
const { data, ...rest } = this.props
return data.cata({
Success: value => <Success importedAddresses={value} {...rest} />,
Success: value => (
<Success
importedAddresses={value}
onTransferAll={this.handleTransferAll}
{...rest}
/>
),
Failure: message => <div>{message}</div>,
Loading: () => <div />,
NotAsked: () => <div />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import AddressRow from '../../Btc/AddressRow'
import { FormattedMessage } from 'react-intl'
import { SettingDescription, SettingHeader } from 'components/Setting'
import {
Button,
Icon,
Table,
TableHeader,
Expand All @@ -15,10 +16,17 @@ import {
const Wrapper = styled.section`
box-sizing: border-box;
`
const ImportedAddressesSettingHeader = SettingHeader.extend`
justify-content: flex-start;
const ImportedAddressesSettingHeader = styled(SettingHeader)`
align-items: flex-start;
justify-content: space-between;
margin-top: 30px;
`
const ImportedActions = styled.div`
display: flex;
> button {
margin-left: 10px;
}
`
const WarningWrapper = styled.div`
display: flex;
.warning-icon {
Expand All @@ -28,7 +36,7 @@ const WarningWrapper = styled.div`
`

const Success = props => {
const { importedAddresses, search } = props
const { importedAddresses, onTransferAll, search } = props

const isMatch = address =>
!search || address.addr.toLowerCase().indexOf(search) > -1
Expand All @@ -42,25 +50,35 @@ const Success = props => {
return (
<Wrapper>
<ImportedAddressesSettingHeader>
<FormattedMessage
id='scenes.settings.addresses.bch.importedaddresses.title'
defaultMessage='Imported Bitcoin Cash Addresses'
/>
</ImportedAddressesSettingHeader>
<SettingDescription>
<WarningWrapper>
<Icon
name='alert-filled'
size='22px'
className={'warning-icon'}
color='brand-yellow'
/>
<div>
<FormattedMessage
id='scenes.settings.addresses.bch.importedaddresses.description'
defaultMessage='Imported funds are not protected by your backup phrase. To ensure these funds are secured, please transfer them directly into your wallet.'
id='scenes.settings.addresses.bch.importedaddresses.title'
defaultMessage='Imported Bitcoin Cash Addresses'
/>
</WarningWrapper>
</SettingDescription>
<SettingDescription>
<WarningWrapper>
<Icon
name='alert-filled'
size='22px'
className={'warning-icon'}
color='brand-yellow'
/>
<FormattedMessage
id='scenes.settings.addresses.bch.importedaddresses.description'
defaultMessage='Imported funds are not protected by your backup phrase. To ensure these funds are secured, please transfer them directly into your wallet.'
/>
</WarningWrapper>
</SettingDescription>
</div>
<ImportedActions>
<Button onClick={onTransferAll} nature='primary'>
<FormattedMessage
id='scenes.settings.addresses.bch.importedaddresses.success.transferall'
defaultMessage='Transfer All'
/>
</Button>
</ImportedActions>
</ImportedAddressesSettingHeader>
{importedAddressesTableRows.length > 0 && (
<Table>
<TableHeader>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,15 @@ export const bchFromLabel = curry((payment, state) => {
.getAccountLabel(state)(payment.fromAccountIdx)
.getOrElse(payment.from[0])
case ADDRESS_TYPES.LEGACY:
return utils.bch.toCashAddr(payment.from[0], true)
const formValues = selectors.form.getFormValues(
model.components.sendBch.FORM
)(state)
const { from } = formValues
if (from === 'allImportedAddresses') {
return 'All Imported Bitcoin Cash Addresses'
} else {
return utils.bch.toCashAddr(payment.from[0], true)
}
case ADDRESS_TYPES.WATCH_ONLY:
return utils.bch.toCashAddr(payment.from[0], true)
case ADDRESS_TYPES.EXTERNAL:
Expand Down

0 comments on commit b0ae36b

Please sign in to comment.