<commit_before>import { useCallback, createElement as h, useState } from "react";
import { useService } from "@xstate/react";
import { IMMATURE, LIVE, UNMINED } from "constants/decrediton";
import { FormattedMessage as T } from "react-intl";
import SettingMixedAccount from "./SetMixedAcctPage/SetMixedAcctPage";
import ProcessUnmanagedTickets from "./ProcessUnmanagedTickets/ProcessUnmanagedTickets";
import ProcessManagedTickets from "./ProcessManagedTickets/ProcessManagedTickets";
import SettingAccountsPassphrase from "./SetAccountsPassphrase";
import { useDaemonStartup, useAccounts, usePrevious } from "hooks";
import { useDispatch } from "react-redux";
import {
  checkAllAccountsEncrypted,
  setAccountsPass
} from "actions/ControlActions";
import { getVSPsPubkeys } from "actions/VSPActions";
import { ExternalLink } from "shared";
import { DecredLoading } from "indicators";

export const useWalletSetup = (settingUpWalletRef) => {
  const dispatch = useDispatch();

  const [current, send] = useService(settingUpWalletRef);
  const [StateComponent, setStateComponent] = useState(null);
  const {
    getCoinjoinOutputspByAcct,
    stakeTransactions,
    onProcessManagedTickets,
    goToHome,
    onProcessUnmanagedTickets,
    isProcessingUnmanaged,
    isProcessingManaged
  } = useDaemonStartup();

  const { mixedAccount } = useAccounts();

  const previousState = usePrevious(current);

  const onCheckAcctsPass = useCallback(() => {
    return dispatch(checkAllAccountsEncrypted());
  }, [dispatch]);

  const onProcessAccounts = useCallback(
    (passphrase) => {
      return dispatch(setAccountsPass(passphrase));
    },
    [dispatch]
  );

  const onGetVSPsPubkeys = useCallback(() => dispatch(getVSPsPubkeys()), [
    dispatch
  ]);

  const sendContinue = useCallback(() => {
    send({ type: "CONTINUE" });
  }, [send]);

  const onSendError = useCallback(
    (error) => {
      send({ type: "ERROR", error });
    },
    [send]
  );

  const onSendBack = useCallback(() => {
    send({ type: "BACK" });
  }, [send]);

  const getStateComponent = useCallback(async () => {
    const { error, isWatchingOnly, isTrezor } = current.context;

    let component, hasSoloTickets;

    // check if we have live tickets.
    const hasLive = Object.keys(stakeTransactions).some((hash) => {
      const tx = stakeTransactions[hash];
      // check if the wallet has at least one vsp live ticket.
      if (
        tx.status === IMMATURE ||
        tx.status === LIVE ||
        tx.status === UNMINED
      ) {
        // On old vsp the fee is an input. So if the tx has more than one
        // input, it means it is an old vsp ticket and have no feeStatus.
        // So we can skip it.
        if (tx.txInputs.length !== 1) {
          return false;
        }
        return true;
      }
    });

    if (previousState && current.value === previousState.value) return;

    switch (current.value) {
      case "settingAccountsPass": {
        // step not needed with trezor or watching only wallets.
        if (isWatchingOnly || isTrezor) {
          sendContinue();
          return;
        }
        const allEncrypted = onCheckAcctsPass();
        if (allEncrypted) {
          sendContinue();
        } else {
          component = h(SettingAccountsPassphrase, {
            error,
            onSendContinue: sendContinue,
            onSendError,
            send,
            title: (
              <T
                id="getstarted.setAccountsPass.title"
                m="Migrate to per-account passphrases"
              />
            ),
            onProcessAccounts,
            description: (
              <T
                id="getstarted.setAccountsPass.description"
                m={`Decrediton now uses per-account locking, which requires a one time migration.
                  Enter your current passphrase to perform this upgrade.
                  Visit {link} to know more.`}
                values={{
                  link: (
                    <ExternalLink
                      href={
                        "https://docs.decred.org/wallets/decrediton/migrations"
                      }>
                      <T id="getstarted.setAccountsPass.docs" m="Decred docs" />
                    </ExternalLink>
                  )
                }}
              />
            )
          });
        }
        break;
      }
      case "settingMixedAccount":
        getCoinjoinOutputspByAcct()
          .then((outputsByAcctMap) => {
            const hasMixedOutputs =
              outputsByAcctMap &&
              outputsByAcctMap.reduce(
                (foundMixed, { coinjoinSum }) => coinjoinSum > 0 || foundMixed,
                false
              );
            if (!hasMixedOutputs || mixedAccount) {
              sendContinue();
            } else {
              component = h(SettingMixedAccount, {
                cancel: sendContinue,
                sendContinue
              });
            }
          })
          .catch((err) => console.log(err));
        break;
      case "gettingVSPInfo":<commit_msg>[startup] Coinjoin account selection not showing on setup (#3434)<commit_after>import { useCallback, createElement as h, useState } from "react";
import { useService } from "@xstate/react";
import { IMMATURE, LIVE, UNMINED } from "constants/decrediton";
import { FormattedMessage as T } from "react-intl";
import SettingMixedAccount from "./SetMixedAcctPage/SetMixedAcctPage";
import ProcessUnmanagedTickets from "./ProcessUnmanagedTickets/ProcessUnmanagedTickets";
import ProcessManagedTickets from "./ProcessManagedTickets/ProcessManagedTickets";
import SettingAccountsPassphrase from "./SetAccountsPassphrase";
import { useDaemonStartup, useAccounts, usePrevious } from "hooks";
import { useDispatch } from "react-redux";
import {
  checkAllAccountsEncrypted,
  setAccountsPass
} from "actions/ControlActions";
import { getVSPsPubkeys } from "actions/VSPActions";
import { ExternalLink } from "shared";
import { DecredLoading } from "indicators";

export const useWalletSetup = (settingUpWalletRef) => {
  const dispatch = useDispatch();

  const [current, send] = useService(settingUpWalletRef);
  const [StateComponent, setStateComponent] = useState(null);
  const {
    getCoinjoinOutputspByAcct,
    stakeTransactions,
    onProcessManagedTickets,
    goToHome,
    onProcessUnmanagedTickets,
    isProcessingUnmanaged,
    isProcessingManaged
  } = useDaemonStartup();

  const { mixedAccount } = useAccounts();

  const previousState = usePrevious(current);

  const onCheckAcctsPass = useCallback(() => {
    return dispatch(checkAllAccountsEncrypted());
  }, [dispatch]);

  const onProcessAccounts = useCallback(
    (passphrase) => {
      return dispatch(setAccountsPass(passphrase));
    },
    [dispatch]
  );

  const onGetVSPsPubkeys = useCallback(() => dispatch(getVSPsPubkeys()), [
    dispatch
  ]);

  const sendContinue = useCallback(() => {
    send({ type: "CONTINUE" });
  }, [send]);

  const onSendError = useCallback(
    (error) => {
      send({ type: "ERROR", error });
    },
    [send]
  );

  const onSendBack = useCallback(() => {
    send({ type: "BACK" });
  }, [send]);

  const getStateComponent = useCallback(async () => {
    const { error, isWatchingOnly, isTrezor } = current.context;

    let component, hasSoloTickets;

    // check if we have live tickets.
    const hasLive = Object.keys(stakeTransactions).some((hash) => {
      const tx = stakeTransactions[hash];
      // check if the wallet has at least one vsp live ticket.
      if (
        tx.status === IMMATURE ||
        tx.status === LIVE ||
        tx.status === UNMINED
      ) {
        // On old vsp the fee is an input. So if the tx has more than one
        // input, it means it is an old vsp ticket and have no feeStatus.
        // So we can skip it.
        if (tx.txInputs.length !== 1) {
          return false;
        }
        return true;
      }
    });

    if (previousState && current.value === previousState.value) return;

    switch (current.value) {
      case "settingAccountsPass": {
        // step not needed with trezor or watching only wallets.
        if (isWatchingOnly || isTrezor) {
          sendContinue();
          return;
        }
        const allEncrypted = onCheckAcctsPass();
        if (allEncrypted) {
          sendContinue();
        } else {
          component = h(SettingAccountsPassphrase, {
            error,
            onSendContinue: sendContinue,
            onSendError,
            send,
            title: (
              <T
                id="getstarted.setAccountsPass.title"
                m="Migrate to per-account passphrases"
              />
            ),
            onProcessAccounts,
            description: (
              <T
                id="getstarted.setAccountsPass.description"
                m={`Decrediton now uses per-account locking, which requires a one time migration.
                  Enter your current passphrase to perform this upgrade.
                  Visit {link} to know more.`}
                values={{
                  link: (
                    <ExternalLink
                      href={
                        "https://docs.decred.org/wallets/decrediton/migrations"
                      }>
                      <T id="getstarted.setAccountsPass.docs" m="Decred docs" />
                    </ExternalLink>
                  )
                }}
              />
            )
          });
        }
        break;
      }
      case "settingMixedAccount":
        {
          const outputsByAcctMap = await getCoinjoinOutputspByAcct();
          const hasMixedOutputs =
            outputsByAcctMap &&
            outputsByAcctMap.reduce(
              (foundMixed, { coinjoinSum }) => coinjoinSum > 0 || foundMixed,
              false
            );
          if (!hasMixedOutputs || mixedAccount) {
            sendContinue();
          } else {
            component = h(SettingMixedAccount, {
              cancel: sendContinue,
              onSendContinue: sendContinue
            });
          }
        }
        break;
      case "gettingVSPInfo":
{'fraction_non_alphanumeric': 0.1042896497441952, 'fraction_numerical': 0.0007870916961826052, 'mean_word_length': 2.0877885783718106, 'pattern_counts': {'":': 6, '<': 13, '<?xml version=': 0, '>': 37, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4736861', 'n_tokens_mistral': 2839, 'n_tokens_neox': 2747, 'n_words': 672}