View on GitHub
File Changes
  }> = new Action();
  submitUserPassword: Action<{ userPassword: string }> = new Action();
  submitCreate: Action<{}> = new Action();
-
  backToCreate: Action<{}> = new Action();
+
  backToCreate: Action<void> = new Action();
  submitVerify: Action<{}> = new Action();
  createPaperWallet: Action<{}> = new Action();
  createPdfDocument: Action<{}> = new Action();
import React, { Component } from 'react';
import { join } from 'lodash';
import { observer } from 'mobx-react';
+
import { action, observable } from 'mobx';
import classnames from 'classnames';
-
import { Autocomplete } from 'react-polymorph/lib/components/Autocomplete';
+
import ReactToolboxMobxForm from '../../utils/ReactToolboxMobxForm';
import { Button } from 'react-polymorph/lib/components/Button';
import { ButtonSkin } from 'react-polymorph/lib/skins/simple/ButtonSkin';
-
import { defineMessages, intlShape } from 'react-intl';
-
import ReactToolboxMobxForm from '../../utils/ReactToolboxMobxForm';
-
import vjf from 'mobx-react-form/lib/validators/VJF';
+
import { intlShape } from 'react-intl';
import BorderedBox from '../widgets/BorderedBox';
import globalMessages from '../../i18n/global-messages';
import styles from './TransferMnemonicPage.scss';
-
import config from '../../config';
-
import { AutocompleteOwnSkin } from '../../themes/skins/AutocompleteOwnSkin';
-

                      
-
const messages = defineMessages({
-
  recoveryPhraseInputLabel: {
-
    id: 'transfer.form.recovery.phrase.input.label',
-
    defaultMessage: '!!!Recovery phrase',
-
  },
-
  recoveryPhraseInputHint: {
-
    id: 'transfer.form.recovery.phrase.input.hint',
-
    defaultMessage: '!!!Enter recovery phrase',
-
  },
-
  recoveryPhraseNoResults: {
-
    id: 'transfer.form.recovery.phrase.input.noResults',
-
    defaultMessage: '!!!No results',
-
  },
-
  invalidRecoveryPhrase: {
-
    id: 'transfer.form.errors.invalidRecoveryPhrase',
-
    defaultMessage: '!!!Invalid recovery phrase',
-
  },
-
});
+
import MnemonicWidget from '../widgets/MnemonicWidget';

                      
type Props = {|
  onSubmit: { recoveryPhrase: string } => void,
    intl: intlShape.isRequired
  };

                      
-
  form = new ReactToolboxMobxForm({
-
    fields: {
-
      recoveryPhrase: {
-
        label: this.context.intl.formatMessage(messages.recoveryPhraseInputLabel),
-
        placeholder: this.props.classicTheme ?
-
          this.context.intl.formatMessage(messages.recoveryPhraseInputHint) : '',
-
        value: '',
-
        validators: [({ field }) => {
-
          const value = join(field.value, ' ');
-
          const wordsLeft = this.props.mnemonicLength - field.value.length;
-
          if (value === '') return [false, this.context.intl.formatMessage(globalMessages.fieldIsRequired)];
-
          if (wordsLeft > 0) {
-
            return [
-
              false,
-
              this.context.intl.formatMessage(globalMessages.shortRecoveryPhrase,
-
                { number: wordsLeft })
-
            ];
-
          }
-
          return [
-
            this.props.mnemonicValidator(value),
-
            this.context.intl.formatMessage(messages.invalidRecoveryPhrase)
-
          ];
-
        }],
-
      },
-
    },
-
  }, {
-
    options: {
-
      validateOnChange: true,
-
      validationDebounceWait: config.forms.FORM_VALIDATION_DEBOUNCE_WAIT,
-
    },
-
    plugins: {
-
      vjf: vjf()
-
    },
-
  });
+
  @observable mnemonicForm: void | ReactToolboxMobxForm;
+

                      
+
  @action
