Merge pull request #652 from seanyesmunt/shapeshift
ShapeShift integration
This commit is contained in:
commit
6108141605
43 changed files with 1477 additions and 179 deletions
|
@ -12,6 +12,9 @@ flow-typed
|
|||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue
|
||||
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='^types\(.*\)$' -> '<PROJECT_ROOT>/js/types\1'
|
||||
module.name_mapper='^component\(.*\)$' -> '<PROJECT_ROOT>/js/component\1'
|
||||
|
||||
[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;
|
||||
}
|
7
src/renderer/js/component/address/index.js
Normal file
7
src/renderer/js/component/address/index.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { connect } from "react-redux";
|
||||
import { doShowSnackBar } from "redux/actions/app";
|
||||
import Address from "./view";
|
||||
|
||||
export default connect(null, {
|
||||
doShowSnackBar,
|
||||
})(Address);
|
52
src/renderer/js/component/address/view.jsx
Normal file
52
src/renderer/js/component/address/view.jsx
Normal file
|
@ -0,0 +1,52 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { clipboard } from "electron";
|
||||
import Link from "component/link";
|
||||
import classnames from "classnames";
|
||||
|
||||
export default class Address extends React.PureComponent {
|
||||
static propTypes = {
|
||||
address: PropTypes.string,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this._inputElem = null;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { address, showCopyButton, doShowSnackBar } = this.props;
|
||||
|
||||
return (
|
||||
<div className="form-field form-field--address">
|
||||
<input
|
||||
className={classnames("input-copyable", {
|
||||
"input-copyable--with-copy-btn": showCopyButton,
|
||||
})}
|
||||
type="text"
|
||||
ref={input => {
|
||||
this._inputElem = input;
|
||||
}}
|
||||
onFocus={() => {
|
||||
this._inputElem.select();
|
||||
}}
|
||||
readOnly="readonly"
|
||||
value={address || ""}
|
||||
/>
|
||||
{showCopyButton && (
|
||||
<span className="header__item">
|
||||
<Link
|
||||
button="alt button--flat"
|
||||
icon="clipboard"
|
||||
onClick={() => {
|
||||
clipboard.writeText(address);
|
||||
doShowSnackBar({ message: __("Address copied") });
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -137,42 +137,6 @@ export class CreditAmount extends React.PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
let addressStyle = {
|
||||
fontFamily:
|
||||
'"Consolas", "Lucida Console", "Adobe Source Code Pro", monospace',
|
||||
};
|
||||
export class Address extends React.PureComponent {
|
||||
static propTypes = {
|
||||
address: PropTypes.string,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this._inputElem = null;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="form-field form-field--address">
|
||||
<input
|
||||
className="input-copyable"
|
||||
type="text"
|
||||
ref={input => {
|
||||
this._inputElem = input;
|
||||
}}
|
||||
onFocus={() => {
|
||||
this._inputElem.select();
|
||||
}}
|
||||
style={addressStyle}
|
||||
readOnly="readonly"
|
||||
value={this.props.address || ""}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class Thumbnail extends React.PureComponent {
|
||||
static propTypes = {
|
||||
src: PropTypes.string,
|
||||
|
|
16
src/renderer/js/component/common/spinner.jsx
Normal file
16
src/renderer/js/component/common/spinner.jsx
Normal file
|
@ -0,0 +1,16 @@
|
|||
import React from "react";
|
||||
import classnames from "classnames";
|
||||
|
||||
export default ({ dark, className }) => {
|
||||
return (
|
||||
<div
|
||||
className={classnames(
|
||||
"spinner",
|
||||
{
|
||||
"spinner--dark": dark,
|
||||
},
|
||||
className
|
||||
)}
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -14,11 +14,12 @@ const Link = props => {
|
|||
navigate,
|
||||
navigateParams,
|
||||
doNavigate,
|
||||
className,
|
||||
} = props;
|
||||
|
||||
const className =
|
||||
(props.className || "") +
|
||||
(!props.className && !button ? "button-text" : "") + // Non-button links get the same look as text buttons
|
||||
const combinedClassName =
|
||||
(className || "") +
|
||||
(!className && !button ? "button-text" : "") + // Non-button links get the same look as text buttons
|
||||
(button ? " button-block button-" + button + " button-set-item" : "") +
|
||||
(disabled ? " disabled" : "");
|
||||
|
||||
|
@ -43,7 +44,7 @@ const Link = props => {
|
|||
|
||||
return (
|
||||
<a
|
||||
className={className}
|
||||
className={combinedClassName}
|
||||
href={href || "javascript:;"}
|
||||
title={title}
|
||||
onClick={onClick}
|
||||
|
|
26
src/renderer/js/component/shapeShift/index.js
Normal file
26
src/renderer/js/component/shapeShift/index.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { connect } from "react-redux";
|
||||
import {
|
||||
createShapeShift,
|
||||
shapeShiftInit,
|
||||
getCoinStats,
|
||||
clearShapeShift,
|
||||
getActiveShift,
|
||||
} from "redux/actions/shape_shift";
|
||||
import { doShowSnackBar } from "redux/actions/app";
|
||||
import { selectReceiveAddress } from "redux/selectors/wallet";
|
||||
import { selectShapeShift } from "redux/selectors/shape_shift";
|
||||
import ShapeShift from "./view";
|
||||
|
||||
const select = state => ({
|
||||
receiveAddress: selectReceiveAddress(state),
|
||||
shapeShift: selectShapeShift(state),
|
||||
});
|
||||
|
||||
export default connect(select, {
|
||||
shapeShiftInit,
|
||||
getCoinStats,
|
||||
createShapeShift,
|
||||
clearShapeShift,
|
||||
getActiveShift,
|
||||
doShowSnackBar,
|
||||
})(ShapeShift);
|
161
src/renderer/js/component/shapeShift/internal/active-shift.jsx
Normal file
161
src/renderer/js/component/shapeShift/internal/active-shift.jsx
Normal file
|
@ -0,0 +1,161 @@
|
|||
// @flow
|
||||
import * as React from "react";
|
||||
import QRCode from "qrcode.react";
|
||||
import * as statuses from "constants/shape_shift";
|
||||
import Address from "component/address";
|
||||
import Link from "component/link";
|
||||
import type { Dispatch } from "redux/actions/shape_shift";
|
||||
import ShiftMarketInfo from "./market_info";
|
||||
|
||||
type Props = {
|
||||
shiftState: ?string,
|
||||
shiftCoinType: ?string,
|
||||
shiftDepositAddress: ?string,
|
||||
shiftReturnAddress: ?string,
|
||||
shiftOrderId: ?string,
|
||||
originCoinDepositMax: ?number,
|
||||
clearShapeShift: Dispatch,
|
||||
doShowSnackBar: Dispatch,
|
||||
getActiveShift: Dispatch,
|
||||
shapeShiftRate: ?number,
|
||||
originCoinDepositMax: ?number,
|
||||
originCoinDepositFee: ?number,
|
||||
originCoinDepositMin: ?string,
|
||||
};
|
||||
|
||||
class ActiveShapeShift extends React.PureComponent<Props> {
|
||||
continousFetch: ?number;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.continousFetch = undefined;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { getActiveShift, shiftDepositAddress } = this.props;
|
||||
|
||||
getActiveShift(shiftDepositAddress);
|
||||
this.continousFetch = setInterval(() => {
|
||||
getActiveShift(shiftDepositAddress);
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
componentWillUpdate(nextProps: Props) {
|
||||
const { shiftState } = nextProps;
|
||||
if (shiftState === statuses.COMPLETE) {
|
||||
this.clearContinuousFetch();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.clearContinuousFetch();
|
||||
}
|
||||
|
||||
clearContinuousFetch() {
|
||||
if (this.continousFetch) {
|
||||
clearInterval(this.continousFetch);
|
||||
this.continousFetch = null;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
shiftCoinType,
|
||||
shiftDepositAddress,
|
||||
shiftReturnAddress,
|
||||
shiftOrderId,
|
||||
shiftState,
|
||||
originCoinDepositMax,
|
||||
clearShapeShift,
|
||||
doShowSnackBar,
|
||||
shapeShiftRate,
|
||||
originCoinDepositFee,
|
||||
originCoinDepositMin,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
{shiftState === statuses.NO_DEPOSITS && (
|
||||
<div>
|
||||
<p>
|
||||
Send up to{" "}
|
||||
<span className="credit-amount--bold">
|
||||
{originCoinDepositMax} {shiftCoinType}
|
||||
</span>{" "}
|
||||
to the address below.
|
||||
</p>
|
||||
<ShiftMarketInfo
|
||||
originCoin={shiftCoinType}
|
||||
shapeShiftRate={shapeShiftRate}
|
||||
originCoinDepositFee={originCoinDepositFee}
|
||||
originCoinDepositMin={originCoinDepositMin}
|
||||
originCoinDepositMax={originCoinDepositMax}
|
||||
/>
|
||||
|
||||
<div className="shapeshift__deposit-address-wrapper">
|
||||
<Address address={shiftDepositAddress} showCopyButton />
|
||||
<div className="shapeshift__qrcode">
|
||||
<QRCode value={shiftDepositAddress} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{shiftState === statuses.RECEIVED && (
|
||||
<div className="card__content--extra-vertical-space">
|
||||
<p>
|
||||
{__(
|
||||
"ShapeShift has received your payment! Sending the funds to your LBRY wallet."
|
||||
)}
|
||||
</p>
|
||||
<span className="help">
|
||||
{__("This can take a while, especially with BTC.")}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{shiftState === statuses.COMPLETE && (
|
||||
<div className="card__content--extra-vertical-space">
|
||||
<p>
|
||||
{__(
|
||||
"Transaction complete! You should see the new LBC in your wallet."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
<div className="card__actions card__actions--only-vertical">
|
||||
<Link
|
||||
button={shiftState === statuses.COMPLETE ? "primary" : "alt"}
|
||||
onClick={clearShapeShift}
|
||||
label={
|
||||
shiftState === statuses.COMPLETE ||
|
||||
shiftState === statuses.RECEIVED
|
||||
? __("Done")
|
||||
: __("Cancel")
|
||||
}
|
||||
/>
|
||||
{shiftOrderId && (
|
||||
<span className="shapeshift__link">
|
||||
<Link
|
||||
button="text"
|
||||
label={__("View the status on Shapeshift.io")}
|
||||
href={`https://shapeshift.io/#/status/${shiftOrderId}`}
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
{shiftState === statuses.NO_DEPOSITS &&
|
||||
shiftReturnAddress && (
|
||||
<div className="shapeshift__actions-help">
|
||||
<span className="help">
|
||||
If the transaction doesn't go through, ShapeShift will return
|
||||
your {shiftCoinType} back to {shiftReturnAddress}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ActiveShapeShift;
|
109
src/renderer/js/component/shapeShift/internal/form.jsx
Normal file
109
src/renderer/js/component/shapeShift/internal/form.jsx
Normal file
|
@ -0,0 +1,109 @@
|
|||
import React from "react";
|
||||
import Link from "component/link";
|
||||
import { getExampleAddress } from "util/shape_shift";
|
||||
import { Submit, FormRow } from "component/form";
|
||||
import type { ShapeShiftFormValues, Dispatch } from "redux/actions/shape_shift";
|
||||
import ShiftMarketInfo from "./market_info";
|
||||
|
||||
type ShapeShiftFormErrors = {
|
||||
returnAddress?: string,
|
||||
};
|
||||
|
||||
type Props = {
|
||||
values: ShapeShiftFormValues,
|
||||
errors: ShapeShiftFormErrors,
|
||||
touched: boolean,
|
||||
handleChange: Event => any,
|
||||
handleBlur: Event => any,
|
||||
handleSubmit: Event => any,
|
||||
isSubmitting: boolean,
|
||||
shiftSupportedCoins: Array<string>,
|
||||
originCoin: string,
|
||||
updating: boolean,
|
||||
getCoinStats: Dispatch,
|
||||
receiveAddress: string,
|
||||
originCoinDepositFee: number,
|
||||
originCoinDepositMin: string,
|
||||
originCoinDepositMax: number,
|
||||
shapeShiftRate: number,
|
||||
};
|
||||
|
||||
export default (props: Props) => {
|
||||
const {
|
||||
values,
|
||||
errors,
|
||||
touched,
|
||||
handleChange,
|
||||
handleBlur,
|
||||
handleSubmit,
|
||||
isSubmitting,
|
||||
shiftSupportedCoins,
|
||||
originCoin,
|
||||
updating,
|
||||
getCoinStats,
|
||||
receiveAddress,
|
||||
originCoinDepositMax,
|
||||
originCoinDepositMin,
|
||||
originCoinDepositFee,
|
||||
shapeShiftRate,
|
||||
} = props;
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="form-field">
|
||||
<span>{__("Exchange")} </span>
|
||||
<select
|
||||
className="form-field__input form-field__input-select"
|
||||
name="originCoin"
|
||||
onChange={e => {
|
||||
getCoinStats(e.target.value);
|
||||
handleChange(e);
|
||||
}}
|
||||
>
|
||||
{shiftSupportedCoins.map(coin => (
|
||||
<option key={coin} value={coin}>
|
||||
{coin}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<span> {__("for LBC")}</span>
|
||||
<div className="shapeshift__tx-info">
|
||||
{!updating &&
|
||||
originCoinDepositMax && (
|
||||
<ShiftMarketInfo
|
||||
originCoin={originCoin}
|
||||
shapeShiftRate={shapeShiftRate}
|
||||
originCoinDepositFee={originCoinDepositFee}
|
||||
originCoinDepositMin={originCoinDepositMin}
|
||||
originCoinDepositMax={originCoinDepositMax}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<FormRow
|
||||
type="text"
|
||||
name="returnAddress"
|
||||
placeholder={getExampleAddress(originCoin)}
|
||||
label={__("Return address")}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
value={values.returnAddress}
|
||||
errorMessage={errors.returnAddress}
|
||||
hasError={touched.returnAddress && !!errors.returnAddress}
|
||||
/>
|
||||
<span className="help">
|
||||
<span>
|
||||
({__("optional but recommended")}) {__("We will return your")}{" "}
|
||||
{originCoin}{" "}
|
||||
{__("to this address if the transaction doesn't go through.")}
|
||||
</span>
|
||||
</span>
|
||||
<div className="card__actions card__actions--only-vertical">
|
||||
<Submit
|
||||
label={__("Begin Conversion")}
|
||||
disabled={isSubmitting || !!Object.keys(errors).length}
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,34 @@
|
|||
// @flow
|
||||
import React from "react";
|
||||
|
||||
type Props = {
|
||||
shapeShiftRate: ?number,
|
||||
originCoin: ?string,
|
||||
originCoinDepositFee: ?number,
|
||||
originCoinDepositMax: ?number,
|
||||
originCoinDepositMin: ?string,
|
||||
};
|
||||
|
||||
export default (props: Props) => {
|
||||
const {
|
||||
shapeShiftRate,
|
||||
originCoin,
|
||||
originCoinDepositFee,
|
||||
originCoinDepositMax,
|
||||
originCoinDepositMin,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<span className="help">
|
||||
{__("Receive")} {shapeShiftRate} LBC
|
||||
{" / "}
|
||||
{"1"} {originCoin} {__("less")} {originCoinDepositFee} LBC {__("fee")}.
|
||||
<br />
|
||||
{__("Exchange max")}: {originCoinDepositMax} {originCoin}
|
||||
<br />
|
||||
{__("Exchange min")}: {originCoinDepositMin} {originCoin}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
150
src/renderer/js/component/shapeShift/view.jsx
Normal file
150
src/renderer/js/component/shapeShift/view.jsx
Normal file
|
@ -0,0 +1,150 @@
|
|||
// @flow
|
||||
import * as React from "react";
|
||||
import { shell } from "electron";
|
||||
import { Formik } from "formik";
|
||||
import classnames from "classnames";
|
||||
import * as statuses from "constants/shape_shift";
|
||||
import { validateShapeShiftForm } from "util/shape_shift";
|
||||
import Link from "component/link";
|
||||
import Spinner from "component/common/spinner";
|
||||
import { BusyMessage } from "component/common";
|
||||
import ShapeShiftForm from "./internal/form";
|
||||
import ActiveShapeShift from "./internal/active-shift";
|
||||
|
||||
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() {
|
||||
const {
|
||||
shapeShiftInit,
|
||||
shapeShift: { hasActiveShift, shiftSupportedCoins },
|
||||
} = this.props;
|
||||
|
||||
if (!hasActiveShift && !shiftSupportedCoins.length) {
|
||||
// calls shapeshift to see list of supported coins for shifting
|
||||
shapeShiftInit();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
getCoinStats,
|
||||
receiveAddress,
|
||||
createShapeShift,
|
||||
shapeShift,
|
||||
clearShapeShift,
|
||||
getActiveShift,
|
||||
doShowSnackBar,
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
loading,
|
||||
updating,
|
||||
error,
|
||||
shiftSupportedCoins,
|
||||
hasActiveShift,
|
||||
originCoin,
|
||||
// ShapeShift response values
|
||||
originCoinDepositMax,
|
||||
originCoinDepositMin,
|
||||
originCoinDepositFee,
|
||||
shiftDepositAddress,
|
||||
shiftReturnAddress,
|
||||
shiftCoinType,
|
||||
shiftOrderId,
|
||||
shiftState,
|
||||
shapeShiftRate,
|
||||
} = shapeShift;
|
||||
|
||||
const initialFormValues: ShapeShiftFormValues = {
|
||||
receiveAddress,
|
||||
originCoin: "BTC",
|
||||
returnAddress: "",
|
||||
};
|
||||
|
||||
return (
|
||||
// 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
|
||||
// if the markup below changes for the initial render (form.jsx) there will be content jumping
|
||||
// the styling in shapeshift.scss will need to be updated to the correct min-height
|
||||
<section
|
||||
className={classnames("card shapeshift__wrapper", {
|
||||
"shapeshift__initial-wrapper": loading,
|
||||
})}
|
||||
>
|
||||
<div className="card__title-primary">
|
||||
<h3>{__("Convert Crypto to LBC")}</h3>
|
||||
<p className="help">
|
||||
{__("Powered by ShapeShift. Read our FAQ")}{" "}
|
||||
<Link href="https://lbry.io/faq/shapeshift">{__("here")}</Link>.
|
||||
{hasActiveShift &&
|
||||
shiftState !== "complete" && (
|
||||
<span>{__("This will update automatically.")}</span>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="card__content shapeshift__content">
|
||||
{error && <div className="form-field__error">{error}</div>}
|
||||
{loading && <Spinner dark />}
|
||||
{!loading &&
|
||||
!hasActiveShift &&
|
||||
!!shiftSupportedCoins.length && (
|
||||
<Formik
|
||||
onSubmit={createShapeShift}
|
||||
validate={validateShapeShiftForm}
|
||||
initialValues={initialFormValues}
|
||||
render={formProps => (
|
||||
<ShapeShiftForm
|
||||
{...formProps}
|
||||
updating={updating}
|
||||
originCoin={originCoin}
|
||||
shiftSupportedCoins={shiftSupportedCoins}
|
||||
getCoinStats={getCoinStats}
|
||||
receiveAddress={receiveAddress}
|
||||
originCoinDepositMax={originCoinDepositMax}
|
||||
originCoinDepositMin={originCoinDepositMin}
|
||||
originCoinDepositFee={originCoinDepositFee}
|
||||
shapeShiftRate={shapeShiftRate}
|
||||
updating={updating}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
{hasActiveShift && (
|
||||
<ActiveShapeShift
|
||||
getActiveShift={getActiveShift}
|
||||
shiftCoinType={shiftCoinType}
|
||||
shiftReturnAddress={shiftReturnAddress}
|
||||
shiftDepositAddress={shiftDepositAddress}
|
||||
originCoinDepositMax={originCoinDepositMax}
|
||||
shiftOrderId={shiftOrderId}
|
||||
shiftState={shiftState}
|
||||
clearShapeShift={clearShapeShift}
|
||||
doShowSnackBar={doShowSnackBar}
|
||||
originCoinDepositMax={originCoinDepositMax}
|
||||
originCoinDepositMin={originCoinDepositMin}
|
||||
originCoinDepositFee={originCoinDepositFee}
|
||||
shapeShiftRate={shapeShiftRate}
|
||||
updating={updating}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ShapeShift;
|
|
@ -1,9 +1,10 @@
|
|||
import React from "react";
|
||||
import Spinner from "component/common/spinner";
|
||||
|
||||
const LoadingScreen = ({ status, spinner = true }) => (
|
||||
<div className="video__loading-screen">
|
||||
<div>
|
||||
{spinner && <div className="video__loading-spinner" />}
|
||||
{spinner && <Spinner />}
|
||||
|
||||
<div className="video__loading-status">{status}</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from "react";
|
||||
import Link from "component/link";
|
||||
import { Address } from "component/common";
|
||||
import Address from "component/address";
|
||||
|
||||
class WalletAddress extends React.PureComponent {
|
||||
componentWillMount() {
|
||||
|
|
|
@ -144,3 +144,18 @@ export const FETCH_REWARD_CONTENT_COMPLETED = "FETCH_REWARD_CONTENT_COMPLETED";
|
|||
//Language
|
||||
export const DOWNLOAD_LANGUAGE_SUCCEEDED = "DOWNLOAD_LANGUAGE_SUCCEEDED";
|
||||
export const DOWNLOAD_LANGUAGE_FAILED = "DOWNLOAD_LANGUAGE_FAILED";
|
||||
|
||||
// ShapeShift
|
||||
export const GET_SUPPORTED_COINS_START = "GET_SUPPORTED_COINS_START";
|
||||
export const GET_SUPPORTED_COINS_SUCCESS = "GET_SUPPORTED_COINS_SUCCESS";
|
||||
export const GET_SUPPORTED_COINS_FAIL = "GET_SUPPORTED_COINS_FAIL";
|
||||
export const GET_COIN_STATS_START = "GET_COIN_STATS_START";
|
||||
export const GET_COIN_STATS_SUCCESS = "GET_COIN_STATS_SUCCESS";
|
||||
export const GET_COIN_STATS_FAIL = "GET_COIN_STATS_FAIL";
|
||||
export const PREPARE_SHAPE_SHIFT_START = "PREPARE_SHAPE_SHIFT_START";
|
||||
export const PREPARE_SHAPE_SHIFT_SUCCESS = "PREPARE_SHAPE_SHIFT_SUCCESS";
|
||||
export const PREPARE_SHAPE_SHIFT_FAIL = "PREPARE_SHAPE_SHIFT_FAIL";
|
||||
export const GET_ACTIVE_SHIFT_START = "GET_ACTIVE_SHIFT_START";
|
||||
export const GET_ACTIVE_SHIFT_SUCCESS = "GET_ACTIVE_SHIFT_SUCCESS";
|
||||
export const GET_ACTIVE_SHIFT_FAIL = "GET_ACTIVE_SHIFT_FAIL";
|
||||
export const CLEAR_SHAPE_SHIFT = "CLEAR_SHAPE_SHIFT";
|
||||
|
|
3
src/renderer/js/constants/shape_shift.js
Normal file
3
src/renderer/js/constants/shape_shift.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
export const NO_DEPOSITS = "no_deposits";
|
||||
export const RECEIVED = "received";
|
||||
export const COMPLETE = "complete";
|
|
@ -2,15 +2,17 @@ import React from "react";
|
|||
import SubHeader from "component/subHeader";
|
||||
import Link from "component/link";
|
||||
import WalletAddress from "component/walletAddress";
|
||||
import ShapeShift from "component/shapeShift";
|
||||
|
||||
const ReceiveCreditsPage = props => {
|
||||
return (
|
||||
<main className="main--single-column">
|
||||
<SubHeader />
|
||||
<WalletAddress />
|
||||
<ShapeShift />
|
||||
<section className="card">
|
||||
<div className="card__title-primary">
|
||||
<h3>{__("Where To Find Credits")}</h3>
|
||||
<h3>{__("More ways to get LBRY Credits")}</h3>
|
||||
</div>
|
||||
<div className="card__content">
|
||||
<p>
|
||||
|
|
137
src/renderer/js/redux/actions/shape_shift.js
Normal file
137
src/renderer/js/redux/actions/shape_shift.js
Normal file
|
@ -0,0 +1,137 @@
|
|||
// @flow
|
||||
import Promise from "bluebird";
|
||||
import * as types from "constants/action_types";
|
||||
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"));
|
||||
|
||||
// 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 });
|
||||
|
||||
return shapeShift
|
||||
.coinsAsync()
|
||||
.then(coinData => {
|
||||
let supportedCoins = [];
|
||||
Object.keys(coinData).forEach(symbol => {
|
||||
if (coinData[symbol].status === "available") {
|
||||
supportedCoins.push(coinData[symbol]);
|
||||
}
|
||||
});
|
||||
|
||||
// only use larger coins with client side validation
|
||||
supportedCoins = supportedCoins
|
||||
.filter(coin => coinRegexPatterns[coin.symbol])
|
||||
.map(coin => coin.symbol);
|
||||
|
||||
dispatch({
|
||||
type: types.GET_SUPPORTED_COINS_SUCCESS,
|
||||
data: supportedCoins,
|
||||
});
|
||||
dispatch(getCoinStats(supportedCoins[0]));
|
||||
})
|
||||
.catch(err =>
|
||||
dispatch({ type: types.GET_SUPPORTED_COINS_FAIL, data: err })
|
||||
);
|
||||
};
|
||||
|
||||
export const getCoinStats = (coin: string) => (
|
||||
dispatch: Dispatch
|
||||
): ThunkAction => {
|
||||
const pair = `${coin.toLowerCase()}_lbc`;
|
||||
|
||||
dispatch({ type: types.GET_COIN_STATS_START, data: coin });
|
||||
|
||||
return shapeShift
|
||||
.marketInfoAsync(pair)
|
||||
.then(marketInfo =>
|
||||
dispatch({ type: types.GET_COIN_STATS_SUCCESS, data: marketInfo })
|
||||
)
|
||||
.catch(err => dispatch({ type: types.GET_COIN_STATS_FAIL, data: err }));
|
||||
};
|
||||
|
||||
export const createShapeShift = (
|
||||
values: ShapeShiftFormValues,
|
||||
actions: FormikActions
|
||||
) => (dispatch: Dispatch): ThunkAction => {
|
||||
const {
|
||||
originCoin,
|
||||
returnAddress,
|
||||
receiveAddress: withdrawalAddress,
|
||||
} = values;
|
||||
|
||||
const pair = `${originCoin.toLowerCase()}_lbc`;
|
||||
const options = {
|
||||
returnAddress: returnAddress,
|
||||
};
|
||||
|
||||
dispatch({ type: types.PREPARE_SHAPE_SHIFT_START });
|
||||
return shapeShift
|
||||
.shiftAsync(withdrawalAddress, pair, options)
|
||||
.then(res =>
|
||||
dispatch({ type: types.PREPARE_SHAPE_SHIFT_SUCCESS, data: res })
|
||||
)
|
||||
.catch(err => {
|
||||
dispatch({ type: types.PREPARE_SHAPE_SHIFT_FAIL, data: err });
|
||||
// for formik to stop the submit
|
||||
actions.setSubmitting(false);
|
||||
});
|
||||
};
|
||||
|
||||
export const getActiveShift = (depositAddress: string) => (
|
||||
dispatch: Dispatch
|
||||
): ThunkAction => {
|
||||
dispatch({ type: types.GET_ACTIVE_SHIFT_START });
|
||||
|
||||
return shapeShift
|
||||
.statusAsync(depositAddress)
|
||||
.then(res => dispatch({ type: types.GET_ACTIVE_SHIFT_SUCCESS, data: res }))
|
||||
.catch(err => dispatch({ type: types.GET_ACTIVE_SHIFT_FAIL, data: err }));
|
||||
};
|
||||
|
||||
export const clearShapeShift = () => (dispatch: Dispatch): Action =>
|
||||
dispatch({ type: types.CLEAR_SHAPE_SHIFT });
|
245
src/renderer/js/redux/reducers/shape_shift.js
Normal file
245
src/renderer/js/redux/reducers/shape_shift.js
Normal file
|
@ -0,0 +1,245 @@
|
|||
// @flow
|
||||
import { handleActions } from "util/redux-utils";
|
||||
import * as actions from "constants/action_types";
|
||||
import * as statuses from "constants/shape_shift";
|
||||
|
||||
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,
|
||||
shapeShiftRate: ?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,
|
||||
rate: number,
|
||||
};
|
||||
|
||||
type ActiveShiftInfo = {
|
||||
deposit: string,
|
||||
depositType: string,
|
||||
returnAddress: string,
|
||||
orderId: string,
|
||||
};
|
||||
|
||||
type ShapeShiftErrorResponse = {
|
||||
message: string,
|
||||
};
|
||||
|
||||
const defaultState: ShapeShiftState = {
|
||||
loading: true,
|
||||
updating: false,
|
||||
shiftSupportedCoins: [],
|
||||
hasActiveShift: false,
|
||||
originCoin: undefined,
|
||||
error: undefined,
|
||||
shiftDepositAddress: undefined, // shapeshift address to send your coins to
|
||||
shiftReturnAddress: undefined,
|
||||
shiftCoinType: undefined,
|
||||
shiftOrderId: undefined,
|
||||
shiftState: undefined,
|
||||
originCoinDepositMax: undefined,
|
||||
originCoinDepositMin: undefined,
|
||||
originCoinDepositFee: undefined,
|
||||
shapeShiftRate: undefined,
|
||||
};
|
||||
|
||||
export default handleActions(
|
||||
{
|
||||
[actions.GET_SUPPORTED_COINS_START]: (
|
||||
state: ShapeShiftState
|
||||
): ShapeShiftState => ({
|
||||
...state,
|
||||
loading: true,
|
||||
error: undefined,
|
||||
}),
|
||||
[actions.GET_SUPPORTED_COINS_SUCCESS]: (
|
||||
state: ShapeShiftState,
|
||||
action: GetSupportedCoinsSuccess
|
||||
): ShapeShiftState => {
|
||||
const shiftSupportedCoins = action.data;
|
||||
return {
|
||||
...state,
|
||||
error: undefined,
|
||||
shiftSupportedCoins,
|
||||
};
|
||||
},
|
||||
[actions.GET_SUPPORTED_COINS_FAIL]: (
|
||||
state: ShapeShiftState
|
||||
): ShapeShiftState => ({
|
||||
...state,
|
||||
loading: false,
|
||||
error: "Error getting available coins",
|
||||
}),
|
||||
|
||||
[actions.GET_COIN_STATS_START]: (
|
||||
state: ShapeShiftState,
|
||||
action: GetCoinStatsStart
|
||||
): ShapeShiftState => {
|
||||
const coin = action.data;
|
||||
return {
|
||||
...state,
|
||||
updating: true,
|
||||
originCoin: coin,
|
||||
};
|
||||
},
|
||||
[actions.GET_COIN_STATS_SUCCESS]: (
|
||||
state: ShapeShiftState,
|
||||
action: GetCoinStatsSuccess
|
||||
): ShapeShiftState => {
|
||||
const marketInfo: ShapeShiftMarketInfo = action.data;
|
||||
|
||||
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,
|
||||
shapeShiftRate: marketInfo.rate,
|
||||
};
|
||||
},
|
||||
[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,
|
||||
}),
|
||||
[actions.PREPARE_SHAPE_SHIFT_SUCCESS]: (
|
||||
state: ShapeShiftState,
|
||||
action: PrepareShapeShiftSuccess
|
||||
) => {
|
||||
const activeShiftInfo: ActiveShiftInfo = action.data;
|
||||
return {
|
||||
...state,
|
||||
hasActiveShift: true,
|
||||
shiftDepositAddress: activeShiftInfo.deposit,
|
||||
shiftCoinType: activeShiftInfo.depositType,
|
||||
shiftReturnAddress: activeShiftInfo.returnAddress,
|
||||
shiftOrderId: activeShiftInfo.orderId,
|
||||
shiftState: statuses.NO_DEPOSITS,
|
||||
};
|
||||
},
|
||||
[actions.PREPARE_SHAPE_SHIFT_FAIL]: (
|
||||
state: ShapeShiftState,
|
||||
action: PrepareShapeShiftFail
|
||||
) => {
|
||||
const error: ShapeShiftErrorResponse = action.data;
|
||||
return {
|
||||
...state,
|
||||
error: error.message,
|
||||
};
|
||||
},
|
||||
|
||||
[actions.CLEAR_SHAPE_SHIFT]: (state: ShapeShiftState): ShapeShiftState => ({
|
||||
...state,
|
||||
loading: false,
|
||||
updating: false,
|
||||
hasActiveShift: false,
|
||||
shiftDepositAddress: undefined,
|
||||
shiftReturnAddress: undefined,
|
||||
shiftCoinType: undefined,
|
||||
shiftOrderId: undefined,
|
||||
originCoin: state.shiftSupportedCoins[0],
|
||||
}),
|
||||
|
||||
[actions.GET_ACTIVE_SHIFT_START]: (
|
||||
state: ShapeShiftState
|
||||
): ShapeShiftState => ({
|
||||
...state,
|
||||
error: undefined,
|
||||
updating: true,
|
||||
}),
|
||||
[actions.GET_ACTIVE_SHIFT_SUCCESS]: (
|
||||
state: ShapeShiftState,
|
||||
action: GetActiveShiftSuccess
|
||||
): ShapeShiftState => {
|
||||
const status = action.data;
|
||||
return {
|
||||
...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
|
||||
);
|
|
@ -44,8 +44,8 @@ export const selectHeaderLinks = createSelector(selectCurrentPage, page => {
|
|||
return {
|
||||
wallet: __("Overview"),
|
||||
history: __("History"),
|
||||
send: __("Send"),
|
||||
receive: __("Receive"),
|
||||
send: __("Send Credits"),
|
||||
receive: __("Get Credits"),
|
||||
rewards: __("Rewards"),
|
||||
invite: __("Invites"),
|
||||
};
|
||||
|
@ -78,9 +78,9 @@ export const selectPageTitle = createSelector(
|
|||
case "wallet":
|
||||
return __("Wallet");
|
||||
case "send":
|
||||
return __("Send Credits");
|
||||
return __("Send LBRY Credits");
|
||||
case "receive":
|
||||
return __("Wallet Address");
|
||||
return __("Get LBRY Credits");
|
||||
case "backup":
|
||||
return __("Backup Your Wallet");
|
||||
case "rewards":
|
||||
|
|
|
@ -65,7 +65,7 @@ export const selectWunderBarIcon = createSelector(
|
|||
return "icon-envelope-open";
|
||||
case "address":
|
||||
case "receive":
|
||||
return "icon-address-book";
|
||||
return "icon-credit-card";
|
||||
case "wallet":
|
||||
case "backup":
|
||||
return "icon-bank";
|
||||
|
|
7
src/renderer/js/redux/selectors/shape_shift.js
Normal file
7
src/renderer/js/redux/selectors/shape_shift.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { createSelector } from "reselect";
|
||||
|
||||
const _selectState = state => state.shapeShift;
|
||||
|
||||
export const selectShapeShift = createSelector(_selectState, state => ({
|
||||
...state,
|
||||
}));
|
|
@ -11,6 +11,7 @@ import searchReducer from "redux/reducers/search";
|
|||
import settingsReducer from "redux/reducers/settings";
|
||||
import userReducer from "redux/reducers/user";
|
||||
import walletReducer from "redux/reducers/wallet";
|
||||
import shapeShiftReducer from "redux/reducers/shape_shift";
|
||||
import { persistStore, autoRehydrate } from "redux-persist";
|
||||
import createCompressor from "redux-persist-transform-compress";
|
||||
import createFilter from "redux-persist-transform-filter";
|
||||
|
@ -67,6 +68,7 @@ const reducers = redux.combineReducers({
|
|||
settings: settingsReducer,
|
||||
wallet: walletReducer,
|
||||
user: userReducer,
|
||||
shapeShift: shapeShiftReducer,
|
||||
});
|
||||
|
||||
const bulkThunk = createBulkThunkMiddleware();
|
||||
|
|
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
|
||||
// based off of redux-actions
|
||||
// https://redux-actions.js.org/docs/api/handleAction.html#handleactions
|
||||
|
||||
export const handleActions = (actionMap, defaultState) => {
|
||||
return (state = defaultState, action) => {
|
||||
const handler = actionMap[action.type];
|
||||
|
|
50
src/renderer/js/util/shape_shift.js
Normal file
50
src/renderer/js/util/shape_shift.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
// these don't need to be exact
|
||||
// shapeshift does a more thourough check on validity
|
||||
// just general matches to prevent unneccesary api calls
|
||||
export const coinRegexPatterns = {
|
||||
BTC: /^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$/,
|
||||
BCH: /^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$/,
|
||||
ETH: /^(0x)?[0-9a-fA-F]{40}$/,
|
||||
DASH: /^X([0-9a-zA-Z]){33}/,
|
||||
LTC: /^L[a-zA-Z0-9]{26,33}$/,
|
||||
XMR: /^4[0-9ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{94}$/,
|
||||
};
|
||||
|
||||
const validateAddress = (coinType, address) => {
|
||||
if (!coinType || !address) return false;
|
||||
|
||||
const coinRegex = coinRegexPatterns[coinType.toUpperCase()];
|
||||
if (!coinRegex) return false;
|
||||
|
||||
return coinRegex.test(address);
|
||||
};
|
||||
|
||||
export const validateShapeShiftForm = (vals, props) => {
|
||||
let errors = {};
|
||||
|
||||
if (!vals.returnAddress) {
|
||||
return errors;
|
||||
}
|
||||
|
||||
const isValidAddress = validateAddress(vals.originCoin, vals.returnAddress);
|
||||
|
||||
if (!isValidAddress) {
|
||||
errors.returnAddress = `Enter a valid ${vals.originCoin} address`;
|
||||
}
|
||||
|
||||
return errors;
|
||||
};
|
||||
|
||||
const exampleCoinAddresses = {
|
||||
BTC: "1745oPaHeW7Fmpb1fUKTtasYfxr4zu9bwq",
|
||||
BCH: "1745oPaHeW7Fmpb1fUKTtasYfxr4zu9bwq",
|
||||
ETH: "0x8507cA6a274123fC8f80d929AF9D83602bC4e8cC",
|
||||
DASH: "XedBP7vLPFXbS3URjrH2Z57Fg9SWftBmQ6",
|
||||
LTC: "LgZivMvFMTDoqcA5weCQ2QrmRp7pa56bBk",
|
||||
XMR:
|
||||
"466XMeJEcowYGx7RzUJj3VDWBZgRWErVQQX6tHYbsacS5QF6v3tidE6LZZnTJgzeEh6bKEEJ6GC9jHirrUKvJwVKVj9e7jm",
|
||||
};
|
||||
|
||||
export const getExampleAddress = coin => {
|
||||
return exampleCoinAddresses[coin];
|
||||
};
|
|
@ -22,10 +22,14 @@
|
|||
},
|
||||
"homepage": "https://github.com/lbryio/lbry-app",
|
||||
"dependencies": {
|
||||
"bluebird": "^3.5.1",
|
||||
"classnames": "^2.2.5",
|
||||
"formik": "^0.10.4",
|
||||
"from2": "^2.3.0",
|
||||
"jshashes": "^1.0.7",
|
||||
"localforage": "^1.5.0",
|
||||
"node-sass": "^4.5.3",
|
||||
"qrcode.react": "^0.7.2",
|
||||
"rc-progress": "^2.0.6",
|
||||
"react": "^16.2.0",
|
||||
"react-dom": "^16.2.0",
|
||||
|
@ -43,6 +47,7 @@
|
|||
"redux-thunk": "^2.2.0",
|
||||
"render-media": "^2.10.0",
|
||||
"reselect": "^3.0.0",
|
||||
"shapeshift.io": "^1.3.1",
|
||||
"y18n": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -34,6 +34,11 @@ body
|
|||
color: var(--color-meta-light);
|
||||
}
|
||||
|
||||
.credit-amount--bold
|
||||
{
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
#main-content
|
||||
{
|
||||
margin: auto;
|
||||
|
|
|
@ -26,4 +26,6 @@
|
|||
@import "component/_divider.scss";
|
||||
@import "component/_checkbox.scss";
|
||||
@import "component/_radio.scss";
|
||||
@import "component/_shapeshift.scss";
|
||||
@import "component/_spinner.scss";
|
||||
@import "page/_show.scss";
|
||||
|
|
|
@ -98,4 +98,4 @@ $button-focus-shift: 12%;
|
|||
.button--submit {
|
||||
font-family: inherit;
|
||||
line-height: 0;
|
||||
}
|
||||
}
|
|
@ -26,6 +26,7 @@
|
|||
.card__actions {
|
||||
padding: 0 var(--card-padding);
|
||||
}
|
||||
|
||||
.card--small {
|
||||
.card__title-primary,
|
||||
.card__title-identity,
|
||||
|
@ -50,7 +51,7 @@
|
|||
.card__actions {
|
||||
margin-top: var(--card-margin);
|
||||
margin-bottom: var(--card-margin);
|
||||
user-select: none;
|
||||
user-select: none;
|
||||
|
||||
}
|
||||
.card__actions--bottom {
|
||||
|
@ -72,6 +73,18 @@
|
|||
margin-bottom: var(--card-margin);
|
||||
}
|
||||
}
|
||||
|
||||
.card__actions--only-vertical {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.card__content--extra-vertical-space {
|
||||
margin: $spacing-vertical 0;
|
||||
}
|
||||
|
||||
$font-size-subtext-multiple: 0.82;
|
||||
.card__subtext {
|
||||
color: var(--color-meta-light);
|
||||
|
|
|
@ -56,6 +56,11 @@
|
|||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
width: 100%;
|
||||
font-family: "Consolas", "Lucida Console", "Adobe Source Code Pro", monospace;
|
||||
|
||||
&.input-copyable--with-copy-btn {
|
||||
width: 85%;
|
||||
}
|
||||
}
|
||||
|
||||
input[readonly] {
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
|
||||
.wunderbar--active .icon-search { color: var(--color-primary); }
|
||||
|
||||
// below styles should be inside the common input styling
|
||||
// will come back to this with the redesign - sean
|
||||
.wunderbar__input {
|
||||
background: var(--search-bg);
|
||||
width: 100%;
|
||||
|
|
40
src/renderer/scss/component/_shapeshift.scss
Normal file
40
src/renderer/scss/component/_shapeshift.scss
Normal file
|
@ -0,0 +1,40 @@
|
|||
// Can't think of a better way to do this
|
||||
// The initial shapeshift form is 311px tall
|
||||
// the .shapeshift__initial-wrapper class is only added when the form is being loaded
|
||||
// Once the form is rendered, there is a very smooth transition because the height doesn't change
|
||||
.shapeshift__wrapper.shapeshift__initial-wrapper {
|
||||
min-height: 346px;
|
||||
}
|
||||
|
||||
.shapeshift__content {
|
||||
.spinner {
|
||||
margin-top: $spacing-vertical * 3;
|
||||
}
|
||||
}
|
||||
|
||||
.shapeshift__tx-info {
|
||||
min-height: 55px;
|
||||
}
|
||||
|
||||
.shapeshift__deposit-address-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
* {
|
||||
align-self: center;
|
||||
}
|
||||
}
|
||||
|
||||
// this should be pulled out into it's own styling when we add more qr codes
|
||||
.shapeshift__qrcode {
|
||||
// don't use a variable here. adds a white border for easier reading in dark mode
|
||||
// needs to stay the same no matter what theme is present
|
||||
background-color: #fff;
|
||||
padding: 2px;
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
|
||||
.shapeshift__link {
|
||||
padding-left: 10px;
|
||||
}
|
58
src/renderer/scss/component/_spinner.scss
Normal file
58
src/renderer/scss/component/_spinner.scss
Normal file
|
@ -0,0 +1,58 @@
|
|||
.spinner {
|
||||
position: relative;
|
||||
width: 11em;
|
||||
height: 11em;
|
||||
margin: 20px auto;
|
||||
font-size: 3px;
|
||||
border-radius: 50%;
|
||||
|
||||
background: linear-gradient(to right, #fff 10%, rgba(255, 255, 255, 0) 50%);
|
||||
animation: spin 1.4s infinite linear;
|
||||
transform: translateZ(0);
|
||||
|
||||
@keyframes spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
&:before {
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
background: #fff;
|
||||
border-radius: 100% 0 0 0;
|
||||
}
|
||||
|
||||
&:after {
|
||||
height: 75%;
|
||||
width: 75%;
|
||||
margin: auto;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: #000;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.spinner.spinner--dark {
|
||||
background: linear-gradient(to right, var(--button-primary-bg) 10%, var(--color-bg) 50%);
|
||||
|
||||
&:before {
|
||||
background: var(--button-primary-bg);
|
||||
}
|
||||
|
||||
&:after {
|
||||
background: var(--color-bg);
|
||||
}
|
||||
}
|
|
@ -46,53 +46,6 @@ video {
|
|||
align-items: center;
|
||||
}
|
||||
|
||||
.video__loading-spinner {
|
||||
position: relative;
|
||||
width: 11em;
|
||||
height: 11em;
|
||||
margin: 20px auto;
|
||||
font-size: 3px;
|
||||
border-radius: 50%;
|
||||
|
||||
background: linear-gradient(to right, #ffffff 10%, rgba(255, 255, 255, 0) 50%);
|
||||
animation: spin 1.4s infinite linear;
|
||||
transform: translateZ(0);
|
||||
|
||||
@keyframes spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
&:before {
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
background: #ffffff;
|
||||
border-radius: 100% 0 0 0;
|
||||
}
|
||||
|
||||
&:after {
|
||||
height: 75%;
|
||||
width: 75%;
|
||||
margin: auto;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: black;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.video__loading-status {
|
||||
padding-top: 20px;
|
||||
color: white;
|
||||
|
|
|
@ -18,7 +18,7 @@ module.exports = {
|
|||
},
|
||||
resolve: {
|
||||
modules: [appPath, "node_modules"],
|
||||
extensions: [".js", ".jsx", ".css"]
|
||||
extensions: [".js", ".jsx", ".css", ".json"]
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
|
|
|
@ -56,9 +56,9 @@ ajv@^4.7.0, ajv@^4.9.1:
|
|||
co "^4.6.0"
|
||||
json-stable-stringify "^1.0.1"
|
||||
|
||||
ajv@^5.0.0, ajv@^5.1.5, ajv@^5.2.3:
|
||||
version "5.4.0"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.4.0.tgz#32d1cf08dbc80c432f426f12e10b2511f6b46474"
|
||||
ajv@^5.0.0, ajv@^5.1.0, ajv@^5.1.5, ajv@^5.2.3:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.0.tgz#eb2840746e9dc48bd5e063a36e3fd400c5eab5a9"
|
||||
dependencies:
|
||||
co "^4.6.0"
|
||||
fast-deep-equal "^1.0.0"
|
||||
|
@ -276,7 +276,11 @@ aws-sign2@~0.6.0:
|
|||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f"
|
||||
|
||||
aws4@^1.2.1:
|
||||
aws-sign2@~0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
|
||||
|
||||
aws4@^1.2.1, aws4@^1.6.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
|
||||
|
||||
|
@ -997,6 +1001,10 @@ block-stream@*:
|
|||
dependencies:
|
||||
inherits "~2.0.0"
|
||||
|
||||
bluebird@^3.5.1:
|
||||
version "3.5.1"
|
||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
|
||||
|
||||
bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0:
|
||||
version "4.11.8"
|
||||
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
|
||||
|
@ -1033,6 +1041,18 @@ boom@2.x.x:
|
|||
dependencies:
|
||||
hoek "2.x.x"
|
||||
|
||||
boom@4.x.x:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31"
|
||||
dependencies:
|
||||
hoek "4.x.x"
|
||||
|
||||
boom@5.x.x:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02"
|
||||
dependencies:
|
||||
hoek "4.x.x"
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.8"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
|
||||
|
@ -1198,8 +1218,8 @@ caniuse-api@^1.5.2:
|
|||
lodash.uniq "^4.5.0"
|
||||
|
||||
caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
|
||||
version "1.0.30000769"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000769.tgz#c230b9c1b9e8db3e1c0d858c96e685741b96cc10"
|
||||
version "1.0.30000775"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000775.tgz#04bccdd0214edf25b97f61a096609f7ad6904333"
|
||||
|
||||
cardinal@^1.0.0:
|
||||
version "1.0.0"
|
||||
|
@ -1376,8 +1396,8 @@ codemirror-spell-checker@*:
|
|||
typo-js "*"
|
||||
|
||||
codemirror@*:
|
||||
version "5.31.0"
|
||||
resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.31.0.tgz#ecf3d057eb74174147066bfc7c5f37b4c4e07df2"
|
||||
version "5.32.0"
|
||||
resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.32.0.tgz#cb6ff5d8ef36d0b10f031130e2d9ebeee92c902e"
|
||||
|
||||
color-convert@^1.3.0, color-convert@^1.9.0:
|
||||
version "1.9.1"
|
||||
|
@ -1426,8 +1446,8 @@ combined-stream@^1.0.5, combined-stream@~1.0.5:
|
|||
delayed-stream "~1.0.0"
|
||||
|
||||
commander@^2.11.0, commander@^2.5.0, commander@^2.9.0:
|
||||
version "2.11.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563"
|
||||
version "2.12.2"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555"
|
||||
|
||||
commondir@^1.0.1:
|
||||
version "1.0.1"
|
||||
|
@ -1525,8 +1545,8 @@ content-type@~1.0.4:
|
|||
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
|
||||
|
||||
convert-source-map@^1.5.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5"
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5"
|
||||
|
||||
cookie-signature@1.0.6:
|
||||
version "1.0.6"
|
||||
|
@ -1613,6 +1633,12 @@ cryptiles@2.x.x:
|
|||
dependencies:
|
||||
boom "2.x.x"
|
||||
|
||||
cryptiles@3.x.x:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe"
|
||||
dependencies:
|
||||
boom "5.x.x"
|
||||
|
||||
crypto-browserify@3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.3.0.tgz#b9fc75bb4a0ed61dcf1cd5dae96eb30c9c3e506c"
|
||||
|
@ -1849,18 +1875,18 @@ detect-indent@^4.0.0:
|
|||
repeating "^2.0.0"
|
||||
|
||||
detect-libc@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.2.tgz#71ad5d204bf17a6a6ca8f450c61454066ef461e1"
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
|
||||
|
||||
detect-node@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.3.tgz#a2033c09cc8e158d37748fbde7507832bd6ce127"
|
||||
|
||||
detective@^4.3.1:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/detective/-/detective-4.5.0.tgz#6e5a8c6b26e6c7a254b1c6b6d7490d98ec91edd1"
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/detective/-/detective-4.6.0.tgz#d1a793ad0bcc829fa225465061096b7bca040527"
|
||||
dependencies:
|
||||
acorn "^4.0.3"
|
||||
acorn "^5.2.1"
|
||||
defined "^1.0.0"
|
||||
|
||||
diffie-hellman@^5.0.0:
|
||||
|
@ -1896,11 +1922,14 @@ doctrine@1.5.0, doctrine@^1.2.2:
|
|||
isarray "^1.0.0"
|
||||
|
||||
doctrine@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63"
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.2.tgz#68f96ce8efc56cc42651f1faadb4f175273b0075"
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
isarray "^1.0.0"
|
||||
|
||||
dom-walk@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018"
|
||||
|
||||
domain-browser@^1.1.1:
|
||||
version "1.1.7"
|
||||
|
@ -2015,8 +2044,8 @@ error-ex@^1.2.0:
|
|||
is-arrayish "^0.2.1"
|
||||
|
||||
es-abstract@^1.7.0:
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.9.0.tgz#690829a07cae36b222e7fd9b75c0d0573eb25227"
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864"
|
||||
dependencies:
|
||||
es-to-primitive "^1.1.1"
|
||||
function-bind "^1.1.1"
|
||||
|
@ -2041,8 +2070,8 @@ es3ify@^0.1.3:
|
|||
through "~2.3.4"
|
||||
|
||||
es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14:
|
||||
version "0.10.35"
|
||||
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.35.tgz#18ee858ce6a3c45c7d79e91c15fcca9ec568494f"
|
||||
version "0.10.37"
|
||||
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.37.tgz#0ee741d148b80069ba27d020393756af257defc3"
|
||||
dependencies:
|
||||
es6-iterator "~2.0.1"
|
||||
es6-symbol "~3.1.1"
|
||||
|
@ -2340,7 +2369,7 @@ expand-range@^1.8.1:
|
|||
dependencies:
|
||||
fill-range "^2.1.0"
|
||||
|
||||
express@^4.13.3:
|
||||
express@^4.16.2:
|
||||
version "4.16.2"
|
||||
resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c"
|
||||
dependencies:
|
||||
|
@ -2375,7 +2404,7 @@ express@^4.13.3:
|
|||
utils-merge "1.0.1"
|
||||
vary "~1.1.2"
|
||||
|
||||
extend@~3.0.0:
|
||||
extend@~3.0.0, extend@~3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
|
||||
|
||||
|
@ -2385,10 +2414,14 @@ extglob@^0.3.1:
|
|||
dependencies:
|
||||
is-extglob "^1.0.0"
|
||||
|
||||
extsprintf@1.3.0, extsprintf@^1.2.0:
|
||||
extsprintf@1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
|
||||
|
||||
extsprintf@^1.2.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
|
||||
|
||||
falafel@^1.0.1:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/falafel/-/falafel-1.2.0.tgz#c18d24ef5091174a497f318cd24b026a25cddab4"
|
||||
|
@ -2567,6 +2600,12 @@ flow-typed@^2.2.3:
|
|||
which "^1.2.14"
|
||||
yargs "^4.2.0"
|
||||
|
||||
for-each@^0.3.2:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.2.tgz#2c40450b9348e97f281322593ba96704b9abd4d4"
|
||||
dependencies:
|
||||
is-function "~1.0.0"
|
||||
|
||||
for-in@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
|
||||
|
@ -2593,6 +2632,22 @@ form-data@~2.1.1:
|
|||
combined-stream "^1.0.5"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
form-data@~2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf"
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
combined-stream "^1.0.5"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
formik@^0.10.4:
|
||||
version "0.10.5"
|
||||
resolved "https://registry.yarnpkg.com/formik/-/formik-0.10.5.tgz#6984d2f22e918c6d2264a3cb86b8582f7277faca"
|
||||
dependencies:
|
||||
lodash.isequal "4.5.0"
|
||||
prop-types "^15.5.10"
|
||||
warning "^3.0.0"
|
||||
|
||||
forwarded@~0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
|
||||
|
@ -2773,6 +2828,13 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1:
|
|||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
global@~4.3.0:
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f"
|
||||
dependencies:
|
||||
min-document "^2.19.0"
|
||||
process "~0.5.1"
|
||||
|
||||
globals@^9.14.0, globals@^9.18.0:
|
||||
version "9.18.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
|
||||
|
@ -2847,6 +2909,10 @@ har-schema@^1.0.5:
|
|||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e"
|
||||
|
||||
har-schema@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
|
||||
|
||||
har-validator@~2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d"
|
||||
|
@ -2863,6 +2929,13 @@ har-validator@~4.2.1:
|
|||
ajv "^4.9.1"
|
||||
har-schema "^1.0.5"
|
||||
|
||||
har-validator@~5.0.3:
|
||||
version "5.0.3"
|
||||
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd"
|
||||
dependencies:
|
||||
ajv "^5.1.0"
|
||||
har-schema "^2.0.0"
|
||||
|
||||
has-ansi@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
|
||||
|
@ -2926,6 +2999,15 @@ hawk@3.1.3, hawk@~3.1.3:
|
|||
hoek "2.x.x"
|
||||
sntp "1.x.x"
|
||||
|
||||
hawk@~6.0.2:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038"
|
||||
dependencies:
|
||||
boom "4.x.x"
|
||||
cryptiles "3.x.x"
|
||||
hoek "4.x.x"
|
||||
sntp "2.x.x"
|
||||
|
||||
hmac-drbg@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
|
||||
|
@ -2938,6 +3020,10 @@ hoek@2.x.x:
|
|||
version "2.16.3"
|
||||
resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
|
||||
|
||||
hoek@4.x.x:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d"
|
||||
|
||||
hoist-non-react-statics@^2.2.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz#343db84c6018c650778898240135a1420ee22ce0"
|
||||
|
@ -3011,6 +3097,14 @@ http-signature@~1.1.0:
|
|||
jsprim "^1.2.2"
|
||||
sshpk "^1.7.0"
|
||||
|
||||
http-signature@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
jsprim "^1.2.2"
|
||||
sshpk "^1.7.0"
|
||||
|
||||
https-browserify@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82"
|
||||
|
@ -3151,8 +3245,8 @@ interpret@^0.6.4:
|
|||
resolved "https://registry.yarnpkg.com/interpret/-/interpret-0.6.6.tgz#fecd7a18e7ce5ca6abfb953e1f86213a49f1625b"
|
||||
|
||||
interpret@^1.0.0:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.4.tgz#820cdd588b868ffb191a809506d6c9c8f212b1b0"
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
|
||||
|
||||
invariant@^2.0.0, invariant@^2.2.2:
|
||||
version "2.2.2"
|
||||
|
@ -3252,6 +3346,10 @@ is-fullwidth-code-point@^2.0.0:
|
|||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
|
||||
|
||||
is-function@^1.0.1, is-function@~1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5"
|
||||
|
||||
is-glob@^2.0.0, is-glob@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863"
|
||||
|
@ -3300,8 +3398,8 @@ is-path-in-cwd@^1.0.0:
|
|||
is-path-inside "^1.0.0"
|
||||
|
||||
is-path-inside@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f"
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036"
|
||||
dependencies:
|
||||
path-is-inside "^1.0.1"
|
||||
|
||||
|
@ -3404,8 +3502,8 @@ isurl@^1.0.0-alpha5:
|
|||
is-object "^1.0.1"
|
||||
|
||||
js-base64@^2.1.8, js-base64@^2.1.9:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.3.2.tgz#a79a923666372b580f8e27f51845c6f7e8fbfbaf"
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.0.tgz#9e566fee624751a1d720c966cd6226d29d4025aa"
|
||||
|
||||
js-tokens@^3.0.0, js-tokens@^3.0.2:
|
||||
version "3.0.2"
|
||||
|
@ -3673,8 +3771,8 @@ loader-utils@^1.0.2, loader-utils@^1.1.0:
|
|||
json5 "^0.5.0"
|
||||
|
||||
localforage@^1.5.0:
|
||||
version "1.5.3"
|
||||
resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.5.3.tgz#698aa16af1022340b240be9d93192e8af022ff16"
|
||||
version "1.5.5"
|
||||
resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.5.5.tgz#55fc1c3a88a47f67f5fac6f1231b25ff13556423"
|
||||
dependencies:
|
||||
lie "3.0.2"
|
||||
|
||||
|
@ -3778,6 +3876,10 @@ lodash.isempty@^4.4.0:
|
|||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e"
|
||||
|
||||
lodash.isequal@4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
||||
|
||||
lodash.isplainobject@^4.0.6:
|
||||
version "4.0.6"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
|
||||
|
@ -4017,7 +4119,11 @@ miller-rabin@^4.0.0:
|
|||
bn.js "^4.0.0"
|
||||
brorand "^1.0.1"
|
||||
|
||||
"mime-db@>= 1.30.0 < 2", mime-db@~1.30.0:
|
||||
"mime-db@>= 1.30.0 < 2":
|
||||
version "1.32.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.32.0.tgz#485b3848b01a3cda5f968b4882c0771e58e09414"
|
||||
|
||||
mime-db@~1.30.0:
|
||||
version "1.30.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01"
|
||||
|
||||
|
@ -4027,10 +4133,14 @@ mime-types@^2.1.12, mime-types@~2.1.15, mime-types@~2.1.16, mime-types@~2.1.17,
|
|||
dependencies:
|
||||
mime-db "~1.30.0"
|
||||
|
||||
mime@1.4.1, mime@^1.2.11, mime@^1.3.4:
|
||||
mime@1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6"
|
||||
|
||||
mime@^1.2.11, mime@^1.5.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
||||
|
||||
mimic-fn@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18"
|
||||
|
@ -4039,6 +4149,12 @@ mimic-response@^1.0.0:
|
|||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e"
|
||||
|
||||
min-document@^2.19.0:
|
||||
version "2.19.0"
|
||||
resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
|
||||
dependencies:
|
||||
dom-walk "^0.1.0"
|
||||
|
||||
minimalistic-assert@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3"
|
||||
|
@ -4053,7 +4169,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1:
|
|||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimist@0.0.8, minimist@~0.0.1:
|
||||
minimist@0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
|
||||
|
||||
|
@ -4061,6 +4177,10 @@ minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0:
|
|||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
|
||||
|
||||
minimist@~0.0.1:
|
||||
version "0.0.10"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
|
||||
|
||||
mkdirp@0.5, mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
|
||||
|
@ -4091,8 +4211,8 @@ multicast-dns-service-types@^1.1.0:
|
|||
resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901"
|
||||
|
||||
multicast-dns@^6.0.1:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.0.tgz#13f22d0c32dc5ee82a32878e3c380d875b3eab22"
|
||||
version "6.2.1"
|
||||
resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.1.tgz#c5035defa9219d30640558a49298067352098060"
|
||||
dependencies:
|
||||
dns-packet "^1.0.1"
|
||||
thunky "^0.1.0"
|
||||
|
@ -4363,7 +4483,7 @@ number-is-nan@^1.0.0:
|
|||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
|
||||
|
||||
oauth-sign@~0.8.1:
|
||||
oauth-sign@~0.8.1, oauth-sign@~0.8.2:
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
|
||||
|
||||
|
@ -4580,6 +4700,13 @@ parse-glob@^3.0.4:
|
|||
is-extglob "^1.0.0"
|
||||
is-glob "^2.0.0"
|
||||
|
||||
parse-headers@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.1.tgz#6ae83a7aa25a9d9b700acc28698cd1f1ed7e9536"
|
||||
dependencies:
|
||||
for-each "^0.3.2"
|
||||
trim "0.0.1"
|
||||
|
||||
parse-json@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
|
||||
|
@ -4660,6 +4787,10 @@ performance-now@^0.2.0:
|
|||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
|
||||
|
||||
performance-now@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
||||
|
||||
pify@^2.0.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
|
||||
|
@ -4976,6 +5107,10 @@ process@^0.11.0, process@^0.11.10:
|
|||
version "0.11.10"
|
||||
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
|
||||
|
||||
process@~0.5.1:
|
||||
version "0.5.2"
|
||||
resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf"
|
||||
|
||||
progress@^1.1.8:
|
||||
version "1.1.8"
|
||||
resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be"
|
||||
|
@ -5047,7 +5182,18 @@ q@^1.1.2:
|
|||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
|
||||
|
||||
qs@6.5.1:
|
||||
qr.js@0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/qr.js/-/qr.js-0.0.0.tgz#cace86386f59a0db8050fa90d9b6b0e88a1e364f"
|
||||
|
||||
qrcode.react@^0.7.2:
|
||||
version "0.7.2"
|
||||
resolved "https://registry.yarnpkg.com/qrcode.react/-/qrcode.react-0.7.2.tgz#72a5718fd56baafe15c2c153fe436628d83aa286"
|
||||
dependencies:
|
||||
prop-types "^15.5.8"
|
||||
qr.js "0.0.0"
|
||||
|
||||
qs@6.5.1, qs@~6.5.1:
|
||||
version "6.5.1"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
|
||||
|
||||
|
@ -5123,8 +5269,8 @@ raw-body@2.3.2:
|
|||
unpipe "1.0.0"
|
||||
|
||||
rc-progress@^2.0.6:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/rc-progress/-/rc-progress-2.2.4.tgz#45dbdb91cdd71cb5ce22e61313a351ceb5b1488a"
|
||||
version "2.2.5"
|
||||
resolved "https://registry.yarnpkg.com/rc-progress/-/rc-progress-2.2.5.tgz#e61d0544bf9d4208e5ba32fc50962159e7f952a3"
|
||||
dependencies:
|
||||
babel-runtime "6.x"
|
||||
prop-types "^15.5.8"
|
||||
|
@ -5164,11 +5310,12 @@ react-markdown@^2.5.0:
|
|||
prop-types "^15.5.1"
|
||||
|
||||
react-modal@^3.1.5:
|
||||
version "3.1.5"
|
||||
resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.1.5.tgz#9cfdb7634b5003148ffb7c8ead13a36f671d744e"
|
||||
version "3.1.6"
|
||||
resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.1.6.tgz#82e63f1ec86b80e242518250d066ee37fa035f8a"
|
||||
dependencies:
|
||||
exenv "^1.2.0"
|
||||
prop-types "^15.5.10"
|
||||
warning "^3.0.0"
|
||||
|
||||
react-paginate@^5.0.0:
|
||||
version "5.0.0"
|
||||
|
@ -5460,32 +5607,34 @@ repeating@^2.0.0:
|
|||
dependencies:
|
||||
is-finite "^1.0.0"
|
||||
|
||||
request@2, request@~2.79.0:
|
||||
version "2.79.0"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de"
|
||||
request@2, request@^2.55.0, request@^2.81.0:
|
||||
version "2.83.0"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356"
|
||||
dependencies:
|
||||
aws-sign2 "~0.6.0"
|
||||
aws4 "^1.2.1"
|
||||
caseless "~0.11.0"
|
||||
aws-sign2 "~0.7.0"
|
||||
aws4 "^1.6.0"
|
||||
caseless "~0.12.0"
|
||||
combined-stream "~1.0.5"
|
||||
extend "~3.0.0"
|
||||
extend "~3.0.1"
|
||||
forever-agent "~0.6.1"
|
||||
form-data "~2.1.1"
|
||||
har-validator "~2.0.6"
|
||||
hawk "~3.1.3"
|
||||
http-signature "~1.1.0"
|
||||
form-data "~2.3.1"
|
||||
har-validator "~5.0.3"
|
||||
hawk "~6.0.2"
|
||||
http-signature "~1.2.0"
|
||||
is-typedarray "~1.0.0"
|
||||
isstream "~0.1.2"
|
||||
json-stringify-safe "~5.0.1"
|
||||
mime-types "~2.1.7"
|
||||
oauth-sign "~0.8.1"
|
||||
qs "~6.3.0"
|
||||
stringstream "~0.0.4"
|
||||
tough-cookie "~2.3.0"
|
||||
tunnel-agent "~0.4.1"
|
||||
uuid "^3.0.0"
|
||||
mime-types "~2.1.17"
|
||||
oauth-sign "~0.8.2"
|
||||
performance-now "^2.1.0"
|
||||
qs "~6.5.1"
|
||||
safe-buffer "^5.1.1"
|
||||
stringstream "~0.0.5"
|
||||
tough-cookie "~2.3.3"
|
||||
tunnel-agent "^0.6.0"
|
||||
uuid "^3.1.0"
|
||||
|
||||
request@2.81.0, request@^2.81.0:
|
||||
request@2.81.0:
|
||||
version "2.81.0"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0"
|
||||
dependencies:
|
||||
|
@ -5512,6 +5661,31 @@ request@2.81.0, request@^2.81.0:
|
|||
tunnel-agent "^0.6.0"
|
||||
uuid "^3.0.0"
|
||||
|
||||
request@~2.79.0:
|
||||
version "2.79.0"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de"
|
||||
dependencies:
|
||||
aws-sign2 "~0.6.0"
|
||||
aws4 "^1.2.1"
|
||||
caseless "~0.11.0"
|
||||
combined-stream "~1.0.5"
|
||||
extend "~3.0.0"
|
||||
forever-agent "~0.6.1"
|
||||
form-data "~2.1.1"
|
||||
har-validator "~2.0.6"
|
||||
hawk "~3.1.3"
|
||||
http-signature "~1.1.0"
|
||||
is-typedarray "~1.0.0"
|
||||
isstream "~0.1.2"
|
||||
json-stringify-safe "~5.0.1"
|
||||
mime-types "~2.1.7"
|
||||
oauth-sign "~0.8.1"
|
||||
qs "~6.3.0"
|
||||
stringstream "~0.0.4"
|
||||
tough-cookie "~2.3.0"
|
||||
tunnel-agent "~0.4.1"
|
||||
uuid "^3.0.0"
|
||||
|
||||
require-directory@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
||||
|
@ -5730,6 +5904,13 @@ sha.js@^2.4.0, sha.js@^2.4.8:
|
|||
inherits "^2.0.1"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
shapeshift.io@^1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/shapeshift.io/-/shapeshift.io-1.3.1.tgz#939f7d89e6a93fad4b556567d3fcdab45d5cc021"
|
||||
dependencies:
|
||||
request "^2.55.0"
|
||||
xhr "^2.0.1"
|
||||
|
||||
shebang-command@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
|
||||
|
@ -5790,6 +5971,12 @@ sntp@1.x.x:
|
|||
dependencies:
|
||||
hoek "2.x.x"
|
||||
|
||||
sntp@2.x.x:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8"
|
||||
dependencies:
|
||||
hoek "4.x.x"
|
||||
|
||||
sockjs-client@1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.1.4.tgz#5babe386b775e4cf14e7520911452654016c8b12"
|
||||
|
@ -5915,7 +6102,11 @@ staged-git-files@0.0.4:
|
|||
version "0.0.4"
|
||||
resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-0.0.4.tgz#d797e1b551ca7a639dec0237dc6eb4bb9be17d35"
|
||||
|
||||
"statuses@>= 1.3.1 < 2", statuses@~1.3.1:
|
||||
"statuses@>= 1.3.1 < 2":
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087"
|
||||
|
||||
statuses@~1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e"
|
||||
|
||||
|
@ -5991,7 +6182,7 @@ string_decoder@^1.0.0, string_decoder@~1.0.3:
|
|||
dependencies:
|
||||
safe-buffer "~5.1.0"
|
||||
|
||||
stringstream@~0.0.4:
|
||||
stringstream@~0.0.4, stringstream@~0.0.5:
|
||||
version "0.0.5"
|
||||
resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
|
||||
|
||||
|
@ -6067,8 +6258,8 @@ svgo@^0.7.0:
|
|||
whet.extend "~0.9.9"
|
||||
|
||||
symbol-observable@^1.0.1, symbol-observable@^1.0.3:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d"
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.1.0.tgz#5c68fd8d54115d9dfb72a84720549222e8db9b32"
|
||||
|
||||
table@^3.7.8:
|
||||
version "3.8.3"
|
||||
|
@ -6162,7 +6353,7 @@ to-fast-properties@^1.0.3:
|
|||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"
|
||||
|
||||
tough-cookie@~2.3.0:
|
||||
tough-cookie@~2.3.0, tough-cookie@~2.3.3:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561"
|
||||
dependencies:
|
||||
|
@ -6180,6 +6371,10 @@ trim-right@^1.0.1:
|
|||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
|
||||
|
||||
trim@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd"
|
||||
|
||||
"true-case-path@^1.0.2":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.2.tgz#7ec91130924766c7f573be3020c34f8fdfd00d62"
|
||||
|
@ -6371,7 +6566,7 @@ uuid@^2.0.2:
|
|||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a"
|
||||
|
||||
uuid@^3.0.0:
|
||||
uuid@^3.0.0, uuid@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"
|
||||
|
||||
|
@ -6423,6 +6618,12 @@ vm-browserify@0.0.4:
|
|||
dependencies:
|
||||
indexof "0.0.1"
|
||||
|
||||
warning@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c"
|
||||
dependencies:
|
||||
loose-envify "^1.0.0"
|
||||
|
||||
watchpack@^0.2.1:
|
||||
version "0.2.9"
|
||||
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-0.2.9.tgz#62eaa4ab5e5ba35fdfc018275626e3c0f5e3fb0b"
|
||||
|
@ -6453,18 +6654,18 @@ webpack-core@~0.6.9:
|
|||
source-map "~0.4.1"
|
||||
|
||||
webpack-dev-middleware@^1.11.0:
|
||||
version "1.12.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.12.0.tgz#d34efefb2edda7e1d3b5dbe07289513219651709"
|
||||
version "1.12.2"
|
||||
resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz#f8fc1120ce3b4fc5680ceecb43d777966b21105e"
|
||||
dependencies:
|
||||
memory-fs "~0.4.1"
|
||||
mime "^1.3.4"
|
||||
mime "^1.5.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
range-parser "^1.0.3"
|
||||
time-stamp "^2.0.0"
|
||||
|
||||
webpack-dev-server@^2.4.4:
|
||||
version "2.9.4"
|
||||
resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.9.4.tgz#7883e61759c6a4b33e9b19ec4037bd4ab61428d1"
|
||||
version "2.9.5"
|
||||
resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.9.5.tgz#79336fba0087a66ae491f4869f6545775b18daa8"
|
||||
dependencies:
|
||||
ansi-html "0.0.7"
|
||||
array-includes "^3.0.3"
|
||||
|
@ -6474,7 +6675,7 @@ webpack-dev-server@^2.4.4:
|
|||
connect-history-api-fallback "^1.3.0"
|
||||
debug "^3.1.0"
|
||||
del "^3.0.0"
|
||||
express "^4.13.3"
|
||||
express "^4.16.2"
|
||||
html-entities "^1.2.0"
|
||||
http-proxy-middleware "~0.17.4"
|
||||
import-local "^0.1.1"
|
||||
|
@ -6509,8 +6710,8 @@ webpack-notifier@^1.5.0:
|
|||
strip-ansi "^3.0.1"
|
||||
|
||||
webpack-sources@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.0.2.tgz#d0148ec083b3b5ccef1035a6b3ec16442983b27a"
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54"
|
||||
dependencies:
|
||||
source-list-map "^2.0.0"
|
||||
source-map "~0.6.1"
|
||||
|
@ -6542,8 +6743,8 @@ webpack@^1.12.0:
|
|||
webpack-core "~0.6.9"
|
||||
|
||||
webpack@^3.0.0:
|
||||
version "3.8.1"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.8.1.tgz#b16968a81100abe61608b0153c9159ef8bb2bd83"
|
||||
version "3.9.1"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.9.1.tgz#9a60aa544ed5d4d454c069e3f521aa007e02643c"
|
||||
dependencies:
|
||||
acorn "^5.0.0"
|
||||
acorn-dynamic-import "^2.0.0"
|
||||
|
@ -6648,6 +6849,15 @@ write@^0.2.1:
|
|||
dependencies:
|
||||
mkdirp "^0.5.1"
|
||||
|
||||
xhr@^2.0.1:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.4.0.tgz#e16e66a45f869861eeefab416d5eff722dc40993"
|
||||
dependencies:
|
||||
global "~4.3.0"
|
||||
is-function "^1.0.1"
|
||||
parse-headers "^2.0.0"
|
||||
xtend "^4.0.0"
|
||||
|
||||
xss-filters@^1.2.6:
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/xss-filters/-/xss-filters-1.2.7.tgz#59fa1de201f36f2f3470dcac5f58ccc2830b0a9a"
|
||||
|
|
Loading…
Reference in a new issue