aboutsummaryrefslogtreecommitdiffstats
path: root/packages/website/ts/components/dialogs/ledger_config_dialog.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/website/ts/components/dialogs/ledger_config_dialog.tsx')
-rw-r--r--packages/website/ts/components/dialogs/ledger_config_dialog.tsx307
1 files changed, 0 insertions, 307 deletions
diff --git a/packages/website/ts/components/dialogs/ledger_config_dialog.tsx b/packages/website/ts/components/dialogs/ledger_config_dialog.tsx
deleted file mode 100644
index 527353aa0..000000000
--- a/packages/website/ts/components/dialogs/ledger_config_dialog.tsx
+++ /dev/null
@@ -1,307 +0,0 @@
-import { colors, constants as sharedConstants } from '@0x/react-shared';
-import { BigNumber, logUtils } from '@0x/utils';
-import { Web3Wrapper } from '@0x/web3-wrapper';
-import * as _ from 'lodash';
-import Dialog from 'material-ui/Dialog';
-import FlatButton from 'material-ui/FlatButton';
-import { Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn } from 'material-ui/Table';
-import TextField from 'material-ui/TextField';
-import * as React from 'react';
-import ReactTooltip from 'react-tooltip';
-import { Blockchain } from 'ts/blockchain';
-import { NetworkDropDown } from 'ts/components/dropdowns/network_drop_down';
-import { LifeCycleRaisedButton } from 'ts/components/ui/lifecycle_raised_button';
-import { Dispatcher } from 'ts/redux/dispatcher';
-import { ProviderType } from 'ts/types';
-import { configs } from 'ts/utils/configs';
-import { constants } from 'ts/utils/constants';
-import { utils } from 'ts/utils/utils';
-
-const VALID_ETHEREUM_DERIVATION_PATH_PREFIX = `44'/60'`;
-
-enum LedgerSteps {
- Connect,
- SelectAddress,
-}
-
-interface LedgerConfigDialogProps {
- isOpen: boolean;
- toggleDialogFn: (isOpen: boolean) => void;
- dispatcher: Dispatcher;
- blockchain: Blockchain;
- networkId?: number;
- providerType: ProviderType;
-}
-
-interface LedgerConfigDialogState {
- connectionErrMsg: string;
- stepIndex: LedgerSteps;
- userAddresses: string[];
- addressBalances: BigNumber[];
- derivationPath: string;
- derivationErrMsg: string;
- preferredNetworkId: number;
-}
-
-export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps, LedgerConfigDialogState> {
- public static defaultProps = {
- networkId: 1,
- };
- constructor(props: LedgerConfigDialogProps) {
- super(props);
- const derivationPathIfExists = props.blockchain.getLedgerDerivationPathIfExists();
- this.state = {
- connectionErrMsg: '',
- stepIndex: LedgerSteps.Connect,
- userAddresses: [],
- addressBalances: [],
- derivationPath: _.isUndefined(derivationPathIfExists)
- ? configs.DEFAULT_DERIVATION_PATH
- : derivationPathIfExists,
- derivationErrMsg: '',
- preferredNetworkId: props.networkId,
- };
- }
- public render(): React.ReactNode {
- const dialogActions = [
- <FlatButton key="ledgerConnectCancel" label="Cancel" onClick={this._onClose.bind(this)} />,
- ];
- const dialogTitle =
- this.state.stepIndex === LedgerSteps.Connect ? 'Connect to your Ledger' : 'Select desired address';
- return (
- <Dialog
- title={dialogTitle}
- titleStyle={{ fontWeight: 100 }}
- actions={dialogActions}
- open={this.props.isOpen}
- onRequestClose={this._onClose.bind(this)}
- autoScrollBodyContent={true}
- bodyStyle={{ paddingBottom: 0 }}
- >
- <div style={{ color: colors.grey700, paddingTop: 1 }}>
- {this.state.stepIndex === LedgerSteps.Connect && this._renderConnectStep()}
- {this.state.stepIndex === LedgerSteps.SelectAddress && this._renderSelectAddressStep()}
- </div>
- </Dialog>
- );
- }
- private _renderConnectStep(): React.ReactNode {
- const networkIds = _.values(sharedConstants.NETWORK_ID_BY_NAME);
- return (
- <div>
- <div className="h4 pt3">Follow these instructions before proceeding:</div>
- <ol className="mb0">
- <li className="pb1">Connect your Ledger Nano S & Open the Ethereum application</li>
- <li className="pb1">Verify that "Browser Support" AND "Contract Data" are enabled in Settings</li>
- <li className="pb1">
- If no Browser Support is found in settings, verify that you have{' '}
- <a href="https://www.ledgerwallet.com/apps/manager" target="_blank">
- Firmware >1.2
- </a>
- </li>
- <li>Choose your desired network:</li>
- </ol>
- <div className="pb2">
- <NetworkDropDown
- updateSelectedNetwork={this._onSelectedNetworkUpdated.bind(this)}
- selectedNetworkId={this.state.preferredNetworkId}
- avialableNetworkIds={networkIds}
- />
- </div>
- <div className="center pb3">
- <LifeCycleRaisedButton
- isPrimary={true}
- labelReady="Connect to Ledger"
- labelLoading="Connecting..."
- labelComplete="Connected!"
- onClickAsyncFn={this._onConnectLedgerClickAsync.bind(this, true)}
- />
- {!_.isEmpty(this.state.connectionErrMsg) && (
- <div className="pt2 left-align" style={{ color: colors.red200 }}>
- {this.state.connectionErrMsg}
- </div>
- )}
- </div>
- </div>
- );
- }
- private _renderSelectAddressStep(): React.ReactNode {
- return (
- <div>
- <div>
- <Table bodyStyle={{ height: 300 }} onRowSelection={this._onAddressSelected.bind(this)}>
- <TableHeader displaySelectAll={false}>
- <TableRow>
- <TableHeaderColumn colSpan={2}>Address</TableHeaderColumn>
- <TableHeaderColumn>Balance</TableHeaderColumn>
- </TableRow>
- </TableHeader>
- <TableBody>{this._renderAddressTableRows()}</TableBody>
- </Table>
- </div>
- <div className="flex pt2" style={{ height: 100 }}>
- <div className="overflow-hidden" style={{ width: 180 }}>
- <TextField
- floatingLabelFixed={true}
- floatingLabelStyle={{ color: colors.grey }}
- floatingLabelText="Update path derivation (advanced)"
- value={this.state.derivationPath}
- errorText={this.state.derivationErrMsg}
- onChange={this._onDerivationPathChanged.bind(this)}
- />
- </div>
- <div className="pl2" style={{ paddingTop: 28 }}>
- <LifeCycleRaisedButton
- labelReady="Update"
- labelLoading="Updating..."
- labelComplete="Updated!"
- onClickAsyncFn={this._onFetchAddressesForDerivationPathAsync.bind(this)}
- />
- </div>
- </div>
- </div>
- );
- }
- private _renderAddressTableRows(): React.ReactNode {
- const rows = _.map(this.state.userAddresses, (userAddress: string, i: number) => {
- const balanceInWei = this.state.addressBalances[i];
- const addressTooltipId = `address-${userAddress}`;
- const balanceTooltipId = `balance-${userAddress}`;
- const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId];
- // We specifically prefix kovan ETH.
- // TODO: We should probably add prefixes for all networks
- const isKovanNetwork = networkName === 'Kovan';
- const balanceInEth = Web3Wrapper.toUnitAmount(balanceInWei, constants.DECIMAL_PLACES_ETH);
- const balanceString = `${balanceInEth.toString()} ${isKovanNetwork ? 'Kovan ' : ''}ETH`;
- return (
- <TableRow key={userAddress} style={{ height: 40 }}>
- <TableRowColumn colSpan={2}>
- <div data-tip={true} data-for={addressTooltipId}>
- {userAddress}
- </div>
- <ReactTooltip id={addressTooltipId}>{userAddress}</ReactTooltip>
- </TableRowColumn>
- <TableRowColumn>
- <div data-tip={true} data-for={balanceTooltipId}>
- {balanceString}
- </div>
- <ReactTooltip id={balanceTooltipId}>{balanceString}</ReactTooltip>
- </TableRowColumn>
- </TableRow>
- );
- });
- return rows;
- }
- private _onClose(): void {
- this.setState({
- connectionErrMsg: '',
- stepIndex: LedgerSteps.Connect,
- });
- const isOpen = false;
- this.props.toggleDialogFn(isOpen);
- }
- private _onAddressSelected(selectedRowIndexes: number[]): void {
- const selectedRowIndex = selectedRowIndexes[0];
- const selectedAddress = this.state.userAddresses[selectedRowIndex];
- const selectAddressBalance = this.state.addressBalances[selectedRowIndex];
- this.props.dispatcher.updateUserAddress(selectedAddress);
- this.props.blockchain.updateWeb3WrapperPrevUserAddress(selectedAddress);
- // tslint:disable-next-line:no-floating-promises
- this.props.blockchain.fetchTokenInformationAsync();
- this.props.dispatcher.updateUserWeiBalance(selectAddressBalance);
- this.setState({
- stepIndex: LedgerSteps.Connect,
- });
- const isOpen = false;
- this.props.toggleDialogFn(isOpen);
- }
- private async _onFetchAddressesForDerivationPathAsync(): Promise<boolean> {
- const currentlySetPath = this.props.blockchain.getLedgerDerivationPathIfExists();
- let didSucceed;
- if (currentlySetPath === this.state.derivationPath) {
- didSucceed = true;
- return didSucceed;
- }
- this.props.blockchain.updateLedgerDerivationPathIfExists(this.state.derivationPath);
- didSucceed = await this._fetchAddressesAndBalancesAsync();
- if (!didSucceed) {
- this.setState({
- derivationErrMsg: 'Failed to connect to Ledger.',
- });
- }
- return didSucceed;
- }
- private async _fetchAddressesAndBalancesAsync(): Promise<boolean> {
- let userAddresses: string[];
- const addressBalances: BigNumber[] = [];
- try {
- userAddresses = await this._getUserAddressesAsync();
- for (const address of userAddresses) {
- const balanceInWei = await this.props.blockchain.getBalanceInWeiAsync(address);
- addressBalances.push(balanceInWei);
- }
- } catch (err) {
- logUtils.log(`Ledger error: ${JSON.stringify(err)}`);
- this.setState({
- connectionErrMsg: 'Failed to connect. Follow the instructions and try again.',
- });
- return false;
- }
- this.setState({
- userAddresses,
- addressBalances,
- });
- return true;
- }
- private _onDerivationPathChanged(_event: any, derivationPath: string): void {
- let derivationErrMsg = '';
- if (!_.startsWith(derivationPath, VALID_ETHEREUM_DERIVATION_PATH_PREFIX)) {
- derivationErrMsg = 'Must be valid Ethereum path.';
- }
-
- this.setState({
- derivationPath,
- derivationErrMsg,
- });
- }
- private async _onConnectLedgerClickAsync(): Promise<boolean> {
- const isU2FSupported = await utils.isU2FSupportedAsync();
- if (!isU2FSupported) {
- logUtils.log(`U2F not supported in this browser`);
- this.setState({
- connectionErrMsg: 'U2F not supported by this browser. Try using Chrome.',
- });
- return false;
- }
-
- if (
- this.props.providerType !== ProviderType.Ledger ||
- (this.props.providerType === ProviderType.Ledger && this.props.networkId !== this.state.preferredNetworkId)
- ) {
- await this.props.blockchain.updateProviderToLedgerAsync(this.state.preferredNetworkId);
- }
-
- const didSucceed = await this._fetchAddressesAndBalancesAsync();
- if (didSucceed) {
- this.setState({
- stepIndex: LedgerSteps.SelectAddress,
- connectionErrMsg: '',
- });
- }
- return didSucceed;
- }
- private async _getUserAddressesAsync(): Promise<string[]> {
- let userAddresses: string[];
- userAddresses = await this.props.blockchain.getUserAccountsAsync();
-
- if (_.isEmpty(userAddresses)) {
- throw new Error('No addresses retrieved.');
- }
- return userAddresses;
- }
- private _onSelectedNetworkUpdated(_event: any, _index: number, networkId: number): void {
- this.setState({
- preferredNetworkId: networkId,
- });
- }
-}