Eddie Wang 88532cdc3c Shapeshift Integration (#564)
* progress

* Normalize bity api response

* Filter api response

* Track swap information in component state

* Update dropdown onchange

* remove dead code

* Update Min Max Validation

* Update minmax err msg && fix onChangeOriginKind

* Add origin & destination to redux state

* Update types & Update tests

* Update types

* Update swap.spec.ts test

* Remove commented out code

* Remove hardcoded coin array

* Create types.ts for swap reducer

* Update swapinput type

* Update bityRates in localStorage & Replace all instances of ...Kind / ...Amount props

* Add shapeshift banner

* initial work for sagas

* Update Types

* Update swap reducer initial state

* Update Types & Store empty obj for bityRates / options

* Update more types

* added shapeshift file and rates comments

* action reducers and prop mapping to components

* add typings and swap icon

* more actions reducers and sagas

* debugging shapeshift service

* add Headers

* Fix content type

* add order reset saga and ui fixes

* remove console log and swap b/w Bity and Shapeshift

* working state for Shapeshift and Bity - tested with mainnet

* add icon component

* UI improvements and fix select bug

* fix timer bug

* add bity fallback options and toFixed floats

* tslint errors

* add arrow to dropdown and add support footer

* Add service provider

* fix minor $ bug and stop timer on order complete

* better load UX and dropdown UX

* fixed single test

* currRate prop bugs and reduce LS bloat

* takeEvery on timer saga and don't clear state.options to restartSwap reducer

* export tx sagas and fix minor type

* Add ShapeShift Rates functionality when selecting a ShapeShift pair.

* type fixes

* BugFix: Don't change displayed ShapeShift Rate Inputs on every dropdown change
Also contains some caching / performance improvements

* BugFix: Don't remote rate inputs when falsy amount

* fix type error

* Progress commit

* Implement saga logic

* Make address field factory component

* Shorten debounce time

* Make new actions / sagas  for handling single token lookup

* Implement working version of litesend

* Change saga into selector

* Add failing spec

* fix broken test

* add debounce to error message

* fix tests

* update snapshots

* test coverage

* move setState disabled property from debounce so we instantly can go to next step on valid amounts

* much deeper test coverage, fix debounce ux, and fix bity flashing at swap page load

* fix minor failing test

* seperate shapeshift erc20 token whitelist

* fix saveState store bug

* break orderTimeRemaining saga up and rewrite tests

* add new swap icon

* remove unused allowReadOnly prop

* change offlineaware to walletdecrypt for litesend

* fix LiteSend changewallet bug

* fix error message UX

* fix button styling to match develop

* fix liteSend test

* Fix LiteSend UX on unavl tokens, dropdown null value, and don't show decrypt in litesend after successful wallet decrypt.

* add litesend network check
2018-01-02 12:04:50 -06:00

284 lines
8.9 KiB
TypeScript

import { showNotification as dShowNotification, TShowNotification } from 'actions/notifications';
import {
initSwap as dInitSwap,
bityOrderCreateRequestedSwap as dBityOrderCreateRequestedSwap,
shapeshiftOrderCreateRequestedSwap as dShapeshiftOrderCreateRequestedSwap,
changeStepSwap as dChangeStepSwap,
destinationAddressSwap as dDestinationAddressSwap,
loadBityRatesRequestedSwap as dLoadBityRatesRequestedSwap,
loadShapeshiftRatesRequestedSwap as dLoadShapeshiftRatesRequestedSwap,
restartSwap as dRestartSwap,
startOrderTimerSwap as dStartOrderTimerSwap,
startPollBityOrderStatus as dStartPollBityOrderStatus,
startPollShapeshiftOrderStatus as dStartPollShapeshiftOrderStatus,
stopLoadBityRatesSwap as dStopLoadBityRatesSwap,
stopLoadShapeshiftRatesSwap as dStopLoadShapeshiftRatesSwap,
stopOrderTimerSwap as dStopOrderTimerSwap,
stopPollBityOrderStatus as dStopPollBityOrderStatus,
stopPollShapeshiftOrderStatus as dStopPollShapeshiftOrderStatus,
changeSwapProvider as dChangeSwapProvider,
TInitSwap,
TBityOrderCreateRequestedSwap,
TChangeStepSwap,
TDestinationAddressSwap,
TLoadBityRatesRequestedSwap,
TShapeshiftOrderCreateRequestedSwap,
TLoadShapeshiftRequestedSwap,
TRestartSwap,
TStartOrderTimerSwap,
TStartPollBityOrderStatus,
TStartPollShapeshiftOrderStatus,
TStopLoadBityRatesSwap,
TStopOrderTimerSwap,
TStopPollBityOrderStatus,
TStopPollShapeshiftOrderStatus,
TChangeSwapProvider,
TStopLoadShapeshiftRatesSwap,
ProviderName
} from 'actions/swap';
import {
SwapInput,
NormalizedOptions,
NormalizedBityRates,
NormalizedShapeshiftRates
} from 'reducers/swap/types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { AppState } from 'reducers';
import CurrencySwap from './components/CurrencySwap';
import CurrentRates from './components/CurrentRates';
import PartThree from './components/PartThree';
import SupportFooter from './components/SupportFooter';
import ReceivingAddress from './components/ReceivingAddress';
import SwapInfoHeader from './components/SwapInfoHeader';
import ShapeshiftBanner from './components/ShapeshiftBanner';
import TabSection from 'containers/TabSection';
import { merge } from 'lodash';
interface ReduxStateProps {
step: number;
origin: SwapInput;
destination: SwapInput;
bityRates: NormalizedBityRates;
shapeshiftRates: NormalizedShapeshiftRates;
options: NormalizedOptions;
provider: ProviderName;
bityOrder: any;
shapeshiftOrder: any;
destinationAddress: string;
isFetchingRates: boolean | null;
secondsRemaining: number | null;
outputTx: string | null;
isPostingOrder: boolean;
bityOrderStatus: string | null;
shapeshiftOrderStatus: string | null;
paymentAddress: string | null;
}
interface ReduxActionProps {
changeStepSwap: TChangeStepSwap;
loadBityRatesRequestedSwap: TLoadBityRatesRequestedSwap;
loadShapeshiftRatesRequestedSwap: TLoadShapeshiftRequestedSwap;
destinationAddressSwap: TDestinationAddressSwap;
restartSwap: TRestartSwap;
stopLoadBityRatesSwap: TStopLoadBityRatesSwap;
stopLoadShapeshiftRatesSwap: TStopLoadShapeshiftRatesSwap;
shapeshiftOrderCreateRequestedSwap: TShapeshiftOrderCreateRequestedSwap;
bityOrderCreateRequestedSwap: TBityOrderCreateRequestedSwap;
startPollShapeshiftOrderStatus: TStartPollShapeshiftOrderStatus;
startPollBityOrderStatus: TStartPollBityOrderStatus;
startOrderTimerSwap: TStartOrderTimerSwap;
stopOrderTimerSwap: TStopOrderTimerSwap;
stopPollBityOrderStatus: TStopPollBityOrderStatus;
stopPollShapeshiftOrderStatus: TStopPollShapeshiftOrderStatus;
showNotification: TShowNotification;
initSwap: TInitSwap;
swapProvider: TChangeSwapProvider;
}
class Swap extends Component<ReduxActionProps & ReduxStateProps, {}> {
public componentDidMount() {
this.props.loadBityRatesRequestedSwap();
this.props.loadShapeshiftRatesRequestedSwap();
}
public componentWillUnmount() {
this.props.stopLoadBityRatesSwap();
this.props.stopLoadShapeshiftRatesSwap();
}
public render() {
const {
// STATE
bityRates,
shapeshiftRates,
provider,
options,
origin,
destination,
destinationAddress,
step,
bityOrder,
shapeshiftOrder,
secondsRemaining,
paymentAddress,
bityOrderStatus,
shapeshiftOrderStatus,
isPostingOrder,
outputTx,
// ACTIONS
initSwap,
restartSwap,
stopLoadBityRatesSwap,
changeStepSwap,
destinationAddressSwap,
bityOrderCreateRequestedSwap,
shapeshiftOrderCreateRequestedSwap,
showNotification,
startOrderTimerSwap,
startPollBityOrderStatus,
stopPollShapeshiftOrderStatus,
startPollShapeshiftOrderStatus,
stopOrderTimerSwap,
stopPollBityOrderStatus,
swapProvider
} = this.props;
const reference = provider === 'shapeshift' ? shapeshiftOrder.orderId : bityOrder.reference;
const ReceivingAddressProps = {
isPostingOrder,
origin,
destinationId: destination.id,
destinationKind: destination.amount as number,
destinationAddressSwap,
destinationAddress,
stopLoadBityRatesSwap,
changeStepSwap,
provider,
bityOrderCreateRequestedSwap,
shapeshiftOrderCreateRequestedSwap
};
const SwapInfoHeaderProps = {
origin,
destination,
reference,
secondsRemaining,
restartSwap,
bityOrderStatus,
shapeshiftOrderStatus,
provider
};
const CurrencySwapProps = {
showNotification,
bityRates,
shapeshiftRates,
provider,
options,
initSwap,
swapProvider,
changeStepSwap
};
const paymentInfo =
provider === 'shapeshift'
? merge(origin, { amount: shapeshiftOrder.depositAmount })
: merge(origin, { amount: bityOrder.amount });
const PaymentInfoProps = {
origin: paymentInfo,
paymentAddress
};
const PartThreeProps = {
...SwapInfoHeaderProps,
...PaymentInfoProps,
reference,
provider,
startOrderTimerSwap,
stopOrderTimerSwap,
startPollBityOrderStatus,
startPollShapeshiftOrderStatus,
stopPollBityOrderStatus,
stopPollShapeshiftOrderStatus,
showNotification,
destinationAddress,
outputTx
};
const SupportProps = {
origin,
destination,
destinationAddress,
paymentAddress,
reference,
provider,
shapeshiftRates,
bityRates
};
const CurrentRatesProps = { provider, bityRates, shapeshiftRates };
return (
<TabSection>
<section className="Tab-content swap-tab">
{step === 1 && <CurrentRates {...CurrentRatesProps} />}
{step === 1 && <ShapeshiftBanner />}
{(step === 2 || step === 3) && <SwapInfoHeader {...SwapInfoHeaderProps} />}
<main className="Tab-content-pane">
{step === 1 && <CurrencySwap {...CurrencySwapProps} />}
{step === 2 && <ReceivingAddress {...ReceivingAddressProps} />}
{step === 3 && <PartThree {...PartThreeProps} />}
</main>
</section>
<SupportFooter {...SupportProps} />
</TabSection>
);
}
}
function mapStateToProps(state: AppState) {
return {
step: state.swap.step,
origin: state.swap.origin,
destination: state.swap.destination,
bityRates: state.swap.bityRates,
shapeshiftRates: state.swap.shapeshiftRates,
provider: state.swap.provider,
options: state.swap.options,
bityOrder: state.swap.bityOrder,
shapeshiftOrder: state.swap.shapeshiftOrder,
destinationAddress: state.swap.destinationAddress,
isFetchingRates: state.swap.isFetchingRates,
secondsRemaining: state.swap.secondsRemaining,
outputTx: state.swap.outputTx,
isPostingOrder: state.swap.isPostingOrder,
bityOrderStatus: state.swap.bityOrderStatus,
shapeshiftOrderStatus: state.swap.shapeshiftOrderStatus,
paymentAddress: state.swap.paymentAddress
};
}
export default connect(mapStateToProps, {
changeStepSwap: dChangeStepSwap,
initSwap: dInitSwap,
bityOrderCreateRequestedSwap: dBityOrderCreateRequestedSwap,
shapeshiftOrderCreateRequestedSwap: dShapeshiftOrderCreateRequestedSwap,
loadBityRatesRequestedSwap: dLoadBityRatesRequestedSwap,
loadShapeshiftRatesRequestedSwap: dLoadShapeshiftRatesRequestedSwap,
destinationAddressSwap: dDestinationAddressSwap,
restartSwap: dRestartSwap,
startOrderTimerSwap: dStartOrderTimerSwap,
startPollBityOrderStatus: dStartPollBityOrderStatus,
startPollShapeshiftOrderStatus: dStartPollShapeshiftOrderStatus,
stopLoadBityRatesSwap: dStopLoadBityRatesSwap,
stopLoadShapeshiftRatesSwap: dStopLoadShapeshiftRatesSwap,
stopOrderTimerSwap: dStopOrderTimerSwap,
stopPollBityOrderStatus: dStopPollBityOrderStatus,
stopPollShapeshiftOrderStatus: dStopPollShapeshiftOrderStatus,
showNotification: dShowNotification,
swapProvider: dChangeSwapProvider
})(Swap);