Skip to content

Commit

Permalink
feat(Borrow): handle form change
Browse files Browse the repository at this point in the history
  • Loading branch information
Philip London committed Jan 22, 2020
1 parent 276bb00 commit ea33585
Show file tree
Hide file tree
Showing 14 changed files with 167 additions and 79 deletions.
2 changes: 2 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ declare module 'blockchain-info-components' {
// type-coverage:ignore-next-line
export function FontGlobalStyles(...args: any): any
// type-coverage:ignore-next-line
export function HeartbeatLoader(...args: any): any
// type-coverage:ignore-next-line
export function Icon(...args: any): any
// type-coverage:ignore-next-line
export function IconGlobalStyles(...args: any): any
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@
"@types/ramda": "0.26.39",
"@types/react": "16.9.17",
"@types/react-intl": "3.0.0",
"@types/redux-form": "7.4.2",
"@types/styled-components": "4.0.3",
"@typescript-eslint/eslint-plugin": "2.13.0",
"@typescript-eslint/parser": "2.13.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,17 @@ export const fetchBorrowOffersFailure = (error): BorrowActionTypes => ({
}
})

export const handleMaxCollateralClick = () => ({
type: AT.MAX_COLLATERAL_CLICK
})

export const initializeBorrow = (coin: CoinType) => ({
type: AT.INITIALIZE_BORROW,
payload: {
coin
}
})

export const handleMaxCollateralClick = () => ({
type: AT.MAX_COLLATERAL_CLICK
})

