use flow
This commit is contained in:
parent
e7a7754a4f
commit
c000ad1bc8
14 changed files with 381 additions and 109 deletions
|
@ -12,6 +12,9 @@ flow-typed
|
||||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe
|
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe
|
||||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue
|
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue
|
||||||
module.name_mapper='^constants\(.*\)$' -> '<PROJECT_ROOT>/js/constants\1'
|
module.name_mapper='^constants\(.*\)$' -> '<PROJECT_ROOT>/js/constants\1'
|
||||||
|
module.name_mapper='^util\(.*\)$' -> '<PROJECT_ROOT>/js/util\1'
|
||||||
module.name_mapper='^redux\(.*\)$' -> '<PROJECT_ROOT>/js/redux\1'
|
module.name_mapper='^redux\(.*\)$' -> '<PROJECT_ROOT>/js/redux\1'
|
||||||
|
module.name_mapper='^types\(.*\)$' -> '<PROJECT_ROOT>/js/types\1'
|
||||||
|
module.name_mapper='^component\(.*\)$' -> '<PROJECT_ROOT>/js/component\1'
|
||||||
|
|
||||||
[strict]
|
[strict]
|
||||||
|
|
3
src/renderer/flow-typed/bluebird.js
vendored
Normal file
3
src/renderer/flow-typed/bluebird.js
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
declare module 'bluebird' {
|
||||||
|
declare module.exports: any;
|
||||||
|
}
|
3
src/renderer/flow-typed/classnames.js
vendored
Normal file
3
src/renderer/flow-typed/classnames.js
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
declare module 'classnames' {
|
||||||
|
declare module.exports: any;
|
||||||
|
}
|
3
src/renderer/flow-typed/formik.js
vendored
Normal file
3
src/renderer/flow-typed/formik.js
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
declare module 'formik' {
|
||||||
|
declare module.exports: any;
|
||||||
|
}
|
1
src/renderer/flow-typed/i18n.js
vendored
Normal file
1
src/renderer/flow-typed/i18n.js
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
declare function __(a: string): string;
|
3
src/renderer/flow-typed/qrcode.react.js
vendored
Normal file
3
src/renderer/flow-typed/qrcode.react.js
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
declare module 'qrcode.react' {
|
||||||
|
declare module.exports: any;
|
||||||
|
}
|
3
src/renderer/flow-typed/shapeshift.io.js
vendored
Normal file
3
src/renderer/flow-typed/shapeshift.io.js
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
declare module 'shapeshift.io' {
|
||||||
|
declare module.exports: any;
|
||||||
|
}
|
|
@ -1,12 +1,27 @@
|
||||||
import React, { PureComponent } from "react";
|
// @flow
|
||||||
|
import * as React from "react";
|
||||||
import QRCode from "qrcode.react";
|
import QRCode from "qrcode.react";
|
||||||
import * as statuses from "constants/shape_shift";
|
import * as statuses from "constants/shape_shift";
|
||||||
import Address from "component/address";
|
import Address from "component/address";
|
||||||
import Link from "component/link";
|
import Link from "component/link";
|
||||||
|
import type { Dispatch } from "redux/actions/shape_shift";
|
||||||
|
|
||||||
export default class ActiveShapeShift extends PureComponent {
|
type Props = {
|
||||||
|
shiftState: ?string,
|
||||||
|
shiftCoinType: ?string,
|
||||||
|
shiftDepositAddress: ?string,
|
||||||
|
shiftReturnAddress: ?string,
|
||||||
|
shiftOrderId: ?string,
|
||||||
|
originCoinDepositMax: ?number,
|
||||||
|
clearShapeShift: Dispatch,
|
||||||
|
doShowSnackBar: Dispatch,
|
||||||
|
getActiveShift: Dispatch,
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActiveShapeShift extends React.PureComponent<Props> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
// $FlowFixMe
|
||||||
this.continousFetch = undefined;
|
this.continousFetch = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,12 +29,13 @@ export default class ActiveShapeShift extends PureComponent {
|
||||||
const { getActiveShift, shiftDepositAddress } = this.props;
|
const { getActiveShift, shiftDepositAddress } = this.props;
|
||||||
|
|
||||||
getActiveShift(shiftDepositAddress);
|
getActiveShift(shiftDepositAddress);
|
||||||
|
// $FlowFixMe
|
||||||
this.continousFetch = setInterval(() => {
|
this.continousFetch = setInterval(() => {
|
||||||
getActiveShift(shiftDepositAddress);
|
getActiveShift(shiftDepositAddress);
|
||||||
}, 10000);
|
}, 10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUpdate(nextProps) {
|
componentWillUpdate(nextProps: Props) {
|
||||||
const { shiftState } = nextProps;
|
const { shiftState } = nextProps;
|
||||||
if (shiftState === statuses.COMPLETE) {
|
if (shiftState === statuses.COMPLETE) {
|
||||||
this.clearContinuousFetch();
|
this.clearContinuousFetch();
|
||||||
|
@ -31,7 +47,9 @@ export default class ActiveShapeShift extends PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
clearContinuousFetch() {
|
clearContinuousFetch() {
|
||||||
|
/// $FlowFixMe
|
||||||
clearInterval(this.continousFetch);
|
clearInterval(this.continousFetch);
|
||||||
|
// $FlowFixMe
|
||||||
this.continousFetch = null;
|
this.continousFetch = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +60,7 @@ export default class ActiveShapeShift extends PureComponent {
|
||||||
shiftReturnAddress,
|
shiftReturnAddress,
|
||||||
shiftOrderId,
|
shiftOrderId,
|
||||||
shiftState,
|
shiftState,
|
||||||
shiftDepositLimit,
|
originCoinDepositMax,
|
||||||
clearShapeShift,
|
clearShapeShift,
|
||||||
doShowSnackBar,
|
doShowSnackBar,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
@ -54,7 +72,7 @@ export default class ActiveShapeShift extends PureComponent {
|
||||||
<p>
|
<p>
|
||||||
Send up to{" "}
|
Send up to{" "}
|
||||||
<span className="credit-amount--bold">
|
<span className="credit-amount--bold">
|
||||||
{shiftDepositLimit}{" "}
|
{originCoinDepositMax}{" "}
|
||||||
<span className="credit-amount--colored">{shiftCoinType}</span>
|
<span className="credit-amount--colored">{shiftCoinType}</span>
|
||||||
</span>{" "}
|
</span>{" "}
|
||||||
to the address below.
|
to the address below.
|
||||||
|
@ -102,13 +120,15 @@ export default class ActiveShapeShift extends PureComponent {
|
||||||
: __("Cancel")
|
: __("Cancel")
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<span className="shapeshift__link">
|
{shiftOrderId && (
|
||||||
<Link
|
<span className="shapeshift__link">
|
||||||
button="text"
|
<Link
|
||||||
label={__("View the status on Shapeshift.io")}
|
button="text"
|
||||||
href={`https://shapeshift.io/#/status/${shiftOrderId}`}
|
label={__("View the status on Shapeshift.io")}
|
||||||
/>
|
href={`https://shapeshift.io/#/status/${shiftOrderId}`}
|
||||||
</span>
|
/>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
{shiftState === statuses.NO_DEPOSITS &&
|
{shiftState === statuses.NO_DEPOSITS &&
|
||||||
shiftReturnAddress && (
|
shiftReturnAddress && (
|
||||||
<div className="shapeshift__actions-help">
|
<div className="shapeshift__actions-help">
|
||||||
|
@ -123,3 +143,5 @@ export default class ActiveShapeShift extends PureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default ActiveShapeShift;
|
||||||
|
|
|
@ -2,25 +2,48 @@ import React from "react";
|
||||||
import Link from "component/link";
|
import Link from "component/link";
|
||||||
import { getExampleAddress } from "util/shape_shift";
|
import { getExampleAddress } from "util/shape_shift";
|
||||||
import { Submit, FormRow } from "component/form";
|
import { Submit, FormRow } from "component/form";
|
||||||
|
import type { ShapeShiftFormValues, Dispatch } from "redux/actions/shape_shift";
|
||||||
|
|
||||||
export default ({
|
type ShapeShiftFormErrors = {
|
||||||
values,
|
returnAddress?: string,
|
||||||
errors,
|
};
|
||||||
touched,
|
|
||||||
handleChange,
|
type Props = {
|
||||||
handleBlur,
|
values: ShapeShiftFormValues,
|
||||||
handleSubmit,
|
errors: ShapeShiftFormErrors,
|
||||||
resetForm,
|
touched: boolean,
|
||||||
isSubmitting,
|
handleChange: Event => any,
|
||||||
shiftSupportedCoins,
|
handleBlur: Event => any,
|
||||||
originCoin,
|
handleSubmit: Event => any,
|
||||||
updating,
|
isSubmitting: boolean,
|
||||||
getCoinStats,
|
shiftSupportedCoins: Array<string>,
|
||||||
receiveAddress,
|
originCoin: string,
|
||||||
originCoinDepositMax,
|
updating: boolean,
|
||||||
originCoinDepositMin,
|
getCoinStats: Dispatch,
|
||||||
originCoinDepositFee,
|
receiveAddress: string,
|
||||||
}) => {
|
originCoinDepositFee: number,
|
||||||
|
originCoinDepositMin: string,
|
||||||
|
originCoinDepositMax: number,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default (props: Props) => {
|
||||||
|
const {
|
||||||
|
values,
|
||||||
|
errors,
|
||||||
|
touched,
|
||||||
|
handleChange,
|
||||||
|
handleBlur,
|
||||||
|
handleSubmit,
|
||||||
|
isSubmitting,
|
||||||
|
shiftSupportedCoins,
|
||||||
|
originCoin,
|
||||||
|
updating,
|
||||||
|
getCoinStats,
|
||||||
|
receiveAddress,
|
||||||
|
originCoinDepositMax,
|
||||||
|
originCoinDepositMin,
|
||||||
|
originCoinDepositFee,
|
||||||
|
} = props;
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
<div className="form-field">
|
<div className="form-field">
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import React from "react";
|
// @flow
|
||||||
|
import * as React from "react";
|
||||||
import { shell } from "electron";
|
import { shell } from "electron";
|
||||||
import { Formik } from "formik";
|
import { Formik } from "formik";
|
||||||
import classnames from "classnames";
|
import classnames from "classnames";
|
||||||
|
@ -8,9 +9,23 @@ import Link from "component/link";
|
||||||
import Spinner from "component/common/spinner";
|
import Spinner from "component/common/spinner";
|
||||||
import { BusyMessage } from "component/common";
|
import { BusyMessage } from "component/common";
|
||||||
import ShapeShiftForm from "./internal/form";
|
import ShapeShiftForm from "./internal/form";
|
||||||
import ActiveShift from "./internal/active-shift";
|
import ActiveShapeShift from "./internal/active-shift";
|
||||||
|
|
||||||
class ShapeShift extends React.PureComponent {
|
import type { ShapeShiftState } from "redux/reducers/shape_shift";
|
||||||
|
import type { Dispatch, ShapeShiftFormValues } from "redux/actions/shape_shift";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
shapeShift: ShapeShiftState,
|
||||||
|
getCoinStats: Dispatch,
|
||||||
|
createShapeShift: Dispatch,
|
||||||
|
clearShapeShift: Dispatch,
|
||||||
|
getActiveShift: Dispatch,
|
||||||
|
doShowSnackBar: Dispatch,
|
||||||
|
shapeShiftInit: Dispatch,
|
||||||
|
receiveAddress: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
class ShapeShift extends React.PureComponent<Props> {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const {
|
const {
|
||||||
shapeShiftInit,
|
shapeShiftInit,
|
||||||
|
@ -49,11 +64,15 @@ class ShapeShift extends React.PureComponent {
|
||||||
shiftReturnAddress,
|
shiftReturnAddress,
|
||||||
shiftCoinType,
|
shiftCoinType,
|
||||||
shiftOrderId,
|
shiftOrderId,
|
||||||
cancelShapeShift,
|
|
||||||
shiftState,
|
shiftState,
|
||||||
origin,
|
|
||||||
} = shapeShift;
|
} = shapeShift;
|
||||||
|
|
||||||
|
const initialFormValues: ShapeShiftFormValues = {
|
||||||
|
receiveAddress,
|
||||||
|
originCoin: "BTC",
|
||||||
|
returnAddress: "",
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
// add the "shapeshift__intital-wrapper class so we can avoid content jumping once everything loads"
|
// add the "shapeshift__intital-wrapper class so we can avoid content jumping once everything loads"
|
||||||
// it just gives the section a min-height equal to the height of the content when the form is rendered
|
// it just gives the section a min-height equal to the height of the content when the form is rendered
|
||||||
|
@ -85,11 +104,7 @@ class ShapeShift extends React.PureComponent {
|
||||||
<Formik
|
<Formik
|
||||||
onSubmit={createShapeShift}
|
onSubmit={createShapeShift}
|
||||||
validate={validateShapeShiftForm}
|
validate={validateShapeShiftForm}
|
||||||
initialValues={{
|
initialValues={initialFormValues}
|
||||||
receiveAddress,
|
|
||||||
originCoin: "BTC",
|
|
||||||
returnAddress: "",
|
|
||||||
}}
|
|
||||||
render={formProps => (
|
render={formProps => (
|
||||||
<ShapeShiftForm
|
<ShapeShiftForm
|
||||||
{...formProps}
|
{...formProps}
|
||||||
|
@ -106,12 +121,12 @@ class ShapeShift extends React.PureComponent {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{hasActiveShift && (
|
{hasActiveShift && (
|
||||||
<ActiveShift
|
<ActiveShapeShift
|
||||||
getActiveShift={getActiveShift}
|
getActiveShift={getActiveShift}
|
||||||
shiftCoinType={shiftCoinType}
|
shiftCoinType={shiftCoinType}
|
||||||
shiftReturnAddress={shiftReturnAddress}
|
shiftReturnAddress={shiftReturnAddress}
|
||||||
shiftDepositAddress={shiftDepositAddress}
|
shiftDepositAddress={shiftDepositAddress}
|
||||||
shiftDepositLimit={originCoinDepositMax}
|
originCoinDepositMax={originCoinDepositMax}
|
||||||
shiftOrderId={shiftOrderId}
|
shiftOrderId={shiftOrderId}
|
||||||
shiftState={shiftState}
|
shiftState={shiftState}
|
||||||
clearShapeShift={clearShapeShift}
|
clearShapeShift={clearShapeShift}
|
||||||
|
|
|
@ -1,11 +1,56 @@
|
||||||
import { createAction } from "util/redux-utils";
|
// @flow
|
||||||
import Promise from "bluebird";
|
import Promise from "bluebird";
|
||||||
import * as types from "constants/action_types";
|
import * as types from "constants/action_types";
|
||||||
import { coinRegexPatterns } from "util/shape_shift";
|
import { coinRegexPatterns } from "util/shape_shift";
|
||||||
|
import type {
|
||||||
|
GetSupportedCoinsSuccess,
|
||||||
|
GetCoinStatsStart,
|
||||||
|
GetCoinStatsSuccess,
|
||||||
|
GetCoinStatsFail,
|
||||||
|
PrepareShapeShiftSuccess,
|
||||||
|
PrepareShapeShiftFail,
|
||||||
|
GetActiveShiftSuccess,
|
||||||
|
GetActiveShiftFail,
|
||||||
|
} from "redux/reducers/shape_shift";
|
||||||
|
import type { FormikActions } from "types/common";
|
||||||
|
|
||||||
|
// use promise chains instead of callbacks for shapeshift api
|
||||||
const shapeShift = Promise.promisifyAll(require("shapeshift.io"));
|
const shapeShift = Promise.promisifyAll(require("shapeshift.io"));
|
||||||
|
|
||||||
export const shapeShiftInit = () => dispatch => {
|
// All ShapeShift actions
|
||||||
|
// Action types defined in the reducer will contain some payload
|
||||||
|
export type Action =
|
||||||
|
| { type: types.GET_SUPPORTED_COINS_START }
|
||||||
|
| { type: types.GET_SUPPORTED_COINS_FAIL }
|
||||||
|
| GetSupportedCoinsSuccess
|
||||||
|
| GetCoinStatsStart
|
||||||
|
| { type: types.GET_COIN_STATS_START }
|
||||||
|
| GetCoinStatsFail
|
||||||
|
| GetCoinStatsSuccess
|
||||||
|
| { type: types.PREPARE_SHAPE_SHIFT_START }
|
||||||
|
| PrepareShapeShiftFail
|
||||||
|
| PrepareShapeShiftSuccess
|
||||||
|
| { type: types.GET_ACTIVE_SHIFT_START }
|
||||||
|
| GetActiveShiftFail
|
||||||
|
| GetActiveShiftSuccess;
|
||||||
|
|
||||||
|
// Basic thunk types
|
||||||
|
// It would be nice to import these from types/common
|
||||||
|
// Not sure how that would work since they rely on the Action type
|
||||||
|
type PromiseAction = Promise<Action>;
|
||||||
|
type ThunkAction = (dispatch: Dispatch) => any;
|
||||||
|
export type Dispatch = (
|
||||||
|
action: Action | ThunkAction | PromiseAction | Array<Action>
|
||||||
|
) => any;
|
||||||
|
|
||||||
|
// ShapeShift form values
|
||||||
|
export type ShapeShiftFormValues = {
|
||||||
|
originCoin: string,
|
||||||
|
returnAddress: ?string,
|
||||||
|
receiveAddress: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const shapeShiftInit = () => (dispatch: Dispatch): ThunkAction => {
|
||||||
dispatch({ type: types.GET_SUPPORTED_COINS_START });
|
dispatch({ type: types.GET_SUPPORTED_COINS_START });
|
||||||
|
|
||||||
return shapeShift
|
return shapeShift
|
||||||
|
@ -34,8 +79,9 @@ export const shapeShiftInit = () => dispatch => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getCoinStats = coin => dispatch => {
|
export const getCoinStats = (coin: string) => (
|
||||||
// TODO: get ShapeShift fee
|
dispatch: Dispatch
|
||||||
|
): ThunkAction => {
|
||||||
const pair = `${coin.toLowerCase()}_lbc`;
|
const pair = `${coin.toLowerCase()}_lbc`;
|
||||||
|
|
||||||
dispatch({ type: types.GET_COIN_STATS_START, data: coin });
|
dispatch({ type: types.GET_COIN_STATS_START, data: coin });
|
||||||
|
@ -48,7 +94,10 @@ export const getCoinStats = coin => dispatch => {
|
||||||
.catch(err => dispatch({ type: types.GET_COIN_STATS_FAIL, data: err }));
|
.catch(err => dispatch({ type: types.GET_COIN_STATS_FAIL, data: err }));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createShapeShift = (values, actions) => dispatch => {
|
export const createShapeShift = (
|
||||||
|
values: ShapeShiftFormValues,
|
||||||
|
actions: FormikActions
|
||||||
|
) => (dispatch: Dispatch): ThunkAction => {
|
||||||
const {
|
const {
|
||||||
originCoin,
|
originCoin,
|
||||||
returnAddress,
|
returnAddress,
|
||||||
|
@ -68,12 +117,14 @@ export const createShapeShift = (values, actions) => dispatch => {
|
||||||
)
|
)
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
dispatch({ type: types.PREPARE_SHAPE_SHIFT_FAIL, data: err });
|
dispatch({ type: types.PREPARE_SHAPE_SHIFT_FAIL, data: err });
|
||||||
// for formik
|
// for formik to stop the submit
|
||||||
actions.setSubmitting(false);
|
actions.setSubmitting(false);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getActiveShift = depositAddress => dispatch => {
|
export const getActiveShift = (depositAddress: string) => (
|
||||||
|
dispatch: Dispatch
|
||||||
|
): ThunkAction => {
|
||||||
dispatch({ type: types.GET_ACTIVE_SHIFT_START });
|
dispatch({ type: types.GET_ACTIVE_SHIFT_START });
|
||||||
|
|
||||||
return shapeShift
|
return shapeShift
|
||||||
|
@ -82,5 +133,5 @@ export const getActiveShift = depositAddress => dispatch => {
|
||||||
.catch(err => dispatch({ type: types.GET_ACTIVE_SHIFT_FAIL, data: err }));
|
.catch(err => dispatch({ type: types.GET_ACTIVE_SHIFT_FAIL, data: err }));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const clearShapeShift = () => dispatch =>
|
export const clearShapeShift = () => (dispatch: Dispatch): Action =>
|
||||||
dispatch({ type: types.CLEAR_SHAPE_SHIFT });
|
dispatch({ type: types.CLEAR_SHAPE_SHIFT });
|
||||||
|
|
|
@ -1,14 +1,88 @@
|
||||||
|
// @flow
|
||||||
import { handleActions } from "util/redux-utils";
|
import { handleActions } from "util/redux-utils";
|
||||||
import * as types from "constants/action_types";
|
import * as actions from "constants/action_types";
|
||||||
import * as statuses from "constants/shape_shift";
|
import * as statuses from "constants/shape_shift";
|
||||||
|
|
||||||
const defaultState = {
|
export type ShapeShiftState = {
|
||||||
|
loading: boolean,
|
||||||
|
updating: boolean,
|
||||||
|
shiftSupportedCoins: Array<string>,
|
||||||
|
hasActiveShift: boolean,
|
||||||
|
originCoin: ?string,
|
||||||
|
error: ?string,
|
||||||
|
shiftDepositAddress: ?string,
|
||||||
|
shiftReturnAddress: ?string,
|
||||||
|
shiftCoinType: ?string,
|
||||||
|
shiftOrderId: ?string,
|
||||||
|
shiftState: ?string,
|
||||||
|
originCoinDepositMax: ?number,
|
||||||
|
// originCoinDepositMin is a string because we need to convert it from scientifc notation
|
||||||
|
// it will usually be something like 0.00000001 coins
|
||||||
|
// using Number(x) or parseInt(x) will either change it back to scientific notation or round to zero
|
||||||
|
originCoinDepositMin: ?string,
|
||||||
|
originCoinDepositFee: ?number,
|
||||||
|
};
|
||||||
|
|
||||||
|
// All ShapeShift actions that will have some payload
|
||||||
|
export type GetSupportedCoinsSuccess = {
|
||||||
|
type: actions.GET_SUPPORTED_COINS_SUCCESS,
|
||||||
|
data: Array<string>,
|
||||||
|
};
|
||||||
|
export type GetCoinStatsStart = {
|
||||||
|
type: actions.GET_SUPPORTED_COINS_SUCCESS,
|
||||||
|
data: string,
|
||||||
|
};
|
||||||
|
export type GetCoinStatsSuccess = {
|
||||||
|
type: actions.GET_COIN_STATS_SUCCESS,
|
||||||
|
data: ShapeShiftMarketInfo,
|
||||||
|
};
|
||||||
|
export type GetCoinStatsFail = {
|
||||||
|
type: actions.GET_COIN_STATS_FAIL,
|
||||||
|
data: string,
|
||||||
|
};
|
||||||
|
export type PrepareShapeShiftSuccess = {
|
||||||
|
type: actions.PREPARE_SHAPE_SHIFT_SUCCESS,
|
||||||
|
data: ActiveShiftInfo,
|
||||||
|
};
|
||||||
|
export type PrepareShapeShiftFail = {
|
||||||
|
type: actions.PREPARE_SHAPE_SHIFT_FAIL,
|
||||||
|
data: ShapeShiftErrorResponse,
|
||||||
|
};
|
||||||
|
export type GetActiveShiftSuccess = {
|
||||||
|
type: actions.GET_ACTIVE_SHIFT_SUCCESS,
|
||||||
|
data: string,
|
||||||
|
};
|
||||||
|
export type GetActiveShiftFail = {
|
||||||
|
type: actions.GET_ACTIVE_SHIFT_FAIL,
|
||||||
|
data: ShapeShiftErrorResponse,
|
||||||
|
};
|
||||||
|
|
||||||
|
// ShapeShift sub-types
|
||||||
|
// Defined for actions that contain an object in the payload
|
||||||
|
type ShapeShiftMarketInfo = {
|
||||||
|
limit: number,
|
||||||
|
minimum: number,
|
||||||
|
minerFee: number,
|
||||||
|
};
|
||||||
|
|
||||||
|
type ActiveShiftInfo = {
|
||||||
|
deposit: string,
|
||||||
|
depositType: string,
|
||||||
|
returnAddress: string,
|
||||||
|
orderId: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
type ShapeShiftErrorResponse = {
|
||||||
|
message: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
const defaultState: ShapeShiftState = {
|
||||||
loading: true,
|
loading: true,
|
||||||
updating: false,
|
updating: false,
|
||||||
error: undefined,
|
|
||||||
shiftSupportedCoins: [],
|
shiftSupportedCoins: [],
|
||||||
originCoin: undefined,
|
|
||||||
hasActiveShift: false,
|
hasActiveShift: false,
|
||||||
|
originCoin: undefined,
|
||||||
|
error: undefined,
|
||||||
shiftDepositAddress: undefined, // shapeshift address to send your coins to
|
shiftDepositAddress: undefined, // shapeshift address to send your coins to
|
||||||
shiftReturnAddress: undefined,
|
shiftReturnAddress: undefined,
|
||||||
shiftCoinType: undefined,
|
shiftCoinType: undefined,
|
||||||
|
@ -21,61 +95,108 @@ const defaultState = {
|
||||||
|
|
||||||
export default handleActions(
|
export default handleActions(
|
||||||
{
|
{
|
||||||
[types.GET_SUPPORTED_COINS_START]: () => ({
|
[actions.GET_SUPPORTED_COINS_START]: (
|
||||||
|
state: ShapeShiftState
|
||||||
|
): ShapeShiftState => ({
|
||||||
|
...state,
|
||||||
loading: true,
|
loading: true,
|
||||||
error: undefined,
|
error: undefined,
|
||||||
}),
|
}),
|
||||||
[types.GET_SUPPORTED_COINS_SUCCESS]: (
|
[actions.GET_SUPPORTED_COINS_SUCCESS]: (
|
||||||
state,
|
state: ShapeShiftState,
|
||||||
{ data: shiftSupportedCoins }
|
action: GetSupportedCoinsSuccess
|
||||||
) => ({
|
): ShapeShiftState => {
|
||||||
error: undefined,
|
const shiftSupportedCoins = action.data;
|
||||||
shiftSupportedCoins,
|
return {
|
||||||
}),
|
...state,
|
||||||
[types.GET_SUPPORTED_COINS_FAIL]: () => ({
|
error: undefined,
|
||||||
|
shiftSupportedCoins,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
[actions.GET_SUPPORTED_COINS_FAIL]: (
|
||||||
|
state: ShapeShiftState
|
||||||
|
): ShapeShiftState => ({
|
||||||
|
...state,
|
||||||
loading: false,
|
loading: false,
|
||||||
error: true,
|
error: "Error getting available coins",
|
||||||
}),
|
}),
|
||||||
|
|
||||||
[types.GET_COIN_STATS_START]: (state, { data: coin }) => ({
|
[actions.GET_COIN_STATS_START]: (
|
||||||
updating: true,
|
state: ShapeShiftState,
|
||||||
originCoin: coin,
|
action: GetCoinStatsStart
|
||||||
}),
|
): ShapeShiftState => {
|
||||||
[types.GET_COIN_STATS_SUCCESS]: (state, { data: marketInfo }) => ({
|
const coin = action.data;
|
||||||
loading: false,
|
return {
|
||||||
updating: false,
|
...state,
|
||||||
originCoinDepositMax: marketInfo.limit,
|
updating: true,
|
||||||
// this will come in scientific notation
|
originCoin: coin,
|
||||||
// toFixed shows the real number, then regex to remove trailing zeros
|
};
|
||||||
originCoinDepositMin: marketInfo.minimum
|
},
|
||||||
.toFixed(10)
|
[actions.GET_COIN_STATS_SUCCESS]: (
|
||||||
.replace(/\.?0+$/, ""),
|
state: ShapeShiftState,
|
||||||
originCoinDepositFee: marketInfo.minerFee,
|
action: GetCoinStatsSuccess
|
||||||
}),
|
): ShapeShiftState => {
|
||||||
[types.GET_COIN_STATS_FAIL]: (state, { data: error }) => ({
|
const marketInfo: ShapeShiftMarketInfo = action.data;
|
||||||
loading: false,
|
|
||||||
error,
|
|
||||||
}),
|
|
||||||
|
|
||||||
[types.PREPARE_SHAPE_SHIFT_START]: () => ({
|
return {
|
||||||
|
...state,
|
||||||
|
loading: false,
|
||||||
|
updating: false,
|
||||||
|
originCoinDepositMax: marketInfo.limit,
|
||||||
|
// this will come in scientific notation
|
||||||
|
// toFixed shows the real number, then regex to remove trailing zeros
|
||||||
|
originCoinDepositMin: marketInfo.minimum
|
||||||
|
.toFixed(10)
|
||||||
|
.replace(/\.?0+$/, ""),
|
||||||
|
originCoinDepositFee: marketInfo.minerFee,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
[actions.GET_COIN_STATS_FAIL]: (
|
||||||
|
state: ShapeShiftState,
|
||||||
|
action: GetCoinStatsFail
|
||||||
|
): ShapeShiftState => {
|
||||||
|
const error = action.data;
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
loading: false,
|
||||||
|
error,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
[actions.PREPARE_SHAPE_SHIFT_START]: (
|
||||||
|
state: ShapeShiftState
|
||||||
|
): ShapeShiftState => ({
|
||||||
|
...state,
|
||||||
error: undefined,
|
error: undefined,
|
||||||
}),
|
}),
|
||||||
[types.PREPARE_SHAPE_SHIFT_SUCCESS]: (
|
[actions.PREPARE_SHAPE_SHIFT_SUCCESS]: (
|
||||||
state,
|
state: ShapeShiftState,
|
||||||
{ data: { deposit, depositType, returnAddress, orderId } }
|
action: PrepareShapeShiftSuccess
|
||||||
) => ({
|
) => {
|
||||||
hasActiveShift: true,
|
const activeShiftInfo: ActiveShiftInfo = action.data;
|
||||||
shiftDepositAddress: deposit,
|
return {
|
||||||
shiftCoinType: depositType,
|
...state,
|
||||||
shiftReturnAddress: returnAddress,
|
hasActiveShift: true,
|
||||||
shiftOrderId: orderId,
|
shiftDepositAddress: activeShiftInfo.deposit,
|
||||||
shiftState: statuses.NO_DEPOSITS,
|
shiftCoinType: activeShiftInfo.depositType,
|
||||||
}),
|
shiftReturnAddress: activeShiftInfo.returnAddress,
|
||||||
[types.PREPARE_SHAPE_SHIFT_FAIL]: (state, { data: error }) => ({
|
shiftOrderId: activeShiftInfo.orderId,
|
||||||
error: error.message,
|
shiftState: statuses.NO_DEPOSITS,
|
||||||
}),
|
};
|
||||||
|
},
|
||||||
|
[actions.PREPARE_SHAPE_SHIFT_FAIL]: (
|
||||||
|
state: ShapeShiftState,
|
||||||
|
action: PrepareShapeShiftFail
|
||||||
|
) => {
|
||||||
|
const error: ShapeShiftErrorResponse = action.data;
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
error: error.message,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
[types.CLEAR_SHAPE_SHIFT]: () => ({
|
[actions.CLEAR_SHAPE_SHIFT]: (state: ShapeShiftState): ShapeShiftState => ({
|
||||||
|
...state,
|
||||||
loading: false,
|
loading: false,
|
||||||
updating: false,
|
updating: false,
|
||||||
hasActiveShift: false,
|
hasActiveShift: false,
|
||||||
|
@ -83,21 +204,38 @@ export default handleActions(
|
||||||
shiftReturnAddress: undefined,
|
shiftReturnAddress: undefined,
|
||||||
shiftCoinType: undefined,
|
shiftCoinType: undefined,
|
||||||
shiftOrderId: undefined,
|
shiftOrderId: undefined,
|
||||||
originCoin: "BTC",
|
originCoin: state.shiftSupportedCoins[0],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
[types.GET_ACTIVE_SHIFT_START]: () => ({
|
[actions.GET_ACTIVE_SHIFT_START]: (
|
||||||
|
state: ShapeShiftState
|
||||||
|
): ShapeShiftState => ({
|
||||||
|
...state,
|
||||||
error: undefined,
|
error: undefined,
|
||||||
updating: true,
|
updating: true,
|
||||||
}),
|
}),
|
||||||
[types.GET_ACTIVE_SHIFT_SUCCESS]: (state, { data: status }) => ({
|
[actions.GET_ACTIVE_SHIFT_SUCCESS]: (
|
||||||
updating: false,
|
state: ShapeShiftState,
|
||||||
shiftState: status,
|
action: GetActiveShiftSuccess
|
||||||
}),
|
): ShapeShiftState => {
|
||||||
[types.GET_ACTIVE_SHIFT_FAIL]: (state, { data: error }) => ({
|
const status = action.data;
|
||||||
updating: false,
|
return {
|
||||||
error: error.message,
|
...state,
|
||||||
}),
|
updating: false,
|
||||||
|
shiftState: status,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
[actions.GET_ACTIVE_SHIFT_FAIL]: (
|
||||||
|
state: ShapeShiftState,
|
||||||
|
action: GetActiveShiftFail
|
||||||
|
): ShapeShiftState => {
|
||||||
|
const error: ShapeShiftErrorResponse = action.data;
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
updating: false,
|
||||||
|
error: error.message,
|
||||||
|
};
|
||||||
|
},
|
||||||
},
|
},
|
||||||
defaultState
|
defaultState
|
||||||
);
|
);
|
||||||
|
|
3
src/renderer/js/types/common.js
Normal file
3
src/renderer/js/types/common.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export type FormikActions = {
|
||||||
|
setSubmitting: boolean => mixed,
|
||||||
|
};
|
|
@ -1,6 +1,7 @@
|
||||||
// util for creating reducers
|
// util for creating reducers
|
||||||
// based off of redux-actions
|
// based off of redux-actions
|
||||||
// https://redux-actions.js.org/docs/api/handleAction.html#handleactions
|
// https://redux-actions.js.org/docs/api/handleAction.html#handleactions
|
||||||
|
|
||||||
export const handleActions = (actionMap, defaultState) => {
|
export const handleActions = (actionMap, defaultState) => {
|
||||||
return (state = defaultState, action) => {
|
return (state = defaultState, action) => {
|
||||||
const handler = actionMap[action.type];
|
const handler = actionMap[action.type];
|
||||||
|
|
Loading…
Reference in a new issue