Skip to content

Commit

Permalink
Merge branch 'develop' into scheduling/move-advanced
Browse files Browse the repository at this point in the history
  • Loading branch information
josipbagaric authored Nov 19, 2018
2 parents 21e0a96 + 21abebf commit 4ce646a
Show file tree
Hide file tree
Showing 37 changed files with 5,160 additions and 2,468 deletions.
7 changes: 6 additions & 1 deletion common/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,14 @@ class RootClass extends Component<Props, State> {

const LegacyRoutes = withRouter(props => {
const { history } = props;
const { pathname } = props.location;
const { pathname, search } = props.location;
let { hash } = props.location;

if (search.includes('redirectToSignMessage')) {
history.push('/sign-and-verify-message');
return null;
}

if (pathname === '/') {
hash = hash.split('?')[0];
switch (hash) {
Expand Down
71 changes: 61 additions & 10 deletions common/api/shapeshift.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import axios from 'axios';
import flatten from 'lodash/flatten';
import uniqBy from 'lodash/uniqBy';
import queryString from 'query-string';

import { checkHttpStatus, parseJSON } from 'api/utils';

export const SHAPESHIFT_API_KEY =
'8abde0f70ca69d5851702d57b10305705d7333e93263124cc2a2649dab7ff9cf86401fc8de7677e8edcd0e7f1eed5270b1b49be8806937ef95d64839e319e6d9';

export const SHAPESHIFT_BASE_URL = 'https://shapeshift.io';

export const SHAPESHIFT_TOKEN_WHITELIST = [
'OMG',
'REP',
Expand All @@ -30,6 +28,10 @@ export const SHAPESHIFT_TOKEN_WHITELIST = [
'GUP'
];
export const SHAPESHIFT_WHITELIST = [...SHAPESHIFT_TOKEN_WHITELIST, 'ETH', 'ETC', 'BTC', 'XMR'];
export const SHAPESHIFT_ACCESS_TOKEN = 'c640aa85-dd01-4db1-a6f2-ed57e6fd6c54';
export const SHAPESHIFT_API_URL = 'https://auth.shapeshift.io/oauth/authorize';
export const SHAPESHIFT_CLIENT_ID = 'fcbbb372-4221-4436-b345-024d91384652';
export const SHAPESHIFT_REDIRECT_URI = 'https://mycrypto.com/swap';

interface IPairData {
limit: number;
Expand Down Expand Up @@ -95,12 +97,21 @@ interface ShapeshiftOptionMap {
class ShapeshiftService {
public whitelist = SHAPESHIFT_WHITELIST;
private url = SHAPESHIFT_BASE_URL;
private apiKey = SHAPESHIFT_API_KEY;
private postHeaders = {
'Content-Type': 'application/json'
};
private supportedCoinsAndTokens: ShapeshiftCoinInfoMap = {};
private fetchedSupportedCoinsAndTokens = false;
private token: string | null = null;

public constructor() {
this.retrieveAccessTokenFromStorage();
}

public hasToken() {
return !!window.localStorage.getItem(SHAPESHIFT_ACCESS_TOKEN);
}

public urlHasCodeParam() {
return !!queryString.parse(window.location.search).code;
}

public checkStatus(address: string) {
return fetch(`${this.url}/txStat/${address}`)
Expand All @@ -121,10 +132,9 @@ class ShapeshiftService {
body: JSON.stringify({
amount: destinationAmount,
pair,
apiKey: this.apiKey,
withdrawal
}),
headers: new Headers(this.postHeaders)
headers: new Headers(this.getPostHeaders())
})
.then(checkHttpStatus)
.then(parseJSON)
Expand Down Expand Up @@ -154,6 +164,29 @@ class ShapeshiftService {
return allRates;
};

public sendUserToAuthorize = () => {
const query = queryString.stringify({
client_id: SHAPESHIFT_CLIENT_ID,
scope: 'users:read',
response_type: 'code',
redirect_uri: SHAPESHIFT_REDIRECT_URI
});
const url = `${SHAPESHIFT_API_URL}?${query}`;

window.open(url, '_blank', 'width=800, height=600, menubar=yes');
};

public requestAccessToken = async () => {
const { code } = queryString.parse(window.location.search);
const { data: { access_token: token } } = await axios.post(
'https://proxy.mycryptoapi.com/request-shapeshift-token',
{ code, grant_type: 'authorization_code' }
);

this.token = token;
this.saveAccessTokenToStorage(token);
};

public addUnavailableCoinsAndTokens = (availableCoinsAndTokens: TokenMap) => {
if (this.fetchedSupportedCoinsAndTokens) {
/** @desc Create a hash for efficiently checking which tokens are currently available. */
Expand Down Expand Up @@ -211,6 +244,11 @@ class ShapeshiftService {
return availableCoinsAndTokens;
};

private getPostHeaders = () => ({
'Content-Type': 'application/json',
Authorization: `Bearer ${this.token}`
});

private filterPairs(marketInfo: ShapeshiftMarketInfo[]) {
return marketInfo.filter(obj => {
const { pair } = obj;
Expand Down Expand Up @@ -300,6 +338,19 @@ class ShapeshiftService {
});
return tokenMap;
}

private saveAccessTokenToStorage = (token: string) => {
if (window && window.localStorage) {
window.localStorage.setItem(SHAPESHIFT_ACCESS_TOKEN, token);
}
};

private retrieveAccessTokenFromStorage = () => {
if (window && window.localStorage) {
const token = window.localStorage.getItem(SHAPESHIFT_ACCESS_TOKEN);
this.token = token;
}
};
}

const shapeshift = new ShapeshiftService();
Expand Down
16 changes: 16 additions & 0 deletions common/assets/images/wallets/trust.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 4 additions & 5 deletions common/components/AddressField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,10 @@ const AddressField: React.SFC<Props> = ({
className={`input-group-input ${!isValid && !isLabelEntry ? 'invalid' : ''}`}
isValid={isValid}
type="text"
value={
value != null
? value
: isCheckSummed ? toChecksumAddress(currentTo.raw) : currentTo.raw
}
value={(value != null
? value
: isCheckSummed ? toChecksumAddress(currentTo.raw) : currentTo.raw
).trim()}
placeholder={placeholder}
readOnly={!!(isReadOnly || readOnly)}
spellCheck={false}
Expand Down
6 changes: 3 additions & 3 deletions common/components/BalanceSidebar/TokenBalances/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ interface StateProps {
isOffline: AppState['config']['meta']['offline'];
}
interface ActionProps {
addCustomToken: customTokensActions.TAddCustomToken;
attemptAddCustomToken: customTokensActions.TAttemptAddCustomToken;
removeCustomToken: customTokensActions.TRemoveCustomToken;
scanWalletForTokens: walletActions.TScanWalletForTokens;
setWalletTokens: walletActions.TSetWalletTokens;
Expand Down Expand Up @@ -85,7 +85,7 @@ class TokenBalances extends React.Component<Props> {
hasSavedWalletTokens={hasSavedWalletTokens}
scanWalletForTokens={this.scanWalletForTokens}
setWalletTokens={this.props.setWalletTokens}
onAddCustomToken={this.props.addCustomToken}
onAddCustomToken={this.props.attemptAddCustomToken}
onRemoveCustomToken={this.props.removeCustomToken}
/>
);
Expand Down Expand Up @@ -121,7 +121,7 @@ function mapStateToProps(state: AppState): StateProps {
}

export default connect(mapStateToProps, {
addCustomToken: customTokensActions.addCustomToken,
attemptAddCustomToken: customTokensActions.attemptAddCustomToken,
removeCustomToken: customTokensActions.removeCustomToken,
scanWalletForTokens: walletActions.scanWalletForTokens,
setWalletTokens: walletActions.setWalletTokens,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ $input-border-radius: 3px;
background: #142c46;
border: 1px solid #4d5f74;
border-radius: $input-border-radius;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-right: none;
color: #fff;
}
}
Expand All @@ -158,6 +161,8 @@ $input-border-radius: 3px;
background: #027796;
border: none;
border-radius: $input-border-radius;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
color: #fff;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,10 @@ class MobileHeader extends Component<Props> {
</ul>
)}
</li>
<li onClick={this.toggleMenu}>
<i className="fa fa-plus" /> {translateRaw('NEW_HEADER_TEXT_6')}
<li>
<Link to="/generate">
<i className="fa fa-plus" /> {translateRaw('NEW_HEADER_TEXT_6')}
</Link>
</li>
</ul>
<ul className="MobileHeader-menu-mid">
Expand Down
34 changes: 24 additions & 10 deletions common/components/WalletDecrypt/WalletDecrypt.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ const WalletDecrypt = withRouter<Props>(
value: null
};

public exists: boolean = true;

public UNSAFE_componentWillReceiveProps(nextProps: Props) {
// Reset state when unlock is hidden / revealed
if (nextProps.hidden !== this.props.hidden) {
Expand All @@ -226,6 +228,10 @@ const WalletDecrypt = withRouter<Props>(
}
}

public componentWillUnmount() {
this.exists = false;
}

public getSelectedWallet() {
const { selectedWalletKey } = this.state;
if (!selectedWalletKey) {
Expand Down Expand Up @@ -401,6 +407,7 @@ const WalletDecrypt = withRouter<Props>(
}

public handleWalletChoice = async (walletType: WalletName) => {
const { showNotification } = this.props;
const wallet = this.WALLETS[walletType];

if (!wallet) {
Expand All @@ -409,20 +416,27 @@ const WalletDecrypt = withRouter<Props>(

let timeout = 0;
if (wallet.attemptUnlock) {
const web3Available = await isWeb3NodeAvailable();
if (web3Available) {
// timeout is only the maximum wait time before secondary view is shown
// send view will be shown immediately on web3 resolve
timeout = 1500;
wallet.unlock();
try {
const web3Available = await isWeb3NodeAvailable();
if (web3Available) {
// timeout is only the maximum wait time before secondary view is shown
// send view will be shown immediately on web3 resolve
timeout = 1500;
wallet.unlock();
}
} catch (e) {
// The permissions request for MetaMask was displayed, but permission was denied.
showNotification('danger', translateRaw('METAMASK_PERMISSION_DENIED'));
}
}

window.setTimeout(() => {
this.setState({
selectedWalletKey: walletType,
value: wallet.initialParams
});
if (this.exists) {
this.setState({
selectedWalletKey: walletType,
value: wallet.initialParams
});
}
}, timeout);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,17 @@ class DeterministicWalletsModalClass extends React.PureComponent<Props, State> {
const label = addressLabels[wallet.address.toLowerCase()];
const spanClassName = label ? 'DWModal-addresses-table-address-text' : '';

let blockExplorer;
if (!network.isCustom) {
blockExplorer = network.blockExplorer;
} else {
blockExplorer = {
addressUrl: (address: string) => {
return `https://ethplorer.io/address/${address}`;
}
};
}

// Get renderable values, but keep 'em short
const token = desiredToken ? wallet.tokenValues[desiredToken] : null;

Expand Down Expand Up @@ -327,7 +338,7 @@ class DeterministicWalletsModalClass extends React.PureComponent<Props, State> {
<td>
<a
target="_blank"
href={`https://ethplorer.io/address/${wallet.address}`}
href={blockExplorer.addressUrl(wallet.address)}
rel="noopener noreferrer"
>
<i className="DWModal-addresses-table-more" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
filter: invert(1);

// Kind of hacky, but we don't want to invert metamask
&[src*="metamask"] {
&[src*='metamask'] {
filter: none;
}
}
Expand Down
48 changes: 35 additions & 13 deletions common/components/WalletDecrypt/components/WalletButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,18 +107,40 @@ export class WalletButton extends React.PureComponent<Props> {
)}

<div className="WalletButton-icons">
{icons.map(i => (
<span className="WalletButton-icons-icon" key={i.icon} onClick={this.stopPropogation}>
{i.href ? (
<NewTabLink href={i.href} onClick={this.stopPropogation} aria-label={i.arialabel}>
<i className={`fa fa-${i.icon}`} />
</NewTabLink>
) : (
<i className={`fa fa-${i.icon}`} aria-label={i.arialabel} />
)}
{!isDisabled && <Tooltip size="sm">{i.tooltip}</Tooltip>}
</span>
))}
{icons.map(i => {
const IconWrapper = (props: any) => {
if (isDisabled) {
return <React.Fragment>{props.children}</React.Fragment>;
}

if (i.href) {
return (
<NewTabLink
href={i.href}
onClick={this.stopPropagation}
aria-label={i.arialabel}
>
{props.children}
</NewTabLink>
);
}

return props.children;
};

return (
<span
className="WalletButton-icons-icon"
key={i.icon}
onClick={this.stopPropagation}
>
<IconWrapper>
<i className={`fa fa-${i.icon}`} aria-label={i.arialabel} />
</IconWrapper>
{!isDisabled && <Tooltip size="sm">{i.tooltip}</Tooltip>}
</span>
);
})}
</div>
</div>

Expand All @@ -135,7 +157,7 @@ export class WalletButton extends React.PureComponent<Props> {
this.props.onClick(this.props.walletType);
};

private stopPropogation = (ev: React.FormEvent<HTMLAnchorElement | HTMLSpanElement>) => {
private stopPropagation = (ev: React.FormEvent<HTMLAnchorElement | HTMLSpanElement>) => {
ev.stopPropagation();
};
}
Loading

0 comments on commit 4ce646a

Please sign in to comment.