+
  setMnemonicFrom(form: ReactToolboxMobxForm) {
+
    this.mnemonicForm = form;
+
  }

                      
  submit = () => {
-
    this.form.submit({
+
    if (this.mnemonicForm == null) {
+
      throw new Error('TransferMnemonicPage form not set');
+
    }
+
    this.mnemonicForm.submit({
      onSuccess: (form) => {
        const { recoveryPhrase } = form.values();
        const payload = {

                      
  render() {
    const { intl } = this.context;
-
    const { form } = this;
    const {
-
      validWords,
      onBack,
      step0,
-
      mnemonicValidator,
-
      mnemonicLength,
      classicTheme
    } = this.props;
-
    const { recoveryPhrase } = form.values();

                      
    const nextButtonClasses = classnames([
      'proceedTransferButtonClasses',
      styles.button,
    ]);

                      
-
    const recoveryPhraseField = form.$('recoveryPhrase');
-

                      
    return (
      <div className={styles.component}>
        <BorderedBox>
              </ul>
            </div>

                      
-
            <Autocomplete
-
              className={styles.inputWrapper}
-
              options={validWords}
-
              maxSelections={mnemonicLength}
-
              {...recoveryPhraseField.bind()}
-
              done={mnemonicValidator(join(recoveryPhrase, ' '))}
-
              error={recoveryPhraseField.error}
-
              maxVisibleOptions={5}
-
              noResultsMessage={intl.formatMessage(messages.recoveryPhraseNoResults)}
-
              skin={AutocompleteOwnSkin}
+
            <MnemonicWidget
+
              setForm={(form) => this.setMnemonicFrom(form)}
+
              mnemonicValidator={this.props.mnemonicValidator}
+
              validWords={this.props.validWords}
+
              mnemonicLength={this.props.mnemonicLength}
+
              classicTheme={this.props.classicTheme}
            />

                      
            <div className={styles.buttonsWrapper}>
|};

                      
type Props = {|
-
  onSubmit: Function,
-
  onCancel: Function,
-
  onBack?: Function,
+
  onSubmit: WalletRestoreDialogValues => void,
+
  onCancel: void => void,
+
  onBack?: void => void,
  isSubmitting: boolean,
-
  mnemonicValidator: Function,
-
  passwordValidator?: Function,
+
  mnemonicValidator: string => boolean,
+
  passwordValidator?: string => boolean,
  numberOfMnemonics: number,
  error?: ?LocalizableError,
  validWords: Array<string>,
import styles from './DialogBackButton.scss';

                      
type Props = {|
-
  onBack: Function
+
  onBack: void => void
|};

                      
export default class DialogBackButton extends Component<Props> {
+
// @flow
+
import React, { Component } from 'react';
+
import { join } from 'lodash';
+
import { observer } from 'mobx-react';
+
import { Autocomplete } from 'react-polymorph/lib/components/Autocomplete';
+
import { defineMessages, intlShape } from 'react-intl';
+
import type { $npm$ReactIntl$IntlFormat } from 'react-intl';
+
import ReactToolboxMobxForm from '../../utils/ReactToolboxMobxForm';
+
import vjf from 'mobx-react-form/lib/validators/VJF';
+
import globalMessages from '../../i18n/global-messages';
+
import styles from './MnemonicWidget.scss';
+
import config from '../../config';
+
import { AutocompleteOwnSkin } from '../../themes/skins/AutocompleteOwnSkin';
+

                      
+
const messages = defineMessages({
+
  recoveryPhraseInputLabel: {
+
    id: 'transfer.form.recovery.phrase.input.label',
+
    defaultMessage: '!!!Recovery phrase',
+
  },
+
  recoveryPhraseInputHint: {
+
    id: 'transfer.form.recovery.phrase.input.hint',
+
    defaultMessage: '!!!Enter recovery phrase',
+
  },
+
  recoveryPhraseNoResults: {
+
    id: 'transfer.form.recovery.phrase.input.noResults',
+
    defaultMessage: '!!!No results',
+
  },
+
  invalidRecoveryPhrase: {
+
    id: 'transfer.form.errors.invalidRecoveryPhrase',
+
    defaultMessage: '!!!Invalid recovery phrase',
+
  },
+
});
+

                      
+
type Props = {|
+
  setForm: ReactToolboxMobxForm => void,
+
  mnemonicValidator: string => boolean,
+
  validWords: Array<string>,
+
  mnemonicLength: number,
+
  classicTheme: boolean,
+
|};
+

                      
+
@observer
+
export default class MnemonicWidget extends Component<Props> {
+

                      
+
  static contextTypes = {
+
    intl: intlShape.isRequired
+
  };
+

                      
+
  form: ReactToolboxMobxForm;
+

                      
+
  constructor(props: Props, context: {| intl: $npm$ReactIntl$IntlFormat |}) {
+
    super(props);
+

                      
+
    this.form = new ReactToolboxMobxForm({
+
      fields: {
+
        recoveryPhrase: {
+
          label: context.intl.formatMessage(messages.recoveryPhraseInputLabel),
+
          placeholder: this.props.classicTheme ?
+
            context.intl.formatMessage(messages.recoveryPhraseInputHint) : '',
+
          value: '',
+
          validators: [({ field }) => {
+
            const value = join(field.value, ' ');
+
            const wordsLeft = this.props.mnemonicLength - field.value.length;
+
            if (value === '') return [false, context.intl.formatMessage(globalMessages.fieldIsRequired)];
+
            if (wordsLeft > 0) {
+
              return [
+
                false,
+
                context.intl.formatMessage(globalMessages.shortRecoveryPhrase,
+
                  { number: wordsLeft })
+
              ];
+
            }
+
            return [
+
              this.props.mnemonicValidator(value),
+
              context.intl.formatMessage(messages.invalidRecoveryPhrase)
+
            ];
+
          }],
+
        },
+
      },
+
    }, {
+
      options: {
+
        validateOnChange: true,
+
        validationDebounceWait: config.forms.FORM_VALIDATION_DEBOUNCE_WAIT,
+
      },
+
      plugins: {
+
        vjf: vjf()
+
      },
+
    });
+

                      
+
    this.props.setForm(this.form);
+
  }
+

                      
+
  render() {
+
    const { intl } = this.context;
+
    const { form } = this;
+
    const {
+
      validWords,
+
      mnemonicValidator,
+
      mnemonicLength,
+
    } = this.props;
+
    const { recoveryPhrase } = form.values();
+

                      
+
    const recoveryPhraseField = form.$('recoveryPhrase');
+

                      
+
    return (
+
      <Autocomplete
+
        className={styles.inputWrapper}
+
        options={validWords}
+
        maxSelections={mnemonicLength}
+
        {...recoveryPhraseField.bind()}
+
        done={mnemonicValidator(join(recoveryPhrase, ' '))}
+
        error={recoveryPhraseField.error}
+
        maxVisibleOptions={5}
+
        noResultsMessage={intl.formatMessage(messages.recoveryPhraseNoResults)}
+
        skin={AutocompleteOwnSkin}
+
      />
+
    );
+
  }
+
}
+
:global(.YoroiModern) {
+
  .inputWrapper span[class*='selectedWordBox'] {
+
    background-color: var(--rp-autocomplete-selected-word-box-bg-color-secondary);
+
  }
+
}
import type { InjectedContainerProps } from '../types/injectedPropsType';
import type { ServerStatusErrorType } from '../types/serverStatusErrorType';

                      
-
export type MainLayoutProps = InjectedContainerProps & {
+
export type MainLayoutProps = {|
+
  ...InjectedContainerProps,
  topbar?: Node,
  classicTheme: boolean,
  connectionErrorType: ServerStatusErrorType,
-
};
+
|};

                      
@observer
export default class MainLayout extends Component<MainLayoutProps> {
  static defaultProps = {
    topbar: null,
-
    connectionErrorType: null,
  };

                      

                      
type Props = {|
  onSubmit: { recoveryPhrase: string } => void,
  onBack: Function,
-
  mnemonicValidator: Function,
+
  mnemonicValidator: string => boolean,
  validWords: Array<string>,
  mnemonicLength: number,
  classicTheme: boolean,
    const wallets = this._getWalletsStore();
    const daedalusTransfer = this._getDaedalusTransferStore();

                      
+
    console.log(daedalusTransfer.status);
    switch (daedalusTransfer.status) {
      case TransferStatus.UNINITIALIZED:
        return (
            <DaedalusTransferFormPage
              onSubmit={this.setupTransferFundsWithMnemonic}
              onBack={this.backToUninitialized}
-
              mnemonicValidator={mnemonic => wallets.isValidMnemonic(
+
              mnemonicValidator={mnemonic => wallets.isValidMnemonic({
                mnemonic,
-
                config.wallets.DAEDALUS_RECOVERY_PHRASE_WORD_COUNT
-
              )}
+
                numberOfWords: config.wallets.DAEDALUS_RECOVERY_PHRASE_WORD_COUNT
+
              })}
              validWords={validWords}
              mnemonicLength={config.wallets.DAEDALUS_RECOVERY_PHRASE_WORD_COUNT}
              classicTheme={profile.isClassicTheme}
            <DaedalusTransferFormPage
              onSubmit={this.setupTransferFundsWithMnemonic}
              onBack={this.backToUninitialized}
-
              mnemonicValidator={mnemonic => wallets.isValidPaperMnemonic(
+
              mnemonicValidator={mnemonic => wallets.isValidPaperMnemonic({
                mnemonic,
-
                config.wallets.DAEDALUS_PAPER_RECOVERY_PHRASE_WORD_COUNT
-
              )}
+
                numberOfWords: config.wallets.DAEDALUS_PAPER_RECOVERY_PHRASE_WORD_COUNT
+
              })}
              validWords={validWords}
              mnemonicLength={config.wallets.DAEDALUS_PAPER_RECOVERY_PHRASE_WORD_COUNT}
              classicTheme={profile.isClassicTheme}
            <YoroiTransferFormPage
              onSubmit={this.setupTransferFundsWithMnemonic}
              onBack={this.backToUninitialized}
-
              mnemonicValidator={mnemonic => wallets.isValidMnemonic(
+
              mnemonicValidator={mnemonic => wallets.isValidMnemonic({
                mnemonic,
-
                config.wallets.WALLET_RECOVERY_PHRASE_WORD_COUNT
-
              )}
+
                numberOfWords: config.wallets.WALLET_RECOVERY_PHRASE_WORD_COUNT
+
              })}
              validWords={validWords}
              mnemonicLength={config.wallets.WALLET_RECOVERY_PHRASE_WORD_COUNT}
              classicTheme={profile.isClassicTheme}
            <YoroiTransferFormPage
              onSubmit={this.setupTransferFundsWithMnemonic}
              onBack={this.backToUninitialized}
-
              mnemonicValidator={mnemonic => wallets.isValidPaperMnemonic(
+
              mnemonicValidator={mnemonic => wallets.isValidPaperMnemonic({
                mnemonic,
-
                config.wallets.YOROI_PAPER_RECOVERY_PHRASE_WORD_COUNT
-
              )}
+
                numberOfWords: config.wallets.YOROI_PAPER_RECOVERY_PHRASE_WORD_COUNT
+
              })}
              validWords={validWords}
              mnemonicLength={config.wallets.YOROI_PAPER_RECOVERY_PHRASE_WORD_COUNT}
              classicTheme={profile.isClassicTheme}

                      
import type { UriParams } from '../../utils/URIHandling';

                      
-
type Props = InjectedDialogContainerProps & {
+
type Props = {|
+
  ...InjectedDialogContainerProps,
  onConfirm: void => void,
  uriParams: ?UriParams,
-
};
-

                      
+
|};

                      
@observer
export default class URILandingDialogContainer extends Component<Props> {
            onSubmit={paperActions.submitVerify.trigger}
            onCancel={onCancel}
            onBack={paperActions.backToCreate.trigger}
-
            numberOfMnemonics={21}
-
            mnemonicValidator={words => paperStore.paper && words === paperStore.paper.scrambledWords.join(' ')}
+
            numberOfMnemonics={config.wallets.YOROI_PAPER_RECOVERY_PHRASE_WORD_COUNT}
+
            mnemonicValidator={words => (
+
              paperStore.paper != null && words === paperStore.paper.scrambledWords.join(' ')
+
            )}
            passwordValidator={pass => pass === paperStore.userPassword}
            isSubmitting={false}
            validWords={validWords}

                      
import { ProgressStep } from '../../../types/HWConnectStoreTypes';

                      
-
type Props = InjectedDialogContainerProps & {
+
type Props = {|
+
  ...InjectedDialogContainerProps,
  onBack: void => void,
-
};
+
|};

                      
@observer
export default class WalletLedgerConnectDialogContainer extends Component<Props> {
declare var CONFIG : ConfigType;
const protocolMagic = CONFIG.network.protocolMagic;

                      
-
type Props = InjectedDialogContainerProps & {
+
type Props = {|
+
  ...InjectedDialogContainerProps,
  mode: "regular" | "paper",
  introMessage?: string,
  onBack: void => void,
-
};
+
|};

                      
const NUMBER_OF_VERIFIED_ADDRESSES = 1;
const NUMBER_OF_VERIFIED_ADDRESSES_PAPER = 5;
export default class WalletRestoreDialogContainer
  extends Component<Props, WalletRestoreDialogContainerState> {

                      
+
  static defaultProps = {
+
    introMessage: undefined
+
  };
+

                      
  state = {
    verifyRestore: undefined,
    submitValues: undefined,
    resolvedRecoveryPhrase: undefined,
-
    notificationElementId: ''
+
    notificationElementId: '',
  };

                      
  onVerifiedSubmit = () => {
      <WalletRestoreDialog
        mnemonicValidator={mnemonic => {
          if (isPaper) {
-
            return wallets.isValidPaperMnemonic(mnemonic, wordsCount);
+
            return wallets.isValidPaperMnemonic({
+
              mnemonic,
+
              numberOfWords: wordsCount
+
            });
          }
-
          return wallets.isValidMnemonic(mnemonic);
+
          return wallets.isValidMnemonic({
+
            mnemonic,
+
            numberOfWords: wordsCount
+
          });
        }}
        validWords={validWords}
        numberOfMnemonics={wordsCount}
}

                      
function getWordsCount(mode: string): number {
-
  return mode === 'paper' ? 21 : 15;
+
  return mode === 'paper'
+
    ? config.wallets.YOROI_PAPER_RECOVERY_PHRASE_WORD_COUNT
+
    : config.wallets.WALLET_RECOVERY_PHRASE_WORD_COUNT;
}
  formattedAmountToNaturalUnits,
} from '../../../utils/formatters';

                      
-
type DialogProps = {
+
type DialogProps = {|
  signRequest: BaseSignRequest,
  currencyUnit: string,
  staleTx: boolean,
-
};
-
type Props = InjectedProps & DialogProps;
+
|};
+
type Props = {|
+
  ...InjectedProps,
+
  ...DialogProps,
+
|};

                      
@observer
export default class WalletSendConfirmationDialogContainer extends Component<Props> {
import { ProgressStep } from '../../../types/HWConnectStoreTypes';
import HWConnectActions from '../../../actions/ada/hw-connect-actions';

                      
-
type Props = InjectedDialogContainerProps & {
+
type Props = {|
+
  ...InjectedDialogContainerProps,
  onBack: void => void,
-
};
+
|};

                      
@observer
export default class WalletTrezorConnectDialogContainer extends Component<Props> {

                      
  isValidAddress = (address: string): Promise<boolean> => this.api.ada.isValidAddress({ address });

                      
-
  isValidMnemonic = (
+
  isValidMnemonic: {|
    mnemonic: string,
-
    numberOfWords: number
-
  ): boolean => this.api.ada.isValidMnemonic({ mnemonic, numberOfWords });
+
    numberOfWords: number,
+
  |} => boolean = request => this.api.ada.isValidMnemonic(request);

                      
-
  isValidPaperMnemonic = (
+
  isValidPaperMnemonic: {|
    mnemonic: string,
-
    numberOfWords: number
-
  ): boolean => this.api.ada.isValidPaperMnemonic({ mnemonic, numberOfWords });
+
    numberOfWords: number,
+
  |} => boolean = request => this.api.ada.isValidPaperMnemonic(request);

                      
  // =================== WALLET RESTORATION ==================== //

                      
  CHECKING_ADDRESSES: 5,
  GENERATING_TX: 6,
  READY_TO_TRANSFER: 7,
-
  ERROR: 7,
-
  SUCCESS: 8,
+
  ERROR: 8,
+
  SUCCESS: 9,
});
export type TransferStatusT = $Values<typeof TransferStatus>;

                      
import type { StoresMap } from '../stores/index';
import type { ActionsMap } from '../actions/index';

                      
-
export type InjectedProps = {
+
export type InjectedProps = {|
  stores: StoresMap,
  actions: ActionsMap,
-
};
+
|};

                      
-
export type InjectedContainerProps = InjectedProps & {
+
export type InjectedContainerProps = {|
+
  ...InjectedProps,
  children?: Node,
-
};
+
|};

                      
-
export type InjectedDialogContainerProps = InjectedContainerProps & {
+
export type InjectedDialogContainerProps = {|
+
  ...InjectedContainerProps,
  onClose: void => void,
  classicTheme: boolean
-
};
+
|};