reducer.ts
1 import { schema, normalize } from 'normalizr'; 2 3 import * as types from './types'; 4 5 export const allIds = (byIds: { [name: string]: {} }) => { 6 return Object.keys(byIds); 7 }; 8 9 export const option = new schema.Entity('options'); 10 export const providerRate = new schema.Entity('providerRates', { 11 options: [option] 12 }); 13 14 export const INITIAL_STATE: types.SwapState = { 15 step: 1, 16 origin: { label: 'BTC', amount: NaN }, 17 destination: { label: 'ETH', amount: NaN }, 18 options: { 19 byId: {}, 20 allIds: [] 21 }, 22 bityRates: { 23 byId: {}, 24 allIds: [] 25 }, 26 shapeshiftRates: { 27 byId: {}, 28 allIds: [] 29 }, 30 provider: 'shapeshift', 31 destinationAddress: '', 32 bityOrder: {}, 33 shapeshiftOrder: {}, 34 isFetchingRates: null, 35 hasNotifiedRatesFailure: false, 36 secondsRemaining: null, 37 outputTx: null, 38 isPostingOrder: false, 39 bityOrderStatus: null, 40 shapeshiftOrderStatus: null, 41 orderTimestampCreatedISOString: null, 42 paymentAddress: null, 43 validFor: null, 44 orderId: null, 45 showLiteSend: false, 46 paymentId: null, 47 xmrPaymentAddress: null 48 }; 49 50 export function swapReducer(state: types.SwapState = INITIAL_STATE, action: types.SwapAction) { 51 switch (action.type) { 52 case types.SwapActions.LOAD_BITY_RATES_SUCCEEDED: 53 const { payload } = action; 54 return { 55 ...state, 56 bityRates: { 57 byId: normalize(payload, [providerRate]).entities.providerRates, 58 allIds: allIds(normalize(payload, [providerRate]).entities.providerRates) 59 }, 60 options: { 61 byId: Object.assign( 62 {}, 63 normalize(payload, [providerRate]).entities.options, 64 state.options.byId 65 ), 66 allIds: [ 67 ...allIds(normalize(payload, [providerRate]).entities.options), 68 ...state.options.allIds 69 ] 70 }, 71 isFetchingRates: false 72 }; 73 case types.SwapActions.LOAD_SHAPESHIFT_RATES_SUCCEEDED: 74 const { 75 entities: { providerRates: normalizedProviderRates, options: normalizedOptions } 76 } = normalize(action.payload, [providerRate]); 77 78 return { 79 ...state, 80 shapeshiftRates: { 81 byId: normalizedProviderRates, 82 allIds: allIds(normalizedProviderRates) 83 }, 84 options: { 85 byId: { ...normalizedOptions, ...state.options.byId }, 86 allIds: [...allIds(normalizedOptions), ...state.options.allIds] 87 }, 88 isFetchingRates: false 89 }; 90 case types.SwapActions.INIT: { 91 return { 92 ...state, 93 origin: action.payload.origin, 94 destination: action.payload.destination 95 }; 96 } 97 case types.SwapActions.STEP: { 98 return { 99 ...state, 100 step: action.payload 101 }; 102 } 103 case types.SwapActions.DESTINATION_ADDRESS: 104 return { 105 ...state, 106 destinationAddress: action.payload 107 }; 108 case types.SwapActions.RESTART: 109 return { 110 ...INITIAL_STATE, 111 options: state.options, 112 bityRates: state.bityRates, 113 shapeshiftRates: state.shapeshiftRates 114 }; 115 case types.SwapActions.BITY_ORDER_CREATE_REQUESTED: 116 return { 117 ...state, 118 isPostingOrder: true 119 }; 120 case types.SwapActions.SHAPESHIFT_ORDER_CREATE_REQUESTED: 121 return { 122 ...state, 123 isPostingOrder: true 124 }; 125 case types.SwapActions.BITY_ORDER_CREATE_FAILED: 126 return { 127 ...state, 128 isPostingOrder: false 129 }; 130 case types.SwapActions.SHAPESHIFT_ORDER_CREATE_FAILED: 131 return { 132 ...state, 133 isPostingOrder: false 134 }; 135 case types.SwapActions.BITY_ORDER_CREATE_SUCCEEDED: 136 return { 137 ...state, 138 bityOrder: { 139 ...action.payload 140 }, 141 isPostingOrder: false, 142 originAmount: parseFloat(action.payload.input.amount), 143 destinationAmount: parseFloat(action.payload.output.amount), 144 secondsRemaining: action.payload.validFor, // will get update 145 validFor: action.payload.validFor, // to build from local storage 146 orderTimestampCreatedISOString: action.payload.timestamp_created, 147 paymentAddress: action.payload.payment_address, 148 bityOrderStatus: action.payload.status, 149 orderId: action.payload.id 150 }; 151 case types.SwapActions.SHAPESHIFT_ORDER_CREATE_SUCCEEDED: 152 const currDate = Date.now(); 153 const secondsRemaining = Math.floor((+new Date(action.payload.expiration) - currDate) / 1000); 154 155 return { 156 ...state, 157 shapeshiftOrder: { 158 ...action.payload 159 }, 160 isPostingOrder: false, 161 originAmount: parseFloat(action.payload.depositAmount), 162 destinationAmount: parseFloat(action.payload.withdrawalAmount), 163 secondsRemaining, 164 validFor: secondsRemaining, 165 orderTimestampCreatedISOString: new Date(currDate).toISOString(), 166 paymentAddress: action.payload.deposit, 167 shapeshiftOrderStatus: 'no_deposits', 168 orderId: action.payload.orderId, 169 // For XMR swaps 170 paymentId: action.payload.deposit, 171 xmrPaymentAddress: action.payload.sAddress 172 }; 173 case types.SwapActions.BITY_ORDER_STATUS_SUCCEEDED: 174 return { 175 ...state, 176 outputTx: action.payload.output.reference, 177 bityOrderStatus: 178 action.payload.output.status === 'FILL' 179 ? action.payload.output.status 180 : action.payload.input.status 181 }; 182 case types.SwapActions.SHAPESHIFT_ORDER_STATUS_SUCCEEDED: 183 return { 184 ...state, 185 outputTx: action.payload && action.payload.transaction ? action.payload.transaction : null, 186 shapeshiftOrderStatus: action.payload.status 187 }; 188 case types.SwapActions.ORDER_TIME: 189 return { 190 ...state, 191 secondsRemaining: action.payload 192 }; 193 194 case types.SwapActions.LOAD_BITY_RATES_REQUESTED: 195 case types.SwapActions.LOAD_SHAPESHIFT_RATES_REQUESTED: 196 return { 197 ...state, 198 isFetchingRates: true, 199 hasNotifiedRatesFailure: false 200 }; 201 case types.SwapActions.LOAD_BITY_RATES_FAILED: 202 case types.SwapActions.LOAD_SHAPESHIFT_RATES_FAILED: 203 return { 204 ...state, 205 hasNotifiedRatesFailure: true 206 }; 207 case types.SwapActions.STOP_LOAD_BITY_RATES: 208 return { 209 ...state, 210 isFetchingRates: false 211 }; 212 case types.SwapActions.STOP_LOAD_SHAPESHIFT_RATES: 213 return { 214 ...state, 215 isFetchingRates: false 216 }; 217 case types.SwapActions.CHANGE_PROVIDER: 218 return { 219 ...state, 220 provider: action.payload 221 }; 222 case types.SwapActions.SHOW_LITE_SEND: 223 return { 224 ...state, 225 showLiteSend: action.payload 226 }; 227 default: 228 return state; 229 } 230 }