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.tsx460
1 files changed, 230 insertions, 230 deletions
diff --git a/packages/website/ts/components/dialogs/ledger_config_dialog.tsx b/packages/website/ts/components/dialogs/ledger_config_dialog.tsx
index 8b7760a1a..60db93c52 100644
--- a/packages/website/ts/components/dialogs/ledger_config_dialog.tsx
+++ b/packages/website/ts/components/dialogs/ledger_config_dialog.tsx
@@ -17,245 +17,245 @@ import { utils } from 'ts/utils/utils';
const VALID_ETHEREUM_DERIVATION_PATH_PREFIX = `44'/60'`;
enum LedgerSteps {
- CONNECT,
- SELECT_ADDRESS,
+ CONNECT,
+ SELECT_ADDRESS,
}
interface LedgerConfigDialogProps {
- isOpen: boolean;
- toggleDialogFn: (isOpen: boolean) => void;
- dispatcher: Dispatcher;
- blockchain: Blockchain;
- networkId: number;
+ isOpen: boolean;
+ toggleDialogFn: (isOpen: boolean) => void;
+ dispatcher: Dispatcher;
+ blockchain: Blockchain;
+ networkId: number;
}
interface LedgerConfigDialogState {
- didConnectFail: boolean;
- stepIndex: LedgerSteps;
- userAddresses: string[];
- addressBalances: BigNumber[];
- derivationPath: string;
- derivationErrMsg: string;
+ didConnectFail: boolean;
+ stepIndex: LedgerSteps;
+ userAddresses: string[];
+ addressBalances: BigNumber[];
+ derivationPath: string;
+ derivationErrMsg: string;
}
export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps, LedgerConfigDialogState> {
- constructor(props: LedgerConfigDialogProps) {
- super(props);
- this.state = {
- didConnectFail: false,
- stepIndex: LedgerSteps.CONNECT,
- userAddresses: [],
- addressBalances: [],
- derivationPath: configs.DEFAULT_DERIVATION_PATH,
- derivationErrMsg: '',
- };
- }
- public render() {
- const dialogActions = [
- <FlatButton key="ledgerConnectCancel" label="Cancel" onTouchTap={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.SELECT_ADDRESS && this._renderSelectAddressStep()}
- </div>
- </Dialog>
- );
- }
- private _renderConnectStep() {
- return (
- <div>
- <div className="h4 pt3">Follow these instructions before proceeding:</div>
- <ol>
- <li className="pb1">Connect your Ledger Nano S & Open the Ethereum application</li>
- <li className="pb1">Verify that Browser Support is 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>
- </ol>
- <div className="center pb3">
- <LifeCycleRaisedButton
- isPrimary={true}
- labelReady="Connect to Ledger"
- labelLoading="Connecting..."
- labelComplete="Connected!"
- onClickAsyncFn={this._onConnectLedgerClickAsync.bind(this, true)}
- />
- {this.state.didConnectFail && (
- <div className="pt2 left-align" style={{ color: colors.red200 }}>
- Failed to connect. Follow the instructions and try again.
- </div>
- )}
- </div>
- </div>
- );
- }
- private _renderSelectAddressStep() {
- 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() {
- const rows = _.map(this.state.userAddresses, (userAddress: string, i: number) => {
- const balance = this.state.addressBalances[i];
- const addressTooltipId = `address-${userAddress}`;
- const balanceTooltipId = `balance-${userAddress}`;
- const networkName = constants.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 balanceString = `${balance.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() {
- this.setState({
- didConnectFail: false,
- });
- const isOpen = false;
- this.props.toggleDialogFn(isOpen);
- }
- private _onAddressSelected(selectedRowIndexes: number[]) {
- const selectedRowIndex = selectedRowIndexes[0];
- this.props.blockchain.updateLedgerDerivationIndex(selectedRowIndex);
- const selectedAddress = this.state.userAddresses[selectedRowIndex];
- const selectAddressBalance = this.state.addressBalances[selectedRowIndex];
- this.props.dispatcher.updateUserAddress(selectedAddress);
- this.props.blockchain.updateWeb3WrapperPrevUserAddress(selectedAddress);
- this.props.dispatcher.updateUserEtherBalance(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() {
- let userAddresses: string[];
- const addressBalances: BigNumber[] = [];
- try {
- userAddresses = await this._getUserAddressesAsync();
- for (const address of userAddresses) {
- const balance = await this.props.blockchain.getBalanceInEthAsync(address);
- addressBalances.push(balance);
- }
- } catch (err) {
- utils.consoleLog(`Ledger error: ${JSON.stringify(err)}`);
- this.setState({
- didConnectFail: true,
- });
- return false;
- }
- this.setState({
- userAddresses,
- addressBalances,
- });
- return true;
- }
- private _onDerivationPathChanged(e: any, derivationPath: string) {
- let derivationErrMsg = '';
- if (!_.startsWith(derivationPath, VALID_ETHEREUM_DERIVATION_PATH_PREFIX)) {
- derivationErrMsg = 'Must be valid Ethereum path.';
- }
+ constructor(props: LedgerConfigDialogProps) {
+ super(props);
+ this.state = {
+ didConnectFail: false,
+ stepIndex: LedgerSteps.CONNECT,
+ userAddresses: [],
+ addressBalances: [],
+ derivationPath: configs.DEFAULT_DERIVATION_PATH,
+ derivationErrMsg: '',
+ };
+ }
+ public render() {
+ const dialogActions = [
+ <FlatButton key="ledgerConnectCancel" label="Cancel" onTouchTap={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.SELECT_ADDRESS && this._renderSelectAddressStep()}
+ </div>
+ </Dialog>
+ );
+ }
+ private _renderConnectStep() {
+ return (
+ <div>
+ <div className="h4 pt3">Follow these instructions before proceeding:</div>
+ <ol>
+ <li className="pb1">Connect your Ledger Nano S & Open the Ethereum application</li>
+ <li className="pb1">Verify that Browser Support is 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>
+ </ol>
+ <div className="center pb3">
+ <LifeCycleRaisedButton
+ isPrimary={true}
+ labelReady="Connect to Ledger"
+ labelLoading="Connecting..."
+ labelComplete="Connected!"
+ onClickAsyncFn={this._onConnectLedgerClickAsync.bind(this, true)}
+ />
+ {this.state.didConnectFail && (
+ <div className="pt2 left-align" style={{ color: colors.red200 }}>
+ Failed to connect. Follow the instructions and try again.
+ </div>
+ )}
+ </div>
+ </div>
+ );
+ }
+ private _renderSelectAddressStep() {
+ 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() {
+ const rows = _.map(this.state.userAddresses, (userAddress: string, i: number) => {
+ const balance = this.state.addressBalances[i];
+ const addressTooltipId = `address-${userAddress}`;
+ const balanceTooltipId = `balance-${userAddress}`;
+ const networkName = constants.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 balanceString = `${balance.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() {
+ this.setState({
+ didConnectFail: false,
+ });
+ const isOpen = false;
+ this.props.toggleDialogFn(isOpen);
+ }
+ private _onAddressSelected(selectedRowIndexes: number[]) {
+ const selectedRowIndex = selectedRowIndexes[0];
+ this.props.blockchain.updateLedgerDerivationIndex(selectedRowIndex);
+ const selectedAddress = this.state.userAddresses[selectedRowIndex];
+ const selectAddressBalance = this.state.addressBalances[selectedRowIndex];
+ this.props.dispatcher.updateUserAddress(selectedAddress);
+ this.props.blockchain.updateWeb3WrapperPrevUserAddress(selectedAddress);
+ this.props.dispatcher.updateUserEtherBalance(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() {
+ let userAddresses: string[];
+ const addressBalances: BigNumber[] = [];
+ try {
+ userAddresses = await this._getUserAddressesAsync();
+ for (const address of userAddresses) {
+ const balance = await this.props.blockchain.getBalanceInEthAsync(address);
+ addressBalances.push(balance);
+ }
+ } catch (err) {
+ utils.consoleLog(`Ledger error: ${JSON.stringify(err)}`);
+ this.setState({
+ didConnectFail: true,
+ });
+ return false;
+ }
+ this.setState({
+ userAddresses,
+ addressBalances,
+ });
+ return true;
+ }
+ private _onDerivationPathChanged(e: any, derivationPath: string) {
+ let derivationErrMsg = '';
+ if (!_.startsWith(derivationPath, VALID_ETHEREUM_DERIVATION_PATH_PREFIX)) {
+ derivationErrMsg = 'Must be valid Ethereum path.';
+ }
- this.setState({
- derivationPath,
- derivationErrMsg,
- });
- }
- private async _onConnectLedgerClickAsync() {
- const didSucceed = await this._fetchAddressesAndBalancesAsync();
- if (didSucceed) {
- this.setState({
- stepIndex: LedgerSteps.SELECT_ADDRESS,
- });
- }
- return didSucceed;
- }
- private async _getUserAddressesAsync(): Promise<string[]> {
- let userAddresses: string[];
- userAddresses = await this.props.blockchain.getUserAccountsAsync();
+ this.setState({
+ derivationPath,
+ derivationErrMsg,
+ });
+ }
+ private async _onConnectLedgerClickAsync() {
+ const didSucceed = await this._fetchAddressesAndBalancesAsync();
+ if (didSucceed) {
+ this.setState({
+ stepIndex: LedgerSteps.SELECT_ADDRESS,
+ });
+ }
+ 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;
- }
+ if (_.isEmpty(userAddresses)) {
+ throw new Error('No addresses retrieved.');
+ }
+ return userAddresses;
+ }
}