export const setPaymentFailure = (error): BorrowActionTypes => ({
type: AT.SET_PAYMENT_FAILURE,
payload: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export const INVALID_COIN_TYPE = 'Invalid coin type'

export const NO_OFFER_EXISTS = 'NO_OFFER_EXISTS'
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { BorrowActionTypes, BorrowState } from './types'
import Remote from 'blockchain-wallet-v4/src/remote/remote'

const INITIAL_STATE: BorrowState = {
coin: 'BTC',
offers: Remote.NotAsked,
payment: Remote.NotAsked
}
Expand All @@ -22,6 +23,11 @@ export function borrowReducer (
...state,
offers: Remote.Failure(action.payload.error)
}
case AT.INITIALIZE_BORROW:
return {
...state,
coin: action.payload.coin
}
case AT.SET_PAYMENT_FAILURE:
return {
...state,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import * as AT from './actionTypes'
import { takeLatest } from 'redux-saga/effects'
import { actionTypes } from 'redux-form'
import { takeEvery, takeLatest } from 'redux-saga/effects'
import sagas from './sagas'

export default ({ api, coreSagas, networks }) => {
const borrowSagas = sagas({ api, coreSagas, networks })

return function * borrowSaga () {
return function* borrowSaga () {
yield takeLatest(AT.CREATE_BORROW, borrowSagas.createBorrow)
yield takeLatest(AT.FETCH_BORROW_OFFERS, borrowSagas.fetchBorrowOffers)
yield takeLatest(AT.INITIALIZE_BORROW, borrowSagas.initializeBorrow)
yield takeLatest(AT.MAX_COLLATERAL_CLICK, borrowSagas.maxCollateralClick)
yield takeEvery(actionTypes.CHANGE, borrowSagas.formChanged)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ import * as S from './selectors'
import { actions, selectors } from 'data'
import { ADDRESS_TYPES } from 'blockchain-wallet-v4/src/redux/payment/btc/utils'
import { APIType } from 'blockchain-wallet-v4/src/network/api'
import { BorrowFormValuesType } from './types'
import { BorrowFormValuesType, PaymentType } from './types'
import { call, put, select } from 'redux-saga/effects'
import { Exchange } from 'blockchain-wallet-v4/src'
import { initialize } from 'redux-form'
import { FormAction, initialize } from 'redux-form'
import { nth } from 'ramda'
import { promptForSecondPassword } from 'services/SagaService'

export default ({
api,
Expand All @@ -18,26 +19,64 @@ export default ({
coreSagas: any
networks: any
}) => {
const createBorrow = function * () {
const paymentR = S.getPayment(yield select())
const payment = paymentR.getOrElse({})
const createBorrow = function* () {
try {
yield put(actions.form.startSubmit('borrowForm'))
const paymentR = S.getPayment(yield select())
let payment = coreSagas.payment.btc.create({
payment: paymentR.getOrElse(<PaymentType>{}),
network: networks.btc
})

// const offerR = S.getOffer(yield select())
// const offer = offerR.getOrFail(NO_OFFER_EXISTS)
payment = yield payment.amount(546, ADDRESS_TYPES.ADDRESS)
payment = yield payment.to('1PEP3UNaohnHqVbUNLFFycUJ3ShQxa5NbD')

// const request = {
// offerId: offer.offerId,
// principalAmount: offer.principalAmount
// }
payment = yield payment.build()
// ask for second password
const password = yield call(promptForSecondPassword)
payment = yield payment.sign(password)
// sign and publish payment
yield put(actions.form.stopSubmit('borrowForm'))
} catch (e) {
yield put(actions.form.stopSubmit('borrowForm'))
}
}

// const loan = yield call(api.createLoan, request)
// payment = yield payment.amount(convert loan amount)
const _createMaxCounter = function* (payment: PaymentType) {
const coin = S.getCoinType(yield select())
const ratesR = yield select(S.getRates)
const rates = ratesR.getOrElse({})
const balance = payment.value().effectiveBalance

// ask for second password
// sign and publish payment
switch (coin) {
case 'BTC':
return Exchange.convertBtcToFiat({
value: balance,
fromUnit: 'SAT',
toCurrency: 'USD',
rates: rates
}).value
}
}

const fetchBorrowOffers = function * () {
const _createPayment = function* (index: number) {
let payment
const coin = S.getCoinType(yield select())

switch (coin) {
case 'BTC':
payment = coreSagas.payment.btc.create({
network: networks.btc
})
payment = yield payment.init()
payment = yield payment.from(index, ADDRESS_TYPES.ACCOUNT)
payment = yield payment.fee('priority')
}

return payment
}

const fetchBorrowOffers = function* () {
try {
yield put(A.fetchBorrowOffersLoading())
const offers = yield call(api.getOffers)
Expand All @@ -47,41 +86,47 @@ export default ({
}
}

const initializeBorrow = function * ({
const formChanged = function* (action: FormAction) {
const form = action.meta.form
if (form !== 'borrowForm') return
const coin = S.getCoinType(yield select())

let payment

switch (action.meta.field) {
case 'collateral':
yield put(A.setPaymentLoading())
switch (coin) {
case 'BTC':
payment = yield call(_createPayment, action.payload.index)
}
const maxCollateralCounter = yield call(_createMaxCounter, payment)

yield put(actions.form.change('borrowForm', 'maxCollateralCounter', maxCollateralCounter))
yield put(A.setPaymentSuccess(payment.value()))
}
}

const initializeBorrow = function* ({
payload
}: ReturnType<typeof A.initializeBorrow>) {
let defaultAccountR
let payment
let rates
let payment: PaymentType = <PaymentType>{}

switch (payload.coin) {
case 'BTC':
payment = coreSagas.payment.btc.create({
network: networks.btc
})
payment = yield payment.init()
const accountsR = yield select(
selectors.core.common.btc.getAccountsBalances
)
const defaultIndex = yield select(
selectors.core.wallet.getDefaultAccountIndex
)
defaultAccountR = accountsR.map(nth(defaultIndex))
payment = yield payment.from(defaultIndex, ADDRESS_TYPES.ACCOUNT)
payment = yield payment.fee('priority')
// TODO: Borrow - get rates from nabu?
const ratesR = yield select(selectors.core.data.btc.getRates)
rates = ratesR.getOrElse({})
payment = yield call(_createPayment, defaultIndex)
break
}

const maxCollateral = payment.value().effectiveBalance
const maxCollateralCounter = Exchange.convertBtcToFiat({
value: maxCollateral,
fromUnit: 'SAT',
toCurrency: 'USD',
rates: rates
}).value
const maxCollateralCounter = yield call(_createMaxCounter, payment)

const initialValues = {
collateral: defaultAccountR.getOrElse(),
Expand All @@ -92,7 +137,7 @@ export default ({
yield put(A.setPaymentSuccess(payment.value()))
}

const maxCollateralClick = function * () {
const maxCollateralClick = function* () {
const values: BorrowFormValuesType = yield select(
selectors.form.getFormValues('borrowForm')
)
Expand All @@ -107,7 +152,9 @@ export default ({
}

return {
createBorrow,
fetchBorrowOffers,
formChanged,
initializeBorrow,
maxCollateralClick
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
import { INVALID_COIN_TYPE } from './model'
import { RootState } from '../../rootReducer'
import { selectors } from 'data'

export const getCoinType = (state: RootState) => state.components.borrow.coin

export const getPayment = (state: RootState) => state.components.borrow.payment

export const getRates = (state: RootState) => {
const coinType = getCoinType(state)

switch (coinType) {
case 'BTC':
return selectors.core.data.btc.getRates(state)
default:
throw new Error(INVALID_COIN_TYPE)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,31 +29,36 @@ export type UTXOType = {
}

export type PaymentType = {
change: string
coins: Array<UTXOType>
effectiveBalance: number
fee: number
amount: (n: number) => PaymentType,
change: string,
coins: Array<UTXOType>,
effectiveBalance: number,
fee: number,
fees: {
limits: {
max: number
min: number
}
priority: number
regular: number
}
from: Array<string>
fromAccountIdx: number
},
from: Array<string>,
fromAccountIdx: number,
fromType:
| 'ACCOUNT'
| 'LEGACY'
| 'WATCH_ONLY'
| 'EXTERNAL'
| 'LOCKBOX'
| 'ADDRESS'
| 'ACCOUNT'
| 'LEGACY'
| 'WATCH_ONLY'
| 'EXTERNAL'
| 'LOCKBOX'
| 'ADDRESS',
sign: (pw: string) => PaymentType,
to: (address: string) => PaymentType,
value: () => PaymentType
}

// State
export interface BorrowState {
coin: CoinType,
offers: RemoteData<NabuApiErrorType, Array<OfferType>>
payment: RemoteData<string | Error, PaymentType>
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as borrow from './borrow/model'
import * as coinify from './coinify/model'
import * as exchange from './exchange/model'
import * as exchangeHistory from './exchangeHistory/model'
Expand All @@ -9,6 +10,7 @@ import * as sendEth from './sendEth/model'
import * as sendXlm from './sendXlm/model'

export {
borrow,
coinify,
exchange,
exchangeHistory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { actions, selectors } from 'data'
import { bindActionCreators, compose, Dispatch } from 'redux'
import { BorrowFormValuesType, PaymentType } from 'data/types'
import { connect } from 'react-redux'
import { reduxForm } from 'redux-form'
import { RemoteData } from 'blockchain-wallet-v4/src/remote/types'
import Loading from './template.loading'
import React, { Component } from 'react'
Expand All @@ -26,9 +25,8 @@ export class BorrowForm extends Component<Props> {
this.props.borrowActions.initializeBorrow('BTC')
}

handleSubmit = (e) => {
e.preventDefault()
console.log('here')
handleSubmit = () => {
this.props.borrowActions.createBorrow()
}

render () {
Expand All @@ -55,7 +53,6 @@ const mapDispatchToProps = (dispatch: Dispatch): LinkDispatchPropsType => ({
})

const enhance = compose<any>(
reduxForm({ form: 'borrowForm' }),
connect(mapStateToProps, mapDispatchToProps)
)

Expand Down

0 comments on commit ea33585

Please sign in to comment.