From 936820aab6564a292474a5e083680d767f235c0d Mon Sep 17 00:00:00 2001 From: David Hill Date: Tue, 22 Nov 2022 16:30:58 -0500 Subject: [PATCH] build: update prettier to 2.7.1 (#3827) --- .github/workflows/nodejs.yml | 10 +- .prettierrc | 4 +- app/actions/AccountMixerActions.js | 252 ++-- app/actions/ClientActions.js | 203 ++- app/actions/ControlActions.js | 1258 ++++++++--------- app/actions/DaemonActions.js | 310 ++-- app/actions/DexActions.js | 157 +- app/actions/GovernanceActions.js | 399 +++--- app/actions/LNActions.js | 756 +++++----- app/actions/SettingsActions.js | 72 +- app/actions/StatisticsActions.js | 8 +- app/actions/TransactionActions.js | 425 +++--- app/actions/TrezorActions.js | 306 ++-- app/actions/VSPActions.js | 841 ++++++----- app/actions/VersionActions.js | 100 +- app/actions/WalletLoaderActions.js | 385 +++-- .../SideBar/MenuBottom/LastBlockTime/hooks.js | 10 +- app/components/SideBar/SideBar.jsx | 8 +- app/components/SideBar/hooks.js | 14 +- app/components/buttons/index.js | 21 +- app/components/modals/Modal/Modal.jsx | 9 +- app/components/modals/Modal/hooks.js | 7 +- .../modals/TrezorModals/TrezorModals.jsx | 6 +- .../TrezorWalletCreationPassphraseModal.jsx | 8 +- app/components/shared/LoadingError.jsx | 7 +- app/components/shared/PoliteiaLink.jsx | 7 +- .../views/AccountsPage/AccountsPage.jsx | 6 +- .../views/AgendaDetailsPage/hooks.js | 7 +- .../views/DexPage/InitPage/InitPage.jsx | 16 +- app/components/views/DexPage/hooks.js | 14 +- .../AdvancedStartup/AdvancedStartup.jsx | 5 +- .../GetStartedPage/CreateWalletPage/hooks.js | 14 +- .../LanguageSelectPage/LanguageSelectPage.jsx | 8 +- .../ResendVotesToRecentlyUpdatedVSPs.jsx | 6 +- .../SetupWallet/SetupWallet.jsx | 5 +- .../views/GetStartedPage/SetupWallet/hooks.js | 7 +- app/components/views/GetStartedPage/hooks.js | 13 +- .../ProposalsListItem/ProposalsListItem.jsx | 8 +- .../views/GovernancePage/Proposals/hooks.js | 8 +- .../Tabs/TransactionsTab/TransactionsTab.jsx | 7 +- .../views/LNPage/AdvancedTab/AdvancedTab.jsx | 9 +- .../AdvancedTab/Watchtowers/Watchtowers.jsx | 8 +- .../views/LNPage/AdvancedTab/hooks.js | 9 +- .../views/LNPage/ChannelDetailsPage/hooks.js | 15 +- .../views/LNPage/ReceiveTab/hooks.js | 9 +- app/components/views/LNPage/hooks.js | 14 +- .../ValidateAddress/ValidateAddress.jsx | 7 +- .../views/ProposalDetailsPage/hooks.js | 15 +- .../views/SettingsPage/LogsTab/LogsTab.jsx | 18 +- .../TutorialsTab/helpers/tutorials.js | 30 +- app/components/views/ShutdownPage/hooks.js | 7 +- .../TicketsPage/MyTicketsTab/MyTicketsTab.jsx | 8 +- .../PurchaseTab/TicketAutoBuyer/hooks.js | 7 +- .../views/TicketsPage/TicketsPage.jsx | 7 +- .../HistoryTab/HistoryTab.jsx | 18 +- app/components/views/TrezorPage/hooks.js | 28 +- .../TutorialsPage/PagedTutorial/hooks.js | 7 +- .../StandardPage/StandardPage.jsx | 5 +- app/containers/App/App.jsx | 8 +- app/fp.js | 39 +- app/helpers/electronRenderer.js | 5 +- app/hooks/useDaemonStartup.js | 91 +- app/hooks/useRescan.js | 14 +- app/hooks/useSettings.js | 7 +- app/hooks/useTrezor.js | 49 +- app/middleware/grpc/client.js | 72 +- app/middleware/ln/client.js | 112 +- app/selectors.js | 10 +- app/wallet/app.js | 60 +- app/wallet/control.js | 9 +- app/wallet/loader.js | 4 +- app/wallet/service.js | 10 +- package.json | 2 +- test/unit/actions/AccountMixerActions.spec.js | 28 +- test/unit/actions/ControlActions.spec.js | 173 +-- test/unit/actions/DaemonActions.spec.js | 10 +- test/unit/actions/DexActions.spec.js | 5 +- test/unit/actions/SettingsActions.spec.js | 15 +- test/unit/actions/TransactionActions.spec.js | 12 +- test/unit/components/SideBar/Sidebar.spec.js | 15 +- .../buttons/SendTransactionButton.spec.js | 7 +- .../AnimatedLinearProgressFull.spec.js | 11 +- .../views/AccountsPage/AccountsPage.spec.js | 25 +- .../components/views/DexPage/DexPage.spec.js | 12 +- .../GetStaredPage/AdvancedStartup.spec.js | 13 +- .../views/GetStaredPage/CreateWallet.spec.js | 175 +-- .../GetStaredPage/GetStartedPage.spec.js | 28 +- .../GetStaredPage/PreCreateWallet.spec.js | 47 +- .../views/GetStaredPage/PrivacyPage.spec.js | 5 +- .../GetStaredPage/SetMixedAcctPage.spec.js | 9 +- .../GetStaredPage/WalletSelection.spec.js | 63 +- .../views/LNPage/AdvancedTab.spec.js | 4 +- .../views/LNPage/OverviewTab.spec.js | 4 +- .../views/LNPage/ReceiveTab.spec.js | 8 +- .../components/views/LNPage/SendTab.spec.js | 16 +- .../views/PrivacyPage/PrivacyTab.spec.js | 10 +- .../views/PrivacyPage/SecurityTab.spec.js | 241 ++-- .../views/SettingsPage/SettingsPage.spec.js | 25 +- .../MyTicketsTab/MyTicketsTab.spec.js | 10 +- .../PurchaseTab/PurchasePage.spec.js | 10 +- .../TransactionPage/TransactionPage.spec.js | 10 +- .../components/views/TransactionPage/mocks.js | 3 +- .../mocks_decodedTransactions.js | 366 +++-- .../mocks_stakeTransactions.js | 3 +- .../HistoryTab/HistoryTab.spec.js | 12 +- .../ReceiveTab/ReceiveTab.spec.js | 4 +- .../TransactionsPage/SendTab/SendTab.spec.js | 9 +- .../views/TrezorPage/TrezorPage.spec.js | 18 +- test/unit/helpers/date.spec.js | 160 +-- yarn.lock | 8 +- 110 files changed, 3834 insertions(+), 4160 deletions(-) diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 371fe2aa5e..2457010322 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -1,5 +1,7 @@ name: Build and Test on: [push, pull_request] +permissions: + contents: read jobs: build: @@ -9,13 +11,13 @@ jobs: node-version: [14.x] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 #v3.1.0 - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@84cbf8094393cdc5fe1fe1671ff2647332956b1a #v3.2.1 with: - go-version: 1.18 + go-version: 1.19 - name: Use nodejs ${{ matrix.node-version }} - uses: actions/setup-node@v3 + uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 #v3.5.1 with: node-version: ${{ matrix.node-version }} diff --git a/.prettierrc b/.prettierrc index 15c593d6af..43ea455237 100644 --- a/.prettierrc +++ b/.prettierrc @@ -7,8 +7,8 @@ "useTabs": false, "jsxSingleQuote": false, "bracketSpacing": true, - "jsxBracketSameLine": true, + "bracketSameLine": true, "arrowParens": "always", "endOfLine": "lf", "trailingComma": "none" -} \ No newline at end of file +} diff --git a/app/actions/AccountMixerActions.js b/app/actions/AccountMixerActions.js index 1e2e4ad0ea..3389702f9e 100644 --- a/app/actions/AccountMixerActions.js +++ b/app/actions/AccountMixerActions.js @@ -70,84 +70,88 @@ export const RUNACCOUNTMIXER_NOBALANCE = "RUNACCOUNTMIXER_NOBALANCE"; export const RUNACCOUNTMIXER_SUFFICIENTBALANCE = "RUNACCOUNTMIXER_SUFFICIENTBALANCE"; -export const checkUnmixedAccountBalance = (changeAccount) => async ( - dispatch -) => { - const spendableBal = await dispatch(getAcctSpendableBalance(changeAccount)); - if (spendableBal < MIN_RELAY_FEE_ATOMS + MIN_MIX_DENOMINATION_ATOMS) { - dispatch({ - error: ( - - ), - type: RUNACCOUNTMIXER_NOBALANCE - }); - } else { - dispatch({ - type: RUNACCOUNTMIXER_SUFFICIENTBALANCE - }); - } -}; +export const checkUnmixedAccountBalance = + (changeAccount) => async (dispatch) => { + const spendableBal = await dispatch(getAcctSpendableBalance(changeAccount)); + if (spendableBal < MIN_RELAY_FEE_ATOMS + MIN_MIX_DENOMINATION_ATOMS) { + dispatch({ + error: ( + + ), + type: RUNACCOUNTMIXER_NOBALANCE + }); + } else { + dispatch({ + type: RUNACCOUNTMIXER_SUFFICIENTBALANCE + }); + } + }; -export const runAccountMixer = ({ - passphrase, - mixedAccount, - mixedAccountBranch, - changeAccount, - csppServer -}) => (dispatch, getState) => - new Promise((resolve) => { - dispatch({ type: RUNACCOUNTMIXER_ATTEMPT }); - const accountUnlocks = [changeAccount]; - const runMixerAsync = async () => { - const mixerStreamer = await dispatch( - unlockAcctAndExecFn( - passphrase, - accountUnlocks, - () => - wallet.runAccountMixerRequest(sel.accountMixerService(getState()), { - mixedAccount, - mixedAccountBranch, - changeAccount, - csppServer - }), - true - ) - ); - return { mixerStreamer }; - }; +export const runAccountMixer = + ({ + passphrase, + mixedAccount, + mixedAccountBranch, + changeAccount, + csppServer + }) => + (dispatch, getState) => + new Promise((resolve) => { + dispatch({ type: RUNACCOUNTMIXER_ATTEMPT }); + const accountUnlocks = [changeAccount]; + const runMixerAsync = async () => { + const mixerStreamer = await dispatch( + unlockAcctAndExecFn( + passphrase, + accountUnlocks, + () => + wallet.runAccountMixerRequest( + sel.accountMixerService(getState()), + { + mixedAccount, + mixedAccountBranch, + changeAccount, + csppServer + } + ), + true + ) + ); + return { mixerStreamer }; + }; - runMixerAsync() - .then(async (resp) => { - const { mixerStreamer, error } = resp; - // we can throw errors, like when the account has a small balance, - // so this check is necessary. - if (error) { + runMixerAsync() + .then(async (resp) => { + const { mixerStreamer, error } = resp; + // we can throw errors, like when the account has a small balance, + // so this check is necessary. + if (error) { + await dispatch({ error: error + "", type: RUNACCOUNTMIXER_FAILED }); + dispatch(relockAccounts(accountUnlocks)); + return; + } + mixerStreamer.on("data", () => resolve()); + mixerStreamer.on("error", (error) => { + // if context was cancelled we can ignore it, as it probably means + // mixer was stopped. + if (!String(error).includes("Cancelled")) { + dispatch({ error: error + "", type: RUNACCOUNTMIXER_FAILED }); + } + }); + mixerStreamer.on("end", (data) => { + // not supposed to get here, but if it does, we log to see. + console.log(data); + }); + dispatch({ type: RUNACCOUNTMIXER_SUCCESS, mixerStreamer }); + }) + .catch(async (error) => { await dispatch({ error: error + "", type: RUNACCOUNTMIXER_FAILED }); dispatch(relockAccounts(accountUnlocks)); - return; - } - mixerStreamer.on("data", () => resolve()); - mixerStreamer.on("error", (error) => { - // if context was cancelled we can ignore it, as it probably means - // mixer was stopped. - if (!String(error).includes("Cancelled")) { - dispatch({ error: error + "", type: RUNACCOUNTMIXER_FAILED }); - } - }); - mixerStreamer.on("end", (data) => { - // not supposed to get here, but if it does, we log to see. - console.log(data); }); - dispatch({ type: RUNACCOUNTMIXER_SUCCESS, mixerStreamer }); - }) - .catch(async (error) => { - await dispatch({ error: error + "", type: RUNACCOUNTMIXER_FAILED }); - dispatch(relockAccounts(accountUnlocks)); - }); - }); + }); export const STOPMIXER_ATTEMPT = "STOPMIXER_ATTEMPT"; export const STOPMIXER_FAILED = "STOPMIXER_FAILED"; @@ -177,66 +181,62 @@ export const CREATEMIXERACCOUNTS_ATTEMPT = "CREATEMIXERACCOUNTS_ATTEMPT"; export const CREATEMIXERACCOUNTS_FAILED = "CREATEMIXERACCOUNTS_FAILED"; export const CREATEMIXERACCOUNTS_SUCCESS = "CREATEMIXERACCOUNTS_SUCCESS"; -export const createNeededAccounts = ( - passphrase, - mixedAccountName, - changeAccountName -) => async (dispatch) => { - dispatch({ type: CREATEMIXERACCOUNTS_ATTEMPT }); +export const createNeededAccounts = + (passphrase, mixedAccountName, changeAccountName) => async (dispatch) => { + dispatch({ type: CREATEMIXERACCOUNTS_ATTEMPT }); - try { - const mixedAccount = await dispatch( - getNextAccountAttempt(passphrase, mixedAccountName) - ); - const changeAccount = await dispatch( - getNextAccountAttempt(passphrase, changeAccountName) - ); + try { + const mixedAccount = await dispatch( + getNextAccountAttempt(passphrase, mixedAccountName) + ); + const changeAccount = await dispatch( + getNextAccountAttempt(passphrase, changeAccountName) + ); - // update accounts selectors - dispatch(getAccountsAttempt(true)); - const mixedNumber = mixedAccount.getNextAccountResponse.accountNumber; - const changeNumber = changeAccount.getNextAccountResponse.accountNumber; + // update accounts selectors + dispatch(getAccountsAttempt(true)); + const mixedNumber = mixedAccount.getNextAccountResponse.accountNumber; + const changeNumber = changeAccount.getNextAccountResponse.accountNumber; - dispatch( - setCoinjoinCfg({ - mixedNumber, - changeNumber - }) - ); - dispatch(getMixerAcctsSpendableBalances()); - } catch (error) { - dispatch({ type: CREATEMIXERACCOUNTS_FAILED, error }); - } -}; + dispatch( + setCoinjoinCfg({ + mixedNumber, + changeNumber + }) + ); + dispatch(getMixerAcctsSpendableBalances()); + } catch (error) { + dispatch({ type: CREATEMIXERACCOUNTS_FAILED, error }); + } + }; -export const setCoinjoinCfg = ({ mixedNumber, changeNumber }) => ( - dispatch, - getState -) => { - const isTestnet = sel.isTestNet(getState()); - const walletName = sel.getWalletName(getState()); - const cfg = wallet.getWalletCfg(isTestnet, walletName); +export const setCoinjoinCfg = + ({ mixedNumber, changeNumber }) => + (dispatch, getState) => { + const isTestnet = sel.isTestNet(getState()); + const walletName = sel.getWalletName(getState()); + const cfg = wallet.getWalletCfg(isTestnet, walletName); - const csppServer = CSPP_URL; - const csppPort = isTestnet ? CSPP_PORT_TESTNET : CSPP_PORT_MAINNET; + const csppServer = CSPP_URL; + const csppPort = isTestnet ? CSPP_PORT_TESTNET : CSPP_PORT_MAINNET; - cfg.set(CSPP_SERVER, csppServer); - cfg.set(CSPP_PORT, csppPort); - cfg.set(MIXED_ACCOUNT_CFG, mixedNumber); - cfg.set(CHANGE_ACCOUNT_CFG, changeNumber); - cfg.set(MIXED_ACC_BRANCH, 0); - // by default it is only allowed to send from mixed account. - cfg.set(SEND_FROM_UNMIXED, false); + cfg.set(CSPP_SERVER, csppServer); + cfg.set(CSPP_PORT, csppPort); + cfg.set(MIXED_ACCOUNT_CFG, mixedNumber); + cfg.set(CHANGE_ACCOUNT_CFG, changeNumber); + cfg.set(MIXED_ACC_BRANCH, 0); + // by default it is only allowed to send from mixed account. + cfg.set(SEND_FROM_UNMIXED, false); - dispatch({ - type: CREATEMIXERACCOUNTS_SUCCESS, - mixedAccount: mixedNumber, - changeAccount: changeNumber, - csppPort, - csppServer, - mixedAccountBranch: 0 - }); -}; + dispatch({ + type: CREATEMIXERACCOUNTS_SUCCESS, + mixedAccount: mixedNumber, + changeAccount: changeNumber, + csppPort, + csppServer, + mixedAccountBranch: 0 + }); + }; // getCoinjoinOutputspByAcct get all possible coinjoin outputs which an account // may have. This is used so we can recover privacy wallets and don't miss diff --git a/app/actions/ClientActions.js b/app/actions/ClientActions.js index 35076e61d1..a3f8c3693a 100644 --- a/app/actions/ClientActions.js +++ b/app/actions/ClientActions.js @@ -271,53 +271,48 @@ export const GETBALANCE_ATTEMPT = "GETBALANCE_ATTEMPT"; export const GETBALANCE_FAILED = "GETBALANCE_FAILED"; export const GETBALANCE_SUCCESS = "GETBALANCE_SUCCESS"; -const getBalanceUpdateSuccess = (accountNumber, getBalanceResponse) => ( - dispatch -) => { - const updatedBalance = { - accountNumber, - total: getBalanceResponse.total, - spendable: getBalanceResponse.spendable, - immatureReward: getBalanceResponse.immatureReward, - immatureStakeGeneration: getBalanceResponse.immatureStakeGeneration, - lockedByTickets: getBalanceResponse.lockedByTickets, - votingAuthority: getBalanceResponse.votingAuthority, - unconfirmed: getBalanceResponse.unconfirmed - }; +const getBalanceUpdateSuccess = + (accountNumber, getBalanceResponse) => (dispatch) => { + const updatedBalance = { + accountNumber, + total: getBalanceResponse.total, + spendable: getBalanceResponse.spendable, + immatureReward: getBalanceResponse.immatureReward, + immatureStakeGeneration: getBalanceResponse.immatureStakeGeneration, + lockedByTickets: getBalanceResponse.lockedByTickets, + votingAuthority: getBalanceResponse.votingAuthority, + unconfirmed: getBalanceResponse.unconfirmed + }; - dispatch(updateAccount(updatedBalance)); + dispatch(updateAccount(updatedBalance)); - return updatedBalance; -}; + return updatedBalance; + }; -export const getBalanceUpdateAttempt = (accountNumber, requiredConfs) => ( - dispatch, - getState -) => - wallet - .getBalance(sel.walletService(getState()), accountNumber, requiredConfs) - .then((resp) => dispatch(getBalanceUpdateSuccess(accountNumber, resp))) - .catch((error) => dispatch({ error, type: GETBALANCE_FAILED })); +export const getBalanceUpdateAttempt = + (accountNumber, requiredConfs) => (dispatch, getState) => + wallet + .getBalance(sel.walletService(getState()), accountNumber, requiredConfs) + .then((resp) => dispatch(getBalanceUpdateSuccess(accountNumber, resp))) + .catch((error) => dispatch({ error, type: GETBALANCE_FAILED })); export const GETACCOUNTNUMBER_ATTEMPT = "GETACCOUNTNUMBER_ATTEMPT"; export const GETACCOUNTNUMBER_FAILED = "GETACCOUNTNUMBER_FAILED"; export const GETACCOUNTNUMBER_SUCCESS = "GETACCOUNTNUMBER_SUCCESS"; -export const getAccountNumberAttempt = (accountName) => ( - dispatch, - getState -) => { - dispatch({ type: GETACCOUNTNUMBER_ATTEMPT }); - wallet - .getAccountNumber(sel.walletService(getState()), accountName) - .then((resp) => - dispatch({ - getAccountNumberResponse: resp, - type: GETACCOUNTNUMBER_SUCCESS - }) - ) - .catch((error) => dispatch({ error, type: GETACCOUNTNUMBER_FAILED })); -}; +export const getAccountNumberAttempt = + (accountName) => (dispatch, getState) => { + dispatch({ type: GETACCOUNTNUMBER_ATTEMPT }); + wallet + .getAccountNumber(sel.walletService(getState()), accountName) + .then((resp) => + dispatch({ + getAccountNumberResponse: resp, + type: GETACCOUNTNUMBER_SUCCESS + }) + ) + .catch((error) => dispatch({ error, type: GETACCOUNTNUMBER_FAILED })); + }; export const GETBESTBLOCK_ATTEMPT = "GETBESTBLOCK_ATTEMPT"; export const GETBESTBLOCK_FAILED = "GETBESTBLOCK_FAILED"; @@ -676,19 +671,17 @@ export const SETVOTECHOICES_ATTEMPT = "SETVOTECHOICES_ATTEMPT"; export const SETVOTECHOICES_FAILED = "SETVOTECHOICES_FAILED"; export const SETVOTECHOICES_SUCCESS = "SETVOTECHOICES_SUCCESS"; -export const setVoteChoicesAttempt = (agendaId, choiceId, passphrase) => ( - dispatch, - getState -) => { - dispatch({ payload: { agendaId, choiceId }, type: SETVOTECHOICES_ATTEMPT }); - wallet - .setAgendaVote(sel.votingService(getState()), agendaId, choiceId) - .then(() => { - dispatch(setVSPDVoteChoices(passphrase)); - dispatch(getVoteChoicesAttempt()); - }) - .catch((error) => dispatch({ error, type: SETVOTECHOICES_FAILED })); -}; +export const setVoteChoicesAttempt = + (agendaId, choiceId, passphrase) => (dispatch, getState) => { + dispatch({ payload: { agendaId, choiceId }, type: SETVOTECHOICES_ATTEMPT }); + wallet + .setAgendaVote(sel.votingService(getState()), agendaId, choiceId) + .then(() => { + dispatch(setVSPDVoteChoices(passphrase)); + dispatch(getVoteChoicesAttempt()); + }) + .catch((error) => dispatch({ error, type: SETVOTECHOICES_FAILED })); + }; export const GETTREASURY_POLICIES_ATTEMPT = "GETTREASURY_POLICIES_ATTEMPT"; export const GETTREASURY_POLICIES_FAILED = "GETTREASURY_POLICIES_FAILED"; @@ -713,29 +706,27 @@ export const SETTREASURY_POLICY_ATTEMPT = "SETTREASURY_POLICY_ATTEMPT"; export const SETTREASURY_POLICY_FAILED = "SETTREASURY_POLICY_FAILED"; export const SETTREASURY_POLICY_SUCCESS = "SETTREASURY_POLICY_SUCCESS"; -export const setTreasuryPolicy = (key, policy, passphrase) => async ( - dispatch, - getState -) => { - dispatch({ payload: { key, policy }, type: SETTREASURY_POLICY_ATTEMPT }); - try { - await dispatch( - unlockAllAcctAndExecFn(passphrase, () => - wallet - .setTreasuryPolicy(sel.votingService(getState()), key, policy) - .then(() => { - dispatch({ type: SETTREASURY_POLICY_SUCCESS }); - dispatch(getTreasuryPolicies()); - }) - .catch((error) => - dispatch({ error, type: SETTREASURY_POLICY_FAILED }) - ) - ) - ); - } catch (error) { - dispatch({ error, type: SETTREASURY_POLICY_FAILED }); - } -}; +export const setTreasuryPolicy = + (key, policy, passphrase) => async (dispatch, getState) => { + dispatch({ payload: { key, policy }, type: SETTREASURY_POLICY_ATTEMPT }); + try { + await dispatch( + unlockAllAcctAndExecFn(passphrase, () => + wallet + .setTreasuryPolicy(sel.votingService(getState()), key, policy) + .then(() => { + dispatch({ type: SETTREASURY_POLICY_SUCCESS }); + dispatch(getTreasuryPolicies()); + }) + .catch((error) => + dispatch({ error, type: SETTREASURY_POLICY_FAILED }) + ) + ) + ); + } catch (error) { + dispatch({ error, type: SETTREASURY_POLICY_FAILED }); + } + }; export const GETMESSAGEVERIFICATIONSERVICE_ATTEMPT = "GETMESSAGEVERIFICATIONSERVICE_ATTEMPT"; @@ -860,41 +851,37 @@ export const abandonTransactionAttempt = (txid) => (dispatch, getState) => { .catch((error) => dispatch({ error, type: ABANDONTRANSACTION_FAILED })); }; -export const getAcctSpendableBalance = (acctId) => async ( - dispatch, - getState -) => { - const acct = await wallet.getBalance( - sel.walletService(getState()), - acctId, - 0 - ); - return acct?.spendable; -}; +export const getAcctSpendableBalance = + (acctId) => async (dispatch, getState) => { + const acct = await wallet.getBalance( + sel.walletService(getState()), + acctId, + 0 + ); + return acct?.spendable; + }; export const MIXERACCOUNTS_SPENDABLE_BALANCE = "MIXERACCOUNTS_SPENDABLE_BALANCE"; -export const getMixerAcctsSpendableBalances = () => async ( - dispatch, - getState -) => { - const mixedAccount = sel.getMixedAccount(getState()); - const changeAccount = sel.getChangeAccount(getState()); - const balances = {}; - if (!isUndefined(mixedAccount)) { - balances.mixedAccountSpendableBalance = await dispatch( - getAcctSpendableBalance(mixedAccount) - ); - } - if (!isUndefined(changeAccount)) { - balances.changeAccountSpendableBalance = await dispatch( - getAcctSpendableBalance(changeAccount) - ); - } - dispatch({ - balances, - type: MIXERACCOUNTS_SPENDABLE_BALANCE - }); -}; +export const getMixerAcctsSpendableBalances = + () => async (dispatch, getState) => { + const mixedAccount = sel.getMixedAccount(getState()); + const changeAccount = sel.getChangeAccount(getState()); + const balances = {}; + if (!isUndefined(mixedAccount)) { + balances.mixedAccountSpendableBalance = await dispatch( + getAcctSpendableBalance(mixedAccount) + ); + } + if (!isUndefined(changeAccount)) { + balances.changeAccountSpendableBalance = await dispatch( + getAcctSpendableBalance(changeAccount) + ); + } + dispatch({ + balances, + type: MIXERACCOUNTS_SPENDABLE_BALANCE + }); + }; export const goToHomePage = () => (dispatch) => dispatch(pushHistory("/home")); diff --git a/app/actions/ControlActions.js b/app/actions/ControlActions.js index 3a3fec6496..55aaeb4e5c 100644 --- a/app/actions/ControlActions.js +++ b/app/actions/ControlActions.js @@ -66,25 +66,23 @@ export const RENAMEACCOUNT_ATTEMPT = "RENAMEACCOUNT_ATTEMPT"; export const RENAMEACCOUNT_FAILED = "RENAMEACCOUNT_FAILED"; export const RENAMEACCOUNT_SUCCESS = "RENAMEACCOUNT_SUCCESS"; -export const renameAccountAttempt = (accountNumber, newName) => ( - dispatch, - getState -) => { - dispatch({ type: RENAMEACCOUNT_ATTEMPT }); - return wallet - .renameAccount(sel.walletService(getState()), accountNumber, newName) - .then((renameAccountResponse) => { - setTimeout( - () => - dispatch({ - renameAccountResponse, - type: RENAMEACCOUNT_SUCCESS - }), - 1000 - ); - }) - .catch((error) => dispatch({ error, type: RENAMEACCOUNT_FAILED })); -}; +export const renameAccountAttempt = + (accountNumber, newName) => (dispatch, getState) => { + dispatch({ type: RENAMEACCOUNT_ATTEMPT }); + return wallet + .renameAccount(sel.walletService(getState()), accountNumber, newName) + .then((renameAccountResponse) => { + setTimeout( + () => + dispatch({ + renameAccountResponse, + type: RENAMEACCOUNT_SUCCESS + }), + 1000 + ); + }) + .catch((error) => dispatch({ error, type: RENAMEACCOUNT_FAILED })); + }; export const RESCAN_ATTEMPT = "RESCAN_ATTEMPT"; export const RESCAN_FAILED = "RESCAN_FAILED"; @@ -140,102 +138,98 @@ export const GETNEXTACCOUNT_ATTEMPT = "GETNEXTACCOUNT_ATTEMPT"; export const GETNEXTACCOUNT_FAILED = "GETNEXTACCOUNT_FAILED"; export const GETNEXTACCOUNT_SUCCESS = "GETNEXTACCOUNT_SUCCESS"; -export const getNextAccountAttempt = (passphrase, accountName) => async ( - dispatch, - getState -) => { - dispatch({ type: GETNEXTACCOUNT_ATTEMPT }); - try { - const getNextAccountResponse = await wallet.getNextAccount( - sel.walletService(getState()), - passphrase, - accountName - ); - const accountNumber = getNextAccountResponse.accountNumber; - await dispatch( - setAccountPassphrase( +export const getNextAccountAttempt = + (passphrase, accountName) => async (dispatch, getState) => { + dispatch({ type: GETNEXTACCOUNT_ATTEMPT }); + try { + const getNextAccountResponse = await wallet.getNextAccount( sel.walletService(getState()), - accountNumber, - null, passphrase, - passphrase - ) - ); - return dispatch({ getNextAccountResponse, type: GETNEXTACCOUNT_SUCCESS }); - } catch (error) { - dispatch({ error, type: GETNEXTACCOUNT_FAILED }); - throw error; - } -}; + accountName + ); + const accountNumber = getNextAccountResponse.accountNumber; + await dispatch( + setAccountPassphrase( + sel.walletService(getState()), + accountNumber, + null, + passphrase, + passphrase + ) + ); + return dispatch({ getNextAccountResponse, type: GETNEXTACCOUNT_SUCCESS }); + } catch (error) { + dispatch({ error, type: GETNEXTACCOUNT_FAILED }); + throw error; + } + }; export const IMPORTPRIVKEY_ATTEMPT = "IMPORTPRIVKEY_ATTEMPT"; export const IMPORTPRIVKEY_FAILED = "IMPORTPRIVKEY_FAILED"; export const IMPORTPRIVKEY_SUCCESS = "IMPORTPRIVKEY_SUCCESS"; -export const importPrivateKeyAttempt = (...args) => (dispatch, getState) => { - dispatch({ type: IMPORTPRIVKEY_ATTEMPT }); - return wallet - .importPrivateKey(sel.walletService(getState()), ...args) - .then((res) => - dispatch({ importPrivateKeyResponse: res, type: IMPORTPRIVKEY_SUCCESS }) - ) - .catch((error) => dispatch({ error, type: IMPORTPRIVKEY_FAILED })); -}; +export const importPrivateKeyAttempt = + (...args) => + (dispatch, getState) => { + dispatch({ type: IMPORTPRIVKEY_ATTEMPT }); + return wallet + .importPrivateKey(sel.walletService(getState()), ...args) + .then((res) => + dispatch({ importPrivateKeyResponse: res, type: IMPORTPRIVKEY_SUCCESS }) + ) + .catch((error) => dispatch({ error, type: IMPORTPRIVKEY_FAILED })); + }; export const CHANGEPASSPHRASE_ATTEMPT = "CHANGEPASSPHRASE_ATTEMPT"; export const CHANGEPASSPHRASE_FAILED = "CHANGEPASSPHRASE_FAILED"; export const CHANGEPASSPHRASE_SUCCESS = "CHANGEPASSPHRASE_SUCCESS"; -export const changePassphraseAttempt = ( - oldPass, - newPass, - priv, - dexAppPassword -) => (dispatch, getState) => { - dispatch({ type: CHANGEPASSPHRASE_ATTEMPT }); - return wallet - .changePassphrase(sel.walletService(getState()), oldPass, newPass, priv) - .then(async (res) => { - if (priv) { - const oldAccounts = sel.balances(getState()); - const dexActive = sel.dexActive(getState()); - const dexAccountName = sel.dexAccount(getState()); - await Promise.all( - oldAccounts.map(async (acct) => { - // just skip if imported account. - if (acct.accountNumber >= Math.pow(2, 31) - 1) { +export const changePassphraseAttempt = + (oldPass, newPass, priv, dexAppPassword) => (dispatch, getState) => { + dispatch({ type: CHANGEPASSPHRASE_ATTEMPT }); + return wallet + .changePassphrase(sel.walletService(getState()), oldPass, newPass, priv) + .then(async (res) => { + if (priv) { + const oldAccounts = sel.balances(getState()); + const dexActive = sel.dexActive(getState()); + const dexAccountName = sel.dexAccount(getState()); + await Promise.all( + oldAccounts.map(async (acct) => { + // just skip if imported account. + if (acct.accountNumber >= Math.pow(2, 31) - 1) { + return acct; + } + // we set the account passphrase as the wallet passphrase to avoid the user + // ending with multiple passphrases. + + await dispatch( + setAccountPassphrase( + sel.walletService(getState()), + acct.accountNumber, + oldPass, + newPass, + null + ) + ); + if ( + dexActive && + dexAppPassword && + acct.accountName === dexAccountName + ) { + await dispatch(setWalletPasswordDex(newPass, dexAppPassword)); + } return acct; - } - // we set the account passphrase as the wallet passphrase to avoid the user - // ending with multiple passphrases. - - await dispatch( - setAccountPassphrase( - sel.walletService(getState()), - acct.accountNumber, - oldPass, - newPass, - null - ) - ); - if ( - dexActive && - dexAppPassword && - acct.accountName === dexAccountName - ) { - await dispatch(setWalletPasswordDex(newPass, dexAppPassword)); - } - return acct; - }) - ); - } - dispatch({ - changePassphraseResponse: res, - type: CHANGEPASSPHRASE_SUCCESS - }); - }) - .catch((error) => dispatch({ error, type: CHANGEPASSPHRASE_FAILED })); -}; + }) + ); + } + dispatch({ + changePassphraseResponse: res, + type: CHANGEPASSPHRASE_SUCCESS + }); + }) + .catch((error) => dispatch({ error, type: CHANGEPASSPHRASE_FAILED })); + }; export const CLEARTX = "CLEARTX"; @@ -245,43 +239,41 @@ export const SIGNTX_ATTEMPT = "SIGNTX_ATTEMPT"; export const SIGNTX_FAILED = "SIGNTX_FAILED"; export const SIGNTX_SUCCESS = "SIGNTX_SUCCESS"; -export const signTransactionAttempt = (passphrase, rawTx, acctNumber) => async ( - dispatch, - getState -) => { - dispatch({ type: SIGNTX_ATTEMPT }); - try { - const signTransactionResponse = await dispatch( - unlockAcctAndExecFn(passphrase, [acctNumber], () => - wallet.signTransaction( - sel.walletService(getState()), - sel.decodeMessageService(getState()), - rawTx +export const signTransactionAttempt = + (passphrase, rawTx, acctNumber) => async (dispatch, getState) => { + dispatch({ type: SIGNTX_ATTEMPT }); + try { + const signTransactionResponse = await dispatch( + unlockAcctAndExecFn(passphrase, [acctNumber], () => + wallet.signTransaction( + sel.walletService(getState()), + sel.decodeMessageService(getState()), + rawTx + ) ) - ) - ); - - dispatch({ - signTransactionResponse: signTransactionResponse, - type: SIGNTX_SUCCESS - }); - dispatch(publishTransactionAttempt(signTransactionResponse.transaction)); - } catch (error) { - if (sel.isTestNet(getState()) === true) { - wallet.log( - "warn", - "Sign Transaction Failed: " + - JSON.stringify({ - error: error.message, - passphrase, - rawTx, - acctNumber - }) ); + + dispatch({ + signTransactionResponse: signTransactionResponse, + type: SIGNTX_SUCCESS + }); + dispatch(publishTransactionAttempt(signTransactionResponse.transaction)); + } catch (error) { + if (sel.isTestNet(getState()) === true) { + wallet.log( + "warn", + "Sign Transaction Failed: " + + JSON.stringify({ + error: error.message, + passphrase, + rawTx, + acctNumber + }) + ); + } + dispatch({ error, type: SIGNTX_FAILED }); } - dispatch({ error, type: SIGNTX_FAILED }); - } -}; + }; export const PUBLISHTX_ATTEMPT = "PUBLISHTX_ATTEMPT"; export const PUBLISHTX_FAILED = "PUBLISHTX_FAILED"; @@ -331,148 +323,142 @@ export const PURCHASETICKETS_SUCCESS = "PURCHASETICKETS_SUCCESS"; export const PURCHASETICKETS_SUCCESS_LESS = "PURCHASETICKETS_SUCCESS_LESS"; export const CREATE_UNSIGNEDTICKETS_SUCCESS = "CREATE_UNSIGNEDTICKETS_SUCCESS"; -export const purchaseTicketsAttempt = ( - passphrase, - account, - numTickets, - vsp -) => async (dispatch, getState) => { - // stop the mixer if it's running - let needToRestartMixer = false; - const isAccountMixerRunning = sel.getAccountMixerRunning(getState()); - if (isAccountMixerRunning) { - await dispatch(stopAccountMixer()); - needToRestartMixer = true; - } - - // Since we are currently using the default account for the ticket's - // voting address we also need to unlock that account so communication - // with the VSP may occur. - try { - const accts = account.value !== 0 ? [account.value, 0] : [account.value]; - await dispatch( - unlockAcctAndExecFn(passphrase, accts, async () => { - try { - const walletService = sel.walletService(getState()); - dispatch({ - numTicketsToBuy: numTickets, - type: PURCHASETICKETS_ATTEMPT - }); - const dontSignTx = sel.isWatchingOnly(getState()); - const csppReq = { - mixedAccount: sel.getMixedAccount(getState()), - changeAccount: sel.getChangeAccount(getState()), - csppServer: sel.getCsppServer(getState()), - csppPort: sel.getCsppPort(getState()), - mixedAcctBranch: sel.getMixedAccountBranch(getState()) - }; - // Since we're about to purchase a ticket, ensure on next startup we'll - // process managed tickets. - dispatch(setNeedsVSPdProcessTickets(true)); - - const purchaseTicketsResponse = await wallet.purchaseTickets( - walletService, - account, - numTickets, - !dontSignTx, - vsp, - csppReq - ); - - // Update the list of dcrwallet tracked VSP tickets. This figures out - // which accounts need to be left unlocked. - await dispatch(getVSPTrackedTickets()); +export const purchaseTicketsAttempt = + (passphrase, account, numTickets, vsp) => async (dispatch, getState) => { + // stop the mixer if it's running + let needToRestartMixer = false; + const isAccountMixerRunning = sel.getAccountMixerRunning(getState()); + if (isAccountMixerRunning) { + await dispatch(stopAccountMixer()); + needToRestartMixer = true; + } - if (dontSignTx) { - return dispatch({ - purchaseTicketsResponse, - type: CREATE_UNSIGNEDTICKETS_SUCCESS - }); - } - // save vsp for future checking if the wallet has all tickets synced. - dispatch(updateUsedVSPs(vsp)); - const numBought = purchaseTicketsResponse.ticketHashes.length; - if (numBought < numTickets) { - dispatch({ - purchaseTicketsResponse, - numAttempted: numTickets, - type: PURCHASETICKETS_SUCCESS_LESS - }); - } else { + // Since we are currently using the default account for the ticket's + // voting address we also need to unlock that account so communication + // with the VSP may occur. + try { + const accts = account.value !== 0 ? [account.value, 0] : [account.value]; + await dispatch( + unlockAcctAndExecFn(passphrase, accts, async () => { + try { + const walletService = sel.walletService(getState()); dispatch({ - purchaseTicketsResponse, - type: PURCHASETICKETS_SUCCESS + numTicketsToBuy: numTickets, + type: PURCHASETICKETS_ATTEMPT }); - } - } catch (error) { - if (String(error).indexOf("insufficient balance") > 0) { - const unspentOutputs = await dispatch( - listUnspentOutputs(account.value) + const dontSignTx = sel.isWatchingOnly(getState()); + const csppReq = { + mixedAccount: sel.getMixedAccount(getState()), + changeAccount: sel.getChangeAccount(getState()), + csppServer: sel.getCsppServer(getState()), + csppPort: sel.getCsppPort(getState()), + mixedAcctBranch: sel.getMixedAccountBranch(getState()) + }; + // Since we're about to purchase a ticket, ensure on next startup we'll + // process managed tickets. + dispatch(setNeedsVSPdProcessTickets(true)); + + const purchaseTicketsResponse = await wallet.purchaseTickets( + walletService, + account, + numTickets, + !dontSignTx, + vsp, + csppReq ); - // we need at least one 2 utxo for each ticket, one for paying the fee - // and another for the splitTx and ticket purchase. - // Note: at least one of them needs to be big enough for ticket purchase. - if (unspentOutputs.length < numTickets * 2) { - // check if amount is indeed insufficient - const ticketPrice = sel.ticketPrice(getState()); - if (account.spendable > ticketPrice * numTickets) { - return dispatch({ - error: `Not enough utxo. Need to break the input so one can be reserved + + // Update the list of dcrwallet tracked VSP tickets. This figures out + // which accounts need to be left unlocked. + await dispatch(getVSPTrackedTickets()); + + if (dontSignTx) { + return dispatch({ + purchaseTicketsResponse, + type: CREATE_UNSIGNEDTICKETS_SUCCESS + }); + } + // save vsp for future checking if the wallet has all tickets synced. + dispatch(updateUsedVSPs(vsp)); + const numBought = purchaseTicketsResponse.ticketHashes.length; + if (numBought < numTickets) { + dispatch({ + purchaseTicketsResponse, + numAttempted: numTickets, + type: PURCHASETICKETS_SUCCESS_LESS + }); + } else { + dispatch({ + purchaseTicketsResponse, + type: PURCHASETICKETS_SUCCESS + }); + } + } catch (error) { + if (String(error).indexOf("insufficient balance") > 0) { + const unspentOutputs = await dispatch( + listUnspentOutputs(account.value) + ); + // we need at least one 2 utxo for each ticket, one for paying the fee + // and another for the splitTx and ticket purchase. + // Note: at least one of them needs to be big enough for ticket purchase. + if (unspentOutputs.length < numTickets * 2) { + // check if amount is indeed insufficient + const ticketPrice = sel.ticketPrice(getState()); + if (account.spendable > ticketPrice * numTickets) { + return dispatch({ + error: `Not enough utxo. Need to break the input so one can be reserved for paying the fee.`, - type: PURCHASETICKETS_FAILED - }); + type: PURCHASETICKETS_FAILED + }); + } } } + dispatch({ error, type: PURCHASETICKETS_FAILED }); } - dispatch({ error, type: PURCHASETICKETS_FAILED }); - } - }) - ); - } catch (error) { - console.log({ error }); - } finally { - if (needToRestartMixer) { - const mixedAccount = sel.getMixedAccount(getState()); - const changeAccount = sel.getChangeAccount(getState()); - const mixedAccountBranch = sel.getMixedAccountBranch(getState()); - const csppServer = sel.getCsppServer(getState()); - const csppPort = sel.getCsppPort(getState()); - - dispatch( - runAccountMixer({ - passphrase, - mixedAccount, - mixedAccountBranch, - changeAccount, - csppServer: `${csppServer}:${csppPort}` }) ); + } catch (error) { + console.log({ error }); + } finally { + if (needToRestartMixer) { + const mixedAccount = sel.getMixedAccount(getState()); + const changeAccount = sel.getChangeAccount(getState()); + const mixedAccountBranch = sel.getMixedAccountBranch(getState()); + const csppServer = sel.getCsppServer(getState()); + const csppPort = sel.getCsppPort(getState()); + + dispatch( + runAccountMixer({ + passphrase, + mixedAccount, + mixedAccountBranch, + changeAccount, + csppServer: `${csppServer}:${csppPort}` + }) + ); + } } - } -}; + }; export const DISCOVERUSAGE_ATTEMPT = "DISCOVERUSAGE_ATTEMPT"; export const DISCOVERUSAGE_FAILED = "DISCOVERUSAGE_FAILED"; export const DISCOVERUSAGE_SUCCESS = "DISCOVERUSAGE_SUCCESS"; -export const discoverUsageAttempt = (gapLimit) => async ( - dispatch, - getState -) => { - dispatch({ type: DISCOVERUSAGE_ATTEMPT }); - const walletService = sel.walletService(getState()); - try { - const discoverUsageResponse = await wallet.discoverUsage( - walletService, - gapLimit - ); - dispatch({ discoverUsageResponse, type: DISCOVERUSAGE_SUCCESS }); - await wallet.loadActiveDataFilters(walletService); - dispatch(rescanAttempt(0)); - } catch (error) { - dispatch({ error, type: DISCOVERUSAGE_FAILED }); - } -}; +export const discoverUsageAttempt = + (gapLimit) => async (dispatch, getState) => { + dispatch({ type: DISCOVERUSAGE_ATTEMPT }); + const walletService = sel.walletService(getState()); + try { + const discoverUsageResponse = await wallet.discoverUsage( + walletService, + gapLimit + ); + dispatch({ discoverUsageResponse, type: DISCOVERUSAGE_SUCCESS }); + await wallet.loadActiveDataFilters(walletService); + dispatch(rescanAttempt(0)); + } catch (error) { + dispatch({ error, type: DISCOVERUSAGE_FAILED }); + } + }; export const STARTTICKETBUYER_ATTEMPT = "STARTTICKETBUYER_ATTEMPT"; export const STARTTICKETBUYER_FAILED = "STARTTICKETBUYER_FAILED"; @@ -482,82 +468,79 @@ export const STOPTICKETBUYER_ATTEMPT = "STOPTICKETBUYER_ATTEMPT"; export const STOPTICKETBUYER_FAILED = "STOPTICKETBUYER_FAILED"; export const STOPTICKETBUYER_SUCCESS = "STOPTICKETBUYER_SUCCESS"; -export const startTicketBuyerAttempt = ( - passphrase, - account, - balanceToMaintain, - vsp -) => async (dispatch, getState) => { - const mixedAccount = sel.getMixedAccount(getState()); - const changeAccount = sel.getChangeAccount(getState()); - const csppServer = sel.getCsppServer(getState()); - const csppPort = sel.getCsppPort(getState()); - const mixedAcctBranch = sel.getMixedAccountBranch(getState()); - const ticketBuyerConfig = { vsp, balanceToMaintain, account }; - - const { ticketBuyerService } = getState().grpc; - dispatch({ ticketBuyerConfig, type: STARTTICKETBUYER_ATTEMPT }); - - const accountNum = account.encrypted ? account.value : null; - const accountUnlocks = mixedAccount - ? [accountNum, changeAccount] - : [accountNum]; - try { - const ticketBuyer = await dispatch( - unlockAcctAndExecFn( - passphrase, - accountUnlocks, - () => { - dispatch(setNeedsVSPdProcessTickets(true)); - return wallet.startTicketAutoBuyer(ticketBuyerService, { - mixedAccount, - mixedAcctBranch, - changeAccount, - csppServer, - csppPort, - balanceToMaintain, - accountNum, - pubkey: vsp.pubkey, - host: vsp.host - }); - }, - true - ) - ); - ticketBuyer.on("data", function (response) { - // No expected responses but log in case. - console.log(response); - }); - ticketBuyer.on("end", function (response) { - // No expected response in end but log in case. - console.log(response); - }); - ticketBuyer.on("error", async (status) => { - status = status + ""; - if (status.indexOf("Cancelled") < 0) { - await dispatch({ error: status, type: STARTTICKETBUYER_FAILED }); - } else { - await dispatch({ type: STOPTICKETBUYER_SUCCESS }); - } +export const startTicketBuyerAttempt = + (passphrase, account, balanceToMaintain, vsp) => + async (dispatch, getState) => { + const mixedAccount = sel.getMixedAccount(getState()); + const changeAccount = sel.getChangeAccount(getState()); + const csppServer = sel.getCsppServer(getState()); + const csppPort = sel.getCsppPort(getState()); + const mixedAcctBranch = sel.getMixedAccountBranch(getState()); + const ticketBuyerConfig = { vsp, balanceToMaintain, account }; + + const { ticketBuyerService } = getState().grpc; + dispatch({ ticketBuyerConfig, type: STARTTICKETBUYER_ATTEMPT }); + + const accountNum = account.encrypted ? account.value : null; + const accountUnlocks = mixedAccount + ? [accountNum, changeAccount] + : [accountNum]; + try { + const ticketBuyer = await dispatch( + unlockAcctAndExecFn( + passphrase, + accountUnlocks, + () => { + dispatch(setNeedsVSPdProcessTickets(true)); + return wallet.startTicketAutoBuyer(ticketBuyerService, { + mixedAccount, + mixedAcctBranch, + changeAccount, + csppServer, + csppPort, + balanceToMaintain, + accountNum, + pubkey: vsp.pubkey, + host: vsp.host + }); + }, + true + ) + ); + ticketBuyer.on("data", function (response) { + // No expected responses but log in case. + console.log(response); + }); + ticketBuyer.on("end", function (response) { + // No expected response in end but log in case. + console.log(response); + }); + ticketBuyer.on("error", async (status) => { + status = status + ""; + if (status.indexOf("Cancelled") < 0) { + await dispatch({ error: status, type: STARTTICKETBUYER_FAILED }); + } else { + await dispatch({ type: STOPTICKETBUYER_SUCCESS }); + } + await dispatch(relockAccounts(accountUnlocks)); + }); + // update used vsps + dispatch(updateUsedVSPs(vsp)); + dispatch({ + ticketBuyerCall: ticketBuyer, + vsp, + balanceToMaintain, + account, + type: STARTTICKETBUYER_SUCCESS + }); + return ticketBuyer; + } catch (error) { + await dispatch({ error, type: STARTTICKETBUYER_FAILED }); + // need to relock accounts here because unlockAcctAndExecFn + // has been called with `leaveUnlock=true` parameter await dispatch(relockAccounts(accountUnlocks)); - }); - // update used vsps - dispatch(updateUsedVSPs(vsp)); - dispatch({ - ticketBuyerCall: ticketBuyer, - vsp, - balanceToMaintain, - account, - type: STARTTICKETBUYER_SUCCESS - }); - return ticketBuyer; - } catch (error) { - await dispatch({ error, type: STARTTICKETBUYER_FAILED }); - // need to relock accounts here because unlockAcctAndExecFn - // has been called with `leaveUnlock=true` parameter - await dispatch(relockAccounts(accountUnlocks)); - } -}; + } + }; export const ticketBuyerCancel = () => async (dispatch, getState) => { dispatch({ type: STOPTICKETBUYER_ATTEMPT }); @@ -570,111 +553,108 @@ export const CONSTRUCTTX_FAILED = "CONSTRUCTTX_FAILED"; export const CONSTRUCTTX_FAILED_LOW_BALANCE = "CONSTRUCTTX_FAILED_LOW_BALANCE"; export const CONSTRUCTTX_SUCCESS = "CONSTRUCTTX_SUCCESS"; -export const constructTransactionAttempt = ( - account, - confirmations, - outputs, - all -) => async (dispatch, getState) => { - const { constructTxRequestAttempt } = getState().control; - if (constructTxRequestAttempt) { - return; - } +export const constructTransactionAttempt = + (account, confirmations, outputs, all) => async (dispatch, getState) => { + const { constructTxRequestAttempt } = getState().control; + if (constructTxRequestAttempt) { + return; + } - // Determine the change address. - let change; - if (!all) { - // If there's a previously stored change address for this account, use it. - // This alleviates a possible gap limit address exhaustion. See - // issue dcrwallet#1622. - const changeScript = - getState().control.changeScriptByAccount[account] || null; - if (changeScript) { - change = { script: changeScript }; - } else { - // set change destination. If it is a privacy wallet we get the - // next unmixed address. - // Otherwise, we can left it empty and it will be filled by dcrwallet. - const mixAcct = sel.getMixedAccount(getState()); - const unmixedAcct = sel.getChangeAccount(getState()); - if (unmixedAcct && account === mixAcct) { - if (!mixAcct) { - return (dispatch) => { - const error = "unmixed account set but no mix account found."; - dispatch({ error, type: CONSTRUCTTX_FAILED }); - }; + // Determine the change address. + let change; + if (!all) { + // If there's a previously stored change address for this account, use it. + // This alleviates a possible gap limit address exhaustion. See + // issue dcrwallet#1622. + const changeScript = + getState().control.changeScriptByAccount[account] || null; + if (changeScript) { + change = { script: changeScript }; + } else { + // set change destination. If it is a privacy wallet we get the + // next unmixed address. + // Otherwise, we can left it empty and it will be filled by dcrwallet. + const mixAcct = sel.getMixedAccount(getState()); + const unmixedAcct = sel.getChangeAccount(getState()); + if (unmixedAcct && account === mixAcct) { + if (!mixAcct) { + return (dispatch) => { + const error = "unmixed account set but no mix account found."; + dispatch({ error, type: CONSTRUCTTX_FAILED }); + }; + } + await dispatch(getNextChangeAddressAttempt()); + const newChangeAddress = sel.nextChangeAddress(getState()); + change = { address: newChangeAddress }; } - await dispatch(getNextChangeAddressAttempt()); - const newChangeAddress = sel.nextChangeAddress(getState()); - change = { address: newChangeAddress }; } } - } - const chainParams = sel.chainParams(getState()); - const { walletService } = getState().grpc; + const chainParams = sel.chainParams(getState()); + const { walletService } = getState().grpc; - dispatch({ type: CONSTRUCTTX_ATTEMPT, constructTxRequestAttempt: true }); - try { - const constructFunc = all - ? wallet.constructSendAllTransaction - : wallet.constructTransaction; - const constructTxResponse = await constructFunc( - walletService, - account, - confirmations, - outputs, - change - ); + dispatch({ type: CONSTRUCTTX_ATTEMPT, constructTxRequestAttempt: true }); + try { + const constructFunc = all + ? wallet.constructSendAllTransaction + : wallet.constructTransaction; + const constructTxResponse = await constructFunc( + walletService, + account, + confirmations, + outputs, + change + ); - const changeScriptByAccount = - getState().control.changeScriptByAccount || {}; + const changeScriptByAccount = + getState().control.changeScriptByAccount || {}; - if (!all) { - // Store the change address we just generated so that future changes to - // the tx being constructed will use the same address and prevent gap - // limit exhaustion (see above note on issue dcrwallet#1622). - const changeIndex = constructTxResponse.changeIndex; - if (changeIndex > -1) { - const rawTx = Buffer.from( - constructTxResponse.unsignedTransaction, - "hex" - ); - const decoded = wallet.decodeRawTransaction(rawTx, chainParams); - changeScriptByAccount[account] = decoded.outputs[changeIndex].script; + if (!all) { + // Store the change address we just generated so that future changes to + // the tx being constructed will use the same address and prevent gap + // limit exhaustion (see above note on issue dcrwallet#1622). + const changeIndex = constructTxResponse.changeIndex; + if (changeIndex > -1) { + const rawTx = Buffer.from( + constructTxResponse.unsignedTransaction, + "hex" + ); + const decoded = wallet.decodeRawTransaction(rawTx, chainParams); + changeScriptByAccount[account] = decoded.outputs[changeIndex].script; + } } - } - - constructTxResponse.rawTx = rawToHex( - constructTxResponse.unsignedTransaction - ); - dispatch({ - constructTxResponse: constructTxResponse, - changeScriptByAccount, - type: CONSTRUCTTX_SUCCESS - }); - } catch (error) { - if (String(error).indexOf("insufficient balance") > 0) { - dispatch({ error, type: CONSTRUCTTX_FAILED_LOW_BALANCE }); - } else if ( - String(error).indexOf("violates the unused address gap limit policy") > 0 - ) { - // Work around dcrwallet#1622: generate a new address in the internal - // branch using the wrap gap policy so that change addresses can be - // regenerated again. - // We'll still error out to let the user know wrapping has occurred. - wallet.getNextAddress( - sel.walletService(getState()), - parseInt(account), - 1 + constructTxResponse.rawTx = rawToHex( + constructTxResponse.unsignedTransaction ); - dispatch({ error, type: CONSTRUCTTX_FAILED }); - } else { - dispatch({ error, type: CONSTRUCTTX_FAILED }); + + dispatch({ + constructTxResponse: constructTxResponse, + changeScriptByAccount, + type: CONSTRUCTTX_SUCCESS + }); + } catch (error) { + if (String(error).indexOf("insufficient balance") > 0) { + dispatch({ error, type: CONSTRUCTTX_FAILED_LOW_BALANCE }); + } else if ( + String(error).indexOf("violates the unused address gap limit policy") > + 0 + ) { + // Work around dcrwallet#1622: generate a new address in the internal + // branch using the wrap gap policy so that change addresses can be + // regenerated again. + // We'll still error out to let the user know wrapping has occurred. + wallet.getNextAddress( + sel.walletService(getState()), + parseInt(account), + 1 + ); + dispatch({ error, type: CONSTRUCTTX_FAILED }); + } else { + dispatch({ error, type: CONSTRUCTTX_FAILED }); + } } - } -}; + }; export const validateAddress = (address) => async (dispatch, getState) => { try { @@ -729,36 +709,34 @@ export const SIGNMESSAGE_FAILED = "SIGNMESSAGE_FAILED"; export const SIGNMESSAGE_SUCCESS = "SIGNMESSAGE_SUCCESS"; export const SIGNMESSAGE_CLEANSTORE = "SIGNMESSAGE_CLEANSTORE"; -export const signMessageAttempt = (address, message, passphrase) => async ( - dispatch, - getState -) => { - dispatch({ type: SIGNMESSAGE_ATTEMPT }); - try { - const response = await wallet.validateAddress( - sel.walletService(getState()), - address - ); - const accountNumber = response.accountNumber; - const getSignMessageResponse = await dispatch( - unlockAcctAndExecFn(passphrase, [accountNumber], () => - wallet.signMessage(sel.walletService(getState()), address, message) - ) - ); - // Originally, signatures were presented as base64 encoded, so convert - // from hex to base64. - const sig = Buffer.from(getSignMessageResponse.signature, "hex").toString( - "base64" - ); - dispatch({ - getSignMessageSignature: sig, - type: SIGNMESSAGE_SUCCESS - }); - return sig; - } catch (error) { - dispatch({ error, type: SIGNMESSAGE_FAILED }); - } -}; +export const signMessageAttempt = + (address, message, passphrase) => async (dispatch, getState) => { + dispatch({ type: SIGNMESSAGE_ATTEMPT }); + try { + const response = await wallet.validateAddress( + sel.walletService(getState()), + address + ); + const accountNumber = response.accountNumber; + const getSignMessageResponse = await dispatch( + unlockAcctAndExecFn(passphrase, [accountNumber], () => + wallet.signMessage(sel.walletService(getState()), address, message) + ) + ); + // Originally, signatures were presented as base64 encoded, so convert + // from hex to base64. + const sig = Buffer.from(getSignMessageResponse.signature, "hex").toString( + "base64" + ); + dispatch({ + getSignMessageSignature: sig, + type: SIGNMESSAGE_SUCCESS + }); + return sig; + } catch (error) { + dispatch({ error, type: SIGNMESSAGE_FAILED }); + } + }; export const signMessageCleanStore = (dispatch) => dispatch({ type: SIGNMESSAGE_CLEANSTORE }); @@ -838,22 +816,22 @@ export const GETACCOUNTEXTENDEDKEY_ATTEMPT = "GETACCOUNTEXTENDEDKEY_ATTEMPT"; export const GETACCOUNTEXTENDEDKEY_FAILED = "GETACCOUNTEXTENDEDKEY_FAILED"; export const GETACCOUNTEXTENDEDKEY_SUCCESS = "GETACCOUNTEXTENDEDKEY_SUCCESS"; -export const getAccountExtendedKeyAttempt = (accountNumber) => ( - dispatch, - getState -) => { - dispatch({ type: GETACCOUNTEXTENDEDKEY_ATTEMPT }); - return wallet - .getAccountExtendedKey(sel.walletService(getState()), accountNumber) - .then((res) => { - res.accountNumber = accountNumber; - return dispatch({ - getAccountExtendedKeyResponse: res, - type: GETACCOUNTEXTENDEDKEY_SUCCESS - }); - }) - .catch((error) => dispatch({ error, type: GETACCOUNTEXTENDEDKEY_FAILED })); -}; +export const getAccountExtendedKeyAttempt = + (accountNumber) => (dispatch, getState) => { + dispatch({ type: GETACCOUNTEXTENDEDKEY_ATTEMPT }); + return wallet + .getAccountExtendedKey(sel.walletService(getState()), accountNumber) + .then((res) => { + res.accountNumber = accountNumber; + return dispatch({ + getAccountExtendedKeyResponse: res, + type: GETACCOUNTEXTENDEDKEY_SUCCESS + }); + }) + .catch((error) => + dispatch({ error, type: GETACCOUNTEXTENDEDKEY_FAILED }) + ); + }; export const GETPEERINFO_ATTEMPT = "GETPEERINFO_ATTEMPT"; export const GETPEERINFO_FAILED = "GETPEERINFO_FAILED"; @@ -874,71 +852,73 @@ export const SETACCOUNTPASSPHRASE_ATTEMPT = "SETACCOUNTPASSPHRASE_ATTEMPT"; export const SETACCOUNTPASSPHRASE_FAILED = "SETACCOUNTPASSPHRASE_FAILED"; export const SETACCOUNTPASSPHRASE_SUCCESS = "SETACCOUNTPASSPHRASE_SUCCESS"; -const setAccountPassphrase = ( - walletService, - accountNumber, - accountPassphrase, - newAcctPassphrase, - walletPassphrase -) => async (dispatch, getState) => { - try { - dispatch({ type: SETACCOUNTPASSPHRASE_ATTEMPT }); - await wallet.setAccountPassphrase( - walletService, - accountNumber, - accountPassphrase, - newAcctPassphrase, - walletPassphrase - ); - const accounts = sel.balances(getState()); - const acct = accounts.find((acct) => acct.accountNumber === accountNumber); - acct.encrypted = true; - acct.locked = true; - return dispatch({ type: SETACCOUNTPASSPHRASE_SUCCESS, accounts }); - } catch (error) { - dispatch({ type: SETACCOUNTPASSPHRASE_FAILED, error }); - throw error; - } -}; +const setAccountPassphrase = + ( + walletService, + accountNumber, + accountPassphrase, + newAcctPassphrase, + walletPassphrase + ) => + async (dispatch, getState) => { + try { + dispatch({ type: SETACCOUNTPASSPHRASE_ATTEMPT }); + await wallet.setAccountPassphrase( + walletService, + accountNumber, + accountPassphrase, + newAcctPassphrase, + walletPassphrase + ); + const accounts = sel.balances(getState()); + const acct = accounts.find( + (acct) => acct.accountNumber === accountNumber + ); + acct.encrypted = true; + acct.locked = true; + return dispatch({ type: SETACCOUNTPASSPHRASE_SUCCESS, accounts }); + } catch (error) { + dispatch({ type: SETACCOUNTPASSPHRASE_FAILED, error }); + throw error; + } + }; export const SETACCOUNTSPASSPHRASE_ATTEMPT = "SETACCOUNTSPASSPHRASE_ATTEMPT"; export const SETACCOUNTSPASSPHRASE_FAILED = "SETACCOUNTSPASSPHRASE_FAILED"; export const SETACCOUNTSPASSPHRASE_SUCCESS = "SETACCOUNTSPASSPHRASE_SUCCESS"; -export const setAccountsPass = (walletPassphrase) => async ( - dispatch, - getState -) => { - dispatch({ type: SETACCOUNTSPASSPHRASE_ATTEMPT }); - try { - const oldAccounts = sel.balances(getState()); - const accounts = await Promise.all( - oldAccounts.map(async (acct) => { - // just skip if imported account. - if (acct.accountNumber === Math.pow(2, 31) - 1) { +export const setAccountsPass = + (walletPassphrase) => async (dispatch, getState) => { + dispatch({ type: SETACCOUNTSPASSPHRASE_ATTEMPT }); + try { + const oldAccounts = sel.balances(getState()); + const accounts = await Promise.all( + oldAccounts.map(async (acct) => { + // just skip if imported account. + if (acct.accountNumber === Math.pow(2, 31) - 1) { + return acct; + } + // we set the account passphrase as the wallet passphrase to avoid the user + // ending with multiple passphrases. + + await dispatch( + setAccountPassphrase( + sel.walletService(getState()), + acct.accountNumber, + null, + walletPassphrase, + walletPassphrase + ) + ); return acct; - } - // we set the account passphrase as the wallet passphrase to avoid the user - // ending with multiple passphrases. - - await dispatch( - setAccountPassphrase( - sel.walletService(getState()), - acct.accountNumber, - null, - walletPassphrase, - walletPassphrase - ) - ); - return acct; - }) - ); - return dispatch({ type: SETACCOUNTSPASSPHRASE_SUCCESS, accounts }); - } catch (error) { - dispatch({ error, type: SETACCOUNTSPASSPHRASE_FAILED }); - throw error; - } -}; + }) + ); + return dispatch({ type: SETACCOUNTSPASSPHRASE_SUCCESS, accounts }); + } catch (error) { + dispatch({ error, type: SETACCOUNTSPASSPHRASE_FAILED }); + throw error; + } + }; // unlock export const UNLOCKACCOUNT_ATTEMPT = "UNLOCKACCOUNT_ATTEMPT"; @@ -999,136 +979,130 @@ export const filterUnlockableAccounts = (accts, getState) => { // unlockAcctAndExecFn unlocks the account and performs some action. Locks the // account in case of success or error, if leaveUnlock is not informed. -export const unlockAcctAndExecFn = ( - passphrase, - acctNumbers, - fn, - leaveUnlock -) => async (dispatch) => { - let res = null; - let fnError = null; - - // Unlock all needed accounts. - dispatch({ type: UNLOCKANDEXECFN_ATTEMPT }); - try { - await Promise.all( - acctNumbers.map((acctNumber) => - dispatch(unlockAccount(passphrase, acctNumber)) - ) - ); - } catch (error) { +export const unlockAcctAndExecFn = + (passphrase, acctNumbers, fn, leaveUnlock) => async (dispatch) => { + let res = null; + let fnError = null; + + // Unlock all needed accounts. + dispatch({ type: UNLOCKANDEXECFN_ATTEMPT }); try { - await dispatch(relockAccounts(acctNumbers)); + await Promise.all( + acctNumbers.map((acctNumber) => + dispatch(unlockAccount(passphrase, acctNumber)) + ) + ); } catch (error) { - dispatch({ type: LOCKACCOUNT_FAILED, error }); + try { + await dispatch(relockAccounts(acctNumbers)); + } catch (error) { + dispatch({ type: LOCKACCOUNT_FAILED, error }); + } + dispatch({ type: UNLOCKANDEXECFN_FAILED, error }); + throw error; } - dispatch({ type: UNLOCKANDEXECFN_FAILED, error }); - throw error; - } - // execute method - try { - res = await fn(); - } catch (error) { - fnError = error; - } + // execute method + try { + res = await fn(); + } catch (error) { + fnError = error; + } + + if (leaveUnlock) { + if (fnError) { + dispatch({ type: UNLOCKANDEXECFN_FAILED, error: fnError }); + throw fnError; + } + dispatch({ type: UNLOCKANDEXECFN_SUCCESS, leaveUnlock }); + return res; + } + + try { + await dispatch(relockAccounts(acctNumbers)); + } catch (error) { + dispatch({ type: UNLOCKANDEXECFN_FAILED, error }); + throw error; + } - if (leaveUnlock) { - if (fnError) { + // return fn error in case some happened. + if (fnError !== null) { dispatch({ type: UNLOCKANDEXECFN_FAILED, error: fnError }); throw fnError; } + dispatch({ type: UNLOCKANDEXECFN_SUCCESS, leaveUnlock }); return res; - } - - try { - await dispatch(relockAccounts(acctNumbers)); - } catch (error) { - dispatch({ type: UNLOCKANDEXECFN_FAILED, error }); - throw error; - } - - // return fn error in case some happened. - if (fnError !== null) { - dispatch({ type: UNLOCKANDEXECFN_FAILED, error: fnError }); - throw fnError; - } - - dispatch({ type: UNLOCKANDEXECFN_SUCCESS, leaveUnlock }); - return res; -}; + }; // unlockAllAcctAndExecFn unlocks all accounts and performs some action. Then // locks all accounts that were unlocked. Dex account is never relocked. -export const unlockAllAcctAndExecFn = (passphrase, fn, leaveUnlock) => ( - dispatch, - getState -) => { - const unlockable = sel - .unlockableAccounts(getState()) - .map((acct) => acct.accountNumber); - return dispatch(unlockAcctAndExecFn(passphrase, unlockable, fn, leaveUnlock)); -}; +export const unlockAllAcctAndExecFn = + (passphrase, fn, leaveUnlock) => (dispatch, getState) => { + const unlockable = sel + .unlockableAccounts(getState()) + .map((acct) => acct.accountNumber); + return dispatch( + unlockAcctAndExecFn(passphrase, unlockable, fn, leaveUnlock) + ); + }; -export const unlockAccount = (passphrase, acctNumber) => async ( - dispatch, - getState -) => { - dispatch({ type: UNLOCKACCOUNT_ATTEMPT, acctNumber }); - try { - const walletService = sel.walletService(getState()); - const accounts = sel.balances(getState()); - const account = accounts.find((acct) => acct.accountNumber === acctNumber); - if (!account) { - throw "Account not found"; - } - if (!account.encrypted) { - throw "Account not encrypted"; +export const unlockAccount = + (passphrase, acctNumber) => async (dispatch, getState) => { + dispatch({ type: UNLOCKACCOUNT_ATTEMPT, acctNumber }); + try { + const walletService = sel.walletService(getState()); + const accounts = sel.balances(getState()); + const account = accounts.find( + (acct) => acct.accountNumber === acctNumber + ); + if (!account) { + throw "Account not found"; + } + if (!account.encrypted) { + throw "Account not encrypted"; + } + await wallet.unlockAccount(walletService, passphrase, acctNumber); + dispatch({ type: UNLOCKACCOUNT_SUCCESS, acctNumber }); + } catch (error) { + dispatch({ type: UNLOCKACCOUNT_FAILED, error }); + throw error; } - await wallet.unlockAccount(walletService, passphrase, acctNumber); - dispatch({ type: UNLOCKACCOUNT_SUCCESS, acctNumber }); - } catch (error) { - dispatch({ type: UNLOCKACCOUNT_FAILED, error }); - throw error; - } -}; + }; export const RELOCKACCOUNTS_ATTEMPT = "RELOCKACCOUNTS_ATTEMPT"; export const RELOCKACCOUNTS_FAILED = "RELOCKACCOUNTS_FAILED"; export const RELOCKACCOUNTS_SUCCESS = "RELOCKACCOUNTS_SUCCESS"; -export const relockAccounts = (accountNumbers) => async ( - dispatch, - getState -) => { - dispatch({ type: RELOCKACCOUNTS_ATTEMPT, accountNumbers }); - try { - let unlockedAccountNumbers; +export const relockAccounts = + (accountNumbers) => async (dispatch, getState) => { + dispatch({ type: RELOCKACCOUNTS_ATTEMPT, accountNumbers }); try { - await dispatch(getAccountsAttempt(true)); - const accounts = sel.balances(getState()); - unlockedAccountNumbers = accounts - .filter((account) => account.unlocked && account.encrypted) - .map((account) => account.accountNumber); - } catch (error) { - // failed to refresh accounts data. as a fallback, - // consider all `accountNumbers` unlocked - unlockedAccountNumbers = accountNumbers; - } + let unlockedAccountNumbers; + try { + await dispatch(getAccountsAttempt(true)); + const accounts = sel.balances(getState()); + unlockedAccountNumbers = accounts + .filter((account) => account.unlocked && account.encrypted) + .map((account) => account.accountNumber); + } catch (error) { + // failed to refresh accounts data. as a fallback, + // consider all `accountNumbers` unlocked + unlockedAccountNumbers = accountNumbers; + } - await Promise.all( - unlockedAccountNumbers.map((acctNumber) => - dispatch(lockAccount(acctNumber)) - ) - ); + await Promise.all( + unlockedAccountNumbers.map((acctNumber) => + dispatch(lockAccount(acctNumber)) + ) + ); - dispatch({ type: RELOCKACCOUNTS_SUCCESS, unlockedAccountNumbers }); - } catch (error) { - dispatch({ type: RELOCKACCOUNTS_FAILED, error }); - throw error; - } -}; + dispatch({ type: RELOCKACCOUNTS_SUCCESS, unlockedAccountNumbers }); + } catch (error) { + dispatch({ type: RELOCKACCOUNTS_FAILED, error }); + throw error; + } + }; export const lockAccount = (acctNumber) => async (dispatch, getState) => { dispatch({ type: LOCKACCOUNT_ATTEMPT, acctNumber }); diff --git a/app/actions/DaemonActions.js b/app/actions/DaemonActions.js index 022546744d..7c05e98534 100644 --- a/app/actions/DaemonActions.js +++ b/app/actions/DaemonActions.js @@ -385,138 +385,140 @@ export const closeDaemonRequest = () => async (dispatch, getState) => { } }; -export const startWallet = (selectedWallet, hasPassPhrase) => ( - dispatch, - getState -) => - new Promise((resolve, reject) => { - const start = async () => { - const { currentSettings } = getState().settings; - const network = currentSettings.network; - - // if selected wallet is not send in the call of the method, - // it probably means it is a refresh, so we get the selected wallet - // stored in ipc memory. - if (!selectedWallet) { - selectedWallet = wallet.getSelectedWallet(); - } - const isTestnet = network == "testnet"; - const walletCfg = wallet.getWalletCfg( - isTestnet, - selectedWallet.value.wallet - ); - - const enableDex = walletCfg.get(cfgConstants.ENABLE_DEX); - const dexReady = walletCfg.get(cfgConstants.DEX_READY); - const dexAccount = walletCfg.get(cfgConstants.DEX_ACCOUNT); - const confirmDexSeed = walletCfg.get(cfgConstants.CONFIRM_DEX_SEED); - let rpcCreds = {}; - if (enableDex) { - rpcCreds = { - rpcUser: walletCfg.get(cfgConstants.DEXWALLET_RPCUSERNAME), - rpcPass: walletCfg.get(cfgConstants.DEXWALLET_RPCPASSWORD), - rpcListen: walletCfg.get(cfgConstants.DEXWALLET_HOSTPORT), - rpcCert: fs.joinPaths( - wallet.getWalletPath(isTestnet, selectedWallet.value.wallet), - "rpc.cert" - ) - }; - } +export const startWallet = + (selectedWallet, hasPassPhrase) => (dispatch, getState) => + new Promise((resolve, reject) => { + const start = async () => { + const { currentSettings } = getState().settings; + const network = currentSettings.network; + + // if selected wallet is not send in the call of the method, + // it probably means it is a refresh, so we get the selected wallet + // stored in ipc memory. + if (!selectedWallet) { + selectedWallet = wallet.getSelectedWallet(); + } + const isTestnet = network == "testnet"; + const walletCfg = wallet.getWalletCfg( + isTestnet, + selectedWallet.value.wallet + ); - // Check to see if wallet config has old cspp.decred.org setting, will - // update to mix.decred.org - const currentCSPP = walletCfg.get(cfgConstants.CSPP_SERVER); - if (currentCSPP == CSPP_URL_LEGACY) { - walletCfg.set(cfgConstants.CSPP_SERVER, CSPP_URL); - } + const enableDex = walletCfg.get(cfgConstants.ENABLE_DEX); + const dexReady = walletCfg.get(cfgConstants.DEX_READY); + const dexAccount = walletCfg.get(cfgConstants.DEX_ACCOUNT); + const confirmDexSeed = walletCfg.get(cfgConstants.CONFIRM_DEX_SEED); + let rpcCreds = {}; + if (enableDex) { + rpcCreds = { + rpcUser: walletCfg.get(cfgConstants.DEXWALLET_RPCUSERNAME), + rpcPass: walletCfg.get(cfgConstants.DEXWALLET_RPCPASSWORD), + rpcListen: walletCfg.get(cfgConstants.DEXWALLET_HOSTPORT), + rpcCert: fs.joinPaths( + wallet.getWalletPath(isTestnet, selectedWallet.value.wallet), + "rpc.cert" + ) + }; + } - const walletStarted = await wallet.startWallet( - selectedWallet.value.wallet, - isTestnet, - rpcCreds, - selectedWallet.value.gapLimit, - selectedWallet.value.disableCoinTypeUpgrades - ); - const { port } = walletStarted; - wallet.setPreviousWallet(selectedWallet); - - const walletName = selectedWallet.value.wallet; - const gapLimit = walletCfg.get(cfgConstants.GAP_LIMIT); - const hiddenAccounts = walletCfg.get(cfgConstants.HIDDEN_ACCOUNTS); - const currencyDisplay = walletCfg.get(cfgConstants.CURRENCY_DISPLAY); - const discoverAccountsComplete = walletCfg.get( - cfgConstants.DISCOVER_ACCOUNTS - ); - const lastPoliteiaAccessTime = walletCfg.get( - cfgConstants.POLITEIA_LAST_ACCESS_TIME - ); - const lastPoliteiaAccessBlock = walletCfg.get( - cfgConstants.POLITEIA_LAST_ACCESS_BLOCK - ); - const enablePrivacy = walletCfg.get(cfgConstants.ENABLE_PRIVACY); - const sendFromUnmixed = walletCfg.get(cfgConstants.SEND_FROM_UNMIXED); - const mixedAccount = walletCfg.get(cfgConstants.MIXED_ACCOUNT_CFG); - const changeAccount = walletCfg.get(cfgConstants.CHANGE_ACCOUNT_CFG); - const csppServer = walletCfg.get(cfgConstants.CSPP_SERVER); - const csppPort = walletCfg.get(cfgConstants.CSPP_PORT); - const mixedAccountBranch = walletCfg.get(cfgConstants.MIXED_ACC_BRANCH); - const rememberedVspHost = walletCfg.get(cfgConstants.REMEMBERED_VSP_HOST); - const needsVSPdProcessManaged = walletCfg.get( - cfgConstants.NEEDS_VSPD_PROCESS_TICKETS - ); - const showStakingWarning = walletCfg.get( - cfgConstants.SHOW_STAKING_WARNING - ); + // Check to see if wallet config has old cspp.decred.org setting, will + // update to mix.decred.org + const currentCSPP = walletCfg.get(cfgConstants.CSPP_SERVER); + if (currentCSPP == CSPP_URL_LEGACY) { + walletCfg.set(cfgConstants.CSPP_SERVER, CSPP_URL); + } - const autobuyerSettings = walletCfg.get(cfgConstants.AUTOBUYER_SETTINGS); - dispatch({ - type: SET_AUTOBUYER_SETTINGS, - autobuyerSettings - }); + const walletStarted = await wallet.startWallet( + selectedWallet.value.wallet, + isTestnet, + rpcCreds, + selectedWallet.value.gapLimit, + selectedWallet.value.disableCoinTypeUpgrades + ); + const { port } = walletStarted; + wallet.setPreviousWallet(selectedWallet); + + const walletName = selectedWallet.value.wallet; + const gapLimit = walletCfg.get(cfgConstants.GAP_LIMIT); + const hiddenAccounts = walletCfg.get(cfgConstants.HIDDEN_ACCOUNTS); + const currencyDisplay = walletCfg.get(cfgConstants.CURRENCY_DISPLAY); + const discoverAccountsComplete = walletCfg.get( + cfgConstants.DISCOVER_ACCOUNTS + ); + const lastPoliteiaAccessTime = walletCfg.get( + cfgConstants.POLITEIA_LAST_ACCESS_TIME + ); + const lastPoliteiaAccessBlock = walletCfg.get( + cfgConstants.POLITEIA_LAST_ACCESS_BLOCK + ); + const enablePrivacy = walletCfg.get(cfgConstants.ENABLE_PRIVACY); + const sendFromUnmixed = walletCfg.get(cfgConstants.SEND_FROM_UNMIXED); + const mixedAccount = walletCfg.get(cfgConstants.MIXED_ACCOUNT_CFG); + const changeAccount = walletCfg.get(cfgConstants.CHANGE_ACCOUNT_CFG); + const csppServer = walletCfg.get(cfgConstants.CSPP_SERVER); + const csppPort = walletCfg.get(cfgConstants.CSPP_PORT); + const mixedAccountBranch = walletCfg.get(cfgConstants.MIXED_ACC_BRANCH); + const rememberedVspHost = walletCfg.get( + cfgConstants.REMEMBERED_VSP_HOST + ); + const needsVSPdProcessManaged = walletCfg.get( + cfgConstants.NEEDS_VSPD_PROCESS_TICKETS + ); + const showStakingWarning = walletCfg.get( + cfgConstants.SHOW_STAKING_WARNING + ); - walletCfg.set(cfgConstants.LAST_ACCESS, Date.now()); - dispatch({ - type: WALLETREADY, - walletName, - network, - hiddenAccounts, - port, - lastPoliteiaAccessTime, - lastPoliteiaAccessBlock - }); - dispatch({ type: WALLET_SETTINGS, currencyDisplay, gapLimit }); - dispatch({ type: SET_REMEMBERED_VSP_HOST, rememberedVspHost }); - dispatch({ type: SET_SHOW_STAKING_WARNING, showStakingWarning }); - const needsPassPhrase = !discoverAccountsComplete && !hasPassPhrase; - dispatch({ - type: WALLET_LOADER_SETTINGS, - discoverAccountsComplete, - needsPassPhrase, - enablePrivacy, - sendFromUnmixed, - mixedAccount, - changeAccount, - csppServer, - csppPort, - mixedAccountBranch, - enableDex, - dexReady, - dexAccount, - rpcCreds, - needsVSPdProcessManaged, - confirmDexSeed - }); - selectedWallet.value.isTrezor && dispatch(enableTrezor()); - await dispatch(getVersionServiceAttempt()); - await dispatch(openWalletAttempt("", false, selectedWallet)); - return discoverAccountsComplete; - }; + const autobuyerSettings = walletCfg.get( + cfgConstants.AUTOBUYER_SETTINGS + ); + dispatch({ + type: SET_AUTOBUYER_SETTINGS, + autobuyerSettings + }); - // TODO better treat errors here. Errors can fail silently. - start() - .then((discoverAccountsComplete) => resolve(discoverAccountsComplete)) - .catch((err) => reject(err)); - }); + walletCfg.set(cfgConstants.LAST_ACCESS, Date.now()); + dispatch({ + type: WALLETREADY, + walletName, + network, + hiddenAccounts, + port, + lastPoliteiaAccessTime, + lastPoliteiaAccessBlock + }); + dispatch({ type: WALLET_SETTINGS, currencyDisplay, gapLimit }); + dispatch({ type: SET_REMEMBERED_VSP_HOST, rememberedVspHost }); + dispatch({ type: SET_SHOW_STAKING_WARNING, showStakingWarning }); + const needsPassPhrase = !discoverAccountsComplete && !hasPassPhrase; + dispatch({ + type: WALLET_LOADER_SETTINGS, + discoverAccountsComplete, + needsPassPhrase, + enablePrivacy, + sendFromUnmixed, + mixedAccount, + changeAccount, + csppServer, + csppPort, + mixedAccountBranch, + enableDex, + dexReady, + dexAccount, + rpcCreds, + needsVSPdProcessManaged, + confirmDexSeed + }); + selectedWallet.value.isTrezor && dispatch(enableTrezor()); + await dispatch(getVersionServiceAttempt()); + await dispatch(openWalletAttempt("", false, selectedWallet)); + return discoverAccountsComplete; + }; + + // TODO better treat errors here. Errors can fail silently. + start() + .then((discoverAccountsComplete) => resolve(discoverAccountsComplete)) + .catch((err) => reject(err)); + }); export const decreditonInit = () => (dispatch) => { dispatch(registerForErrors()); @@ -702,33 +704,31 @@ export const generateRandomGradient = () => { return `linear-gradient(#${randomColor} 0%, #${invertedColor} 100%)`; }; -export const checkDisplayWalletGradients = (availableWallets) => ( - dispatch, - getState -) => { - const missingGradientWallets = []; - let availableGradients = [...preDefinedGradients]; - availableWallets - .sort((a, b) => b.lastAccess - a.lastAccess) - .forEach(({ wallet, displayWalletGradient }) => { - if (!displayWalletGradient) { - missingGradientWallets.push(wallet); - } else { - availableGradients = availableGradients.filter( - (gradient) => gradient != displayWalletGradient - ); - } - }); +export const checkDisplayWalletGradients = + (availableWallets) => (dispatch, getState) => { + const missingGradientWallets = []; + let availableGradients = [...preDefinedGradients]; + availableWallets + .sort((a, b) => b.lastAccess - a.lastAccess) + .forEach(({ wallet, displayWalletGradient }) => { + if (!displayWalletGradient) { + missingGradientWallets.push(wallet); + } else { + availableGradients = availableGradients.filter( + (gradient) => gradient != displayWalletGradient + ); + } + }); - // set missing gradients - if (missingGradientWallets.length > 0) { - availableGradients.reverse(); - missingGradientWallets.forEach((walletName) => { - const gradient = availableGradients.pop() ?? generateRandomGradient(); - const config = wallet.getWalletCfg(isTestNet(getState()), walletName); - config.set(cfgConstants.DISPLAY_WALLET_GRADIENT, gradient); - }); + // set missing gradients + if (missingGradientWallets.length > 0) { + availableGradients.reverse(); + missingGradientWallets.forEach((walletName) => { + const gradient = availableGradients.pop() ?? generateRandomGradient(); + const config = wallet.getWalletCfg(isTestNet(getState()), walletName); + config.set(cfgConstants.DISPLAY_WALLET_GRADIENT, gradient); + }); - dispatch(getAvailableWallets()); - } -}; + dispatch(getAvailableWallets()); + } + }; diff --git a/app/actions/DexActions.js b/app/actions/DexActions.js index 779ddcb07b..1a37b73ffa 100644 --- a/app/actions/DexActions.js +++ b/app/actions/DexActions.js @@ -218,73 +218,68 @@ export const DEX_CREATEWALLET_ATTEMPT = "DEX_CREATEWALLET_ATTEMPT"; export const DEX_CREATEWALLET_SUCCESS = "DEX_CREATEWALLET_SUCCESS"; export const DEX_CREATEWALLET_FAILED = "DEX_CREATEWALLET_FAILED"; -export const createWalletDex = ( - passphrase, - appPassphrase, - accountName -) => async (dispatch, getState) => { - dispatch({ type: DEX_CREATEWALLET_ATTEMPT }); - if (!sel.dexActive(getState())) { - dispatch({ type: DEX_CREATEWALLET_FAILED, error: "Dex isn't active" }); - return; - } - try { - const { - walletLoader: { dexRpcSettings } - } = getState(); - const rpcCreds = dexRpcSettings; - const account = accountName; - const rpcuser = rpcCreds.rpcUser; - const rpcpass = rpcCreds.rpcPass; - const rpclisten = rpcCreds.rpcListen; - const rpccert = rpcCreds.rpcCert; - const assetID = 42; - const walletType = "dcrwalletRPC"; - await dex.createWallet( - assetID, - walletType, - passphrase, - appPassphrase, - account, - rpcuser, - rpcpass, - rpclisten, - rpccert - ); - dispatch({ type: DEX_CREATEWALLET_SUCCESS }); - // Request current user information - dispatch(userDex()); - } catch (error) { - dispatch({ type: DEX_CREATEWALLET_FAILED, error }); - return; - } -}; +export const createWalletDex = + (passphrase, appPassphrase, accountName) => async (dispatch, getState) => { + dispatch({ type: DEX_CREATEWALLET_ATTEMPT }); + if (!sel.dexActive(getState())) { + dispatch({ type: DEX_CREATEWALLET_FAILED, error: "Dex isn't active" }); + return; + } + try { + const { + walletLoader: { dexRpcSettings } + } = getState(); + const rpcCreds = dexRpcSettings; + const account = accountName; + const rpcuser = rpcCreds.rpcUser; + const rpcpass = rpcCreds.rpcPass; + const rpclisten = rpcCreds.rpcListen; + const rpccert = rpcCreds.rpcCert; + const assetID = 42; + const walletType = "dcrwalletRPC"; + await dex.createWallet( + assetID, + walletType, + passphrase, + appPassphrase, + account, + rpcuser, + rpcpass, + rpclisten, + rpccert + ); + dispatch({ type: DEX_CREATEWALLET_SUCCESS }); + // Request current user information + dispatch(userDex()); + } catch (error) { + dispatch({ type: DEX_CREATEWALLET_FAILED, error }); + return; + } + }; export const DEX_SETWALLET_PASSWORD_ATTEMPT = "DEX_SETWALLET_PASSWORD_ATTEMPT"; export const DEX_SETWALLET_PASSWORD_SUCCESS = "DEX_SETWALLET_PASSWORD_SUCCESS"; export const DEX_SETWALLET_PASSWORD_FAILED = "DEX_SETWALLET_PASSWORD_FAILED"; -export const setWalletPasswordDex = (passphrase, appPassphrase) => async ( - dispatch, - getState -) => { - dispatch({ type: DEX_SETWALLET_PASSWORD_ATTEMPT }); - if (!sel.dexActive(getState())) { - dispatch({ - type: DEX_SETWALLET_PASSWORD_FAILED, - error: "Dex isn't active" - }); - return; - } - try { - const assetID = 42; - await dex.setWalletPassword(assetID, passphrase, appPassphrase); - dispatch({ type: DEX_SETWALLET_PASSWORD_SUCCESS }); - } catch (error) { - dispatch({ type: DEX_SETWALLET_PASSWORD_FAILED, error }); - return; - } -}; +export const setWalletPasswordDex = + (passphrase, appPassphrase) => async (dispatch, getState) => { + dispatch({ type: DEX_SETWALLET_PASSWORD_ATTEMPT }); + if (!sel.dexActive(getState())) { + dispatch({ + type: DEX_SETWALLET_PASSWORD_FAILED, + error: "Dex isn't active" + }); + return; + } + try { + const assetID = 42; + await dex.setWalletPassword(assetID, passphrase, appPassphrase); + dispatch({ type: DEX_SETWALLET_PASSWORD_SUCCESS }); + } catch (error) { + dispatch({ type: DEX_SETWALLET_PASSWORD_FAILED, error }); + return; + } + }; export const DEX_USER_ATTEMPT = "DEX_USER_ATTEMPT"; export const DEX_USER_SUCCESS = "DEX_USER_SUCCESS"; @@ -343,27 +338,25 @@ export const CREATEDEXACCOUNT_ATTEMPT = "CREATEDEXACCOUNT_ATTEMPT"; export const CREATEDEXACCOUNT_FAILED = "CREATEDEXACCOUNT_FAILED"; export const CREATEDEXACCOUNT_SUCCESS = "CREATEDEXACCOUNT_SUCCESS"; -export const createDexAccount = (passphrase, accountName) => async ( - dispatch, - getState -) => { - const { - daemon: { walletName } - } = getState(); +export const createDexAccount = + (passphrase, accountName) => async (dispatch, getState) => { + const { + daemon: { walletName } + } = getState(); - try { - const walletConfig = wallet.getWalletCfg( - sel.isTestNet(getState()), - walletName - ); - dispatch({ type: CREATEDEXACCOUNT_ATTEMPT }); - await dispatch(getNextAccountAttempt(passphrase, accountName)); - dispatch({ dexAccount: accountName, type: CREATEDEXACCOUNT_SUCCESS }); - walletConfig.set(configConstants.DEX_ACCOUNT, accountName); - } catch (error) { - dispatch({ error, type: CREATEDEXACCOUNT_FAILED }); - } -}; + try { + const walletConfig = wallet.getWalletCfg( + sel.isTestNet(getState()), + walletName + ); + dispatch({ type: CREATEDEXACCOUNT_ATTEMPT }); + await dispatch(getNextAccountAttempt(passphrase, accountName)); + dispatch({ dexAccount: accountName, type: CREATEDEXACCOUNT_SUCCESS }); + walletConfig.set(configConstants.DEX_ACCOUNT, accountName); + } catch (error) { + dispatch({ error, type: CREATEDEXACCOUNT_FAILED }); + } + }; export const SELECT_DEXACCOUNT_ATTEMPT = "SELECT_DEXACCOUNT_ATTEMPT"; export const SELECT_DEXACCOUNT_FAILED = "SELECT_DEXACCOUNT_FAILED"; diff --git a/app/actions/GovernanceActions.js b/app/actions/GovernanceActions.js index f6ae929b50..70c7618e33 100644 --- a/app/actions/GovernanceActions.js +++ b/app/actions/GovernanceActions.js @@ -381,121 +381,119 @@ export const GETPROPROSAL_UPDATEVOTESTATUS_FAILED = // // tokensBatch length can not exceed politeia's proposallistpagesize // limit; otherwise it will return ErrorStatusMaxProposalsExceededPolicy. -export const getProposalsAndUpdateVoteStatus = (tokensBatch) => async ( - dispatch, - getState -) => { - const findProposal = (proposals, token) => - proposals.find((proposal) => - proposal.censorshiprecord.token === token ? proposal : null - ); +export const getProposalsAndUpdateVoteStatus = + (tokensBatch) => async (dispatch, getState) => { + const findProposal = (proposals, token) => + proposals.find((proposal) => + proposal.censorshiprecord.token === token ? proposal : null + ); - const concatProposals = (oldProposals, newProposals) => { - const response = {}; - // We copy oldProposals in order to avoid modifying it triggering render - const oldProposalsCopy = Object.assign({}, oldProposals); - Object.keys(oldProposalsCopy).forEach((key) => { - if (oldProposalsCopy[key] && oldProposalsCopy[key].length > 0) { - for (let i = 0; i < newProposals[key].length; i++) { - const newProp = newProposals[key][i]; - if (findProposal(oldProposalsCopy[key], newProp.token)) { - oldProposalsCopy[key][i] = newProp; - continue; + const concatProposals = (oldProposals, newProposals) => { + const response = {}; + // We copy oldProposals in order to avoid modifying it triggering render + const oldProposalsCopy = Object.assign({}, oldProposals); + Object.keys(oldProposalsCopy).forEach((key) => { + if (oldProposalsCopy[key] && oldProposalsCopy[key].length > 0) { + for (let i = 0; i < newProposals[key].length; i++) { + const newProp = newProposals[key][i]; + if (findProposal(oldProposalsCopy[key], newProp.token)) { + oldProposalsCopy[key][i] = newProp; + continue; + } + oldProposalsCopy[key].push(newProp); } - oldProposalsCopy[key].push(newProp); + response[key] = oldProposalsCopy[key]; + } else { + response[key] = newProposals[key]; } - response[key] = oldProposalsCopy[key]; - } else { - response[key] = newProposals[key]; - } - }); - - return response; - }; + }); - dispatch({ type: GETPROPROSAL_UPDATEVOTESTATUS_ATTEMPT, tokensBatch }); - const proposalsUpdated = getDefaultInventory(); - const blockTimestampFromNow = sel.blockTimestampFromNow(getState()); - const blocksFromBestBlock = sel.blocksFromBestBlock(getState()); - const piURL = sel.politeiaURL(getState()); - // If proposals is null at our redux state, it probably means first starting or - // the wallet was closed. - const oldProposals = - sel.proposals(getState()) === null - ? getDefaultInventory() - : sel.proposals(getState()); - const lastPoliteiaAccessTime = sel.lastPoliteiaAccessTime(getState()); - const walletName = sel.getWalletName(getState()); - const testnet = sel.isTestNet(getState()); - const lastPoliteiaAccessBlock = sel.lastPoliteiaAccessBlock(getState()); + return response; + }; - try { - const { records } = await getProposalsBatch(tokensBatch, piURL); - const { summaries } = await getProposalsVoteSummaryBatch( - tokensBatch, - piURL - ); - tokensBatch.forEach((token) => { - const proposalSummary = summaries[token]; - const { status } = proposalSummary; - const prop = parseRawProposal(records[token]); - prop.token = token; - prop.proposalStatus = prop.status; - - // Fill vote information in proposal object. - fillVoteSummary( - prop, - proposalSummary, - blockTimestampFromNow, - blocksFromBestBlock + dispatch({ type: GETPROPROSAL_UPDATEVOTESTATUS_ATTEMPT, tokensBatch }); + const proposalsUpdated = getDefaultInventory(); + const blockTimestampFromNow = sel.blockTimestampFromNow(getState()); + const blocksFromBestBlock = sel.blocksFromBestBlock(getState()); + const piURL = sel.politeiaURL(getState()); + // If proposals is null at our redux state, it probably means first starting or + // the wallet was closed. + const oldProposals = + sel.proposals(getState()) === null + ? getDefaultInventory() + : sel.proposals(getState()); + const lastPoliteiaAccessTime = sel.lastPoliteiaAccessTime(getState()); + const walletName = sel.getWalletName(getState()); + const testnet = sel.isTestNet(getState()); + const lastPoliteiaAccessBlock = sel.lastPoliteiaAccessBlock(getState()); + + try { + const { records } = await getProposalsBatch(tokensBatch, piURL); + const { summaries } = await getProposalsVoteSummaryBatch( + tokensBatch, + piURL ); - prop.currentVoteChoice = - (walletName && - getVoteOption(token, prop, null, null, testnet, walletName)) || - "abstain"; + tokensBatch.forEach((token) => { + const proposalSummary = summaries[token]; + const { status } = proposalSummary; + const prop = parseRawProposal(records[token]); + prop.token = token; + prop.proposalStatus = prop.status; + + // Fill vote information in proposal object. + fillVoteSummary( + prop, + proposalSummary, + blockTimestampFromNow, + blocksFromBestBlock + ); + prop.currentVoteChoice = + (walletName && + getVoteOption(token, prop, null, null, testnet, walletName)) || + "abstain"; - if (prop.timestamp > lastPoliteiaAccessTime) { - prop.modifiedSinceLastAccess = true; - } - if (prop.startVoteHeight > lastPoliteiaAccessBlock) { - prop.votingSinceLastAccess = true; - } + if (prop.timestamp > lastPoliteiaAccessTime) { + prop.modifiedSinceLastAccess = true; + } + if (prop.startVoteHeight > lastPoliteiaAccessBlock) { + prop.votingSinceLastAccess = true; + } - // if proposal is not abandoned we check its votestatus - if (prop.proposalStatus === PROPOSAL_STATUS_ABANDONED) { - proposalsUpdated.abandonedVote.push(prop); - } else { - switch (status) { - case PROPOSAL_VOTING_ACTIVE: - proposalsUpdated.activeVote.push(prop); - break; - case PROPOSAL_VOTING_REJECTED: - case PROPOSAL_VOTING_APPROVED: - proposalsUpdated.finishedVote.push(prop); - if (status === PROPOSAL_VOTING_APPROVED) { - proposalsUpdated.approvedVote.push(prop); - } else { - proposalsUpdated.rejectedVote.push(prop); - } - break; - default: - proposalsUpdated.preVote.push(prop); - break; + // if proposal is not abandoned we check its votestatus + if (prop.proposalStatus === PROPOSAL_STATUS_ABANDONED) { + proposalsUpdated.abandonedVote.push(prop); + } else { + switch (status) { + case PROPOSAL_VOTING_ACTIVE: + proposalsUpdated.activeVote.push(prop); + break; + case PROPOSAL_VOTING_REJECTED: + case PROPOSAL_VOTING_APPROVED: + proposalsUpdated.finishedVote.push(prop); + if (status === PROPOSAL_VOTING_APPROVED) { + proposalsUpdated.approvedVote.push(prop); + } else { + proposalsUpdated.rejectedVote.push(prop); + } + break; + default: + proposalsUpdated.preVote.push(prop); + break; + } } - } - }); + }); - // concat new proposals list array to old proposals list array - const concatedProposals = concatProposals(oldProposals, proposalsUpdated); - return dispatch({ - type: GETPROPROSAL_UPDATEVOTESTATUS_SUCCESS, - proposals: concatedProposals - }); - } catch (error) { - dispatch({ type: GETPROPROSAL_UPDATEVOTESTATUS_FAILED, error }); - throw error; - } -}; + // concat new proposals list array to old proposals list array + const concatedProposals = concatProposals(oldProposals, proposalsUpdated); + return dispatch({ + type: GETPROPROSAL_UPDATEVOTESTATUS_SUCCESS, + proposals: concatedProposals + }); + } catch (error) { + dispatch({ type: GETPROPROSAL_UPDATEVOTESTATUS_FAILED, error }); + throw error; + } + }; export const GETPROPOSAL_ATTEMPT = "GETPROPOSAL_ATTEMPT"; export const GETPROPOSAL_FAILED = "GETPROPOSAL_FAILED"; @@ -642,109 +640,108 @@ export const UPDATEVOTECHOICE_FAILED = "UPDATEVOTECHOICE_FAILED"; // updateVoteChoice cast vote into pi server, if success we cache the vote // information updates the proposal vote summary and dispatch it with its new // result. -export const updateVoteChoice = ( - proposal, - newVoteChoiceID, - passphrase -) => async (dispatch, getState) => { - const { walletService } = getState().grpc; - const blockTimestampFromNow = sel.blockTimestampFromNow(getState()); - const blocksFromBestBlock = sel.blocksFromBestBlock(getState()); - const piURL = sel.politeiaURL(getState()); - const walletName = sel.getWalletName(getState()); - const testnet = sel.isTestNet(getState()); - const { walletEligibleTickets, token } = proposal; +export const updateVoteChoice = + (proposal, newVoteChoiceID, passphrase) => async (dispatch, getState) => { + const { walletService } = getState().grpc; + const blockTimestampFromNow = sel.blockTimestampFromNow(getState()); + const blocksFromBestBlock = sel.blocksFromBestBlock(getState()); + const piURL = sel.politeiaURL(getState()); + const walletName = sel.getWalletName(getState()); + const testnet = sel.isTestNet(getState()); + const { walletEligibleTickets, token } = proposal; - const voteChoice = proposal.voteOptions.find((o) => o.id === newVoteChoiceID); - if (!voteChoice) throw "Unknown vote choice for proposal"; + const voteChoice = proposal.voteOptions.find( + (o) => o.id === newVoteChoiceID + ); + if (!voteChoice) throw "Unknown vote choice for proposal"; - // get account number. We consider all votes come from same account. - const address = walletEligibleTickets[0].address; - const response = await wallet.validateAddress( - sel.walletService(getState()), - address - ); - const accountNumber = response.accountNumber; - // msg here needs to follow the same syntax as what is defined on - // politeiavoter. - const messages = walletEligibleTickets.map((t) => ({ - address: t.address, - message: `${token}${t.ticket}${voteChoice.bit.toString(16)}` - })); - - const updatePropRef = (proposals, token, newProposal) => { - const keys = Object.keys(proposals); - for (let i = 0; i < keys.length; i++) { - const key = keys[i]; - let j; - const proposal = proposals[key].find((p, ind) => { - j = ind; - return p.token === token; - }); - if (proposal) { - newProposal.currentVoteChoice = voteChoice; - return (proposals[key][j] = { ...newProposal }); + // get account number. We consider all votes come from same account. + const address = walletEligibleTickets[0].address; + const response = await wallet.validateAddress( + sel.walletService(getState()), + address + ); + const accountNumber = response.accountNumber; + // msg here needs to follow the same syntax as what is defined on + // politeiavoter. + const messages = walletEligibleTickets.map((t) => ({ + address: t.address, + message: `${token}${t.ticket}${voteChoice.bit.toString(16)}` + })); + + const updatePropRef = (proposals, token, newProposal) => { + const keys = Object.keys(proposals); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + let j; + const proposal = proposals[key].find((p, ind) => { + j = ind; + return p.token === token; + }); + if (proposal) { + newProposal.currentVoteChoice = voteChoice; + return (proposals[key][j] = { ...newProposal }); + } } - } - }; + }; - dispatch({ type: UPDATEVOTECHOICE_ATTEMPT }); - try { - const signed = await dispatch( - unlockAcctAndExecFn(passphrase, [accountNumber], () => - wallet.signMessages(walletService, messages) - ) - ); + dispatch({ type: UPDATEVOTECHOICE_ATTEMPT }); + try { + const signed = await dispatch( + unlockAcctAndExecFn(passphrase, [accountNumber], () => + wallet.signMessages(walletService, messages) + ) + ); - const votes = []; - const votesToCache = { token, walletEligibleTickets, voteChoice }; - const sigs = signed.replies; - walletEligibleTickets.forEach((t, i) => { - const { signature } = sigs[i]; - if (signature.error) { - throw signature.error; - } - const votebit = voteChoice.bit.toString(16); - const vote = { token, ticket: t.ticket, votebit, signature }; - votes.push(vote); - }); + const votes = []; + const votesToCache = { token, walletEligibleTickets, voteChoice }; + const sigs = signed.replies; + walletEligibleTickets.forEach((t, i) => { + const { signature } = sigs[i]; + if (signature.error) { + throw signature.error; + } + const votebit = voteChoice.bit.toString(16); + const vote = { token, ticket: t.ticket, votebit, signature }; + votes.push(vote); + }); - // cast vote into pi server - const response = await pi.castBallot({ piURL, votes }); - const { errorcontext: voteCastError } = - response.data.receipts.find(({ errorcontext }) => errorcontext) || {}; + // cast vote into pi server + const response = await pi.castBallot({ piURL, votes }); + const { errorcontext: voteCastError } = + response.data.receipts.find(({ errorcontext }) => errorcontext) || {}; - if (voteCastError) { - throw voteCastError; - } + if (voteCastError) { + throw voteCastError; + } - // cache information locally so we can show them without querying from - // pi server. - savePiVote(votesToCache, token, testnet, walletName); - - // update proposal vote status, so we can see our vote counting towards - // the totals. - const newProposal = { ...proposal }; - const { summaries } = await getProposalsVoteSummaryBatch([token], piURL); - fillVoteSummary( - newProposal, - summaries[token], - blockTimestampFromNow, - blocksFromBestBlock - ); + // cache information locally so we can show them without querying from + // pi server. + savePiVote(votesToCache, token, testnet, walletName); - const proposals = getState().governance.proposals; - await updatePropRef(proposals, token, newProposal); + // update proposal vote status, so we can see our vote counting towards + // the totals. + const newProposal = { ...proposal }; + const { summaries } = await getProposalsVoteSummaryBatch([token], piURL); + fillVoteSummary( + newProposal, + summaries[token], + blockTimestampFromNow, + blocksFromBestBlock + ); - dispatch({ - votes, - proposals, - proposal: newProposal, - token, - type: UPDATEVOTECHOICE_SUCCESS - }); - } catch (error) { - dispatch({ error, type: UPDATEVOTECHOICE_FAILED }); - throw error; - } -}; + const proposals = getState().governance.proposals; + await updatePropRef(proposals, token, newProposal); + + dispatch({ + votes, + proposals, + proposal: newProposal, + token, + type: UPDATEVOTECHOICE_SUCCESS + }); + } catch (error) { + dispatch({ error, type: UPDATEVOTECHOICE_FAILED }); + throw error; + } + }; diff --git a/app/actions/LNActions.js b/app/actions/LNActions.js index e2b5ff356f..8968a98742 100644 --- a/app/actions/LNActions.js +++ b/app/actions/LNActions.js @@ -46,176 +46,173 @@ export const LNWALLET_STARTUPSTAGE_SCBRESTORE = // create a new wallet account for LN operations. export const CREATE_LN_ACCOUNT = "**create ln account**"; -export const startDcrlnd = ( - passphrase, - autopilotEnabled, - walletAccount, - scbFile -) => async (dispatch, getState) => { - dispatch({ type: LNWALLET_STARTUP_ATTEMPT }); +export const startDcrlnd = + (passphrase, autopilotEnabled, walletAccount, scbFile) => + async (dispatch, getState) => { + dispatch({ type: LNWALLET_STARTUP_ATTEMPT }); - const { - grpc: { port } - } = getState(); - const { - daemon: { walletName } - } = getState(); - const isTestnet = sel.isTestNet(getState()); - const walletPath = wallet.getWalletPath(isTestnet, walletName); - const walletPort = port; - const lnCfg = dispatch(getLNWalletConfig()); - - // Use the stored account if it exists, the specified account if it's a number - // or create an account specifically for LN usage. - let lnAccount = lnCfg.account; - let creating = false; - if (walletAccount === CREATE_LN_ACCOUNT) { - try { - const acctResp = await dispatch( - getNextAccountAttempt(passphrase, "LN Account") - ); - if (acctResp instanceof Error) { - throw acctResp; - } else if (acctResp.error) { - throw acctResp.error; + const { + grpc: { port } + } = getState(); + const { + daemon: { walletName } + } = getState(); + const isTestnet = sel.isTestNet(getState()); + const walletPath = wallet.getWalletPath(isTestnet, walletName); + const walletPort = port; + const lnCfg = dispatch(getLNWalletConfig()); + + // Use the stored account if it exists, the specified account if it's a number + // or create an account specifically for LN usage. + let lnAccount = lnCfg.account; + let creating = false; + if (walletAccount === CREATE_LN_ACCOUNT) { + try { + const acctResp = await dispatch( + getNextAccountAttempt(passphrase, "LN Account") + ); + if (acctResp instanceof Error) { + throw acctResp; + } else if (acctResp.error) { + throw acctResp.error; + } + lnAccount = acctResp.getNextAccountResponse.accountNumber; + creating = true; + } catch (error) { + dispatch({ error, type: LNWALLET_CREATEACCOUNT_FAILED }); + dispatch({ type: LNWALLET_STARTUP_FAILED }); + throw error; } - lnAccount = acctResp.getNextAccountResponse.accountNumber; + } else if (isNumber(walletAccount)) { + lnAccount = walletAccount; creating = true; + } + + const rpcCreds = wallet.getDcrdRpcCredentials(); + const walletClientKeyCert = wallet.getDcrwalletGrpcKeyCert(); + + let dcrlndCreds; + let wuClient; + + try { + dispatch({ + stage: LNWALLET_STARTUPSTAGE_STARTDCRLND, + type: LNWALLET_STARTUP_CHANGEDSTAGE + }); + const res = await ln.startDcrlnd( + lnAccount, + walletPort, + rpcCreds, + walletPath, + isTestnet, + autopilotEnabled + ); + dcrlndCreds = res; } catch (error) { - dispatch({ error, type: LNWALLET_CREATEACCOUNT_FAILED }); dispatch({ type: LNWALLET_STARTUP_FAILED }); - throw error; + dispatch({ error, type: LNWALLET_STARTDCRLND_FAILED }); + return; } - } else if (isNumber(walletAccount)) { - lnAccount = walletAccount; - creating = true; - } - - const rpcCreds = wallet.getDcrdRpcCredentials(); - const walletClientKeyCert = wallet.getDcrwalletGrpcKeyCert(); - let dcrlndCreds; - let wuClient; + // Cleanup function for when the next few operations fail. At this point, + // dcrlnd is already running so if some error occurs we need to shut it down. + const cleanup = () => { + // Force dcrlnd to stop. + ln.stopDcrlnd(); + dispatch({ type: LNWALLET_STARTUP_FAILED }); - try { - dispatch({ - stage: LNWALLET_STARTUPSTAGE_STARTDCRLND, - type: LNWALLET_STARTUP_CHANGEDSTAGE - }); - const res = await ln.startDcrlnd( - lnAccount, - walletPort, - rpcCreds, - walletPath, - isTestnet, - autopilotEnabled - ); - dcrlndCreds = res; - } catch (error) { - dispatch({ type: LNWALLET_STARTUP_FAILED }); - dispatch({ error, type: LNWALLET_STARTDCRLND_FAILED }); - return; - } + if (creating) { + // When the error happens during ln wallet creation, remove the dir so + // that the next attempt can try to create the wallet again. We do it + // after a timeout to ensure the previous shutdown has completed. + setTimeout(() => ln.removeDcrlnd(walletName, isTestnet), 2000); + } + }; - // Cleanup function for when the next few operations fail. At this point, - // dcrlnd is already running so if some error occurs we need to shut it down. - const cleanup = () => { - // Force dcrlnd to stop. - ln.stopDcrlnd(); - dispatch({ type: LNWALLET_STARTUP_FAILED }); + try { + wuClient = await ln.getWalletUnlockerClient( + dcrlndCreds.address, + dcrlndCreds.port, + dcrlndCreds.certPath, + null + ); - if (creating) { - // When the error happens during ln wallet creation, remove the dir so - // that the next attempt can try to create the wallet again. We do it - // after a timeout to ensure the previous shutdown has completed. - setTimeout(() => ln.removeDcrlnd(walletName, isTestnet), 2000); + dispatch({ + stage: LNWALLET_STARTUPSTAGE_UNLOCK, + type: LNWALLET_STARTUP_CHANGEDSTAGE + }); + await ln.unlockWallet(wuClient, passphrase, walletClientKeyCert); + } catch (error) { + // An unimplemented error here probably means dcrlnd was already running, + // so just continue with the connection attempt. + if (error.code !== 12) { + // 12 === UNIMPLEMENTED. + // Otherwise, throw the error. + cleanup(); + dispatch({ error, type: LNWALLET_UNLOCK_FAILED }); + return; + } } - }; - - try { - wuClient = await ln.getWalletUnlockerClient( - dcrlndCreds.address, - dcrlndCreds.port, - dcrlndCreds.certPath, - null - ); - dispatch({ - stage: LNWALLET_STARTUPSTAGE_UNLOCK, - type: LNWALLET_STARTUP_CHANGEDSTAGE - }); - await ln.unlockWallet(wuClient, passphrase, walletClientKeyCert); - } catch (error) { - // An unimplemented error here probably means dcrlnd was already running, - // so just continue with the connection attempt. - if (error.code !== 12) { - // 12 === UNIMPLEMENTED. - // Otherwise, throw the error. + let lnClient; + try { + dispatch({ + stage: LNWALLET_STARTUPSTAGE_CONNECT, + type: LNWALLET_STARTUP_CHANGEDSTAGE + }); + const { client } = await dispatch( + connectToLNWallet( + dcrlndCreds.address, + dcrlndCreds.port, + dcrlndCreds.certPath, + dcrlndCreds.macaroonPath, + lnAccount + ) + ); + lnClient = client; + } catch (error) { cleanup(); - dispatch({ error, type: LNWALLET_UNLOCK_FAILED }); + dispatch({ error, type: LNWALLET_CONNECT_FAILED }); return; } - } - let lnClient; - try { - dispatch({ - stage: LNWALLET_STARTUPSTAGE_CONNECT, - type: LNWALLET_STARTUP_CHANGEDSTAGE - }); - const { client } = await dispatch( - connectToLNWallet( - dcrlndCreds.address, - dcrlndCreds.port, - dcrlndCreds.certPath, - dcrlndCreds.macaroonPath, - lnAccount - ) - ); - lnClient = client; - } catch (error) { - cleanup(); - dispatch({ error, type: LNWALLET_CONNECT_FAILED }); - return; - } - - try { - dispatch({ - stage: LNWALLET_STARTUPSTAGE_STARTUPSYNC, - type: LNWALLET_STARTUP_CHANGEDSTAGE - }); - await dispatch(waitForDcrlndSynced(lnClient)); - } catch (error) { - cleanup(); - dispatch({ error, type: LNWALLET_STARTUPSYNC_FAILED }); - return; - } + try { + dispatch({ + stage: LNWALLET_STARTUPSTAGE_STARTUPSYNC, + type: LNWALLET_STARTUP_CHANGEDSTAGE + }); + await dispatch(waitForDcrlndSynced(lnClient)); + } catch (error) { + cleanup(); + dispatch({ error, type: LNWALLET_STARTUPSYNC_FAILED }); + return; + } - try { - dispatch({ - stage: LNWALLET_STARTUPSTAGE_SCBRESTORE, - type: LNWALLET_STARTUP_CHANGEDSTAGE - }); - scbFile && (await ln.restoreBackup(lnClient, scbFile)); - } catch (error) { - cleanup(); - if (String(error).indexOf("unable to unpack chan backup") > -1) { - // This error means the restore itself failed due to a MAC check error, - // so either the SCB file is damaged or the user is attempting to restore - // it on the wrong wallet/account. - dispatch({ error, type: LNWALLET_SCBRESTOREUNPACK_FAILED }); - } else { - // This is a generic error in case something else goes wrong. - dispatch({ error, type: LNWALLET_SCBRESTORE_FAILED }); + try { + dispatch({ + stage: LNWALLET_STARTUPSTAGE_SCBRESTORE, + type: LNWALLET_STARTUP_CHANGEDSTAGE + }); + scbFile && (await ln.restoreBackup(lnClient, scbFile)); + } catch (error) { + cleanup(); + if (String(error).indexOf("unable to unpack chan backup") > -1) { + // This error means the restore itself failed due to a MAC check error, + // so either the SCB file is damaged or the user is attempting to restore + // it on the wrong wallet/account. + dispatch({ error, type: LNWALLET_SCBRESTOREUNPACK_FAILED }); + } else { + // This is a generic error in case something else goes wrong. + dispatch({ error, type: LNWALLET_SCBRESTORE_FAILED }); + } + return; } - return; - } - // Startup only succeeded if we reached this point. - dispatch(setLNWalletConfig(lnAccount)); - dispatch(loadLNStartupInfo()); - dispatch({ type: LNWALLET_STARTUP_SUCCESS }); -}; + // Startup only succeeded if we reached this point. + dispatch(setLNWalletConfig(lnAccount)); + dispatch(loadLNStartupInfo()); + dispatch({ type: LNWALLET_STARTUP_SUCCESS }); + }; export const LNWALLET_DCRLND_STOPPED = "LNWALLET_DCRLND_STOPPED"; @@ -274,109 +271,107 @@ export const checkLnWallet = () => async (dispatch) => { export const LNWALLET_CONNECT_SUCCESS = "LNWALLET_CONNECT_SUCCESS"; -const connectToLNWallet = ( - address, - port, - certPath, - macaroonPath, - account -) => async (dispatch, getState) => { - const client = getState().ln.client; - if (client) { - // Already active and with a setup client. - return { client }; - } - - const sleepMs = 3000; - const sleepCount = 60 / (sleepMs / 1000); - const sleep = () => new Promise((resolve) => setTimeout(resolve, sleepMs)); +const connectToLNWallet = + (address, port, certPath, macaroonPath, account) => + async (dispatch, getState) => { + const client = getState().ln.client; + if (client) { + // Already active and with a setup client. + return { client }; + } - // Attempt to connect to the lnrpc service of the wallet. Since the underlying - // gRPC service of the dcrlnd node is restarted after it's unlocked, we might - // need to try a few times until we get a proper connection. - let lnClient, wtClient, inClient, apClient; - let lastError; - for (let i = 0; i < sleepCount; i++) { - try { - lnClient = await ln.getLightningClient( - address, - port, - certPath, - macaroonPath - ); - wtClient = await ln.getWatchtowerClient( - address, - port, - certPath, - macaroonPath - ); - inClient = await ln.getLNInvoiceClient( - address, - port, - certPath, - macaroonPath - ); - apClient = await ln.getLNAutopilotClient( - address, - port, - certPath, - macaroonPath - ); - // Force a getInfo call to ensure we're connected and the server provides - // the Lightning service. - await ln.getInfo(lnClient); - lastError = null; - break; - } catch (error) { - // An unimplemented error here probably means dcrlnd was just unlocked - // and is currently starting up the services. Wait a bit and try again. - if (error.code !== 12) { - // 12 === UNIMPLEMENTED. - throw error; + const sleepMs = 3000; + const sleepCount = 60 / (sleepMs / 1000); + const sleep = () => new Promise((resolve) => setTimeout(resolve, sleepMs)); + + // Attempt to connect to the lnrpc service of the wallet. Since the underlying + // gRPC service of the dcrlnd node is restarted after it's unlocked, we might + // need to try a few times until we get a proper connection. + let lnClient, wtClient, inClient, apClient; + let lastError; + for (let i = 0; i < sleepCount; i++) { + try { + lnClient = await ln.getLightningClient( + address, + port, + certPath, + macaroonPath + ); + wtClient = await ln.getWatchtowerClient( + address, + port, + certPath, + macaroonPath + ); + inClient = await ln.getLNInvoiceClient( + address, + port, + certPath, + macaroonPath + ); + apClient = await ln.getLNAutopilotClient( + address, + port, + certPath, + macaroonPath + ); + // Force a getInfo call to ensure we're connected and the server provides + // the Lightning service. + await ln.getInfo(lnClient); + lastError = null; + break; + } catch (error) { + // An unimplemented error here probably means dcrlnd was just unlocked + // and is currently starting up the services. Wait a bit and try again. + if (error.code !== 12) { + // 12 === UNIMPLEMENTED. + throw error; + } + lastError = error; + await sleep(); } - lastError = error; - await sleep(); } - } - if (lastError) throw lastError; - - // Ensure the dcrlnd instance and decrediton are connected to the same(ish) - // wallet. For this test to fail the user would have had to manually change a - // lot of config files and it should only happen when reconnecting to a - // running instance, but we'll err on the side of being safe. We generate an - // address on the lnwallet and check if this is also an address owned by the - // wallet. This can still not completely ensure they are the same wallet - // (since this would also pass in the case of different running wallets using - // the same seed) but is good enough for our purposes. - const lnWalletAddr = await ln.newAddress(lnClient); - const validResp = await wallet.validateAddress( - sel.walletService(getState()), - lnWalletAddr - ); - if (!validResp.isValid) { - throw new Error("Invalid address returned by lnwallet: " + lnWalletAddr); - } - if (!validResp.isMine) { - throw new Error("Wallet returned that address from lnwallet is not owned"); - } - const addrAccount = validResp.accountNumber; - if (addrAccount != account) { - throw new Error( - `Wallet returned that address is not from the ln account; account= - ${addrAccount}` + if (lastError) throw lastError; + + // Ensure the dcrlnd instance and decrediton are connected to the same(ish) + // wallet. For this test to fail the user would have had to manually change a + // lot of config files and it should only happen when reconnecting to a + // running instance, but we'll err on the side of being safe. We generate an + // address on the lnwallet and check if this is also an address owned by the + // wallet. This can still not completely ensure they are the same wallet + // (since this would also pass in the case of different running wallets using + // the same seed) but is good enough for our purposes. + const lnWalletAddr = await ln.newAddress(lnClient); + const validResp = await wallet.validateAddress( + sel.walletService(getState()), + lnWalletAddr ); - } + if (!validResp.isValid) { + throw new Error("Invalid address returned by lnwallet: " + lnWalletAddr); + } + if (!validResp.isMine) { + throw new Error( + "Wallet returned that address from lnwallet is not owned" + ); + } + const addrAccount = validResp.accountNumber; + if (addrAccount != account) { + throw new Error( + `Wallet returned that address is not from the ln account; account= + ${addrAccount}` + ); + } - dispatch({ - lnClient, - wtClient, - inClient, - apClient, - type: LNWALLET_CONNECT_SUCCESS - }); + dispatch({ + lnClient, + wtClient, + inClient, + apClient, + type: LNWALLET_CONNECT_SUCCESS + }); - return { client: lnClient, wtClient }; -}; + return { client: lnClient, wtClient }; + }; export const LNWALLET_WAITSYNC_PROGRESS = "LNWALLET_WAITSYNC_PROGRESS"; @@ -774,80 +769,83 @@ export const LNWALLET_OPENCHANNEL_FAILED = "LNWALLET_OPENCHANNEL_FAILED"; export const LNWALLET_RECENTLY_OPENEDCHANNEL = "LNWALLET_RECENTLY_OPENEDCHANNEL"; -export const openChannel = (node, localAmt, pushAmt) => async ( - dispatch, - getState -) => { - const { client } = getState().ln; - if (!client) throw new Error("unconnected to ln wallet"); - - // Split the node string into a node pubkey and (optional) network address. - // If the network address is specified, then try to connect first. - - const split = node.split("@"); - if (split.length > 2) - throw new Error("remote than one @ in the node address"); - - let nodePubKey; - - if (split.length == 2) { - // Try to connect first. - try { - await ln.connectPeer(client, split[0], split[1]); - } catch (error) { - const errorStr = "" + error; - if (errorStr.indexOf("already connected") === -1) { - // Any errors except "already connected to peer" are fatal failures. - dispatch({ error, type: LNWALLET_OPENCHANNEL_FAILED }); - throw error; +export const openChannel = + (node, localAmt, pushAmt) => async (dispatch, getState) => { + const { client } = getState().ln; + if (!client) throw new Error("unconnected to ln wallet"); + + // Split the node string into a node pubkey and (optional) network address. + // If the network address is specified, then try to connect first. + + const split = node.split("@"); + if (split.length > 2) + throw new Error("remote than one @ in the node address"); + + let nodePubKey; + + if (split.length == 2) { + // Try to connect first. + try { + await ln.connectPeer(client, split[0], split[1]); + } catch (error) { + const errorStr = "" + error; + if (errorStr.indexOf("already connected") === -1) { + // Any errors except "already connected to peer" are fatal failures. + dispatch({ error, type: LNWALLET_OPENCHANNEL_FAILED }); + throw error; + } } + nodePubKey = split[0]; + } else { + nodePubKey = node; } - nodePubKey = split[0]; - } else { - nodePubKey = node; - } - const dispatchUpdates = () => { - setTimeout(() => dispatch(updateLNChannelBalances()), 1000); - setTimeout(() => dispatch(updateChannelList()), 1000); - setTimeout(() => dispatch(updateLNWalletBalances()), 1000); - }; - - try { - await new Promise((resolve, reject) => { - const chanStream = ln.openChannel(client, nodePubKey, localAmt, pushAmt); - chanStream.on("data", (update) => { - if (update.chanPending) { - resolve(); - dispatch({ type: LNWALLET_OPENCHANNEL_CHANPENDING }); - dispatchUpdates(); - const txId = Buffer.from(update.chanPending.txid, "base64") - .reverse() - .toString("hex"); - const channelPoint = `${txId}:${update.chanPending.outputIndex}`; - - dispatch({ - type: LNWALLET_RECENTLY_OPENEDCHANNEL, - channelPoint: channelPoint - }); - } - if (update.chanOpen) { - dispatch({ type: LNWALLET_OPENCHANNEL_CHANOPEN }); - dispatchUpdates(); - } - }); + const dispatchUpdates = () => { + setTimeout(() => dispatch(updateLNChannelBalances()), 1000); + setTimeout(() => dispatch(updateChannelList()), 1000); + setTimeout(() => dispatch(updateLNWalletBalances()), 1000); + }; - chanStream.on("error", (error) => { - reject(error); + try { + await new Promise((resolve, reject) => { + const chanStream = ln.openChannel( + client, + nodePubKey, + localAmt, + pushAmt + ); + chanStream.on("data", (update) => { + if (update.chanPending) { + resolve(); + dispatch({ type: LNWALLET_OPENCHANNEL_CHANPENDING }); + dispatchUpdates(); + const txId = Buffer.from(update.chanPending.txid, "base64") + .reverse() + .toString("hex"); + const channelPoint = `${txId}:${update.chanPending.outputIndex}`; + + dispatch({ + type: LNWALLET_RECENTLY_OPENEDCHANNEL, + channelPoint: channelPoint + }); + } + if (update.chanOpen) { + dispatch({ type: LNWALLET_OPENCHANNEL_CHANOPEN }); + dispatchUpdates(); + } + }); + + chanStream.on("error", (error) => { + reject(error); + }); }); - }); - dispatchUpdates(); - } catch (error) { - dispatch({ error, type: LNWALLET_OPENCHANNEL_FAILED }); - throw error; - } -}; + dispatchUpdates(); + } catch (error) { + dispatch({ error, type: LNWALLET_OPENCHANNEL_FAILED }); + throw error; + } + }; export const clearRecentlyOpenedChannelNodePubkey = () => (dispatch) => { dispatch({ @@ -899,61 +897,57 @@ export const closeChannel = (channelPoint, force) => (dispatch, getState) => { export const LNWALLET_FUNDWALLET_FAILED = "LNWALLET_FUNDWALLET_FAILED"; export const LNWALLET_FUNDWALLET_SUCCESS = "LNWALLET_FUNDWALLET_SUCCESS"; -export const fundWallet = (amount, accountNb, passphrase) => async ( - dispatch, - getState -) => { - const { client } = getState().ln; - if (!client) throw new Error("unconnected to ln wallet"); +export const fundWallet = + (amount, accountNb, passphrase) => async (dispatch, getState) => { + const { client } = getState().ln; + if (!client) throw new Error("unconnected to ln wallet"); - try { - const walletService = sel.walletService(getState()); - const lnWalletAddr = await ln.newAddress(client); - const outputs = [{ destination: lnWalletAddr, amount }]; - const txResp = await wallet.constructTransaction( - walletService, - accountNb, - 0, - outputs - ); - const unsignedTx = txResp.unsignedTransaction; - const signResp = await wallet.signTransaction( - walletService, - passphrase, - unsignedTx - ); - const signedTx = signResp.transaction; - await wallet.publishTransaction(walletService, signedTx); - dispatch({ type: LNWALLET_FUNDWALLET_SUCCESS }); - setTimeout(() => dispatch(updateLNWalletBalances(), 3000)); - } catch (error) { - dispatch({ error, type: LNWALLET_FUNDWALLET_FAILED }); - throw error; - } -}; + try { + const walletService = sel.walletService(getState()); + const lnWalletAddr = await ln.newAddress(client); + const outputs = [{ destination: lnWalletAddr, amount }]; + const txResp = await wallet.constructTransaction( + walletService, + accountNb, + 0, + outputs + ); + const unsignedTx = txResp.unsignedTransaction; + const signResp = await wallet.signTransaction( + walletService, + passphrase, + unsignedTx + ); + const signedTx = signResp.transaction; + await wallet.publishTransaction(walletService, signedTx); + dispatch({ type: LNWALLET_FUNDWALLET_SUCCESS }); + setTimeout(() => dispatch(updateLNWalletBalances(), 3000)); + } catch (error) { + dispatch({ error, type: LNWALLET_FUNDWALLET_FAILED }); + throw error; + } + }; export const LNWALLET_WITHDRAWWALLET_FAILED = "LNWALLET_WITHDRAWWALLET_FAILED"; export const LNWALLET_WITHDRAWWALLET_SUCCESS = "LNWALLET_WITHDRAWWALLET_SUCCESS"; -export const withdrawWallet = (amount, accountNb) => async ( - dispatch, - getState -) => { - const { client } = getState().ln; - if (!client) throw new Error("unconnected to ln wallet"); +export const withdrawWallet = + (amount, accountNb) => async (dispatch, getState) => { + const { client } = getState().ln; + if (!client) throw new Error("unconnected to ln wallet"); - try { - const walletService = sel.walletService(getState()); - const walletAddr = await wallet.getNextAddress(walletService, accountNb); - await ln.sendCoins(client, walletAddr.address, amount); - dispatch({ type: LNWALLET_WITHDRAWWALLET_SUCCESS }); - setTimeout(() => dispatch(updateLNWalletBalances(), 3000)); - } catch (error) { - dispatch({ error, type: LNWALLET_WITHDRAWWALLET_FAILED }); - throw error; - } -}; + try { + const walletService = sel.walletService(getState()); + const walletAddr = await wallet.getNextAddress(walletService, accountNb); + await ln.sendCoins(client, walletAddr.address, amount); + dispatch({ type: LNWALLET_WITHDRAWWALLET_SUCCESS }); + setTimeout(() => dispatch(updateLNWalletBalances(), 3000)); + } catch (error) { + dispatch({ error, type: LNWALLET_WITHDRAWWALLET_FAILED }); + throw error; + } + }; const getLNWalletConfig = () => (dispatch, getState) => { // This (and setWalletConfig) are less than ideal for dealing with config @@ -1225,25 +1219,23 @@ export const LNWALLET_GETTRANSACTIONS_SUCCESS = export const LNWALLET_GETTRANSACTIONS_FAILED = "LNWALLET_GETTRANSACTIONS_FAILED"; -export const getTransactions = (startHeight, endHeight) => ( - dispatch, - getState -) => { - const { client } = getState().ln; - if (!client) return; - - dispatch({ type: LNWALLET_GETTRANSACTIONS_ATTEMPT }); - ln.getTransactions(client, startHeight, endHeight) - .then((transactions) => { - dispatch({ - transactions, - type: LNWALLET_GETTRANSACTIONS_SUCCESS +export const getTransactions = + (startHeight, endHeight) => (dispatch, getState) => { + const { client } = getState().ln; + if (!client) return; + + dispatch({ type: LNWALLET_GETTRANSACTIONS_ATTEMPT }); + ln.getTransactions(client, startHeight, endHeight) + .then((transactions) => { + dispatch({ + transactions, + type: LNWALLET_GETTRANSACTIONS_SUCCESS + }); + }) + .catch((error) => { + dispatch({ error, type: LNWALLET_GETTRANSACTIONS_FAILED }); }); - }) - .catch((error) => { - dispatch({ error, type: LNWALLET_GETTRANSACTIONS_FAILED }); - }); -}; + }; export const goToChannelsTab = (pubKey) => (dispatch) => dispatch(pushHistory(`/ln/channels?pubKey=${pubKey}`)); diff --git a/app/actions/SettingsActions.js b/app/actions/SettingsActions.js index 17cb903625..b39cbb99c4 100644 --- a/app/actions/SettingsActions.js +++ b/app/actions/SettingsActions.js @@ -111,44 +111,42 @@ export const saveSettings = (settings) => async (dispatch, getState) => { }; export const ALLOWEDEXTERNALREQUESTS_ADDED = "ALLOWEDEXTERNALREQUESTS_ADDED"; -export const addAllowedExternalRequest = (requestType) => ( - dispatch, - getState -) => - new Promise((resolve) => { - const config = wallet.getGlobalCfg(); - const allowed = config.get(configConstants.ALLOWED_EXTERNAL_REQUESTS); - - if (allowed.indexOf(requestType) > -1) return resolve(true); - - allowed.push(requestType); - config.set(configConstants.ALLOWED_EXTERNAL_REQUESTS, allowed); - wallet.allowExternalRequest(requestType); - - const { - settings: { currentSettings, tempSettings } - } = getState(); - const newSettings = { ...currentSettings }; - newSettings.allowedExternalRequests = allowed; - - // Also modify temp settings, given that it may be different than the current - // settings. - const newTempSettings = { ...tempSettings }; - newTempSettings.allowedExternalRequests = [ - ...newTempSettings.allowedExternalRequests - ]; - if (newTempSettings.allowedExternalRequests.indexOf(requestType) === -1) { - newTempSettings.allowedExternalRequests.push(requestType); - } - - dispatch({ - newSettings, - newTempSettings, - type: ALLOWEDEXTERNALREQUESTS_ADDED, - requestType +export const addAllowedExternalRequest = + (requestType) => (dispatch, getState) => + new Promise((resolve) => { + const config = wallet.getGlobalCfg(); + const allowed = config.get(configConstants.ALLOWED_EXTERNAL_REQUESTS); + + if (allowed.indexOf(requestType) > -1) return resolve(true); + + allowed.push(requestType); + config.set(configConstants.ALLOWED_EXTERNAL_REQUESTS, allowed); + wallet.allowExternalRequest(requestType); + + const { + settings: { currentSettings, tempSettings } + } = getState(); + const newSettings = { ...currentSettings }; + newSettings.allowedExternalRequests = allowed; + + // Also modify temp settings, given that it may be different than the current + // settings. + const newTempSettings = { ...tempSettings }; + newTempSettings.allowedExternalRequests = [ + ...newTempSettings.allowedExternalRequests + ]; + if (newTempSettings.allowedExternalRequests.indexOf(requestType) === -1) { + newTempSettings.allowedExternalRequests.push(requestType); + } + + dispatch({ + newSettings, + newTempSettings, + type: ALLOWEDEXTERNALREQUESTS_ADDED, + requestType + }); + resolve(true); }); - resolve(true); - }); export function updateStateSettingsChanged(settings, norestart) { return (dispatch, getState) => { diff --git a/app/actions/StatisticsActions.js b/app/actions/StatisticsActions.js index 89b69756bc..21bf723192 100644 --- a/app/actions/StatisticsActions.js +++ b/app/actions/StatisticsActions.js @@ -1044,12 +1044,8 @@ export const balancesStats = (opts) => async (dispatch, getState) => { backwards } = opts; - const { - currentBlockHeight, - walletService, - recentBlockTimestamp, - balances - } = getState().grpc; + const { currentBlockHeight, walletService, recentBlockTimestamp, balances } = + getState().grpc; const chainParams = sel.chainParams(getState()); diff --git a/app/actions/TransactionActions.js b/app/actions/TransactionActions.js index d66fb49db0..8732efa53e 100644 --- a/app/actions/TransactionActions.js +++ b/app/actions/TransactionActions.js @@ -98,196 +98,193 @@ export const MATURINGHEIGHTS_CHANGED = "MATURINGHEIGHTS_CHANGED"; // newTransactionsReceived should be called when a new set of transactions has // been received from the wallet (through a notification). -export const newTransactionsReceived = ( - newlyMinedTransactions, - newlyUnminedTransactions -) => async (dispatch, getState) => { - if (!newlyMinedTransactions.length && !newlyUnminedTransactions.length) - return; - let { - unminedTransactions, - stakeTransactions, - regularTransactions, - recentRegularTransactions, - recentStakeTransactions - } = getState().grpc; - const { walletService, maturingBlockHeights } = getState().grpc; - const chainParams = sel.chainParams(getState()); - // Normalize transactions with missing data. - // All transactions must being normalized before being dispatched to the - // selector. - newlyUnminedTransactions = await normalizeBatchTx( - walletService, - chainParams, - dispatch, - newlyUnminedTransactions - ); - newlyMinedTransactions = await normalizeBatchTx( - walletService, - chainParams, - dispatch, - newlyMinedTransactions - ); - // aux maps of [txhash] => tx (used to ensure no duplicate txs) - const newlyMinedMap = newlyMinedTransactions.reduce((m, v) => { - m[v.txHash] = v; - // update our txs selector value. - v.isStake - ? (stakeTransactions[v.txHash] = v) - : (regularTransactions[v.txHash] = v); - return m; - }, {}); - let newlyUnminedMap = divideTransactions(newlyUnminedTransactions); - - // get vsp tickets fee status in case there is a stake tx and we show the - // proper ticket value. - const vspHashes = {}; - vspHashes[VSP_FEE_PROCESS_ERRORED] = await dispatch( - getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_ERRORED) - ); - vspHashes[VSP_FEE_PROCESS_STARTED] = await dispatch( - getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_STARTED) - ); - vspHashes[VSP_FEE_PROCESS_PAID] = await dispatch( - getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_PAID) - ); - vspHashes[VSP_FEE_PROCESS_CONFIRMED] = await dispatch( - getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_CONFIRMED) - ); +export const newTransactionsReceived = + (newlyMinedTransactions, newlyUnminedTransactions) => + async (dispatch, getState) => { + if (!newlyMinedTransactions.length && !newlyUnminedTransactions.length) + return; + let { + unminedTransactions, + stakeTransactions, + regularTransactions, + recentRegularTransactions, + recentStakeTransactions + } = getState().grpc; + const { walletService, maturingBlockHeights } = getState().grpc; + const chainParams = sel.chainParams(getState()); + // Normalize transactions with missing data. + // All transactions must being normalized before being dispatched to the + // selector. + newlyUnminedTransactions = await normalizeBatchTx( + walletService, + chainParams, + dispatch, + newlyUnminedTransactions + ); + newlyMinedTransactions = await normalizeBatchTx( + walletService, + chainParams, + dispatch, + newlyMinedTransactions + ); + // aux maps of [txhash] => tx (used to ensure no duplicate txs) + const newlyMinedMap = newlyMinedTransactions.reduce((m, v) => { + m[v.txHash] = v; + // update our txs selector value. + v.isStake + ? (stakeTransactions[v.txHash] = v) + : (regularTransactions[v.txHash] = v); + return m; + }, {}); + let newlyUnminedMap = divideTransactions(newlyUnminedTransactions); + + // get vsp tickets fee status in case there is a stake tx and we show the + // proper ticket value. + const vspHashes = {}; + vspHashes[VSP_FEE_PROCESS_ERRORED] = await dispatch( + getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_ERRORED) + ); + vspHashes[VSP_FEE_PROCESS_STARTED] = await dispatch( + getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_STARTED) + ); + vspHashes[VSP_FEE_PROCESS_PAID] = await dispatch( + getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_PAID) + ); + vspHashes[VSP_FEE_PROCESS_CONFIRMED] = await dispatch( + getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_CONFIRMED) + ); - // add feeStatus into unmined txs. With that there is no need to add into - // mined txs. - Object.keys(vspHashes).forEach((feeStatus) => { - vspHashes[feeStatus].forEach((ticketHash) => { - if (!newlyUnminedMap.stakeTransactions[ticketHash]) { - return; - } - newlyUnminedMap.stakeTransactions[ticketHash].feeStatus = feeStatus; + // add feeStatus into unmined txs. With that there is no need to add into + // mined txs. + Object.keys(vspHashes).forEach((feeStatus) => { + vspHashes[feeStatus].forEach((ticketHash) => { + if (!newlyUnminedMap.stakeTransactions[ticketHash]) { + return; + } + newlyUnminedMap.stakeTransactions[ticketHash].feeStatus = feeStatus; + }); }); - }); - - // update our txs selector value. - stakeTransactions = { - ...newlyUnminedMap.stakeTransactions, - ...stakeTransactions - }; - regularTransactions = { - ...newlyUnminedMap.regularTransactions, - ...regularTransactions - }; - // flat stake and regular unmined transactions. - newlyUnminedMap = { - ...newlyUnminedMap.stakeTransactions, - ...newlyUnminedMap.regularTransactions - }; - // update accounts related to the transaction balance. - const accountsToUpdate = checkAccountsToUpdate([ - ...newlyUnminedTransactions, - ...newlyMinedTransactions - ]); - accountsToUpdate.forEach((v) => dispatch(getBalanceUpdateAttempt(v, 0))); + // update our txs selector value. + stakeTransactions = { + ...newlyUnminedMap.stakeTransactions, + ...stakeTransactions + }; + regularTransactions = { + ...newlyUnminedMap.regularTransactions, + ...regularTransactions + }; + // flat stake and regular unmined transactions. + newlyUnminedMap = { + ...newlyUnminedMap.stakeTransactions, + ...newlyUnminedMap.regularTransactions + }; - // get new addresses for accounts which received decred - dispatch( - getNewAccountAddresses([ + // update accounts related to the transaction balance. + const accountsToUpdate = checkAccountsToUpdate([ ...newlyUnminedTransactions, ...newlyMinedTransactions - ]) - ); + ]); + accountsToUpdate.forEach((v) => dispatch(getBalanceUpdateAttempt(v, 0))); + + // get new addresses for accounts which received decred + dispatch( + getNewAccountAddresses([ + ...newlyUnminedTransactions, + ...newlyMinedTransactions + ]) + ); - // Update mixer accounts balances - const changeAccount = sel.getChangeAccount(getState()); - dispatch(checkUnmixedAccountBalance(changeAccount)); - dispatch(getMixerAcctsSpendableBalances()); + // Update mixer accounts balances + const changeAccount = sel.getChangeAccount(getState()); + dispatch(checkUnmixedAccountBalance(changeAccount)); + dispatch(getMixerAcctsSpendableBalances()); - const hasStakeTxs = - checkForStakeTransactions(newlyUnminedTransactions) || - checkForStakeTransactions(newlyMinedTransactions); - if (hasStakeTxs) { - dispatch(getStakeInfoAttempt()); - } + const hasStakeTxs = + checkForStakeTransactions(newlyUnminedTransactions) || + checkForStakeTransactions(newlyMinedTransactions); + if (hasStakeTxs) { + dispatch(getStakeInfoAttempt()); + } - unminedTransactions = [ - ...newlyUnminedTransactions, - ...unminedTransactions.filter( - (tx) => !newlyMinedMap[tx.txHash] && !newlyUnminedMap[tx.txHash] - ) - ]; + unminedTransactions = [ + ...newlyUnminedTransactions, + ...unminedTransactions.filter( + (tx) => !newlyMinedMap[tx.txHash] && !newlyUnminedMap[tx.txHash] + ) + ]; + + // filterTxsArray is an aux function to filter the passed transactions so + // we avoid duplicated txs. + const filterTxsArray = (transactions) => + transactions.filter((tx) => { + // remove transactions which are already at the old state of unmined + // transactions array to avoid duplicated txs. If the tx is already at + // the array, no need for re-adding it. + const txIsAtArray = unminedTransactions.find( + (unminedTx) => unminedTx.txHash === tx.txHash + ); + if (txIsAtArray) { + return false; + } + // If it is not on the older array, nor the newly ones, we re-add it. + if (!newlyMinedMap[tx.txHash] && !newlyUnminedMap[tx.txHash]) { + return true; + } + }); - // filterTxsArray is an aux function to filter the passed transactions so - // we avoid duplicated txs. - const filterTxsArray = (transactions) => - transactions.filter((tx) => { - // remove transactions which are already at the old state of unmined - // transactions array to avoid duplicated txs. If the tx is already at - // the array, no need for re-adding it. - const txIsAtArray = unminedTransactions.find( - (unminedTx) => unminedTx.txHash === tx.txHash - ); - if (txIsAtArray) { - return false; - } - // If it is not on the older array, nor the newly ones, we re-add it. - if (!newlyMinedMap[tx.txHash] && !newlyUnminedMap[tx.txHash]) { - return true; - } + // update recent regular and stake transactions selector + recentRegularTransactions = [ + ...unminedTransactions, + ...newlyMinedTransactions, + ...filterTxsArray(recentRegularTransactions) + ].filter((tx) => !tx.isStake); + + recentStakeTransactions = [ + ...unminedTransactions, + ...newlyMinedTransactions, + ...filterTxsArray(recentStakeTransactions) + ].filter((tx) => tx.isStake); + + // update maturing heights, so we can know when to update account balances + // on their specific blocks. + const newMaturingHeights = { ...maturingBlockHeights }; + const mergeNewMaturingHeights = (hs) => + Object.keys(hs).forEach((h) => { + const accounts = newMaturingHeights[h] || []; + hs[h].forEach((a) => + accounts.indexOf(a) === -1 ? accounts.push(a) : null + ); + newMaturingHeights[h] = accounts; + }); + mergeNewMaturingHeights( + transactionsMaturingHeights(newlyMinedTransactions, chainParams) + ); + dispatch({ + maturingBlockHeights: newMaturingHeights, + type: MATURINGHEIGHTS_CHANGED }); - // update recent regular and stake transactions selector - recentRegularTransactions = [ - ...unminedTransactions, - ...newlyMinedTransactions, - ...filterTxsArray(recentRegularTransactions) - ].filter((tx) => !tx.isStake); - - recentStakeTransactions = [ - ...unminedTransactions, - ...newlyMinedTransactions, - ...filterTxsArray(recentStakeTransactions) - ].filter((tx) => tx.isStake); - - // update maturing heights, so we can know when to update account balances - // on their specific blocks. - const newMaturingHeights = { ...maturingBlockHeights }; - const mergeNewMaturingHeights = (hs) => - Object.keys(hs).forEach((h) => { - const accounts = newMaturingHeights[h] || []; - hs[h].forEach((a) => - accounts.indexOf(a) === -1 ? accounts.push(a) : null - ); - newMaturingHeights[h] = accounts; + dispatch({ + recentRegularTransactions, + recentStakeTransactions, + unminedTransactions, + newlyUnminedTransactions, + newlyMinedTransactions, + stakeTransactions, + regularTransactions, + type: NEW_TRANSACTIONS_RECEIVED }); - mergeNewMaturingHeights( - transactionsMaturingHeights(newlyMinedTransactions, chainParams) - ); - dispatch({ - maturingBlockHeights: newMaturingHeights, - type: MATURINGHEIGHTS_CHANGED - }); - - dispatch({ - recentRegularTransactions, - recentStakeTransactions, - unminedTransactions, - newlyUnminedTransactions, - newlyMinedTransactions, - stakeTransactions, - regularTransactions, - type: NEW_TRANSACTIONS_RECEIVED - }); - if (newlyMinedTransactions.length > 0) { - const { - startupStatsEndCalcTime, - startupStatsCalcSeconds - } = getState().statistics; - const secFromLastStats = (new Date() - startupStatsEndCalcTime) / 1000; - if (secFromLastStats > 5 * startupStatsCalcSeconds) { - dispatch(getStartupStats()); + if (newlyMinedTransactions.length > 0) { + const { startupStatsEndCalcTime, startupStatsCalcSeconds } = + getState().statistics; + const secFromLastStats = (new Date() - startupStatsEndCalcTime) / 1000; + if (secFromLastStats > 5 * startupStatsCalcSeconds) { + dispatch(getStartupStats()); + } } - } -}; + }; export const CHANGE_TRANSACTIONS_FILTER = "CHANGE_TRANSACTIONS_FILTER"; export const changeTransactionsFilter = (newFilter) => (dispatch, getState) => { @@ -466,9 +463,8 @@ export const getStartupTransactions = () => async (dispatch, getState) => { } } - const { stakeTransactions, regularTransactions } = divideTransactions( - transactions - ); + const { stakeTransactions, regularTransactions } = + divideTransactions(transactions); dispatch({ type: GETSTARTUPTRANSACTIONS_SUCCESS, @@ -840,46 +836,47 @@ export const transactionsMaturingHeights = (txs, chainParams) => { // getAmountFromTxInputs receives a decoded tx and adds the amount of // each input from the previous transaction. We need this because when decoding // a tx, the amount of the input is not decoded with it. -export const getAmountFromTxInputs = (decodedTx) => async ( - dispatch, - getState -) => { - const { walletService } = getState().grpc; - const chainParams = sel.chainParams(getState()); - try { - const inputWithAmount = decodedTx.inputs.map( - async ({ prevTxId, outputIndex }, i) => { - const oldTx = await wallet.getTransaction(walletService, prevTxId); - if (!oldTx) { - return Promise.reject(new Error(`Transaction ${prevTxId} not found`)); - } - const rawTxBuffer = Buffer.from(hexToBytes(oldTx.rawTx)); - const decodedOldTx = wallet.decodeRawTransaction( - rawTxBuffer, - chainParams - ); - const oldOutput = decodedOldTx.outputs[outputIndex]; - if (!oldOutput) { - return Promise.reject( - new Error(`Unknown outpoint ${prevTxId}:${outputIndex} not found`) +export const getAmountFromTxInputs = + (decodedTx) => async (dispatch, getState) => { + const { walletService } = getState().grpc; + const chainParams = sel.chainParams(getState()); + try { + const inputWithAmount = decodedTx.inputs.map( + async ({ prevTxId, outputIndex }, i) => { + const oldTx = await wallet.getTransaction(walletService, prevTxId); + if (!oldTx) { + return Promise.reject( + new Error(`Transaction ${prevTxId} not found`) + ); + } + const rawTxBuffer = Buffer.from(hexToBytes(oldTx.rawTx)); + const decodedOldTx = wallet.decodeRawTransaction( + rawTxBuffer, + chainParams ); + const oldOutput = decodedOldTx.outputs[outputIndex]; + if (!oldOutput) { + return Promise.reject( + new Error(`Unknown outpoint ${prevTxId}:${outputIndex} not found`) + ); + } + decodedTx.inputs[i].amountIn = + decodedOldTx.outputs[outputIndex].value; + // we also save the outpoint address to perform sanity checkes on trezor txs. + decodedTx.inputs[i].outpointAddress = + decodedOldTx.outputs[outputIndex].decodedScript.address; + decodedTx.inputs[i].outpoint = `${prevTxId}:${outputIndex}`; + return decodedTx.inputs[i]; } - decodedTx.inputs[i].amountIn = decodedOldTx.outputs[outputIndex].value; - // we also save the outpoint address to perform sanity checkes on trezor txs. - decodedTx.inputs[i].outpointAddress = - decodedOldTx.outputs[outputIndex].decodedScript.address; - decodedTx.inputs[i].outpoint = `${prevTxId}:${outputIndex}`; - return decodedTx.inputs[i]; - } - ); + ); - decodedTx.inputs = await Promise.all(inputWithAmount); + decodedTx.inputs = await Promise.all(inputWithAmount); - return decodedTx; - } catch (e) { - return Promise.reject(e); - } -}; + return decodedTx; + } catch (e) { + return Promise.reject(e); + } + }; // getTxFromInputs receives a decoded unsignedTx as parameter and gets the txs // which participate in the input. diff --git a/app/actions/TrezorActions.js b/app/actions/TrezorActions.js index 0f115d33e9..b43a067f00 100644 --- a/app/actions/TrezorActions.js +++ b/app/actions/TrezorActions.js @@ -441,113 +441,115 @@ const checkTrezorIsDcrwallet = () => async (dispatch, getState) => { if (addrValidResp.index !== 0) throw "Wallet replied with wrong index."; }; -export const signTransactionAttemptTrezor = ( - rawUnsigTx, - constructTxResponse -) => async (dispatch, getState) => { - dispatch({ type: SIGNTX_ATTEMPT }); +export const signTransactionAttemptTrezor = + (rawUnsigTx, constructTxResponse) => async (dispatch, getState) => { + dispatch({ type: SIGNTX_ATTEMPT }); - const { - grpc: { walletService }, - trezor: { debug } - } = getState(); - const chainParams = selectors.chainParams(getState()); + const { + grpc: { walletService }, + trezor: { debug } + } = getState(); + const chainParams = selectors.chainParams(getState()); - debug && console.log("construct tx response", constructTxResponse); + debug && console.log("construct tx response", constructTxResponse); - try { - const changeIndex = constructTxResponse.changeIndex; + try { + const changeIndex = constructTxResponse.changeIndex; - const decodedUnsigTxResp = wallet.decodeRawTransaction( - Buffer.from(rawUnsigTx, "hex"), - chainParams - ); - const unsignedTx = await dispatch( - getAmountFromTxInputs(decodedUnsigTxResp) - ); - const txCompletedInputs = await dispatch(getAmountFromTxInputs(unsignedTx)); - const inputTxs = await dispatch(getTxFromInputs(unsignedTx)); - const { inputs, outputs } = await walletTxToBtcjsTx( - walletService, - chainParams, - txCompletedInputs, - inputTxs, - changeIndex - ); + const decodedUnsigTxResp = wallet.decodeRawTransaction( + Buffer.from(rawUnsigTx, "hex"), + chainParams + ); + const unsignedTx = await dispatch( + getAmountFromTxInputs(decodedUnsigTxResp) + ); + const txCompletedInputs = await dispatch( + getAmountFromTxInputs(unsignedTx) + ); + const inputTxs = await dispatch(getTxFromInputs(unsignedTx)); + const { inputs, outputs } = await walletTxToBtcjsTx( + walletService, + chainParams, + txCompletedInputs, + inputTxs, + changeIndex + ); - const refTxs = await Promise.all( - inputTxs.map((inpTx) => walletTxToRefTx(walletService, inpTx)) - ); + const refTxs = await Promise.all( + inputTxs.map((inpTx) => walletTxToRefTx(walletService, inpTx)) + ); - const payload = await deviceRun(dispatch, getState, async () => { - await dispatch(checkTrezorIsDcrwallet()); + const payload = await deviceRun(dispatch, getState, async () => { + await dispatch(checkTrezorIsDcrwallet()); - const res = await session.signTransaction({ - inputs: inputs, - outputs: outputs, - refTxs: refTxs, - coin: chainParams.trezorCoinName + const res = await session.signTransaction({ + inputs: inputs, + outputs: outputs, + refTxs: refTxs, + coin: chainParams.trezorCoinName + }); + return res.payload; }); - return res.payload; - }); - const signedRaw = payload.serializedTx; + const signedRaw = payload.serializedTx; - dispatch({ type: SIGNTX_SUCCESS }); - dispatch(publishTransactionAttempt(hexToBytes(signedRaw))); - } catch (error) { - dispatch({ error, type: SIGNTX_FAILED }); - } -}; + dispatch({ type: SIGNTX_SUCCESS }); + dispatch(publishTransactionAttempt(hexToBytes(signedRaw))); + } catch (error) { + dispatch({ error, type: SIGNTX_FAILED }); + } + }; -export const signMessageAttemptTrezor = (address, message) => async ( - dispatch, - getState -) => { - dispatch({ type: SIGNMESSAGE_ATTEMPT }); +export const signMessageAttemptTrezor = + (address, message) => async (dispatch, getState) => { + dispatch({ type: SIGNMESSAGE_ATTEMPT }); - if (noDevice(getState)) { - dispatch({ error: "Device not connected", type: SIGNMESSAGE_FAILED }); - return; - } + if (noDevice(getState)) { + dispatch({ error: "Device not connected", type: SIGNMESSAGE_FAILED }); + return; + } - const chainParams = selectors.chainParams(getState()); - const { - grpc: { walletService } - } = getState(); + const chainParams = selectors.chainParams(getState()); + const { + grpc: { walletService } + } = getState(); - try { - const addrValidResp = await wallet.validateAddress(walletService, address); - if (!addrValidResp.isValid) throw "Input has an invalid address " + address; - if (!addrValidResp.isMine) - throw "Trezor only supports signing with wallet addresses"; - const addrIndex = addrValidResp.index; - const addrBranch = addrValidResp.isInternal ? 1 : 0; - const address_n = addressPath( - addrIndex, - addrBranch, - WALLET_ACCOUNT, - chainParams.HDCoinType - ); + try { + const addrValidResp = await wallet.validateAddress( + walletService, + address + ); + if (!addrValidResp.isValid) + throw "Input has an invalid address " + address; + if (!addrValidResp.isMine) + throw "Trezor only supports signing with wallet addresses"; + const addrIndex = addrValidResp.index; + const addrBranch = addrValidResp.isInternal ? 1 : 0; + const address_n = addressPath( + addrIndex, + addrBranch, + WALLET_ACCOUNT, + chainParams.HDCoinType + ); - const payload = await deviceRun(dispatch, getState, async () => { - await dispatch(checkTrezorIsDcrwallet()); + const payload = await deviceRun(dispatch, getState, async () => { + await dispatch(checkTrezorIsDcrwallet()); - const res = await session.signMessage({ - path: address_n, - coin: chainParams.trezorCoinName, - message: str2utf8hex(message), - hex: true + const res = await session.signMessage({ + path: address_n, + coin: chainParams.trezorCoinName, + message: str2utf8hex(message), + hex: true + }); + return res.payload; }); - return res.payload; - }); - dispatch({ - getSignMessageSignature: payload.signature, - type: SIGNMESSAGE_SUCCESS - }); - } catch (error) { - dispatch({ error, type: SIGNMESSAGE_FAILED }); - } -}; + dispatch({ + getSignMessageSignature: payload.signature, + type: SIGNMESSAGE_SUCCESS + }); + } catch (error) { + dispatch({ error, type: SIGNMESSAGE_FAILED }); + } + }; export const TRZ_TOGGLEPINPROTECTION_ATTEMPT = "TRZ_TOGGLEPINPROTECTION_ATTEMPT"; @@ -889,74 +891,72 @@ export const TRZ_GETWALLETCREATIONMASTERPUBKEY_FAILED = export const TRZ_GETWALLETCREATIONMASTERPUBKEY_SUCCESS = "TRZ_GETWALLETCREATIONMASTERPUBKEY_SUCCESS"; -export const getWalletCreationMasterPubKey = () => async ( - dispatch, - getState -) => { - dispatch({ type: TRZ_GETWALLETCREATIONMASTERPUBKEY_ATTEMPT }); +export const getWalletCreationMasterPubKey = + () => async (dispatch, getState) => { + dispatch({ type: TRZ_GETWALLETCREATIONMASTERPUBKEY_ATTEMPT }); - if (noDevice(getState)) { - dispatch({ - error: "Device not connected", - type: TRZ_GETWALLETCREATIONMASTERPUBKEY_FAILED - }); - return; - } + if (noDevice(getState)) { + dispatch({ + error: "Device not connected", + type: TRZ_GETWALLETCREATIONMASTERPUBKEY_FAILED + }); + return; + } - const chainParams = selectors.chainParams(getState()); + const chainParams = selectors.chainParams(getState()); - try { - // Check that the firmware running in this trezor has the seed constant fix. - const features = await dispatch(getFeatures()).catch((error) => { - dispatch({ error, type: TRZ_GETWALLETCREATIONMASTERPUBKEY_FAILED }); - return; - }); - const versionLessThan = (wantMajor, wantMinor) => - features.major_version < wantMajor || - (features.major_version == wantMajor && - features.minor_version < wantMinor); - // TODO: Confirm these versions. Confirmed on 1.9.3. Older versions may - // not give us decred specific addresses with connect. - if (features.model == 1 && versionLessThan(1, 9)) { - throw new Error( - "Trezor Model One needs to run on firmware >= 1.9.0. Found " + - features.major_version + - "." + - features.minor_version + - "." + - features.patch_version - ); - // TODO: Confirm these versions. Confirmed on 2.3.4. Older versions may + try { + // Check that the firmware running in this trezor has the seed constant fix. + const features = await dispatch(getFeatures()).catch((error) => { + dispatch({ error, type: TRZ_GETWALLETCREATIONMASTERPUBKEY_FAILED }); + return; + }); + const versionLessThan = (wantMajor, wantMinor) => + features.major_version < wantMajor || + (features.major_version == wantMajor && + features.minor_version < wantMinor); + // TODO: Confirm these versions. Confirmed on 1.9.3. Older versions may // not give us decred specific addresses with connect. - } else if (features.model == "T" && versionLessThan(2, 3)) { - throw new Error( - "Trezor Model T needs to run on firmware >= 2.1.0. Found " + - features.major_version + - "." + - features.minor_version + - "." + - features.patch_version - ); - } else if (!features.model) { - throw new Error("Unknown firmware model/version"); - } + if (features.model == 1 && versionLessThan(1, 9)) { + throw new Error( + "Trezor Model One needs to run on firmware >= 1.9.0. Found " + + features.major_version + + "." + + features.minor_version + + "." + + features.patch_version + ); + // TODO: Confirm these versions. Confirmed on 2.3.4. Older versions may + // not give us decred specific addresses with connect. + } else if (features.model == "T" && versionLessThan(2, 3)) { + throw new Error( + "Trezor Model T needs to run on firmware >= 2.1.0. Found " + + features.major_version + + "." + + features.minor_version + + "." + + features.patch_version + ); + } else if (!features.model) { + throw new Error("Unknown firmware model/version"); + } - const path = accountPath(WALLET_ACCOUNT, chainParams.HDCoinType); + const path = accountPath(WALLET_ACCOUNT, chainParams.HDCoinType); - const payload = await deviceRun(dispatch, getState, async () => { - const res = await session.getPublicKey({ - path: path, - coin: chainParams.trezorCoinName, - showOnTrezor: false + const payload = await deviceRun(dispatch, getState, async () => { + const res = await session.getPublicKey({ + path: path, + coin: chainParams.trezorCoinName, + showOnTrezor: false + }); + return res.payload; }); - return res.payload; - }); - dispatch({ type: TRZ_GETWALLETCREATIONMASTERPUBKEY_SUCCESS }); + dispatch({ type: TRZ_GETWALLETCREATIONMASTERPUBKEY_SUCCESS }); - return payload.xpub; - } catch (error) { - dispatch({ error, type: TRZ_GETWALLETCREATIONMASTERPUBKEY_FAILED }); - throw error; - } -}; + return payload.xpub; + } catch (error) { + dispatch({ error, type: TRZ_GETWALLETCREATIONMASTERPUBKEY_FAILED }); + throw error; + } + }; diff --git a/app/actions/VSPActions.js b/app/actions/VSPActions.js index d176df98fc..ad9b2054d3 100644 --- a/app/actions/VSPActions.js +++ b/app/actions/VSPActions.js @@ -147,69 +147,64 @@ export const SYNCVSPTICKETS_ATTEMPT = "SYNCVSPTICKETS_ATTEMPT"; export const SYNCVSPTICKETS_FAILED = "SYNCVSPTICKETS_FAILED"; export const SYNCVSPTICKETS_SUCCESS = "SYNCVSPTICKETS_SUCCESS"; -export const syncVSPTicketsRequest = ({ - passphrase, - vspHost, - vspPubkey, - account -}) => async (dispatch, getState) => { - dispatch({ type: SYNCVSPTICKETS_ATTEMPT }); - try { - let feeAcct = account; - let changeAcct = account; - const mixedAccount = sel.getMixedAccount(getState()); - const changeAccount = sel.getChangeAccount(getState()); - if (mixedAccount) { - feeAcct = mixedAccount; - } - if (changeAccount) { - changeAcct = changeAccount; - } +export const syncVSPTicketsRequest = + ({ passphrase, vspHost, vspPubkey, account }) => + async (dispatch, getState) => { + dispatch({ type: SYNCVSPTICKETS_ATTEMPT }); + try { + let feeAcct = account; + let changeAcct = account; + const mixedAccount = sel.getMixedAccount(getState()); + const changeAccount = sel.getChangeAccount(getState()); + if (mixedAccount) { + feeAcct = mixedAccount; + } + if (changeAccount) { + changeAcct = changeAccount; + } - await dispatch( - unlockAllAcctAndExecFn(passphrase, () => - wallet.syncVSPTickets( - getState().grpc.walletService, - vspHost, - vspPubkey, - feeAcct, - changeAcct + await dispatch( + unlockAllAcctAndExecFn(passphrase, () => + wallet.syncVSPTickets( + getState().grpc.walletService, + vspHost, + vspPubkey, + feeAcct, + changeAcct + ) ) - ) - ); - dispatch({ type: SYNCVSPTICKETS_SUCCESS }); - dispatch(getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_ERRORED)); - } catch (error) { - dispatch({ type: SYNCVSPTICKETS_FAILED, error }); - } + ); + dispatch({ type: SYNCVSPTICKETS_SUCCESS }); + dispatch(getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_ERRORED)); + } catch (error) { + dispatch({ type: SYNCVSPTICKETS_FAILED, error }); + } - // Finally, ask the wallet to reprocess existing tickets. We do this via a - // setTimeout to avoid stalling the return of this function. - setTimeout(() => dispatch(processManagedTickets(passphrase), 500)); -}; + // Finally, ask the wallet to reprocess existing tickets. We do this via a + // setTimeout to avoid stalling the return of this function. + setTimeout(() => dispatch(processManagedTickets(passphrase), 500)); + }; // getTicketSignature receives the tickethash and request and sign it using the // ticket sstxcommitment address. -export const getTicketSignature = (tickethash, message, passphrase) => async ( - dispatch, - getState -) => { - const walletService = sel.walletService(getState()); - const chainParams = sel.chainParams(getState()); - - const sstxAddr = await wallet.getSstxCommitmentAddress( - walletService, - chainParams, - tickethash - ); - const resp = await wallet.signMessage( - walletService, - sstxAddr, - message, - passphrase - ); - return resp.toObject().signature; -}; +export const getTicketSignature = + (tickethash, message, passphrase) => async (dispatch, getState) => { + const walletService = sel.walletService(getState()); + const chainParams = sel.chainParams(getState()); + + const sstxAddr = await wallet.getSstxCommitmentAddress( + walletService, + chainParams, + tickethash + ); + const resp = await wallet.signMessage( + walletService, + sstxAddr, + message, + passphrase + ); + return resp.toObject().signature; + }; export const DISCOVERAVAILABLEVSPS_ATTEMPT = "DISCOVERAVAILABLEVSPS_ATTEMPT"; export const DISCOVERAVAILABLEVSPS_SUCCESS = "DISCOVERAVAILABLEVSPS_SUCCESS"; @@ -280,18 +275,19 @@ export const updateUsedVSPs = (vsp) => (dispatch, getState) => { }; export const SET_REMEMBERED_VSP_HOST = "SET_REMEMBERED_VSP_HOST"; -export const setRememberedVspHost = (rememberedVspHost) => ( - dispatch, - getState -) => { - dispatch({ type: SET_REMEMBERED_VSP_HOST, rememberedVspHost }); - - const { - daemon: { walletName } - } = getState(); - const walletCfg = wallet.getWalletCfg(sel.isTestNet(getState()), walletName); - walletCfg.set(cfgConstants.REMEMBERED_VSP_HOST, rememberedVspHost); -}; +export const setRememberedVspHost = + (rememberedVspHost) => (dispatch, getState) => { + dispatch({ type: SET_REMEMBERED_VSP_HOST, rememberedVspHost }); + + const { + daemon: { walletName } + } = getState(); + const walletCfg = wallet.getWalletCfg( + sel.isTestNet(getState()), + walletName + ); + walletCfg.set(cfgConstants.REMEMBERED_VSP_HOST, rememberedVspHost); + }; export const GETVSPSPUBKEYS_ATTEMPT = "GETAVAILABLEVSP_ATTEMPT"; export const GETVSPSPUBKEYS_SUCCESS = "GETVSPSPUBKEYS_SUCCESS"; @@ -342,66 +338,64 @@ export const PROCESSMANAGEDTICKETS_FAILED = "PROCESSMANAGEDTICKETS_FAILED"; // processManagedTickets gets all vsp and check for tickets which still not // synced, and sync them. -export const processManagedTickets = (passphrase) => async ( - dispatch, - getState -) => { - const walletService = sel.walletService(getState()); - let availableVSPsPubkeys = sel.getAvailableVSPsPubkeys(getState()); - - if (!availableVSPsPubkeys) { - availableVSPsPubkeys = await dispatch(getVSPsPubkeys()); - } - try { - dispatch({ type: PROCESSMANAGEDTICKETS_ATTEMPT }); - let feeAccount, changeAccount; - const mixedAccount = sel.getMixedAccount(getState()); - if (mixedAccount) { - feeAccount = mixedAccount; - changeAccount = sel.getChangeAccount(getState()); - } else { - feeAccount = sel.defaultSpendingAccount(getState()).value; - changeAccount = sel.defaultSpendingAccount(getState()).value; +export const processManagedTickets = + (passphrase) => async (dispatch, getState) => { + const walletService = sel.walletService(getState()); + let availableVSPsPubkeys = sel.getAvailableVSPsPubkeys(getState()); + + if (!availableVSPsPubkeys) { + availableVSPsPubkeys = await dispatch(getVSPsPubkeys()); } - await dispatch( - unlockAllAcctAndExecFn(passphrase, async () => { - // Process all managed tickets on all VSPs. - await Promise.all( - availableVSPsPubkeys.map((vsp) => - wallet.processManagedTickets( - walletService, - vsp.host, - vsp.pubkey, - feeAccount, - changeAccount + try { + dispatch({ type: PROCESSMANAGEDTICKETS_ATTEMPT }); + let feeAccount, changeAccount; + const mixedAccount = sel.getMixedAccount(getState()); + if (mixedAccount) { + feeAccount = mixedAccount; + changeAccount = sel.getChangeAccount(getState()); + } else { + feeAccount = sel.defaultSpendingAccount(getState()).value; + changeAccount = sel.defaultSpendingAccount(getState()).value; + } + await dispatch( + unlockAllAcctAndExecFn(passphrase, async () => { + // Process all managed tickets on all VSPs. + await Promise.all( + availableVSPsPubkeys.map((vsp) => + wallet.processManagedTickets( + walletService, + vsp.host, + vsp.pubkey, + feeAccount, + changeAccount + ) ) - ) - ); + ); - // Update the list of dcrwallet tracked VSP tickets. This figures out - // which accounts need to be left unlocked. - await dispatch(getVSPTrackedTickets()); - }) - ); + // Update the list of dcrwallet tracked VSP tickets. This figures out + // which accounts need to be left unlocked. + await dispatch(getVSPTrackedTickets()); + }) + ); - // get vsp tickets fee status errored so we can resync them - await dispatch(getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_ERRORED)); - await dispatch(getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_STARTED)); - await dispatch(getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_PAID)); - await dispatch(getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_CONFIRMED)); - dispatch({ type: PROCESSMANAGEDTICKETS_SUCCESS }); - } catch (error) { - dispatch({ type: PROCESSMANAGEDTICKETS_FAILED, error }); - if ( - String(error).indexOf( - "wallet.Unlock: invalid passphrase:: secretkey.DeriveKey" - ) > 0 - ) { - throw "Invalid private passphrase, please try again."; + // get vsp tickets fee status errored so we can resync them + await dispatch(getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_ERRORED)); + await dispatch(getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_STARTED)); + await dispatch(getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_PAID)); + await dispatch(getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_CONFIRMED)); + dispatch({ type: PROCESSMANAGEDTICKETS_SUCCESS }); + } catch (error) { + dispatch({ type: PROCESSMANAGEDTICKETS_FAILED, error }); + if ( + String(error).indexOf( + "wallet.Unlock: invalid passphrase:: secretkey.DeriveKey" + ) > 0 + ) { + throw "Invalid private passphrase, please try again."; + } + throw error; } - throw error; - } -}; + }; export const PROCESSUNMANAGEDTICKETS_ATTEMPT = "PROCESSUNMANAGEDTICKETS_ATTEMPT"; @@ -411,63 +405,61 @@ export const PROCESSUNMANAGEDTICKETS_FAILED = "PROCESSUNMANAGEDTICKETS_FAILED"; // processUnmanagedTickets process vsp tickets which are still unprocessed. // It is called on wallet restore. -export const processUnmanagedTickets = (passphrase, vspHost, vspPubkey) => ( - dispatch, - getState -) => - new Promise((resolve, reject) => { - const asyncProcess = async () => { - dispatch({ type: PROCESSUNMANAGEDTICKETS_ATTEMPT }); - try { - const walletService = sel.walletService(getState()); - let feeAccount, changeAccount; - const mixedAccount = sel.getMixedAccount(getState()); - if (mixedAccount) { - feeAccount = mixedAccount; - changeAccount = sel.getChangeAccount(getState()); - } else { - feeAccount = sel.defaultSpendingAccount(getState()).value; - changeAccount = sel.defaultSpendingAccount(getState()).value; - } +export const processUnmanagedTickets = + (passphrase, vspHost, vspPubkey) => (dispatch, getState) => + new Promise((resolve, reject) => { + const asyncProcess = async () => { + dispatch({ type: PROCESSUNMANAGEDTICKETS_ATTEMPT }); + try { + const walletService = sel.walletService(getState()); + let feeAccount, changeAccount; + const mixedAccount = sel.getMixedAccount(getState()); + if (mixedAccount) { + feeAccount = mixedAccount; + changeAccount = sel.getChangeAccount(getState()); + } else { + feeAccount = sel.defaultSpendingAccount(getState()).value; + changeAccount = sel.defaultSpendingAccount(getState()).value; + } - if (passphrase) { - await dispatch( - unlockAllAcctAndExecFn(passphrase, () => - wallet.processUnmanagedTicketsStartup( - walletService, - vspHost, - vspPubkey, - feeAccount, - changeAccount + if (passphrase) { + await dispatch( + unlockAllAcctAndExecFn(passphrase, () => + wallet.processUnmanagedTicketsStartup( + walletService, + vspHost, + vspPubkey, + feeAccount, + changeAccount + ) ) - ) - ); - } else { - await wallet.processUnmanagedTicketsStartup( - walletService, - vspHost, - vspPubkey, - feeAccount, - changeAccount - ); - } + ); + } else { + await wallet.processUnmanagedTicketsStartup( + walletService, + vspHost, + vspPubkey, + feeAccount, + changeAccount + ); + } - // get vsp tickets fee status errored so we can resync them - await dispatch(getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_ERRORED)); - await dispatch(getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_STARTED)); - await dispatch(getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_PAID)); - await dispatch(getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_CONFIRMED)); - dispatch({ type: PROCESSUNMANAGEDTICKETS_SUCCESS }); - return null; - } catch (error) { - dispatch({ type: PROCESSUNMANAGEDTICKETS_FAILED, error }); - return error; - } - }; - asyncProcess() - .then((r) => resolve(r)) - .catch((error) => reject(error)); - }); + // get vsp tickets fee status errored so we can resync them + await dispatch(getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_ERRORED)); + await dispatch(getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_STARTED)); + await dispatch(getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_PAID)); + await dispatch(getVSPTicketsByFeeStatus(VSP_FEE_PROCESS_CONFIRMED)); + dispatch({ type: PROCESSUNMANAGEDTICKETS_SUCCESS }); + return null; + } catch (error) { + dispatch({ type: PROCESSUNMANAGEDTICKETS_FAILED, error }); + return error; + } + }; + asyncProcess() + .then((r) => resolve(r)) + .catch((error) => reject(error)); + }); export const SETVSPDVOTECHOICE_ATTEMPT = "SETVSPDVOTECHOICE_ATTEMPT"; export const SETVSPDVOTECHOICE_SUCCESS = "SETVSPDVOTECHOICE_SUCCESS"; @@ -479,174 +471,173 @@ export const SETVSPDVOTECHOICE_PARTIAL_SUCCESS = // setVSPDVoteChoices gets all vsps and updates the set vote choices to // whatever the wallet has. -export const setVSPDVoteChoices = (passphrase, vsps) => async ( - dispatch, - getState -) => { - try { - dispatch({ type: SETVSPDVOTECHOICE_ATTEMPT }); +export const setVSPDVoteChoices = + (passphrase, vsps) => async (dispatch, getState) => { + try { + dispatch({ type: SETVSPDVOTECHOICE_ATTEMPT }); - if (!vsps) { - vsps = await dispatch(discoverAvailableVSPs()); - } - if (!isArray(vsps)) { - throw new Error("INVALID_VSPS"); - } - const walletService = sel.walletService(getState()); - let feeAccount, changeAccount; - const mixedAccount = sel.getMixedAccount(getState()); - if (mixedAccount) { - feeAccount = mixedAccount; - changeAccount = sel.getChangeAccount(getState()); - } else { - feeAccount = sel.defaultSpendingAccount(getState()).value; - changeAccount = sel.defaultSpendingAccount(getState()).value; - } + if (!vsps) { + vsps = await dispatch(discoverAvailableVSPs()); + } + if (!isArray(vsps)) { + throw new Error("INVALID_VSPS"); + } + const walletService = sel.walletService(getState()); + let feeAccount, changeAccount; + const mixedAccount = sel.getMixedAccount(getState()); + if (mixedAccount) { + feeAccount = mixedAccount; + changeAccount = sel.getChangeAccount(getState()); + } else { + feeAccount = sel.defaultSpendingAccount(getState()).value; + changeAccount = sel.defaultSpendingAccount(getState()).value; + } - await dispatch( - unlockAllAcctAndExecFn(passphrase, () => - Promise.allSettled( - vsps.map((vsp) => { - return new Promise((resolve, reject) => - dispatch(getVSPInfo(vsp.host)) - .then(async ({ pubkey }) => { - if (pubkey) { - try { - await wallet.setVspdAgendaChoices( - walletService, - vsp.host, - pubkey, - feeAccount, - changeAccount - ); - await dispatch( - updateUsedVSPs({ + await dispatch( + unlockAllAcctAndExecFn(passphrase, () => + Promise.allSettled( + vsps.map((vsp) => { + return new Promise((resolve, reject) => + dispatch(getVSPInfo(vsp.host)) + .then(async ({ pubkey }) => { + if (pubkey) { + try { + await wallet.setVspdAgendaChoices( + walletService, + vsp.host, + pubkey, + feeAccount, + changeAccount + ); + await dispatch( + updateUsedVSPs({ + host: vsp.host, + vspdversion: vsp.vspData?.vspdversion + }) + ); + } catch (error) { + reject({ host: vsp.host, - vspdversion: vsp.vspData?.vspdversion - }) - ); - } catch (error) { + error + }); + } + } else { reject({ host: vsp.host, - error + error: "Error: missing pubkey" }); } - } else { + resolve(); + }) + .catch((error) => { reject({ host: vsp.host, - error: "Error: missing pubkey" + error: error?.isTimeout ? "Error: timeout exceded" : error }); - } - resolve(); - }) - .catch((error) => { - reject({ - host: vsp.host, - error: error?.isTimeout ? "Error: timeout exceded" : error - }); - }) + }) + ); + }) + ).then((results) => { + const failedAttempt = results.filter( + (result) => result.status !== "fulfilled" ); - }) - ).then((results) => { - const failedAttempt = results.filter( - (result) => result.status !== "fulfilled" - ); - if (failedAttempt.length > 0) { - failedAttempt.forEach((result) => { - dispatch({ - type: SETVSPDVOTECHOICE_SINGLE_FAILED, - host: result.reason.host, - error: result.reason.error + if (failedAttempt.length > 0) { + failedAttempt.forEach((result) => { + dispatch({ + type: SETVSPDVOTECHOICE_SINGLE_FAILED, + host: result.reason.host, + error: result.reason.error + }); }); - }); - if (failedAttempt.length < results.length) { - dispatch({ type: SETVSPDVOTECHOICE_PARTIAL_SUCCESS }); + if (failedAttempt.length < results.length) { + dispatch({ type: SETVSPDVOTECHOICE_PARTIAL_SUCCESS }); + } + dispatch({ type: SETVSPDVOTECHOICE_SUCCESS }); + } else { + dispatch({ type: SETVOTECHOICES_SUCCESS }); + dispatch({ type: SETVSPDVOTECHOICE_SUCCESS }); } - dispatch({ type: SETVSPDVOTECHOICE_SUCCESS }); - } else { - dispatch({ type: SETVOTECHOICES_SUCCESS }); - dispatch({ type: SETVSPDVOTECHOICE_SUCCESS }); - } - }) - ) - ); + }) + ) + ); - return true; - } catch (error) { - dispatch({ type: SETVSPDVOTECHOICE_FAILED, error }); - } -}; + return true; + } catch (error) { + dispatch({ type: SETVSPDVOTECHOICE_FAILED, error }); + } + }; export const SET_AUTOBUYER_SETTINGS = "SET_AUTOBUYER_SETTINGS"; -export const saveAutoBuyerSettings = ( - balanceToMaintain, - account, - maxFeePercentage -) => (dispatch, getState) => { - const { - daemon: { walletName } - } = getState(); - const walletCfg = wallet.getWalletCfg(sel.isTestNet(getState()), walletName); - const autobuyerSettings = { - balanceToMaintain: parseInt(balanceToMaintain.atomValue), - account: account.name, - maxFeePercentage: parseInt(maxFeePercentage) +export const saveAutoBuyerSettings = + (balanceToMaintain, account, maxFeePercentage) => (dispatch, getState) => { + const { + daemon: { walletName } + } = getState(); + const walletCfg = wallet.getWalletCfg( + sel.isTestNet(getState()), + walletName + ); + const autobuyerSettings = { + balanceToMaintain: parseInt(balanceToMaintain.atomValue), + account: account.name, + maxFeePercentage: parseInt(maxFeePercentage) + }; + walletCfg.set(cfgConstants.AUTOBUYER_SETTINGS, autobuyerSettings); + dispatch({ + type: SET_AUTOBUYER_SETTINGS, + autobuyerSettings + }); }; - walletCfg.set(cfgConstants.AUTOBUYER_SETTINGS, autobuyerSettings); - dispatch({ - type: SET_AUTOBUYER_SETTINGS, - autobuyerSettings - }); -}; export const SET_CANDISABLEPROCESSMANAGED = "SET_CANDISABLEPROCESSMANAGED"; export const setCanDisableProcessManaged = (value) => (dispatch) => { dispatch({ type: SET_CANDISABLEPROCESSMANAGED, value }); }; -export const getRandomVSP = (maxFeePercentage) => async ( - dispatch, - getState -) => { - const availableVSPs = sel.getAvailableVSPs(getState()); - if (availableVSPs.length == 0) { - throw new Error("The available VSPs list is empty."); - } - const filteredVSPs = availableVSPs.filter( - (vsp) => - vsp.vspData.feepercentage <= parseFloat(maxFeePercentage) && !vsp.outdated - ); - if (filteredVSPs.length == 0) { - const minFee = availableVSPs.reduce((acc, vsp) => { - if (vsp.outdated || !vsp.vspData.feepercentage) { - return acc; - } - return acc < vsp.vspData.feepercentage ? acc : vsp.vspData.feepercentage; - }, undefined); - throw new Error( - `No VSPs available for that fee rate. (Minimum is currently ${minFee}%)` +export const getRandomVSP = + (maxFeePercentage) => async (dispatch, getState) => { + const availableVSPs = sel.getAvailableVSPs(getState()); + if (availableVSPs.length == 0) { + throw new Error("The available VSPs list is empty."); + } + const filteredVSPs = availableVSPs.filter( + (vsp) => + vsp.vspData.feepercentage <= parseFloat(maxFeePercentage) && + !vsp.outdated ); - } + if (filteredVSPs.length == 0) { + const minFee = availableVSPs.reduce((acc, vsp) => { + if (vsp.outdated || !vsp.vspData.feepercentage) { + return acc; + } + return acc < vsp.vspData.feepercentage + ? acc + : vsp.vspData.feepercentage; + }, undefined); + throw new Error( + `No VSPs available for that fee rate. (Minimum is currently ${minFee}%)` + ); + } - const shuffledArray = shuffle(filteredVSPs); - let randomVSP; - do { - randomVSP = shuffledArray.pop(); - if (randomVSP?.pubkey == null) { - try { - const { pubkey } = await dispatch(getVSPInfo(randomVSP.host)); - randomVSP.pubkey = pubkey; - } catch (error) { - // Skip to the next vsp. + const shuffledArray = shuffle(filteredVSPs); + let randomVSP; + do { + randomVSP = shuffledArray.pop(); + if (randomVSP?.pubkey == null) { + try { + const { pubkey } = await dispatch(getVSPInfo(randomVSP.host)); + randomVSP.pubkey = pubkey; + } catch (error) { + // Skip to the next vsp. + } } - } - } while (randomVSP?.pubkey == null && shuffledArray.length > 0); + } while (randomVSP?.pubkey == null && shuffledArray.length > 0); - if (randomVSP?.pubkey == null) { - throw new Error("Fetching VSP info failed."); - } - return randomVSP; -}; + if (randomVSP?.pubkey == null) { + throw new Error("Fetching VSP info failed."); + } + return randomVSP; + }; export const GETUNSPENTUNEXPIREDVSPTICKETS_ATTEMPT = "GETUNSPENTUNEXPIREDVSPTICKETS_ATTEMPT"; @@ -654,51 +645,49 @@ export const GETUNSPENTUNEXPIREDVSPTICKETS_FAILED = "GETUNSPENTUNEXPIREDVSPTICKETS_FAILED"; export const GETUNSPENTUNEXPIREDVSPTICKETS_SUCCESS = "GETUNSPENTUNEXPIREDVSPTICKETS_SUCCESS"; -export const getUnspentUnexpiredVspTickets = () => async ( - dispatch, - getState -) => { - const { currentBlockHeight, walletService } = getState().grpc; - let vsps = []; - dispatch({ type: GETUNSPENTUNEXPIREDVSPTICKETS_ATTEMPT }); - - try { - const tickets = await wallet.getTickets( - walletService, - 0, - currentBlockHeight - ); - tickets.forEach(({ ticket: { vspHost, txHash }, status }) => { - if ( - vspHost && - vspHost != "" && - (status === LIVE || status === IMMATURE || status === UNMINED) - ) { - let foundVsp = false; - vsps = vsps.map((v) => { - if (v.host === vspHost) { - foundVsp = true; - return { ...v, tickets: [...v.tickets, txHash] }; +export const getUnspentUnexpiredVspTickets = + () => async (dispatch, getState) => { + const { currentBlockHeight, walletService } = getState().grpc; + let vsps = []; + dispatch({ type: GETUNSPENTUNEXPIREDVSPTICKETS_ATTEMPT }); + + try { + const tickets = await wallet.getTickets( + walletService, + 0, + currentBlockHeight + ); + tickets.forEach(({ ticket: { vspHost, txHash }, status }) => { + if ( + vspHost && + vspHost != "" && + (status === LIVE || status === IMMATURE || status === UNMINED) + ) { + let foundVsp = false; + vsps = vsps.map((v) => { + if (v.host === vspHost) { + foundVsp = true; + return { ...v, tickets: [...v.tickets, txHash] }; + } + return v; + }); + if (!foundVsp) { + vsps.push({ host: vspHost, tickets: [txHash] }); } - return v; - }); - if (!foundVsp) { - vsps.push({ host: vspHost, tickets: [txHash] }); } - } - }); - dispatch({ - type: GETUNSPENTUNEXPIREDVSPTICKETS_SUCCESS, - vsps - }); - return vsps; - } catch (error) { - dispatch({ - type: GETUNSPENTUNEXPIREDVSPTICKETS_FAILED, - error - }); - } -}; + }); + dispatch({ + type: GETUNSPENTUNEXPIREDVSPTICKETS_SUCCESS, + vsps + }); + return vsps; + } catch (error) { + dispatch({ + type: GETUNSPENTUNEXPIREDVSPTICKETS_FAILED, + error + }); + } + }; // getNotAbstainVotes returns all saved votes which are not // abstaining and related to an in-progress agenda. @@ -811,81 +800,79 @@ export const GETVSP_TICKET_STATUS_ATTEMPT = "GETVSP_TICKET_STATUS_ATTEMPT"; export const GETVSP_TICKET_STATUS_SUCCESS = "GETVSP_TICKET_STATUS_SUCCESS"; export const GETVSP_TICKET_STATUS_FAILED = "GETVSP_TICKET_STATUS_FAILED"; -export const getVSPTicketStatus = (passphrase, tx, decodedTx) => async ( - dispatch, - getState -) => { - let commitmentAddress; - let json; - try { - if (!tx || !tx.ticketTx || !tx.ticketTx.vspHost || !tx.txHash) { - throw new Error("Invalid tx parameter"); - } +export const getVSPTicketStatus = + (passphrase, tx, decodedTx) => async (dispatch, getState) => { + let commitmentAddress; + let json; + try { + if (!tx || !tx.ticketTx || !tx.ticketTx.vspHost || !tx.txHash) { + throw new Error("Invalid tx parameter"); + } - if ( - !decodedTx || - !decodedTx.outputs || - decodedTx.outputs.length < 2 || - !decodedTx.outputs[1].decodedScript || - !decodedTx.outputs[1].decodedScript.address - ) { - throw new Error("Invalid decodedTx parameter"); - } + if ( + !decodedTx || + !decodedTx.outputs || + decodedTx.outputs.length < 2 || + !decodedTx.outputs[1].decodedScript || + !decodedTx.outputs[1].decodedScript.address + ) { + throw new Error("Invalid decodedTx parameter"); + } - // This only considers the first commitment address which is the first odd output - commitmentAddress = decodedTx.outputs[1].decodedScript.address; + // This only considers the first commitment address which is the first odd output + commitmentAddress = decodedTx.outputs[1].decodedScript.address; - json = { - tickethash: tx.txHash - }; - } catch (error) { - dispatch({ type: GETVSP_TICKET_STATUS_FAILED, error }); - return; - } + json = { + tickethash: tx.txHash + }; + } catch (error) { + dispatch({ type: GETVSP_TICKET_STATUS_FAILED, error }); + return; + } - const sig = await dispatch( - signMessageAttempt(commitmentAddress, JSON.stringify(json), passphrase) - ); + const sig = await dispatch( + signMessageAttempt(commitmentAddress, JSON.stringify(json), passphrase) + ); - if (!sig) { - return; - } + if (!sig) { + return; + } - dispatch({ type: GETVSP_TICKET_STATUS_ATTEMPT }); - try { - // Check if user allows access to this VSP. This might trigger a confirmation - // dialog. - await wallet.allowVSPHost(tx.ticketTx.vspHost); - const info = await wallet.getVSPTicketStatus({ - host: tx.ticketTx.vspHost, - sig, - json - }); + dispatch({ type: GETVSP_TICKET_STATUS_ATTEMPT }); + try { + // Check if user allows access to this VSP. This might trigger a confirmation + // dialog. + await wallet.allowVSPHost(tx.ticketTx.vspHost); + const info = await wallet.getVSPTicketStatus({ + host: tx.ticketTx.vspHost, + sig, + json + }); - if (!info || !info.data) { - throw new Error("Invalid response from the VSP"); - } + if (!info || !info.data) { + throw new Error("Invalid response from the VSP"); + } - if (info.data.code) { - throw new Error(`${info.data.message} (code: ${info.data.code})`); - } + if (info.data.code) { + throw new Error(`${info.data.message} (code: ${info.data.code})`); + } - if ( - (tx.status === LIVE || tx.status === IMMATURE) && - info.data.feetxstatus === "confirmed" && - tx.feeStatus != VSP_FEE_PROCESS_CONFIRMED - ) { - dispatch(processManagedTickets(passphrase)); - } + if ( + (tx.status === LIVE || tx.status === IMMATURE) && + info.data.feetxstatus === "confirmed" && + tx.feeStatus != VSP_FEE_PROCESS_CONFIRMED + ) { + dispatch(processManagedTickets(passphrase)); + } - dispatch({ type: GETVSP_TICKET_STATUS_SUCCESS }); - const txURLBuilder = sel.txURLBuilder(getState()); - info.data.feetxUrl = txURLBuilder(info.data.feetxhash); - return info.data; - } catch (error) { - dispatch({ type: GETVSP_TICKET_STATUS_FAILED, error }); - } -}; + dispatch({ type: GETVSP_TICKET_STATUS_SUCCESS }); + const txURLBuilder = sel.txURLBuilder(getState()); + info.data.feetxUrl = txURLBuilder(info.data.feetxhash); + return info.data; + } catch (error) { + dispatch({ type: GETVSP_TICKET_STATUS_FAILED, error }); + } + }; export const SET_ACCOUNT_FOR_TICKET_PURCHASE = "SET_ACCOUNT_FOR_TICKET_PURCHASE"; diff --git a/app/actions/VersionActions.js b/app/actions/VersionActions.js index 82cd65d2b5..a537bd79d6 100644 --- a/app/actions/VersionActions.js +++ b/app/actions/VersionActions.js @@ -46,60 +46,58 @@ export const WALLETRPCVERSION_FAILED = "WALLETRPCVERSION_FAILED"; export const WALLETRPCVERSION_SUCCESS = "WALLETRPCVERSION_SUCCESS"; export const VERSION_NOT_VALID = "VERSION_NOT_VALID"; -export const getWalletRPCVersionAttempt = (versionService) => ( - dispatch, - getState -) => - new Promise((resolve, reject) => { - const getVersion = async () => { - dispatch({ type: WALLETRPCVERSION_ATTEMPT }); +export const getWalletRPCVersionAttempt = + (versionService) => (dispatch, getState) => + new Promise((resolve, reject) => { + const getVersion = async () => { + dispatch({ type: WALLETRPCVERSION_ATTEMPT }); - try { - const getWalletRPCVersionResponse = await wallet.getVersionResponse( - versionService - ); - dispatch({ - getWalletRPCVersionResponse, - type: WALLETRPCVERSION_SUCCESS - }); - const { - version: { requiredVersion } - } = getState(); - let versionErr = null; - const walletVersion = getWalletRPCVersionResponse.versionString; - wallet.grpcVersionsDetermined({ - requiredVersion, - walletVersion - }); - if (!walletVersion) { - versionErr = "Unable to obtain Dcrwallet API version"; - } else if (!semverCompatible(requiredVersion, walletVersion)) { - versionErr = - "API versions not compatible.. Decrediton requires " + - requiredVersion + - " but wallet " + - walletVersion + - " does not satisfy the requirement. Please check your" + - " installation, Decrediton and Dcrwallet versions should match."; + try { + const getWalletRPCVersionResponse = await wallet.getVersionResponse( + versionService + ); + dispatch({ + getWalletRPCVersionResponse, + type: WALLETRPCVERSION_SUCCESS + }); + const { + version: { requiredVersion } + } = getState(); + let versionErr = null; + const walletVersion = getWalletRPCVersionResponse.versionString; + wallet.grpcVersionsDetermined({ + requiredVersion, + walletVersion + }); + if (!walletVersion) { + versionErr = "Unable to obtain Dcrwallet API version"; + } else if (!semverCompatible(requiredVersion, walletVersion)) { + versionErr = + "API versions not compatible.. Decrediton requires " + + requiredVersion + + " but wallet " + + walletVersion + + " does not satisfy the requirement. Please check your" + + " installation, Decrediton and Dcrwallet versions should match."; + } + if (versionErr) { + dispatch({ error: versionErr, type: VERSION_NOT_VALID }); + dispatch(pushHistory("/invalidRPCVersion")); + return reject(versionErr); + } + const { address, port } = getState().grpc; + await dispatch(loaderRequest(address, port)); + await dispatch(getWalletSeedService(address, port)); + } catch (error) { + dispatch({ error, type: WALLETRPCVERSION_FAILED }); + reject(error); } - if (versionErr) { - dispatch({ error: versionErr, type: VERSION_NOT_VALID }); - dispatch(pushHistory("/invalidRPCVersion")); - return reject(versionErr); - } - const { address, port } = getState().grpc; - await dispatch(loaderRequest(address, port)); - await dispatch(getWalletSeedService(address, port)); - } catch (error) { - dispatch({ error, type: WALLETRPCVERSION_FAILED }); - reject(error); - } - }; + }; - getVersion() - .then((r) => resolve(r)) - .catch((error) => reject(error)); - }); + getVersion() + .then((r) => resolve(r)) + .catch((error) => reject(error)); + }); export function semverCompatible(req, act) { const required = req.split("."), diff --git a/app/actions/WalletLoaderActions.js b/app/actions/WalletLoaderActions.js index 39d7b08e1b..b3b6c77e7d 100644 --- a/app/actions/WalletLoaderActions.js +++ b/app/actions/WalletLoaderActions.js @@ -126,66 +126,63 @@ export const CREATEWALLET_ATTEMPT = "CREATEWALLET_ATTEMPT"; export const CREATEWALLET_FAILED = "CREATEWALLET_FAILED"; export const CREATEWALLET_SUCCESS = "CREATEWALLET_SUCCESS"; -export const createWalletRequest = (pubPass, privPass, seed, isNew) => ( - dispatch, - getState -) => - new Promise((resolve, reject) => { - dispatch({ existing: !isNew, type: CREATEWALLET_ATTEMPT }); - return wallet - .createWallet(getState().walletLoader.loader, pubPass, privPass, seed) - .then(() => { - const { - daemon: { walletName } - } = getState(); - const config = wallet.getWalletCfg(isTestNet(getState()), walletName); - config.delete(cfgConstants.DISCOVER_ACCOUNTS); - config.delete(cfgConstants.WALLET_CREATED_AS_NEW); - config.set(cfgConstants.DISCOVER_ACCOUNTS, isNew); - dispatch({ complete: isNew, type: UPDATEDISCOVERACCOUNTS }); - dispatch({ type: CREATEWALLET_SUCCESS }); - dispatch(getWalletServiceAttempt()); - resolve(true); - }) - .catch((error) => { - dispatch({ error, type: CREATEWALLET_FAILED }); - reject(error); - }); - }); +export const createWalletRequest = + (pubPass, privPass, seed, isNew) => (dispatch, getState) => + new Promise((resolve, reject) => { + dispatch({ existing: !isNew, type: CREATEWALLET_ATTEMPT }); + return wallet + .createWallet(getState().walletLoader.loader, pubPass, privPass, seed) + .then(() => { + const { + daemon: { walletName } + } = getState(); + const config = wallet.getWalletCfg(isTestNet(getState()), walletName); + config.delete(cfgConstants.DISCOVER_ACCOUNTS); + config.delete(cfgConstants.WALLET_CREATED_AS_NEW); + config.set(cfgConstants.DISCOVER_ACCOUNTS, isNew); + dispatch({ complete: isNew, type: UPDATEDISCOVERACCOUNTS }); + dispatch({ type: CREATEWALLET_SUCCESS }); + dispatch(getWalletServiceAttempt()); + resolve(true); + }) + .catch((error) => { + dispatch({ error, type: CREATEWALLET_FAILED }); + reject(error); + }); + }); export const CREATEWATCHONLYWALLET_ATTEMPT = "CREATEWATCHONLYWALLET_ATTEMPT"; export const CREATEWATCHONLYWALLET_FAILED = "CREATEWATCHONLYWALLET_FAILED"; export const CREATEWATCHONLYWALLET_SUCCESS = "CREATEWATCHONLYWALLET_SUCCESS"; -export const createWatchOnlyWalletRequest = (extendedPubKey, pubPass = "") => ( - dispatch, - getState -) => - new Promise((resolve, reject) => { - dispatch({ type: CREATEWATCHONLYWALLET_ATTEMPT }); - return wallet - .createWatchingOnlyWallet( - getState().walletLoader.loader, - extendedPubKey, - pubPass - ) - .then(() => { - const { - daemon: { walletName } - } = getState(); - const config = wallet.getWalletCfg(isTestNet(getState()), walletName); - config.set(cfgConstants.IS_WATCH_ONLY, true); - config.delete(cfgConstants.DISCOVER_ACCOUNTS); - wallet.setIsWatchingOnly(true); - dispatch({ response: {}, type: CREATEWATCHONLYWALLET_SUCCESS }); - dispatch(getWalletServiceAttempt()); - resolve(true); - }) - .catch((error) => { - dispatch({ error, type: CREATEWATCHONLYWALLET_FAILED }); - reject(error); - }); - }); +export const createWatchOnlyWalletRequest = + (extendedPubKey, pubPass = "") => + (dispatch, getState) => + new Promise((resolve, reject) => { + dispatch({ type: CREATEWATCHONLYWALLET_ATTEMPT }); + return wallet + .createWatchingOnlyWallet( + getState().walletLoader.loader, + extendedPubKey, + pubPass + ) + .then(() => { + const { + daemon: { walletName } + } = getState(); + const config = wallet.getWalletCfg(isTestNet(getState()), walletName); + config.set(cfgConstants.IS_WATCH_ONLY, true); + config.delete(cfgConstants.DISCOVER_ACCOUNTS); + wallet.setIsWatchingOnly(true); + dispatch({ response: {}, type: CREATEWATCHONLYWALLET_SUCCESS }); + dispatch(getWalletServiceAttempt()); + resolve(true); + }) + .catch((error) => { + dispatch({ error, type: CREATEWATCHONLYWALLET_FAILED }); + reject(error); + }); + }); export const OPENWALLET_INPUT = "OPENWALLET_INPUT"; export const OPENWALLET_INPUTPRIVPASS = "OPENWALLET_INPUTPRIVPASS"; @@ -194,62 +191,60 @@ export const OPENWALLET_ATTEMPT = "OPENWALLET_ATTEMPT"; export const OPENWALLET_FAILED = "OPENWALLET_FAILED"; export const OPENWALLET_SUCCESS = "OPENWALLET_SUCCESS"; -export const openWalletAttempt = (pubPass, retryAttempt, selectedWallet) => ( - dispatch, - getState -) => - new Promise((resolve, reject) => { - dispatch({ type: OPENWALLET_ATTEMPT }); - return wallet - .openWallet(getState().walletLoader.loader, pubPass) - .then(async (response) => { - await dispatch(getWalletServiceAttempt()); - wallet.setIsWatchingOnly(response.watchingOnly); - // needsPassPhrase is reset by OPENWALLET_SUCCESS, so store it here if - // we need to ask for the passphrase before starting the sync process. - const needsPassPhrase = getState().walletLoader.needsPassPhrase; - dispatch({ - isWatchingOnly: response.watchingOnly, - type: OPENWALLET_SUCCESS - }); +export const openWalletAttempt = + (pubPass, retryAttempt, selectedWallet) => (dispatch, getState) => + new Promise((resolve, reject) => { + dispatch({ type: OPENWALLET_ATTEMPT }); + return wallet + .openWallet(getState().walletLoader.loader, pubPass) + .then(async (response) => { + await dispatch(getWalletServiceAttempt()); + wallet.setIsWatchingOnly(response.watchingOnly); + // needsPassPhrase is reset by OPENWALLET_SUCCESS, so store it here if + // we need to ask for the passphrase before starting the sync process. + const needsPassPhrase = getState().walletLoader.needsPassPhrase; + dispatch({ + isWatchingOnly: response.watchingOnly, + type: OPENWALLET_SUCCESS + }); + + if (needsPassPhrase) { + reject(OPENWALLET_INPUTPRIVPASS); + return; + } + resolve(true); + }) + .catch(async (error) => { + // This error message happens after creating a new wallet as we already + // started it on creation. So we just ignore it. + if (error.message.includes("wallet already")) { + dispatch(getWalletServiceAttempt()); + const isWatchingOnly = await wallet.getIsWatchingOnly(); + dispatch({ isWatchingOnly, type: OPENWALLET_SUCCESS }); + return resolve(true); + } + // Wallet with pub pass + if (error.message.includes("invalid passphrase:: wallet.Open")) { + if (retryAttempt) { + dispatch({ error, type: OPENWALLET_FAILED_INPUT }); + return reject(OPENWALLET_FAILED_INPUT); + } + return reject(OPENWALLET_INPUT); + } - if (needsPassPhrase) { - reject(OPENWALLET_INPUTPRIVPASS); - return; - } - resolve(true); - }) - .catch(async (error) => { - // This error message happens after creating a new wallet as we already - // started it on creation. So we just ignore it. - if (error.message.includes("wallet already")) { - dispatch(getWalletServiceAttempt()); - const isWatchingOnly = await wallet.getIsWatchingOnly(); - dispatch({ isWatchingOnly, type: OPENWALLET_SUCCESS }); - return resolve(true); - } - // Wallet with pub pass - if (error.message.includes("invalid passphrase:: wallet.Open")) { - if (retryAttempt) { - dispatch({ error, type: OPENWALLET_FAILED_INPUT }); - return reject(OPENWALLET_FAILED_INPUT); + if (!selectedWallet.finished) { + const walletCfg = wallet.getWalletCfg( + isTestNet(getState()), + selectedWallet.value.wallet + ); + error.walletCreatedAsNew = !!walletCfg.get( + cfgConstants.WALLET_CREATED_AS_NEW + ); } - return reject(OPENWALLET_INPUT); - } - - if (!selectedWallet.finished) { - const walletCfg = wallet.getWalletCfg( - isTestNet(getState()), - selectedWallet.value.wallet - ); - error.walletCreatedAsNew = !!walletCfg.get( - cfgConstants.WALLET_CREATED_AS_NEW - ); - } - dispatch({ error, type: OPENWALLET_FAILED }); - reject(error); - }); - }); + dispatch({ error, type: OPENWALLET_FAILED }); + reject(error); + }); + }); export const CLOSEWALLET_ATTEMPT = "CLOSEWALLET_ATTEMPT"; export const CLOSEWALLET_FAILED = "CLOSEWALLET_FAILED"; @@ -304,87 +299,85 @@ export const STARTRPC_FAILED = "STARTRPC_FAILED"; export const STARTRPC_SUCCESS = "STARTRPC_SUCCESS"; export const STARTRPC_RETRY = "STARTRPC_RETRY"; -export const startRpcRequestFunc = (privPass, isRetry) => ( - dispatch, - getState -) => { - const { syncAttemptRequest } = getState().walletLoader; - if (syncAttemptRequest) { - return; - } - const { - daemon: { walletName }, - walletLoader: { discoverAccountsComplete } - } = getState(); - - const credentials = wallet.getDcrdRpcCredentials(); - const discoverAccts = !discoverAccountsComplete && privPass; - const setPrivPass = discoverAccts - ? new Uint8Array(Buffer.from(privPass)) - : null; - - return new Promise((resolve, reject) => { - if (!isRetry) dispatch({ type: SYNC_ATTEMPT }); - const { loader } = getState().walletLoader; - setTimeout(async () => { - const rpcSyncCall = await wallet.rpcSync( - loader, - credentials, - discoverAccts, - setPrivPass - ); - dispatch({ syncCall: rpcSyncCall, type: SYNC_UPDATE }); - rpcSyncCall.on("data", async (response) => { - const synced = await dispatch(syncConsumer(response)); - if (synced) { - return resolve(); - } - }); - rpcSyncCall.on("end", function () { - // Connection closed. - }); - rpcSyncCall.on("error", function (status) { - status = status + ""; - if (status.indexOf("Cancelled") < 0) { - if (isRetry) { - const { rpcRetryAttempts } = getState().walletLoader; - if (rpcRetryAttempts < MAX_RPC_RETRIES) { - dispatch({ - rpcRetryAttempts: rpcRetryAttempts + 1, - type: STARTRPC_RETRY - }); - setTimeout( - () => dispatch(startRpcRequestFunc(privPass, isRetry)), - RPC_RETRY_DELAY - ); +export const startRpcRequestFunc = + (privPass, isRetry) => (dispatch, getState) => { + const { syncAttemptRequest } = getState().walletLoader; + if (syncAttemptRequest) { + return; + } + const { + daemon: { walletName }, + walletLoader: { discoverAccountsComplete } + } = getState(); + + const credentials = wallet.getDcrdRpcCredentials(); + const discoverAccts = !discoverAccountsComplete && privPass; + const setPrivPass = discoverAccts + ? new Uint8Array(Buffer.from(privPass)) + : null; + + return new Promise((resolve, reject) => { + if (!isRetry) dispatch({ type: SYNC_ATTEMPT }); + const { loader } = getState().walletLoader; + setTimeout(async () => { + const rpcSyncCall = await wallet.rpcSync( + loader, + credentials, + discoverAccts, + setPrivPass + ); + dispatch({ syncCall: rpcSyncCall, type: SYNC_UPDATE }); + rpcSyncCall.on("data", async (response) => { + const synced = await dispatch(syncConsumer(response)); + if (synced) { + return resolve(); + } + }); + rpcSyncCall.on("end", function () { + // Connection closed. + }); + rpcSyncCall.on("error", function (status) { + status = status + ""; + if (status.indexOf("Cancelled") < 0) { + if (isRetry) { + const { rpcRetryAttempts } = getState().walletLoader; + if (rpcRetryAttempts < MAX_RPC_RETRIES) { + dispatch({ + rpcRetryAttempts: rpcRetryAttempts + 1, + type: STARTRPC_RETRY + }); + setTimeout( + () => dispatch(startRpcRequestFunc(privPass, isRetry)), + RPC_RETRY_DELAY + ); + } else { + dispatch({ + error: `${status}. You may need to edit ${wallet.getWalletPath( + isTestNet(getState()), + walletName + )} and try again`, + type: STARTRPC_FAILED + }); + } + } else if (status.includes("wallet.Unlock: invalid passphrase")) { + // Wallet needs unlocking to discover accounts and passphrase + // is wrong. + dispatch({ error: status, type: SYNC_FAILED }); + return reject(OPENWALLET_INPUTPRIVPASS); + } else if ( + status.indexOf("invalid passphrase") > 0 || + status.indexOf("Stream removed") + ) { + dispatch({ error: status, type: SYNC_FAILED }); + reject(status); } else { - dispatch({ - error: `${status}. You may need to edit ${wallet.getWalletPath( - isTestNet(getState()), - walletName - )} and try again`, - type: STARTRPC_FAILED - }); + dispatch(startRpcRequestFunc(privPass, true)); } - } else if (status.includes("wallet.Unlock: invalid passphrase")) { - // Wallet needs unlocking to discover accounts and passphrase - // is wrong. - dispatch({ error: status, type: SYNC_FAILED }); - return reject(OPENWALLET_INPUTPRIVPASS); - } else if ( - status.indexOf("invalid passphrase") > 0 || - status.indexOf("Stream removed") - ) { - dispatch({ error: status, type: SYNC_FAILED }); - reject(status); - } else { - dispatch(startRpcRequestFunc(privPass, true)); } - } - }); - }, 500); - }); -}; + }); + }, 500); + }); + }; export const WALLET_SELECTED = "WALLET_SELECTED"; @@ -706,14 +699,12 @@ export const stopUnfinishedWallet = () => async (dispatch) => { } }; -export const setAutoWalletLaunching = (autoWalletLaunching) => async ( - dispatch, - getState -) => { - dispatch(updateStateSettingsChanged({ autoWalletLaunching }, true)); - const tempSettings = getState().settings.tempSettings; - const config = wallet.getGlobalCfg(); - config.set(cfgConstants.AUTO_WALLET_LAUNCHING, autoWalletLaunching); +export const setAutoWalletLaunching = + (autoWalletLaunching) => async (dispatch, getState) => { + dispatch(updateStateSettingsChanged({ autoWalletLaunching }, true)); + const tempSettings = getState().settings.tempSettings; + const config = wallet.getGlobalCfg(); + config.set(cfgConstants.AUTO_WALLET_LAUNCHING, autoWalletLaunching); - await dispatch(saveSettings(tempSettings)); -}; + await dispatch(saveSettings(tempSettings)); + }; diff --git a/app/components/SideBar/MenuBottom/LastBlockTime/hooks.js b/app/components/SideBar/MenuBottom/LastBlockTime/hooks.js index 89bbf8b92e..c5222cb593 100644 --- a/app/components/SideBar/MenuBottom/LastBlockTime/hooks.js +++ b/app/components/SideBar/MenuBottom/LastBlockTime/hooks.js @@ -23,9 +23,8 @@ export function useLastBlockTime(lastBlockTimestamp, clearTimeout, setTimeout) { _lastBlockIsRecent = timeFromLastBlock < 60000; if (_lastBlockIsRecent) { updateRecentTimer.current = setTimeout(() => { - const { _lastBlockDate, _lastBlockIsRecent } = getBlockDate( - lastBlockTimestamp - ); + const { _lastBlockDate, _lastBlockIsRecent } = + getBlockDate(lastBlockTimestamp); setLastBlockDate(_lastBlockDate); setLastBlockIsRecent(_lastBlockIsRecent); }, 60000 - timeFromLastBlock); @@ -37,9 +36,8 @@ export function useLastBlockTime(lastBlockTimestamp, clearTimeout, setTimeout) { ); useEffect(() => { - const { _lastBlockDate, _lastBlockIsRecent } = getBlockDate( - lastBlockTimestamp - ); + const { _lastBlockDate, _lastBlockIsRecent } = + getBlockDate(lastBlockTimestamp); setLastBlockDate(_lastBlockDate); setLastBlockIsRecent(_lastBlockIsRecent); }, [lastBlockTimestamp, getBlockDate]); diff --git a/app/components/SideBar/SideBar.jsx b/app/components/SideBar/SideBar.jsx index 125d4dbebe..a1b7d83ae7 100644 --- a/app/components/SideBar/SideBar.jsx +++ b/app/components/SideBar/SideBar.jsx @@ -33,12 +33,8 @@ const SideBar = () => { onAccountsListWheel, uiAnimations } = useSideBar(); - const { - rescanEndBlock, - rescanCurrentBlock, - rescanAttempt, - rescanCancel - } = useRescan(); + const { rescanEndBlock, rescanCurrentBlock, rescanAttempt, rescanCancel } = + useRescan(); return (
dispatch(sba.expandSideBar()), [ - dispatch - ]); - const onReduceSideBar = useCallback(() => dispatch(sba.reduceSideBar()), [ - dispatch - ]); + const onExpandSideBar = useCallback( + () => dispatch(sba.expandSideBar()), + [dispatch] + ); + const onReduceSideBar = useCallback( + () => dispatch(sba.reduceSideBar()), + [dispatch] + ); return { isShowingAccounts, diff --git a/app/components/buttons/index.js b/app/components/buttons/index.js index e71f6c42d5..d8d0708063 100644 --- a/app/components/buttons/index.js +++ b/app/components/buttons/index.js @@ -60,16 +60,17 @@ import styles from "./Buttons.module.css"; // mbb = ModalButtonBuilder (func to build a functional ModalButton component // with extra fixed props) -const mbb = (className, modalComponent, buttonComponent) => (p) => ( - -); +const mbb = (className, modalComponent, buttonComponent) => (p) => + ( + + ); const helpLinkButton = ({ icon, onClick, title, subtitle }) => ( { - const { - showingSidebarMenu, - expandSideBar, - mouseUp, - onKeyDown, - modalRef - } = useModal(onCancelModal); + const { showingSidebarMenu, expandSideBar, mouseUp, onKeyDown, modalRef } = + useModal(onCancelModal); const domNode = document.getElementById("modal-portal"); if (!domNode) return null; // modal-portal not mounted yet. diff --git a/app/components/modals/Modal/hooks.js b/app/components/modals/Modal/hooks.js index 6c79aebe83..a71cbe8737 100644 --- a/app/components/modals/Modal/hooks.js +++ b/app/components/modals/Modal/hooks.js @@ -11,9 +11,10 @@ export function useModal(onCancelModal) { const modalRef = useRef(null); const dispatch = useDispatch(); - const onModalVisible = useCallback(() => dispatch(modalVisible()), [ - dispatch - ]); + const onModalVisible = useCallback( + () => dispatch(modalVisible()), + [dispatch] + ); const onModalHidden = useCallback(() => dispatch(modalHidden()), [dispatch]); // This switches modalVisible redux switch on when modal mount diff --git a/app/components/modals/TrezorModals/TrezorModals.jsx b/app/components/modals/TrezorModals/TrezorModals.jsx index 857febe072..c16000bcca 100644 --- a/app/components/modals/TrezorModals/TrezorModals.jsx +++ b/app/components/modals/TrezorModals/TrezorModals.jsx @@ -19,10 +19,8 @@ const TrezorModals = () => { ...props } = useTrezor(); - const [ - wordAlreadyHasBeenRequested, - setWordAlreadyHasBeenRequested - ] = useState(false); + const [wordAlreadyHasBeenRequested, setWordAlreadyHasBeenRequested] = + useState(false); useEffect(() => { if (waitingForWord) { setWordAlreadyHasBeenRequested(true); diff --git a/app/components/modals/TrezorModals/TrezorWalletCreationPassphraseModal.jsx b/app/components/modals/TrezorModals/TrezorWalletCreationPassphraseModal.jsx index 9cbc7086ba..e3661965b5 100644 --- a/app/components/modals/TrezorModals/TrezorWalletCreationPassphraseModal.jsx +++ b/app/components/modals/TrezorModals/TrezorWalletCreationPassphraseModal.jsx @@ -52,10 +52,10 @@ const TrezorWalletCreationPassphraseModal = ({ [] ); - const isValid = useMemo(() => passphraseValue === passphraseConfirmValue, [ - passphraseValue, - passphraseConfirmValue - ]); + const isValid = useMemo( + () => passphraseValue === passphraseConfirmValue, + [passphraseValue, passphraseConfirmValue] + ); return ( { const dispatch = useDispatch(); - const goBackHistory = useCallback(() => dispatch(cli.goBackHistory()), [ - dispatch - ]); + const goBackHistory = useCallback( + () => dispatch(cli.goBackHistory()), + [dispatch] + ); return (
diff --git a/app/components/shared/PoliteiaLink.jsx b/app/components/shared/PoliteiaLink.jsx index b6db59423a..7527b6ec50 100644 --- a/app/components/shared/PoliteiaLink.jsx +++ b/app/components/shared/PoliteiaLink.jsx @@ -16,9 +16,10 @@ const PoliteiaLink = ({ }`, [isTestnet, path] ); - const onClickHandler = useCallback(() => wallet.openExternalURL(href), [ - href - ]); + const onClickHandler = useCallback( + () => wallet.openExternalURL(href), + [href] + ); return ( { - const { - isCreateAccountDisabled, - onGetNextAccountAttempt - } = useAccountsPage(); + const { isCreateAccountDisabled, onGetNextAccountAttempt } = + useAccountsPage(); return ( { const isLoading = settingVspdVoteChoices; const dispatch = useDispatch(); - const goBackHistory = useCallback(() => dispatch(cli.goBackHistory()), [ - dispatch - ]); + const goBackHistory = useCallback( + () => dispatch(cli.goBackHistory()), + [dispatch] + ); const onUpdateVotePreference = (agendaId, choiceId, passphrase) => dispatch(cli.setVoteChoicesAttempt(agendaId, choiceId, passphrase)); const updatePreferences = async (passphrase) => { diff --git a/app/components/views/DexPage/InitPage/InitPage.jsx b/app/components/views/DexPage/InitPage/InitPage.jsx index 40434774ee..c67673e4a0 100644 --- a/app/components/views/DexPage/InitPage/InitPage.jsx +++ b/app/components/views/DexPage/InitPage/InitPage.jsx @@ -8,17 +8,11 @@ import styles from "./InitPage.module.css"; const InitPage = () => { const { onInitDex, onInitDexWithSeed, initDexAttempt } = useDex(); - const { - hasSeed, - toggleHasSeed, - seed, - setSeed, - onInitDexCall, - seedError - } = useInitPage({ - onInitDex, - onInitDexWithSeed - }); + const { hasSeed, toggleHasSeed, seed, setSeed, onInitDexCall, seedError } = + useInitPage({ + onInitDex, + onInitDexWithSeed + }); return (
diff --git a/app/components/views/DexPage/hooks.js b/app/components/views/DexPage/hooks.js index 7e63c945f3..c3a956f8fd 100644 --- a/app/components/views/DexPage/hooks.js +++ b/app/components/views/DexPage/hooks.js @@ -50,9 +50,10 @@ export const useDex = () => { const dexSeed = useSelector(sel.dexSeed); const onGetDexLogs = () => dispatch(dm.getDexLogs()); - const onLaunchDexWindow = useCallback(() => dispatch(da.launchDexWindow()), [ - dispatch - ]); + const onLaunchDexWindow = useCallback( + () => dispatch(da.launchDexWindow()), + [dispatch] + ); const onInitDex = useCallback( (passphrase) => dispatch(da.initDex(passphrase)), @@ -75,9 +76,10 @@ export const useDex = () => { [dispatch] ); - const onConfirmDexSeed = useCallback(() => dispatch(da.confirmDexSeed()), [ - dispatch - ]); + const onConfirmDexSeed = useCallback( + () => dispatch(da.confirmDexSeed()), + [dispatch] + ); const onCreateDexAccount = useCallback( (passphrase, name) => dispatch(da.createDexAccount(passphrase, name)), diff --git a/app/components/views/GetStartedPage/AdvancedStartup/AdvancedStartup.jsx b/app/components/views/GetStartedPage/AdvancedStartup/AdvancedStartup.jsx index 7921ba1ac5..1b263d66f5 100644 --- a/app/components/views/GetStartedPage/AdvancedStartup/AdvancedStartup.jsx +++ b/app/components/views/GetStartedPage/AdvancedStartup/AdvancedStartup.jsx @@ -24,9 +24,8 @@ export const AdvancedStartupBody = ({ const [rpc_host, setRpcHostState] = useState(rpchost); const [rpc_port, setRpcPortState] = useState(rpcport); const [rpcUserHasFailedAttempt, setUserHasFailedAttempt] = useState(false); - const [rpcPasswordHasFailedAttempt, setPasswordHasFailedAttempt] = useState( - false - ); + const [rpcPasswordHasFailedAttempt, setPasswordHasFailedAttempt] = + useState(false); const [rpcHostHasFailedAttempt, setHostHasFailedAttempt] = useState(false); const [rpcPortHasFailedAttempt, setPortHasFailedAttempt] = useState(false); const [rpcCertHasFailedAttempt, setCertHasFailedAttempt] = useState(false); diff --git a/app/components/views/GetStartedPage/CreateWalletPage/hooks.js b/app/components/views/GetStartedPage/CreateWalletPage/hooks.js index 9e1f63ee45..cdcb279050 100644 --- a/app/components/views/GetStartedPage/CreateWalletPage/hooks.js +++ b/app/components/views/GetStartedPage/CreateWalletPage/hooks.js @@ -7,16 +7,18 @@ import * as ca from "actions/ControlActions"; export const useCreateWallet = () => { const pageBodyTopRef = useSelector(sel.pageBodyTopRef); const dispatch = useDispatch(); - const decodeSeed = useCallback((seed) => dispatch(wla.decodeSeed(seed)), [ - dispatch - ]); + const decodeSeed = useCallback( + (seed) => dispatch(wla.decodeSeed(seed)), + [dispatch] + ); const cancelCreateWallet = useCallback( () => dispatch(wla.cancelCreateWallet()), [dispatch] ); - const generateSeed = useCallback(() => dispatch(wla.generateSeed()), [ - dispatch - ]); + const generateSeed = useCallback( + () => dispatch(wla.generateSeed()), + [dispatch] + ); // TODO implement pubpass const createWatchOnlyWalletRequest = useCallback( (extendedPubKey, pubPass = "") => diff --git a/app/components/views/GetStartedPage/LanguageSelectPage/LanguageSelectPage.jsx b/app/components/views/GetStartedPage/LanguageSelectPage/LanguageSelectPage.jsx index e6a3016ef8..94a01b8ac8 100644 --- a/app/components/views/GetStartedPage/LanguageSelectPage/LanguageSelectPage.jsx +++ b/app/components/views/GetStartedPage/LanguageSelectPage/LanguageSelectPage.jsx @@ -3,12 +3,8 @@ import LanguageSelectPage from "./Page"; import { useDaemonStartup } from "hooks"; const LanguageSelect = () => { - const { - availableLanguages, - defaultLocale, - onSelectLanguage, - isTestNet - } = useDaemonStartup(); + const { availableLanguages, defaultLocale, onSelectLanguage, isTestNet } = + useDaemonStartup(); const defaultLang = useMemo( () => diff --git a/app/components/views/GetStartedPage/SetupWallet/ResendVotesToRecentlyUpdatedVSPs/ResendVotesToRecentlyUpdatedVSPs.jsx b/app/components/views/GetStartedPage/SetupWallet/ResendVotesToRecentlyUpdatedVSPs/ResendVotesToRecentlyUpdatedVSPs.jsx index 335d93beac..144561de8e 100644 --- a/app/components/views/GetStartedPage/SetupWallet/ResendVotesToRecentlyUpdatedVSPs/ResendVotesToRecentlyUpdatedVSPs.jsx +++ b/app/components/views/GetStartedPage/SetupWallet/ResendVotesToRecentlyUpdatedVSPs/ResendVotesToRecentlyUpdatedVSPs.jsx @@ -5,10 +5,8 @@ import styles from "./ResendVotesToRecentlyUpdatedVSPs.module.css"; import { useResendVotesToRecentlyUpdatedVSPs } from "./hooks"; const ResendVotesToRecentlyUpdatedVSPs = ({ cancel, send, vsps, votes }) => { - const { - resendVSPDVoteChoicesAttempt, - onResendVSPDVoteChoices - } = useResendVotesToRecentlyUpdatedVSPs(); + const { resendVSPDVoteChoicesAttempt, onResendVSPDVoteChoices } = + useResendVotesToRecentlyUpdatedVSPs(); const onSubmitContinue = (passphrase) => onResendVSPDVoteChoices(vsps, passphrase) diff --git a/app/components/views/GetStartedPage/SetupWallet/SetupWallet.jsx b/app/components/views/GetStartedPage/SetupWallet/SetupWallet.jsx index 0466840147..00552953eb 100644 --- a/app/components/views/GetStartedPage/SetupWallet/SetupWallet.jsx +++ b/app/components/views/GetStartedPage/SetupWallet/SetupWallet.jsx @@ -12,9 +12,8 @@ const SetupWallet = ({ LoadingPageComponent, settingUpWalletRef }) => { - const { getStateComponent, StateComponent } = useWalletSetup( - settingUpWalletRef - ); + const { getStateComponent, StateComponent } = + useWalletSetup(settingUpWalletRef); useEffect(() => { getStateComponent(); diff --git a/app/components/views/GetStartedPage/SetupWallet/hooks.js b/app/components/views/GetStartedPage/SetupWallet/hooks.js index 9019aad899..d6195921e7 100644 --- a/app/components/views/GetStartedPage/SetupWallet/hooks.js +++ b/app/components/views/GetStartedPage/SetupWallet/hooks.js @@ -58,9 +58,10 @@ export const useWalletSetup = (settingUpWalletRef) => { [dispatch] ); - const onGetVSPsPubkeys = useCallback(() => dispatch(getVSPsPubkeys()), [ - dispatch - ]); + const onGetVSPsPubkeys = useCallback( + () => dispatch(getVSPsPubkeys()), + [dispatch] + ); const onGetRecentlyUpdatedUsedVSPs = useCallback( () => dispatch(getRecentlyUpdatedUsedVSPs()), diff --git a/app/components/views/GetStartedPage/hooks.js b/app/components/views/GetStartedPage/hooks.js index a57b4e414f..6d6f6bfbc5 100644 --- a/app/components/views/GetStartedPage/hooks.js +++ b/app/components/views/GetStartedPage/hooks.js @@ -64,10 +64,8 @@ export const useGetStarted = () => { const [PageComponent, setPageComponent] = useState(null); const [showNavLinks, setShowNavLinks] = useState(true); const [NavlinkComponent, setNavlinkComponent] = useState(null); - const [ - nextStateAfterWalletLoading, - setNextStateAfterWalletLoading - ] = useState(null); + const [nextStateAfterWalletLoading, setNextStateAfterWalletLoading] = + useState(null); const [state, send] = useMachine(getStartedMachine, { actions: { @@ -369,9 +367,10 @@ export const useGetStarted = () => { setShowNavLinks(true); }, [send]); - const onSendError = useCallback((error) => send({ type: "ERROR", error }), [ - send - ]); + const onSendError = useCallback( + (error) => send({ type: "ERROR", error }), + [send] + ); const onSendCreateWallet = useCallback( (isNew, isTrezor) => send({ type: "CREATE_WALLET", isNew, isTrezor }), diff --git a/app/components/views/GovernancePage/Proposals/ProposalsListItem/ProposalsListItem.jsx b/app/components/views/GovernancePage/Proposals/ProposalsListItem/ProposalsListItem.jsx index 843b8027c9..d6b0bcffe7 100644 --- a/app/components/views/GovernancePage/Proposals/ProposalsListItem/ProposalsListItem.jsx +++ b/app/components/views/GovernancePage/Proposals/ProposalsListItem/ProposalsListItem.jsx @@ -26,12 +26,8 @@ const ProposalsListItem = ({ version, isDarkTheme }) => { - const { - viewProposalDetailsHandler, - tsDate, - isTestnet, - linkedProposal - } = useProposalsListItem(token); + const { viewProposalDetailsHandler, tsDate, isTestnet, linkedProposal } = + useProposalsListItem(token); const isVoting = voteStatus === PROPOSAL_VOTING_ACTIVE; const isModified = (!isVoting && modifiedSinceLastAccess) || diff --git a/app/components/views/GovernancePage/Proposals/hooks.js b/app/components/views/GovernancePage/Proposals/hooks.js index ed2c38b663..7b80704c0d 100644 --- a/app/components/views/GovernancePage/Proposals/hooks.js +++ b/app/components/views/GovernancePage/Proposals/hooks.js @@ -42,10 +42,10 @@ export function useProposalsListItem(token) { const proposals = useSelector(sel.proposals); const proposalsDetails = useSelector(sel.proposalsDetails); - const viewedProposalDetails = useMemo(() => proposalsDetails[token], [ - token, - proposalsDetails - ]); + const viewedProposalDetails = useMemo( + () => proposalsDetails[token], + [token, proposalsDetails] + ); const linkedProposal = useMemo( () => diff --git a/app/components/views/HomePage/Tabs/TransactionsTab/TransactionsTab.jsx b/app/components/views/HomePage/Tabs/TransactionsTab/TransactionsTab.jsx index 8a4c8afc95..99b55fd476 100644 --- a/app/components/views/HomePage/Tabs/TransactionsTab/TransactionsTab.jsx +++ b/app/components/views/HomePage/Tabs/TransactionsTab/TransactionsTab.jsx @@ -7,11 +7,8 @@ import sharedStyles from "../../HomePage.module.css"; import GovernanceNotification from "../../GovernanceNotification"; const TransactionsTab = () => { - const { - balanceReceived, - balanceSent, - sentAndReceivedTransactions - } = useTransactions(); + const { balanceReceived, balanceSent, sentAndReceivedTransactions } = + useTransactions(); return (
diff --git a/app/components/views/LNPage/AdvancedTab/AdvancedTab.jsx b/app/components/views/LNPage/AdvancedTab/AdvancedTab.jsx index 4541f121ac..dfd9b5c3a3 100644 --- a/app/components/views/LNPage/AdvancedTab/AdvancedTab.jsx +++ b/app/components/views/LNPage/AdvancedTab/AdvancedTab.jsx @@ -26,13 +26,8 @@ export const AdvancedTabHeader = () => ( ); const AdvancedTab = () => { - const { - info, - scbPath, - scbUpdatedTime, - onBackup, - onVerifyBackup - } = useAdvancedTab(); + const { info, scbPath, scbUpdatedTime, onBackup, onVerifyBackup } = + useAdvancedTab(); const { alias, identityPubkey } = info; diff --git a/app/components/views/LNPage/AdvancedTab/Watchtowers/Watchtowers.jsx b/app/components/views/LNPage/AdvancedTab/Watchtowers/Watchtowers.jsx index a91b7bc9fd..bdd3e3f2d4 100644 --- a/app/components/views/LNPage/AdvancedTab/Watchtowers/Watchtowers.jsx +++ b/app/components/views/LNPage/AdvancedTab/Watchtowers/Watchtowers.jsx @@ -6,12 +6,8 @@ import { Subtitle } from "shared"; import AddWatchtower from "./AddWatchtower"; const Watchtowers = () => { - const { - addWatchtower, - removeWatchtower, - listWatchtowers, - towersList - } = useWatchtowers(); + const { addWatchtower, removeWatchtower, listWatchtowers, towersList } = + useWatchtowers(); return ( <> diff --git a/app/components/views/LNPage/AdvancedTab/hooks.js b/app/components/views/LNPage/AdvancedTab/hooks.js index d0d8ac07d4..d800ebb263 100644 --- a/app/components/views/LNPage/AdvancedTab/hooks.js +++ b/app/components/views/LNPage/AdvancedTab/hooks.js @@ -2,13 +2,8 @@ import { wallet } from "wallet-preload-shim"; import { useLNPage } from "../hooks"; export function useAdvancedTab() { - const { - exportBackup, - verifyBackup, - info, - scbPath, - scbUpdatedTime - } = useLNPage(); + const { exportBackup, verifyBackup, info, scbPath, scbUpdatedTime } = + useLNPage(); const onBackup = async () => { const { filePath } = await wallet.showSaveDialog(); diff --git a/app/components/views/LNPage/ChannelDetailsPage/hooks.js b/app/components/views/LNPage/ChannelDetailsPage/hooks.js index b540230827..3cc77f36e2 100644 --- a/app/components/views/LNPage/ChannelDetailsPage/hooks.js +++ b/app/components/views/LNPage/ChannelDetailsPage/hooks.js @@ -6,12 +6,8 @@ import { useLNPage } from "../hooks"; export const useChannelDetails = () => { const { channelPoint } = useParams(); - const { - channels, - pendingChannels, - closedChannels, - closeChannel - } = useLNPage(); + const { channels, pendingChannels, closedChannels, closeChannel } = + useLNPage(); const channel = useMemo( () => [...channels, ...pendingChannels, ...closedChannels].find( @@ -21,9 +17,10 @@ export const useChannelDetails = () => { ); const dispatch = useDispatch(); - const goBackHistory = useCallback(() => dispatch(cli.goBackHistory()), [ - dispatch - ]); + const goBackHistory = useCallback( + () => dispatch(cli.goBackHistory()), + [dispatch] + ); const onCloseChannel = (channel) => closeChannel(channel.channelPoint, !channel.active); diff --git a/app/components/views/LNPage/ReceiveTab/hooks.js b/app/components/views/LNPage/ReceiveTab/hooks.js index ca164afb48..4b3ed12e2e 100644 --- a/app/components/views/LNPage/ReceiveTab/hooks.js +++ b/app/components/views/LNPage/ReceiveTab/hooks.js @@ -24,13 +24,8 @@ export function useReceiveTab() { const [selectedInvoice, setSelectedInvoice] = useState(null); const intl = useIntl(); - const { - invoices, - tsDate, - addInvoiceAttempt, - addInvoice, - cancelInvoice - } = useLNPage(); + const { invoices, tsDate, addInvoiceAttempt, addInvoice, cancelInvoice } = + useLNPage(); const onValueChanged = ({ atomValue }) => setAtomValue(atomValue); diff --git a/app/components/views/LNPage/hooks.js b/app/components/views/LNPage/hooks.js index e0cfb2b1b4..45cb03312a 100644 --- a/app/components/views/LNPage/hooks.js +++ b/app/components/views/LNPage/hooks.js @@ -92,12 +92,14 @@ export function useLNPage() { ), [dispatch] ); - const exportBackup = useCallback((path) => dispatch(lna.exportBackup(path)), [ - dispatch - ]); - const verifyBackup = useCallback((path) => dispatch(lna.verifyBackup(path)), [ - dispatch - ]); + const exportBackup = useCallback( + (path) => dispatch(lna.exportBackup(path)), + [dispatch] + ); + const verifyBackup = useCallback( + (path) => dispatch(lna.verifyBackup(path)), + [dispatch] + ); const cancelInvoice = useCallback( (paymentHash) => dispatch(lna.cancelInvoice(paymentHash)), diff --git a/app/components/views/PrivacyPage/SecurityTab/ValidateAddress/ValidateAddress.jsx b/app/components/views/PrivacyPage/SecurityTab/ValidateAddress/ValidateAddress.jsx index 4e09f10b56..181cdb94ba 100644 --- a/app/components/views/PrivacyPage/SecurityTab/ValidateAddress/ValidateAddress.jsx +++ b/app/components/views/PrivacyPage/SecurityTab/ValidateAddress/ValidateAddress.jsx @@ -3,11 +3,8 @@ import ValidateAddressForm from "./ValidateAddressForm"; import { useValidateAddress } from "./hooks"; const ValidateAddress = () => { - const { - intl, - onValidateAddress, - validateAddressSuccess - } = useValidateAddress(); + const { intl, onValidateAddress, validateAddressSuccess } = + useValidateAddress(); const [address, setAddress] = useState(""); const [error, setError] = useState(null); diff --git a/app/components/views/ProposalDetailsPage/hooks.js b/app/components/views/ProposalDetailsPage/hooks.js index 211c0af46f..3978d21b32 100644 --- a/app/components/views/ProposalDetailsPage/hooks.js +++ b/app/components/views/ProposalDetailsPage/hooks.js @@ -24,10 +24,10 @@ export const useProposalDetailsPage = () => { const proposalsDetails = useSelector(sel.proposalsDetails); const getProposalError = useSelector(sel.getProposalError); - const viewedProposalDetails = useMemo(() => proposalsDetails[token], [ - token, - proposalsDetails - ]); + const viewedProposalDetails = useMemo( + () => proposalsDetails[token], + [token, proposalsDetails] + ); const linkedProposal = useMemo( () => @@ -46,9 +46,10 @@ export const useProposalDetailsPage = () => { (token) => dispatch(gov.getProposalDetails(token)), [dispatch] ); - const goBackHistory = useCallback(() => dispatch(cli.goBackHistory()), [ - dispatch - ]); + const goBackHistory = useCallback( + () => dispatch(cli.goBackHistory()), + [dispatch] + ); const [{ value: votingStatus }, send] = useMachine(fetchMachine, { actions: { diff --git a/app/components/views/SettingsPage/LogsTab/LogsTab.jsx b/app/components/views/SettingsPage/LogsTab/LogsTab.jsx index b8fd47634a..dd84cd6662 100644 --- a/app/components/views/SettingsPage/LogsTab/LogsTab.jsx +++ b/app/components/views/SettingsPage/LogsTab/LogsTab.jsx @@ -24,17 +24,13 @@ const LogsTabBody = ({ setInterval, clearInterval }) => { } = useLogging(); const getLogs = useCallback(async () => { - const [ - rawDcrdLogs, - rawDcrwalletLogs, - decreditonLogsNew, - rawDcrlndLogs - ] = await Promise.all([ - wallet.getDcrdLogs(), - wallet.getDcrwalletLogs(), - wallet.getDecreditonLogs(), - wallet.getDcrlndLogs() - ]); + const [rawDcrdLogs, rawDcrwalletLogs, decreditonLogsNew, rawDcrlndLogs] = + await Promise.all([ + wallet.getDcrdLogs(), + wallet.getDcrwalletLogs(), + wallet.getDecreditonLogs(), + wallet.getDcrlndLogs() + ]); const dcrdLogsNew = Buffer.from(rawDcrdLogs).toString("utf8"); const dcrwalletLogsNew = Buffer.from(rawDcrwalletLogs).toString("utf8"); const dcrlndLogsNew = Buffer.from(rawDcrlndLogs).toString("utf8"); diff --git a/app/components/views/SettingsPage/TutorialsTab/helpers/tutorials.js b/app/components/views/SettingsPage/TutorialsTab/helpers/tutorials.js index 53b0f92c50..83cd3183c6 100644 --- a/app/components/views/SettingsPage/TutorialsTab/helpers/tutorials.js +++ b/app/components/views/SettingsPage/TutorialsTab/helpers/tutorials.js @@ -4,8 +4,7 @@ const tutorials = {}; tutorials.decredIntro = { title: "Decred Intro", - desc: - "Small description of the tutorial in 1-2 sentences. Small description of the tutorial in 1-2 sentences. ", // TODO + desc: "Small description of the tutorial in 1-2 sentences. Small description of the tutorial in 1-2 sentences. ", // TODO thumbnailImage: "decredIntroThumb", slides: [ { @@ -34,8 +33,7 @@ tutorials.decredIntro = { tutorials.ln = { title: "What is Lightning Network?", - desc: - "Small description of the tutorial in 1-2 sentences. Small description of the tutorial in 1-2 sentences. ", // TODO + desc: "Small description of the tutorial in 1-2 sentences. Small description of the tutorial in 1-2 sentences. ", // TODO thumbnailImage: "lnThumb", slides: [ { @@ -109,8 +107,7 @@ tutorials.ln = { tutorials.consensusCode = { title: "Consensus Code", - desc: - "Small description of decredIntroThumbthe tutorial in 1-2 sentences. Small description of the tutorial in 1-2 sentences. ", // TODO + desc: "Small description of decredIntroThumbthe tutorial in 1-2 sentences. Small description of the tutorial in 1-2 sentences. ", // TODO thumbnailImage: "consensusCodeThumb", slides: [ { @@ -126,8 +123,7 @@ tutorials.consensusCode = { tutorials.powPos = { title: "Hybrid PoW/PoS", - desc: - "Small description of the tutorial in 1-2 sentences. Small description of the tutorial in 1-2 sentences. ", // TODO + desc: "Small description of the tutorial in 1-2 sentences. Small description of the tutorial in 1-2 sentences. ", // TODO thumbnailImage: "powPosThumb", slides: [ { @@ -162,8 +158,7 @@ tutorials.powPos = { tutorials.tickets = { title: "Staking and Tickets", - desc: - "Small description of the tutorial in 1-2 sentences. Small description of the tutorial in 1-2 sentences. ", // TODO + desc: "Small description of the tutorial in 1-2 sentences. Small description of the tutorial in 1-2 sentences. ", // TODO thumbnailImage: "ticketsThumb", slides: [ { @@ -198,8 +193,7 @@ tutorials.tickets = { tutorials.staking = { title: "Core Functions of Staking", - desc: - "Small description of the tutorial in 1-2 sentences. Small description of the tutorial in 1-2 sentences. ", // TODO + desc: "Small description of the tutorial in 1-2 sentences. Small description of the tutorial in 1-2 sentences. ", // TODO thumbnailImage: "stakingThumb", slides: [ { @@ -234,8 +228,7 @@ tutorials.staking = { tutorials.lifecycle = { title: "Ticket Lifecycle", - desc: - "Small description of the tutorial in 1-2 sentences. Small description of the tutorial in 1-2 sentences. ", // TODO + desc: "Small description of the tutorial in 1-2 sentences. Small description of the tutorial in 1-2 sentences. ", // TODO thumbnailImage: "lifecycleThumb", slides: [ { @@ -303,8 +296,7 @@ tutorials.lifecycle = { tutorials.consensusVoting = { title: "Consensus Voting", - desc: - "Small description of the tutorial in 1-2 sentences. Small description of the tutorial in 1-2 sentences. ", // TODO + desc: "Small description of the tutorial in 1-2 sentences. Small description of the tutorial in 1-2 sentences. ", // TODO thumbnailImage: "consensusVotingThumb", slides: [ { @@ -354,8 +346,7 @@ tutorials.consensusVoting = { tutorials.blocks = { title: "Block Creation", - desc: - "Small description of the tutorial in 1-2 sentences. Small description of the tutorial in 1-2 sentences. ", // TODO + desc: "Small description of the tutorial in 1-2 sentences. Small description of the tutorial in 1-2 sentences. ", // TODO thumbnailImage: "blocksThumb", slides: [ { @@ -397,8 +388,7 @@ tutorials.blocks = { tutorials.identity = { title: "Identity (Pi/CMS)", - desc: - "Small description of the tutorial in 1-2 sentences. Small description of the tutorial in 1-2 sentences. ", // TODO + desc: "Small description of the tutorial in 1-2 sentences. Small description of the tutorial in 1-2 sentences. ", // TODO slides: [ { label: , // TODO diff --git a/app/components/views/ShutdownPage/hooks.js b/app/components/views/ShutdownPage/hooks.js index b8ffccd562..13cc0eec88 100644 --- a/app/components/views/ShutdownPage/hooks.js +++ b/app/components/views/ShutdownPage/hooks.js @@ -4,9 +4,10 @@ import * as da from "actions/DaemonActions"; export const useShutdown = () => { const dispatch = useDispatch(); - const cleanShutdown = useCallback(() => dispatch(da.cleanShutdown()), [ - dispatch - ]); + const cleanShutdown = useCallback( + () => dispatch(da.cleanShutdown()), + [dispatch] + ); return { cleanShutdown }; }; diff --git a/app/components/views/TicketsPage/MyTicketsTab/MyTicketsTab.jsx b/app/components/views/TicketsPage/MyTicketsTab/MyTicketsTab.jsx index 8d0cb272b2..a563e9dec7 100644 --- a/app/components/views/TicketsPage/MyTicketsTab/MyTicketsTab.jsx +++ b/app/components/views/TicketsPage/MyTicketsTab/MyTicketsTab.jsx @@ -132,10 +132,10 @@ const MyTickets = () => { } }; - const visibleTickets = useMemo(() => tickets.slice(0, index), [ - index, - tickets - ]); + const visibleTickets = useMemo( + () => tickets.slice(0, index), + [index, tickets] + ); const isMounted = useRef(false); useEffect(() => { diff --git a/app/components/views/TicketsPage/PurchaseTab/TicketAutoBuyer/hooks.js b/app/components/views/TicketsPage/PurchaseTab/TicketAutoBuyer/hooks.js index 601f24c78a..df5a61714b 100644 --- a/app/components/views/TicketsPage/PurchaseTab/TicketAutoBuyer/hooks.js +++ b/app/components/views/TicketsPage/PurchaseTab/TicketAutoBuyer/hooks.js @@ -91,9 +91,10 @@ export const useTicketAutoBuyer = () => { [dispatch] ); - const onStopAutoBuyer = useCallback(() => dispatch(ca.ticketBuyerCancel()), [ - dispatch - ]); + const onStopAutoBuyer = useCallback( + () => dispatch(ca.ticketBuyerCancel()), + [dispatch] + ); const getRandomVSP = async (maxFeePercentage) => { let randomVSP; diff --git a/app/components/views/TicketsPage/TicketsPage.jsx b/app/components/views/TicketsPage/TicketsPage.jsx index 28e8a42f81..c848105955 100644 --- a/app/components/views/TicketsPage/TicketsPage.jsx +++ b/app/components/views/TicketsPage/TicketsPage.jsx @@ -83,11 +83,8 @@ const tabs = [ ]; const TicketsPage = () => { - const { - showStakingWarning, - ticketPrice, - onAcceptStakingWarning - } = useTicketsPage(); + const { showStakingWarning, ticketPrice, onAcceptStakingWarning } = + useTicketsPage(); return showStakingWarning ? ( }> diff --git a/app/components/views/TransactionsPage/HistoryTab/HistoryTab.jsx b/app/components/views/TransactionsPage/HistoryTab/HistoryTab.jsx index 73801c415e..ea16d87946 100644 --- a/app/components/views/TransactionsPage/HistoryTab/HistoryTab.jsx +++ b/app/components/views/TransactionsPage/HistoryTab/HistoryTab.jsx @@ -44,9 +44,8 @@ const HistoryTab = () => { const [index, setIndex] = useState(() => Math.min(BATCH_TX_COUNT, transactions.length) ); - const [noMoreTransactionsToShow, setNoMoreTransactionsToShow] = useState( - false - ); + const [noMoreTransactionsToShow, setNoMoreTransactionsToShow] = + useState(false); const { search, listDirection } = transactionsFilter; const isMounted = useRef(false); @@ -63,9 +62,8 @@ const HistoryTab = () => { const [searchText, setSearchText] = useState(search); const [selectedTxTypeKeys, setSelectedTxTypeKeys] = useState(selTxTypeKeys); - const [selectedSortOrderKey, setSelectedSortOrderKey] = useState( - listDirection - ); + const [selectedSortOrderKey, setSelectedSortOrderKey] = + useState(listDirection); const [isChangingFilterTimer, setIsChangingFilterTimer] = useState(null); const loadMoreThreshold = 250 + Math.max(0, window.innerHeight - 765); @@ -150,10 +148,10 @@ const HistoryTab = () => { }); }; - const visibleTransactions = useMemo(() => transactions.slice(0, index), [ - index, - transactions - ]); + const visibleTransactions = useMemo( + () => transactions.slice(0, index), + [index, transactions] + ); return !walletService ? ( diff --git a/app/components/views/TrezorPage/hooks.js b/app/components/views/TrezorPage/hooks.js index c65487fb70..8a8bffc450 100644 --- a/app/components/views/TrezorPage/hooks.js +++ b/app/components/views/TrezorPage/hooks.js @@ -52,24 +52,28 @@ export function useTrezorPage() { [dispatch] ); const wipeDevice = useCallback(() => dispatch(trza.wipeDevice()), [dispatch]); - const recoverDevice = useCallback(() => dispatch(trza.recoverDevice()), [ - dispatch - ]); + const recoverDevice = useCallback( + () => dispatch(trza.recoverDevice()), + [dispatch] + ); const initDevice = useCallback(() => dispatch(trza.initDevice()), [dispatch]); - const backupDevice = useCallback(() => dispatch(trza.backupDevice()), [ - dispatch - ]); + const backupDevice = useCallback( + () => dispatch(trza.backupDevice()), + [dispatch] + ); const updateFirmware = useCallback( (path) => dispatch(trza.updateFirmware(path)), [dispatch] ); - const enableTrezor = useCallback(() => dispatch(trza.enableTrezor()), [ - dispatch - ]); + const enableTrezor = useCallback( + () => dispatch(trza.enableTrezor()), + [dispatch] + ); - const getFeatures = useCallback(() => dispatch(trza.getFeatures()), [ - dispatch - ]); + const getFeatures = useCallback( + () => dispatch(trza.getFeatures()), + [dispatch] + ); useEffect(() => { if (device) { diff --git a/app/components/views/TutorialsPage/PagedTutorial/hooks.js b/app/components/views/TutorialsPage/PagedTutorial/hooks.js index caa40596a7..cd3d42b48b 100644 --- a/app/components/views/TutorialsPage/PagedTutorial/hooks.js +++ b/app/components/views/TutorialsPage/PagedTutorial/hooks.js @@ -6,9 +6,10 @@ import * as ca from "actions/ClientActions"; export const usePagedTutorial = () => { const location = useSelector(sel.location); const dispatch = useDispatch(); - const onGoBackHistory = useCallback(() => dispatch(ca.goBackHistory()), [ - dispatch - ]); + const onGoBackHistory = useCallback( + () => dispatch(ca.goBackHistory()), + [dispatch] + ); return { location, onGoBackHistory diff --git a/app/components/views/TutorialsPage/StandardPage/StandardPage.jsx b/app/components/views/TutorialsPage/StandardPage/StandardPage.jsx index 10a7519935..a9019d67df 100644 --- a/app/components/views/TutorialsPage/StandardPage/StandardPage.jsx +++ b/app/components/views/TutorialsPage/StandardPage/StandardPage.jsx @@ -4,9 +4,8 @@ import { StepIndicator } from "indicators"; import { Documentation } from "shared"; import styles from "./StandardPage.module.css"; -export const MakeStandardPage = (image, docName) => (props) => ( - -); +export const MakeStandardPage = (image, docName) => (props) => + ; const StandardPage = ({ image, diff --git a/app/containers/App/App.jsx b/app/containers/App/App.jsx index a818614d50..c862784613 100644 --- a/app/containers/App/App.jsx +++ b/app/containers/App/App.jsx @@ -14,12 +14,8 @@ import { useApp } from "../hooks"; import styles from "./App.module.css"; const App = () => { - const { - hideAboutModalMacOS, - locale, - aboutModalMacOSVisible, - theme - } = useApp(); + const { hideAboutModalMacOS, locale, aboutModalMacOSVisible, theme } = + useApp(); return ( (...args) => !fn(...args); +export const not = + (fn) => + (...args) => + !fn(...args); export const bool = compose(not, not); -export const or = (...fns) => (...args) => { - let result; - return fns.find((fn) => (result = fn(...args))) ? result : false; -}; -export const and = (...fns) => (...args) => { - let result; - return !fns.find((fn, idx) => - idx === 0 ? !(result = fn(...args)) : !fn(...args) - ) - ? result - : false; -}; +export const or = + (...fns) => + (...args) => { + let result; + return fns.find((fn) => (result = fn(...args))) ? result : false; + }; +export const and = + (...fns) => + (...args) => { + let result; + return !fns.find((fn, idx) => + idx === 0 ? !(result = fn(...args)) : !fn(...args) + ) + ? result + : false; + }; // Currently redux state is not immutable causing issues with real selectors // This is a temporary hack to allow same code style until that is fixed. -export const createSelectorEager = (keyFns, resultFn) => (...args) => - resultFn(...keyFns.map((fn) => fn(...args))); +export const createSelectorEager = + (keyFns, resultFn) => + (...args) => + resultFn(...keyFns.map((fn) => fn(...args))); // Given a hash of keys to functions, creates a selector that returns a map of function results export const selectorMap = (fns) => diff --git a/app/helpers/electronRenderer.js b/app/helpers/electronRenderer.js index 252be00e1c..31de95af5d 100644 --- a/app/helpers/electronRenderer.js +++ b/app/helpers/electronRenderer.js @@ -10,7 +10,10 @@ export const invoke = async (...args) => { // Invocable generates a function that calls invoke for the given channel, // passing all args. -export const invocable = (channel) => (...args) => invoke(channel, ...args); +export const invocable = + (channel) => + (...args) => + invoke(channel, ...args); // This shims a streamed response returned by a gRPC call by using an EventEmitter // instance to proxy events. This is needed to avoid some serialization issues diff --git a/app/hooks/useDaemonStartup.js b/app/hooks/useDaemonStartup.js index dcb642ba41..676aea1f0f 100644 --- a/app/hooks/useDaemonStartup.js +++ b/app/hooks/useDaemonStartup.js @@ -89,30 +89,36 @@ const useDaemonStartup = () => { // general methods // Methods for showing positions when first starting decrediton - const onShowTutorial = useCallback(() => dispatch(da.showTutorial()), [ - dispatch - ]); - const onShowSpvChoice = useCallback(() => dispatch(da.showSpvChoice()), [ - dispatch - ]); - const onShowPrivacy = useCallback(() => dispatch(da.showPrivacy()), [ - dispatch - ]); - const onShowLanguage = useCallback(() => dispatch(da.showLanguage()), [ - dispatch - ]); - const onShowGetStarted = useCallback(() => dispatch(da.showGetStarted()), [ - dispatch - ]); + const onShowTutorial = useCallback( + () => dispatch(da.showTutorial()), + [dispatch] + ); + const onShowSpvChoice = useCallback( + () => dispatch(da.showSpvChoice()), + [dispatch] + ); + const onShowPrivacy = useCallback( + () => dispatch(da.showPrivacy()), + [dispatch] + ); + const onShowLanguage = useCallback( + () => dispatch(da.showLanguage()), + [dispatch] + ); + const onShowGetStarted = useCallback( + () => dispatch(da.showGetStarted()), + [dispatch] + ); // language page const onSelectLanguage = useCallback( (selectedLanguage) => dispatch(da.selectLanguage(selectedLanguage)), [dispatch] ); // spv page - const toggleSpv = useCallback((isSPV) => dispatch(da.toggleSpv(isSPV)), [ - dispatch - ]); + const toggleSpv = useCallback( + (isSPV) => dispatch(da.toggleSpv(isSPV)), + [dispatch] + ); // privacy page const setupStandardPrivacy = useCallback( () => dispatch(da.setupStandardPrivacy()), @@ -123,13 +129,15 @@ const useDaemonStartup = () => { [dispatch] ); // tutorial page - const finishTutorial = useCallback(() => dispatch(da.finishTutorial()), [ - dispatch - ]); + const finishTutorial = useCallback( + () => dispatch(da.finishTutorial()), + [dispatch] + ); // end of general methods - const finishPrivacy = useCallback(() => dispatch(da.finishPrivacy()), [ - dispatch - ]); + const finishPrivacy = useCallback( + () => dispatch(da.finishPrivacy()), + [dispatch] + ); // start daemon and wallet methods const onRetryStartRPC = useCallback( async (privPass, isRetry) => @@ -179,9 +187,10 @@ const useDaemonStartup = () => { (selectedWallet) => dispatch(da.startWallet(selectedWallet)), [dispatch] ); - const onCloseWallet = useCallback(() => dispatch(wla.closeWalletRequest()), [ - dispatch - ]); + const onCloseWallet = useCallback( + () => dispatch(wla.closeWalletRequest()), + [dispatch] + ); const onRemoveWallet = useCallback( (selectedWallet) => dispatch(da.removeWallet(selectedWallet)), [dispatch] @@ -193,22 +202,26 @@ const useDaemonStartup = () => { (selectedWallet) => dispatch(da.createWallet(selectedWallet)), [dispatch] ); - const onGetDcrdLogs = useCallback(() => dispatch(da.getDcrdLastLineLogs()), [ - dispatch - ]); - const getDcrwalletLogs = useCallback(() => dispatch(da.getDcrwalletLogs()), [ - dispatch - ]); + const onGetDcrdLogs = useCallback( + () => dispatch(da.getDcrdLastLineLogs()), + [dispatch] + ); + const getDcrwalletLogs = useCallback( + () => dispatch(da.getDcrwalletLogs()), + [dispatch] + ); const trezorLoadDeviceList = useCallback( () => dispatch(trza.loadDeviceList()), [dispatch] ); - const trezorEnable = useCallback(() => dispatch(trza.enableTrezor()), [ - dispatch - ]); - const trezorDisable = useCallback(() => dispatch(trza.disableTrezor()), [ - dispatch - ]); + const trezorEnable = useCallback( + () => dispatch(trza.enableTrezor()), + [dispatch] + ); + const trezorDisable = useCallback( + () => dispatch(trza.disableTrezor()), + [dispatch] + ); const trezorAlertNoConnectedDevice = useCallback( () => dispatch(trza.alertNoConnectedDevice()), [dispatch] diff --git a/app/hooks/useRescan.js b/app/hooks/useRescan.js index 05db00dba3..0308f75913 100644 --- a/app/hooks/useRescan.js +++ b/app/hooks/useRescan.js @@ -12,12 +12,14 @@ const useRescan = () => { const dispatch = useDispatch(); - const rescanAttempt = useCallback(() => dispatch(ca.rescanAttempt()), [ - dispatch - ]); - const rescanCancel = useCallback(() => dispatch(ca.rescanCancel()), [ - dispatch - ]); + const rescanAttempt = useCallback( + () => dispatch(ca.rescanAttempt()), + [dispatch] + ); + const rescanCancel = useCallback( + () => dispatch(ca.rescanCancel()), + [dispatch] + ); return { rescanRequest, diff --git a/app/hooks/useSettings.js b/app/hooks/useSettings.js index 2c49ef99bc..7a09c2b75e 100644 --- a/app/hooks/useSettings.js +++ b/app/hooks/useSettings.js @@ -63,9 +63,10 @@ const useSettings = () => { [dispatch, isVSPListingEnabled] ); - const onCloseWallet = useCallback(() => dispatch(wla.closeWalletRequest()), [ - dispatch - ]); + const onCloseWallet = useCallback( + () => dispatch(wla.closeWalletRequest()), + [dispatch] + ); const onAddAllowedRequestType = useCallback( (requestType) => dispatch(sa.addAllowedExternalRequest(requestType)), diff --git a/app/hooks/useTrezor.js b/app/hooks/useTrezor.js index aac43e79b8..57a5c70430 100644 --- a/app/hooks/useTrezor.js +++ b/app/hooks/useTrezor.js @@ -37,16 +37,18 @@ const useTrezor = () => { () => dispatch(trza.cancelCurrentOperation()), [dispatch] ); - const onSubmitPin = useCallback((pin) => dispatch(trza.submitPin(pin)), [ - dispatch - ]); + const onSubmitPin = useCallback( + (pin) => dispatch(trza.submitPin(pin)), + [dispatch] + ); const onSubmitPassPhrase = useCallback( (passPhrase) => dispatch(trza.submitPassPhrase(passPhrase)), [dispatch] ); - const onSubmitWord = useCallback((word) => dispatch(trza.submitWord(word)), [ - dispatch - ]); + const onSubmitWord = useCallback( + (word) => dispatch(trza.submitWord(word)), + [dispatch] + ); const onTogglePinProtection = useCallback( () => dispatch(trza.togglePinProtection()), [dispatch] @@ -63,25 +65,30 @@ const useTrezor = () => { (label) => dispatch(trza.changeLabel(label)), [dispatch] ); - const onWipeDevice = useCallback(() => dispatch(trza.wipeDevice()), [ - dispatch - ]); - const onRecoverDevice = useCallback(() => dispatch(trza.recoverDevice()), [ - dispatch - ]); - const onInitDevice = useCallback(() => dispatch(trza.initDevice()), [ - dispatch - ]); - const onBackupDevice = useCallback(() => dispatch(trza.backupDevice()), [ - dispatch - ]); + const onWipeDevice = useCallback( + () => dispatch(trza.wipeDevice()), + [dispatch] + ); + const onRecoverDevice = useCallback( + () => dispatch(trza.recoverDevice()), + [dispatch] + ); + const onInitDevice = useCallback( + () => dispatch(trza.initDevice()), + [dispatch] + ); + const onBackupDevice = useCallback( + () => dispatch(trza.backupDevice()), + [dispatch] + ); const onUpdateFirmware = useCallback( (path) => dispatch(trza.updateFirmware(path)), [dispatch] ); - const onEnableTrezor = useCallback(() => dispatch(trza.enableTrezor()), [ - dispatch - ]); + const onEnableTrezor = useCallback( + () => dispatch(trza.enableTrezor()), + [dispatch] + ); return { isTrezor, diff --git a/app/middleware/grpc/client.js b/app/middleware/grpc/client.js index ab34285551..32427cc2a4 100644 --- a/app/middleware/grpc/client.js +++ b/app/middleware/grpc/client.js @@ -8,46 +8,40 @@ import { getWalletPath } from "main_dev/paths.js"; const proto = require("../walletrpc/api_grpc_pb.js"); const services = grpc.loadPackageDefinition(proto).walletrpc; -const getServiceClient = (clientClass) => ( - isTestNet, - walletPath, - address, - port, - grpcKey, - grpcCert, - cb -) => { - const cert = getWalletCert(getWalletPath(isTestNet, walletPath)); - if (cert == "") { - return cb( - null, - "Unable to load dcrwallet certificate. dcrwallet not running?" - ); - } +const getServiceClient = + (clientClass) => + (isTestNet, walletPath, address, port, grpcKey, grpcCert, cb) => { + const cert = getWalletCert(getWalletPath(isTestNet, walletPath)); + if (cert == "") { + return cb( + null, + "Unable to load dcrwallet certificate. dcrwallet not running?" + ); + } - try { - // dcrwallet sends the key and cert on the same payload after starting. - // So we can use the same value for both of them. - const creds = grpc.credentials.createSsl( - cert, - Buffer.from(grpcKey), - Buffer.from(grpcCert) - ); - const client = new clientClass(address + ":" + port, creds); - const deadline = new Date(); - const deadlineInSeconds = 30; - deadline.setSeconds(deadline.getSeconds() + deadlineInSeconds); - grpc.waitForClientReady(client, deadline, function (err) { - if (err) { - return cb(null, err); - } else { - return cb(client); - } - }); - } catch (err) { - return cb(null, err); - } -}; + try { + // dcrwallet sends the key and cert on the same payload after starting. + // So we can use the same value for both of them. + const creds = grpc.credentials.createSsl( + cert, + Buffer.from(grpcKey), + Buffer.from(grpcCert) + ); + const client = new clientClass(address + ":" + port, creds); + const deadline = new Date(); + const deadlineInSeconds = 30; + deadline.setSeconds(deadline.getSeconds() + deadlineInSeconds); + grpc.waitForClientReady(client, deadline, function (err) { + if (err) { + return cb(null, err); + } else { + return cb(client); + } + }); + } catch (err) { + return cb(null, err); + } + }; export const getWalletService = getServiceClient(services.WalletService); export const getTicketBuyerV2Service = getServiceClient( diff --git a/app/middleware/ln/client.js b/app/middleware/ln/client.js index fcb1afb0c7..d08e095a67 100644 --- a/app/middleware/ln/client.js +++ b/app/middleware/ln/client.js @@ -19,72 +19,70 @@ const wtServices = grpc.loadPackageDefinition(wtProto).wtclientrpc; const apProto = require("./autopilot_grpc_pb.js"); const apServices = grpc.loadPackageDefinition(apProto).autopilotrpc; -const getServiceClient = (clientClass) => async ( - address, - port, - certPath, - macaroonPath -) => { - let macaroon, macaroonCreds; +const getServiceClient = + (clientClass) => async (address, port, certPath, macaroonPath) => { + let macaroon, macaroonCreds; - const readFile = (fname) => - new Promise((resolve, reject) => { - let tries = 0; - const maxTries = 30; - const wait = 1000; + const readFile = (fname) => + new Promise((resolve, reject) => { + let tries = 0; + const maxTries = 30; + const wait = 1000; - const readIfExists = () => { - try { - const file = fs.readFileSync(fname); - resolve(file); - } catch (err) { - tries++; - if (tries < maxTries) { - setTimeout(readIfExists, wait); - return; + const readIfExists = () => { + try { + const file = fs.readFileSync(fname); + resolve(file); + } catch (err) { + tries++; + if (tries < maxTries) { + setTimeout(readIfExists, wait); + return; + } + if (err.code === "ENOENT") { + reject(new Error("file " + fname + " does not exist")); + } else if (err.code === "EACCES") { + reject(new Error("file " + fname + " cannot be opened")); + } else { + reject(new Error("error accessing file " + fname + ": " + err)); + } } - if (err.code === "ENOENT") { - reject(new Error("file " + fname + " does not exist")); - } else if (err.code === "EACCES") { - reject(new Error("file " + fname + " cannot be opened")); - } else { - reject(new Error("error accessing file " + fname + ": " + err)); - } - } - }; - readIfExists(); - }); + }; + readIfExists(); + }); - const cert = await readFile(certPath); + const cert = await readFile(certPath); - if (macaroonPath) { - macaroon = await readFile(macaroonPath); - macaroonCreds = grpc.credentials.createFromMetadataGenerator((args, cb) => { - const metadata = new grpc.Metadata(); - metadata.add("macaroon", macaroon.toString("hex")); - cb(null, metadata); - }); - } + if (macaroonPath) { + macaroon = await readFile(macaroonPath); + macaroonCreds = grpc.credentials.createFromMetadataGenerator( + (args, cb) => { + const metadata = new grpc.Metadata(); + metadata.add("macaroon", macaroon.toString("hex")); + cb(null, metadata); + } + ); + } - const sslCreds = grpc.credentials.createSsl(cert); - const creds = macaroonCreds - ? grpc.credentials.combineChannelCredentials(sslCreds, macaroonCreds) - : sslCreds; + const sslCreds = grpc.credentials.createSsl(cert); + const creds = macaroonCreds + ? grpc.credentials.combineChannelCredentials(sslCreds, macaroonCreds) + : sslCreds; - const client = new clientClass(address + ":" + port, creds); + const client = new clientClass(address + ":" + port, creds); - const deadlineInSeconds = 30; - const deadline = new Date().getTime() + deadlineInSeconds * 1000; - return await new Promise((resolve, reject) => { - grpc.waitForClientReady(client, deadline, function (err) { - if (err) { - reject(err); - } else { - resolve(trackClient(client)); - } + const deadlineInSeconds = 30; + const deadline = new Date().getTime() + deadlineInSeconds * 1000; + return await new Promise((resolve, reject) => { + grpc.waitForClientReady(client, deadline, function (err) { + if (err) { + reject(err); + } else { + resolve(trackClient(client)); + } + }); }); - }); -}; + }; export const getLightningClient = getServiceClient(services.Lightning); export const getWatchtowerClient = getServiceClient( diff --git a/app/selectors.js b/app/selectors.js index 0c3dd2f06d..d368070780 100644 --- a/app/selectors.js +++ b/app/selectors.js @@ -385,10 +385,12 @@ export const locale = createSelector( } ); -export const txURLBuilder = createSelector([network], (network) => (txHash) => - `https://${ - network !== TESTNET ? "dcrdata" : "testnet" - }.decred.org/tx/${txHash}` +export const txURLBuilder = createSelector( + [network], + (network) => (txHash) => + `https://${ + network !== TESTNET ? "dcrdata" : "testnet" + }.decred.org/tx/${txHash}` ); export const blockURLBuilder = createSelector( diff --git a/app/wallet/app.js b/app/wallet/app.js index 9444080d3d..a721158666 100644 --- a/app/wallet/app.js +++ b/app/wallet/app.js @@ -90,36 +90,38 @@ const formatLogArgs = (msg, args) => { // Higher Order Function that wraps the promise-generating function f with log // calls. Calling f() **must** return a promise. -export const withLog = (f, msg, opts = {}) => (...args) => { - if (opts.noArguments) { - log("info", msg); - } else { - const { logMsg } = formatLogArgs(msg, args); - log("info", logMsg); - } +export const withLog = + (f, msg, opts = {}) => + (...args) => { + if (opts.noArguments) { + log("info", msg); + } else { + const { logMsg } = formatLogArgs(msg, args); + log("info", logMsg); + } - return new Promise((resolve, reject) => { - f(...args) - .then((...res) => { - if (res.length === 1 && res[0] === undefined) { - log("debug", `${msg} returned without data`); - } else if (opts.noResponseData) { - log("debug", `${msg} returned [response data omitted]`); - } else { - const { logMsg } = formatLogArgs(`${msg} returned `, res); - log("debug", logMsg); - } - - resolve(...res); - }) - .catch((err) => { - const { logMsg } = formatLogArgs(`${msg} errored `, [err]); - log("error", logMsg); - - reject(err); - }); - }); -}; + return new Promise((resolve, reject) => { + f(...args) + .then((...res) => { + if (res.length === 1 && res[0] === undefined) { + log("debug", `${msg} returned without data`); + } else if (opts.noResponseData) { + log("debug", `${msg} returned [response data omitted]`); + } else { + const { logMsg } = formatLogArgs(`${msg} returned `, res); + log("debug", logMsg); + } + + resolve(...res); + }) + .catch((err) => { + const { logMsg } = formatLogArgs(`${msg} errored `, [err]); + log("error", logMsg); + + reject(err); + }); + }); + }; export const withLogNoArgs = (f, msg, opts = {}) => withLog(f, msg, logOptionNoArgs(opts)); diff --git a/app/wallet/control.js b/app/wallet/control.js index d59bd3d124..0384c38105 100644 --- a/app/wallet/control.js +++ b/app/wallet/control.js @@ -257,7 +257,8 @@ export const constructTransaction = ( request.setRequiredConfirmations(confirmations); request.setOutputSelectionAlgorithm(0); outputs.forEach(({ destination, amount }) => { - const outputDest = new api.ConstructTransactionRequest.OutputDestination(); + const outputDest = + new api.ConstructTransactionRequest.OutputDestination(); const output = new api.ConstructTransactionRequest.Output(); outputDest.setAddress(destination); output.setDestination(outputDest); @@ -266,11 +267,13 @@ export const constructTransaction = ( }); if (change?.script) { - const changeDest = new api.ConstructTransactionRequest.OutputDestination(); + const changeDest = + new api.ConstructTransactionRequest.OutputDestination(); changeDest.setScript(Buffer.from(change.script)); request.setChangeDestination(changeDest); } else if (change?.address) { - const outputDest = new api.ConstructTransactionRequest.OutputDestination(); + const outputDest = + new api.ConstructTransactionRequest.OutputDestination(); outputDest.setAddress(change.address); request.setChangeDestination(outputDest); } diff --git a/app/wallet/loader.js b/app/wallet/loader.js index 01fa5e781b..e1adde4f5f 100644 --- a/app/wallet/loader.js +++ b/app/wallet/loader.js @@ -140,9 +140,7 @@ export const discoverAddresses = log( export const subscribeToBlockNotifications = log( (loader) => new Promise((resolve, reject) => - getClient( - loader - ).subscribeToBlockNotifications( + getClient(loader).subscribeToBlockNotifications( new SubscribeToBlockNotificationsRequest(), (error) => (error ? reject(error) : resolve()) ) diff --git a/app/wallet/service.js b/app/wallet/service.js index 2f44767902..e607f07c15 100644 --- a/app/wallet/service.js +++ b/app/wallet/service.js @@ -33,10 +33,12 @@ import { rawToHex } from "../helpers/byteActions"; -const promisify = (fn) => (...args) => - new Promise((ok, fail) => - fn(...args, (res, err) => (err ? fail(err) : ok(trackClient(res)))) - ); +const promisify = + (fn) => + (...args) => + new Promise((ok, fail) => + fn(...args, (res, err) => (err ? fail(err) : ok(trackClient(res)))) + ); export const getWalletService = promisify(client.getWalletService); export const getTicketBuyerService = promisify(client.getTicketBuyerV2Service); diff --git a/package.json b/package.json index a922f61353..c202829712 100644 --- a/package.json +++ b/package.json @@ -256,7 +256,7 @@ "madge": "^4.0.2", "mini-css-extract-plugin": "^1.4.0", "node-loader": "^1.0.2", - "prettier": "^2.2.1", + "prettier": "2.7.1", "react-intl-translations-manager": "^5.0.0", "redux-logger": "^2.7.4", "source-map-explorer": "^2.5.3", diff --git a/test/unit/actions/AccountMixerActions.spec.js b/test/unit/actions/AccountMixerActions.spec.js index 281694d356..774e1f9303 100644 --- a/test/unit/actions/AccountMixerActions.spec.js +++ b/test/unit/actions/AccountMixerActions.spec.js @@ -129,9 +129,10 @@ beforeEach(() => { set: mockWalletCfgSet })); - mockGetMixerAcctsSpendableBalances = clientActions.getMixerAcctsSpendableBalances = jest.fn( - () => () => Promise.resolve() - ); + mockGetMixerAcctsSpendableBalances = + clientActions.getMixerAcctsSpendableBalances = jest.fn( + () => () => Promise.resolve() + ); mockGetNextAccountAttempt = controlActions.getNextAccountAttempt = jest.fn( (_, accountName) => () => { if (accountName === testMixedAccountName) { @@ -143,9 +144,8 @@ beforeEach(() => { } ); - mockGetCoinjoinOutputspByAcctReq = wallet.getCoinjoinOutputspByAcctReq = jest.fn( - () => Promise.resolve(testGetCoinjoinOutputsByAccResponse) - ); + mockGetCoinjoinOutputspByAcctReq = wallet.getCoinjoinOutputspByAcctReq = + jest.fn(() => Promise.resolve(testGetCoinjoinOutputsByAccResponse)); }); const testGetAccountMixerServiceAttempt = async ( @@ -265,10 +265,8 @@ test("test checkUnmixedAccountBalance - insufficient balance", async () => { }); test("test runAccountMixer start and stop", async () => { - const { - mockLockAccount, - mockUnlockAccount - } = mockUnlockLockAndGetAccountsAttempt(); + const { mockLockAccount, mockUnlockAccount } = + mockUnlockLockAndGetAccountsAttempt(); const events = {}; mockMixerStreamer = { @@ -550,9 +548,8 @@ test("test getCoinjoinOutputspByAcct", async () => { }); test("test getCoinjoinOutputspByAcct - rejected", async () => { - mockGetCoinjoinOutputspByAcctReq = wallet.getCoinjoinOutputspByAcctReq = jest.fn( - () => Promise.reject(testError) - ); + mockGetCoinjoinOutputspByAcctReq = wallet.getCoinjoinOutputspByAcctReq = + jest.fn(() => Promise.reject(testError)); const store = createStore(cloneDeep(initialState)); let receivedError; try { @@ -567,9 +564,8 @@ test("test getCoinjoinOutputspByAcct - rejected", async () => { }); test("test getCoinjoinOutputspByAcct - not valid response from wallet", async () => { - mockGetCoinjoinOutputspByAcctReq = wallet.getCoinjoinOutputspByAcctReq = jest.fn( - () => Promise.resolve({ wrappers_: null }) - ); + mockGetCoinjoinOutputspByAcctReq = wallet.getCoinjoinOutputspByAcctReq = + jest.fn(() => Promise.resolve({ wrappers_: null })); const store = createStore(cloneDeep(initialState)); const result = await store.dispatch( accountMixerActions.getCoinjoinOutputspByAcct() diff --git a/test/unit/actions/ControlActions.spec.js b/test/unit/actions/ControlActions.spec.js index 073a6de477..073026eb27 100644 --- a/test/unit/actions/ControlActions.spec.js +++ b/test/unit/actions/ControlActions.spec.js @@ -93,31 +93,8 @@ const testPublishTransactionResponse = { "865628391fc121d1bd8e7f4542d7f12886e4a1a69216db168864c77359e89662" }; const testScript = [ - 118, - 169, - 20, - 40, - 47, - 141, - 68, - 49, - 252, - 243, - 127, - 23, - 24, - 82, - 210, - 183, - 200, - 29, - 46, - 125, - 230, - 190, - 22, - 136, - 172 + 118, 169, 20, 40, 47, 141, 68, 49, 252, 243, 127, 23, 24, 82, 210, 183, 200, + 29, 46, 125, 230, 190, 22, 136, 172 ]; const testChangeScriptByAccount = { [defaultAccountNumber]: testScript @@ -251,9 +228,8 @@ beforeEach(() => { Promise.resolve(); } ); - mockSetNeedsVSPdProcessTickets = settingsActions.setNeedsVSPdProcessTickets = jest.fn( - () => () => {} - ); + mockSetNeedsVSPdProcessTickets = settingsActions.setNeedsVSPdProcessTickets = + jest.fn(() => () => {}); mockCallbackFunction = jest.fn(() => new Promise((r) => setTimeout(r, 10))); mockPurchaseTickets = wallet.purchaseTickets = jest.fn(() => Promise.resolve({ ticketHashes: [] }) @@ -321,15 +297,13 @@ beforeEach(() => { mockGetPeerInfo = wallet.getPeerInfo = jest.fn(() => Promise.resolve(testPeerInfoResponse) ); - mockOnConfirmationDialogCallbacks = wallet.onConfirmationDialogCallbacks = jest.fn( - () => {} - ); + mockOnConfirmationDialogCallbacks = wallet.onConfirmationDialogCallbacks = + jest.fn(() => {}); mockConstructTransaction = wallet.constructTransaction = jest.fn( () => testConstructTxResponse ); - mockConstructSendAllTransaction = wallet.constructSendAllTransaction = jest.fn( - () => testConstructTxResponse - ); + mockConstructSendAllTransaction = wallet.constructSendAllTransaction = + jest.fn(() => testConstructTxResponse); }); afterEach(() => { @@ -635,10 +609,8 @@ test("test checkAllAccountsEncrypted", async () => { }); test("test monitorLockableAccounts", async () => { - const { - addUnlockedAccount, - mockLockAccount - } = mockUnlockLockAndGetAccountsAttempt(); + const { addUnlockedAccount, mockLockAccount } = + mockUnlockLockAndGetAccountsAttempt(); jest.useFakeTimers(); const store = createStore(cloneDeep({ ...initialState })); @@ -771,10 +743,8 @@ test("test monitorLockableAccounts - lockAccount failed", async () => { }); test("test unlockAcctAndExecFn", async () => { - const { - mockLockAccount, - mockUnlockAccount - } = mockUnlockLockAndGetAccountsAttempt(); + const { mockLockAccount, mockUnlockAccount } = + mockUnlockLockAndGetAccountsAttempt(); const store = createStore(cloneDeep({ ...initialState })); store.dispatch( @@ -800,10 +770,8 @@ test("test unlockAcctAndExecFn", async () => { }); test("test unlockAcctAndExecFn - unknown account", async () => { - const { - mockLockAccount, - mockUnlockAccount - } = mockUnlockLockAndGetAccountsAttempt(); + const { mockLockAccount, mockUnlockAccount } = + mockUnlockLockAndGetAccountsAttempt(); const store = createStore(cloneDeep({ ...initialState })); @@ -838,10 +806,8 @@ test("test unlockAcctAndExecFn - unknown account", async () => { }); test("test unlockAcctAndExecFn - unencrypted account", async () => { - const { - mockLockAccount, - mockUnlockAccount - } = mockUnlockLockAndGetAccountsAttempt(); + const { mockLockAccount, mockUnlockAccount } = + mockUnlockLockAndGetAccountsAttempt(); const store = createStore(cloneDeep({ ...initialState })); @@ -875,11 +841,8 @@ test("test unlockAcctAndExecFn - unencrypted account", async () => { }); test("test unlockAcctAndExecFn - callback function failed, lock after, multi accounts", async () => { - const { - mockLockAccount, - mockUnlockAccount, - mockGetAccountsAttempt - } = mockUnlockLockAndGetAccountsAttempt(); + const { mockLockAccount, mockUnlockAccount, mockGetAccountsAttempt } = + mockUnlockLockAndGetAccountsAttempt(); mockCallbackFunction = jest.fn( () => new Promise((_, reject) => setTimeout(reject(testError), 10)) @@ -932,10 +895,8 @@ test("test unlockAcctAndExecFn - callback function failed, lock after, multi acc }); test("test unlockAcctAndExecFn - callback function failed, leave unlock", async () => { - const { - mockLockAccount, - mockUnlockAccount - } = mockUnlockLockAndGetAccountsAttempt(); + const { mockLockAccount, mockUnlockAccount } = + mockUnlockLockAndGetAccountsAttempt(); mockCallbackFunction = jest.fn( () => new Promise((_, reject) => setTimeout(reject(testError), 10)) @@ -1066,10 +1027,8 @@ test("test unlockAcctAndExecFn - unlock failed", async () => { }); test("test unlockAcctAndExecFn - does not unlock change account if account mixer is running", async () => { - const { - mockLockAccount, - mockUnlockAccount - } = mockUnlockLockAndGetAccountsAttempt(); + const { mockLockAccount, mockUnlockAccount } = + mockUnlockLockAndGetAccountsAttempt(); const store = createStore( cloneDeep({ @@ -1140,10 +1099,8 @@ test("test unlockAcctAndExecFn - relock failed - get accounts failed", async () }); test("test purchase tickets - in a private wallet, mixer is not running", async () => { - const { - mockLockAccount, - mockUnlockAccount - } = mockUnlockLockAndGetAccountsAttempt(); + const { mockLockAccount, mockUnlockAccount } = + mockUnlockLockAndGetAccountsAttempt(); const store = createStore( cloneDeep({ @@ -1207,10 +1164,8 @@ test("test purchase tickets - in a private wallet, mixer is not running", async }); test("test purchase tickets - failed to unlock account", async () => { - const { - mockLockAccount, - addUnlockedAccount - } = mockUnlockLockAndGetAccountsAttempt(); + const { mockLockAccount, addUnlockedAccount } = + mockUnlockLockAndGetAccountsAttempt(); addUnlockedAccount(changeAccountNumber); const events = {}; @@ -1275,11 +1230,8 @@ test("test purchase tickets - failed to unlock account", async () => { }); test("test purchase tickets - in a private wallet, mixer is running", async () => { - const { - addUnlockedAccount, - mockLockAccount, - mockUnlockAccount - } = mockUnlockLockAndGetAccountsAttempt(); + const { addUnlockedAccount, mockLockAccount, mockUnlockAccount } = + mockUnlockLockAndGetAccountsAttempt(); addUnlockedAccount(changeAccountNumber); const events = {}; @@ -1387,10 +1339,8 @@ test("test purchase tickets - in a private wallet, mixer is running", async () = }); test("test purchase tickets - in a non private wallet", async () => { - const { - mockLockAccount, - mockUnlockAccount - } = mockUnlockLockAndGetAccountsAttempt(); + const { mockLockAccount, mockUnlockAccount } = + mockUnlockLockAndGetAccountsAttempt(); const store = createStore( cloneDeep({ @@ -1432,10 +1382,8 @@ test("test purchase tickets - in a non private wallet", async () => { }); test("test purchase tickets - in a watching wallet", async () => { - const { - mockLockAccount, - mockUnlockAccount - } = mockUnlockLockAndGetAccountsAttempt(); + const { mockLockAccount, mockUnlockAccount } = + mockUnlockLockAndGetAccountsAttempt(); const store = createStore( cloneDeep({ @@ -1535,11 +1483,8 @@ test("test purchase tickets - bought expected number of tickets", async () => { }); test("test purchase tickets - failed ", async () => { - const { - addUnlockedAccount, - mockLockAccount, - mockUnlockAccount - } = mockUnlockLockAndGetAccountsAttempt(); + const { addUnlockedAccount, mockLockAccount, mockUnlockAccount } = + mockUnlockLockAndGetAccountsAttempt(); addUnlockedAccount(changeAccountNumber); const events = {}; @@ -1618,11 +1563,8 @@ test("test purchase tickets - failed ", async () => { }); test("test purchase tickets - failed with insufficient balance", async () => { - const { - addUnlockedAccount, - mockLockAccount, - mockUnlockAccount - } = mockUnlockLockAndGetAccountsAttempt(); + const { addUnlockedAccount, mockLockAccount, mockUnlockAccount } = + mockUnlockLockAndGetAccountsAttempt(); addUnlockedAccount(changeAccountNumber); const events = {}; @@ -1904,10 +1846,8 @@ test("test start ticket autobuyer in a non-private wallet - receive unknown erro }); test("test signMessageAttempt", async () => { - const { - mockLockAccount, - mockUnlockAccount - } = mockUnlockLockAndGetAccountsAttempt(); + const { mockLockAccount, mockUnlockAccount } = + mockUnlockLockAndGetAccountsAttempt(); const store = createStore(cloneDeep(initialState)); await store.dispatch( @@ -1947,10 +1887,8 @@ test("test signMessageAttempt - validateAddress failed", async () => { mockValidateAddress = wallet.validateAddress = jest.fn(() => { throw testError; }); - const { - mockLockAccount, - mockUnlockAccount - } = mockUnlockLockAndGetAccountsAttempt(); + const { mockLockAccount, mockUnlockAccount } = + mockUnlockLockAndGetAccountsAttempt(); const store = createStore(cloneDeep(initialState)); await store.dispatch( @@ -1973,10 +1911,8 @@ test("test signMessageAttempt - validateAddress failed", async () => { }); test("test signMessageAttempt - signMessage failed", async () => { - const { - mockLockAccount, - mockUnlockAccount - } = mockUnlockLockAndGetAccountsAttempt(); + const { mockLockAccount, mockUnlockAccount } = + mockUnlockLockAndGetAccountsAttempt(); mockSignMessage = wallet.signMessage = jest.fn(() => { throw testError; @@ -2478,10 +2414,8 @@ test("test changePassphraseAttempt - failed", async () => { }); test("test signTransactionAttempt", async () => { - const { - mockLockAccount, - mockUnlockAccount - } = mockUnlockLockAndGetAccountsAttempt(); + const { mockLockAccount, mockUnlockAccount } = + mockUnlockLockAndGetAccountsAttempt(); const store = createStore( cloneDeep({ ...initialState, @@ -2571,10 +2505,8 @@ test("test signTransactionAttempt - failed", async () => { throw testError; }); - const { - mockLockAccount, - mockUnlockAccount - } = mockUnlockLockAndGetAccountsAttempt(); + const { mockLockAccount, mockUnlockAccount } = + mockUnlockLockAndGetAccountsAttempt(); const store = createStore(cloneDeep(initialState)); await store.dispatch( controlActions.signTransactionAttempt( @@ -2612,10 +2544,8 @@ test("test signTransactionAttempt publish transaction failed", async () => { mockPublishTransaction = wallet.publishTransaction = jest.fn(() => Promise.reject(testError) ); - const { - mockLockAccount, - mockUnlockAccount - } = mockUnlockLockAndGetAccountsAttempt(); + const { mockLockAccount, mockUnlockAccount } = + mockUnlockLockAndGetAccountsAttempt(); const store = createStore(cloneDeep(initialState)); await store.dispatch( controlActions.signTransactionAttempt( @@ -2999,12 +2929,11 @@ test("test setAccountsPass - failed", async () => { test("test listenForConfirmationDialogRequests", async () => { let requestedCb; let hiddenCb; - mockOnConfirmationDialogCallbacks = wallet.onConfirmationDialogCallbacks = jest.fn( - (rcb, hcb) => { + mockOnConfirmationDialogCallbacks = wallet.onConfirmationDialogCallbacks = + jest.fn((rcb, hcb) => { requestedCb = rcb; hiddenCb = hcb; - } - ); + }); const store = createStore(cloneDeep(initialState)); await store.dispatch(controlActions.listenForConfirmationDialogRequests()); diff --git a/test/unit/actions/DaemonActions.spec.js b/test/unit/actions/DaemonActions.spec.js index c2f639d11f..971a8ca48f 100644 --- a/test/unit/actions/DaemonActions.spec.js +++ b/test/unit/actions/DaemonActions.spec.js @@ -274,9 +274,8 @@ beforeEach(() => { Promise.resolve(testReleaseFetchReponse) ); mockWalletLog = wallet.log = jest.fn(() => {}); - mockUpdateStateSettingsChanged = settingsActions.updateStateSettingsChanged = jest.fn( - () => () => {} - ); + mockUpdateStateSettingsChanged = settingsActions.updateStateSettingsChanged = + jest.fn(() => () => {}); mockSaveSettings = settingsActions.saveSettings = jest.fn(() => () => {}); mockStartDaemon = wallet.startDaemon = jest.fn(() => Promise.resolve(testDaemonStartResponse) @@ -310,9 +309,8 @@ beforeEach(() => { Promise.resolve(testStartWalletResponse) ); mockSetPreviousWallet = wallet.setPreviousWallet = jest.fn(() => {}); - mockGetVersionServiceAttempt = versionActions.getVersionServiceAttempt = jest.fn( - () => () => {} - ); + mockGetVersionServiceAttempt = versionActions.getVersionServiceAttempt = + jest.fn(() => () => {}); mockOpenWalletAttempt = walletLoaderActions.openWalletAttempt = jest.fn( () => () => {} ); diff --git a/test/unit/actions/DexActions.spec.js b/test/unit/actions/DexActions.spec.js index 697dc00ae4..e098c340a7 100644 --- a/test/unit/actions/DexActions.spec.js +++ b/test/unit/actions/DexActions.spec.js @@ -82,9 +82,8 @@ beforeEach(() => { set: mockWalletCfgSet }); helpers.makeRandomString = jest.fn(() => testRandomString); - mockAddAllowedExternalRequest = settingsActions.addAllowedExternalRequest = jest.fn( - () => () => {} - ); + mockAddAllowedExternalRequest = settingsActions.addAllowedExternalRequest = + jest.fn(() => () => {}); mockCloseWalletRequest = walletLoaderActions.closeWalletRequest = jest.fn( () => () => {} ); diff --git a/test/unit/actions/SettingsActions.spec.js b/test/unit/actions/SettingsActions.spec.js index c29331383e..8c6781aac2 100644 --- a/test/unit/actions/SettingsActions.spec.js +++ b/test/unit/actions/SettingsActions.spec.js @@ -122,15 +122,12 @@ beforeEach(() => { set: mockGlobalCfgSet })); mockChangeMenuLocale = wallet.changeMenuLocale = jest.fn(() => {}); - mockReloadAllowedExternalRequests = wallet.reloadAllowedExternalRequests = jest.fn( - () => {} - ); - mockGetTokenAndInitialBatch = governanceActions.getTokenAndInitialBatch = jest.fn( - () => () => {} - ); - mockResetInventoryAndProposals = governanceActions.resetInventoryAndProposals = jest.fn( - () => () => {} - ); + mockReloadAllowedExternalRequests = wallet.reloadAllowedExternalRequests = + jest.fn(() => {}); + mockGetTokenAndInitialBatch = governanceActions.getTokenAndInitialBatch = + jest.fn(() => () => {}); + mockResetInventoryAndProposals = + governanceActions.resetInventoryAndProposals = jest.fn(() => () => {}); mockGetTreasuryBalance = clientActions.getTreasuryBalance = jest.fn( () => () => {} diff --git a/test/unit/actions/TransactionActions.spec.js b/test/unit/actions/TransactionActions.spec.js index e4de62cf00..33362d01bf 100644 --- a/test/unit/actions/TransactionActions.spec.js +++ b/test/unit/actions/TransactionActions.spec.js @@ -243,12 +243,12 @@ beforeEach(() => { mockGetStakeInfoAttempt = clientActions.getStakeInfoAttempt = jest.fn( () => () => Promise.resolve() ); - mockCheckUnmixedAccountBalance = accountMixerActions.checkUnmixedAccountBalance = jest.fn( - () => () => Promise.resolve() - ); - mockGetMixerAcctsSpendableBalances = clientActions.getMixerAcctsSpendableBalances = jest.fn( - () => () => {} - ); + mockCheckUnmixedAccountBalance = + accountMixerActions.checkUnmixedAccountBalance = jest.fn( + () => () => Promise.resolve() + ); + mockGetMixerAcctsSpendableBalances = + clientActions.getMixerAcctsSpendableBalances = jest.fn(() => () => {}); }); test("test transactionNormalizer and ticketNormalizer", async () => { diff --git a/test/unit/components/SideBar/Sidebar.spec.js b/test/unit/components/SideBar/Sidebar.spec.js index 550a62531e..8fa654e536 100644 --- a/test/unit/components/SideBar/Sidebar.spec.js +++ b/test/unit/components/SideBar/Sidebar.spec.js @@ -505,9 +505,8 @@ test("tests tooltip on Logo when accountMixerRunning mode is active", () => { }); test("tests notification icon on the menu link", () => { - const mockNewProposalsStartedVoting = (selectors.newProposalsStartedVoting = jest.fn( - () => true - )); + const mockNewProposalsStartedVoting = (selectors.newProposalsStartedVoting = + jest.fn(() => true)); render(); const { menuLink } = getMenuContentByTestId("menuLinkContent-governance"); expect(menuLink).toHaveClass("notificationIcon"); @@ -516,9 +515,8 @@ test("tests notification icon on the menu link", () => { }); test("tests notification icon on the menu link (newNotYetVotedAgendasCount)", () => { - const mockNewNotYetVotedAgendasCount = (selectors.newNotYetVotedAgendasCount = jest.fn( - () => 3 - )); + const mockNewNotYetVotedAgendasCount = (selectors.newNotYetVotedAgendasCount = + jest.fn(() => 3)); render(); const { menuLink } = getMenuContentByTestId("menuLinkContent-governance"); expect(menuLink).toHaveClass("notificationIcon"); @@ -527,9 +525,8 @@ test("tests notification icon on the menu link (newNotYetVotedAgendasCount)", () }); test("tests notification icon on the menu link (newNotYetVotedActiveProposalsCount)", () => { - const mockNewNotYetVotedActiveProposalsCount = (selectors.newNotYetVotedActiveProposalsCount = jest.fn( - () => 3 - )); + const mockNewNotYetVotedActiveProposalsCount = + (selectors.newNotYetVotedActiveProposalsCount = jest.fn(() => 3)); render(); const { menuLink } = getMenuContentByTestId("menuLinkContent-governance"); expect(menuLink).toHaveClass("notificationIcon"); diff --git a/test/unit/components/buttons/SendTransactionButton.spec.js b/test/unit/components/buttons/SendTransactionButton.spec.js index 872f73a51a..badecc48c7 100644 --- a/test/unit/components/buttons/SendTransactionButton.spec.js +++ b/test/unit/components/buttons/SendTransactionButton.spec.js @@ -23,9 +23,10 @@ let mockIsSendingTransaction; beforeEach(() => { mockOnSubmit = jest.fn(() => {}); - mockSignTransactionAttemptTrezor = trezorActions.signTransactionAttemptTrezor = jest.fn( - () => () => Promise.resolve() - ); + mockSignTransactionAttemptTrezor = + trezorActions.signTransactionAttemptTrezor = jest.fn( + () => () => Promise.resolve() + ); mockSignTransactionAttempt = controlActions.signTransactionAttempt = jest.fn( () => () => Promise.resolve() ); diff --git a/test/unit/components/indicators/AnimatedLinearProgressFull.spec.js b/test/unit/components/indicators/AnimatedLinearProgressFull.spec.js index 87979cb78d..0647ad6ced 100644 --- a/test/unit/components/indicators/AnimatedLinearProgressFull.spec.js +++ b/test/unit/components/indicators/AnimatedLinearProgressFull.spec.js @@ -31,9 +31,10 @@ test("tests default AnimatedLinearProgressFull", () => { const mockGetSelectedWallet = (selectors.getSelectedWallet = jest.fn(() => { return {}; })); - const mockSyncFetchHeadersLastHeaderTime = (selectors.syncFetchHeadersLastHeaderTime = jest.fn( - () => testSyncFetchHeadersLastHeaderTime - )); + const mockSyncFetchHeadersLastHeaderTime = + (selectors.syncFetchHeadersLastHeaderTime = jest.fn( + () => testSyncFetchHeadersLastHeaderTime + )); let mockGetCurrentBlockCount = (selectors.getCurrentBlockCount = jest.fn( () => testCurrentBlockCount @@ -169,8 +170,8 @@ test("dcrwallet log line is shown or log the error to console", async () => { ); // test DcrwalletLogLine error - mockGetDcrwalletLogs = daemonActions.getDcrwalletLogs = jest.fn(() => () => - Promise.reject() + mockGetDcrwalletLogs = daemonActions.getDcrwalletLogs = jest.fn( + () => () => Promise.reject() ); act(() => { jest.advanceTimersByTime(2001); diff --git a/test/unit/components/views/AccountsPage/AccountsPage.spec.js b/test/unit/components/views/AccountsPage/AccountsPage.spec.js index 7aa9ee749f..be663dbbbf 100644 --- a/test/unit/components/views/AccountsPage/AccountsPage.spec.js +++ b/test/unit/components/views/AccountsPage/AccountsPage.spec.js @@ -101,18 +101,19 @@ beforeEach(() => { return {}; }); selectors.getWalletName = jest.fn(() => mockWalletName); - mockGetAccountExtendedKeyAttempt = controlActions.getAccountExtendedKeyAttempt = jest.fn( - (accountNumber) => (dispatch) => { - const res = { - accExtendedPubKey: `${mockPubKey}-${accountNumber}`, - accountNumber - }; - return dispatch({ - getAccountExtendedKeyResponse: res, - type: controlActions.GETACCOUNTEXTENDEDKEY_SUCCESS - }); - } - ); + mockGetAccountExtendedKeyAttempt = + controlActions.getAccountExtendedKeyAttempt = jest.fn( + (accountNumber) => (dispatch) => { + const res = { + accExtendedPubKey: `${mockPubKey}-${accountNumber}`, + accountNumber + }; + return dispatch({ + getAccountExtendedKeyResponse: res, + type: controlActions.GETACCOUNTEXTENDEDKEY_SUCCESS + }); + } + ); mockRenameAccountAttempt = controlActions.renameAccountAttempt = jest.fn( () => () => {} ); diff --git a/test/unit/components/views/DexPage/DexPage.spec.js b/test/unit/components/views/DexPage/DexPage.spec.js index e955657343..77a2979664 100644 --- a/test/unit/components/views/DexPage/DexPage.spec.js +++ b/test/unit/components/views/DexPage/DexPage.spec.js @@ -105,8 +105,8 @@ beforeEach(() => { mockCreateWalletDex = dexActions.createWalletDex = jest.fn(() => () => {}); mockLaunchDexWindow = dexActions.launchDexWindow = jest.fn(() => () => {}); mockLoginDex = dexActions.loginDex = jest.fn(() => () => {}); - mockGetDexLogs = daemonActions.getDexLogs = jest.fn(() => () => - Promise.resolve(testLog) + mockGetDexLogs = daemonActions.getDexLogs = jest.fn( + () => () => Promise.resolve(testLog) ); }); @@ -424,8 +424,8 @@ test("test when dex is ready", async () => { user.click(screen.getByText("Logs")); mockGetDexLogs.mockClear(); - mockGetDexLogs = daemonActions.getDexLogs = jest.fn(() => () => - Promise.resolve(testLog2) + mockGetDexLogs = daemonActions.getDexLogs = jest.fn( + () => () => Promise.resolve(testLog2) ); act(() => { jest.advanceTimersByTime(2001); @@ -442,8 +442,8 @@ test("receive error while getting error", async () => { selectors.dexReady = jest.fn(() => true); jest.useFakeTimers(); - mockGetDexLogs = daemonActions.getDexLogs = jest.fn(() => () => - Promise.reject("error") + mockGetDexLogs = daemonActions.getDexLogs = jest.fn( + () => () => Promise.reject("error") ); render(); diff --git a/test/unit/components/views/GetStaredPage/AdvancedStartup.spec.js b/test/unit/components/views/GetStaredPage/AdvancedStartup.spec.js index ab97306ed4..0a55a28cb8 100644 --- a/test/unit/components/views/GetStaredPage/AdvancedStartup.spec.js +++ b/test/unit/components/views/GetStaredPage/AdvancedStartup.spec.js @@ -44,11 +44,11 @@ beforeEach(() => { mockSetRemoteCredentials = wallet.setRemoteCredentials = jest.fn(() => {}); mockGetAppdataPath = wallet.getAppdataPath = jest.fn(() => ""); mockSetAppdataPath = wallet.setAppdataPath = jest.fn(() => ""); - mockConnectDaemon = daemonActions.connectDaemon = jest.fn(() => () => - Promise.reject(testConnectDaemonErrorMsg) + mockConnectDaemon = daemonActions.connectDaemon = jest.fn( + () => () => Promise.reject(testConnectDaemonErrorMsg) ); - mockStartDaemon = daemonActions.startDaemon = jest.fn(() => () => - Promise.reject(testStartDaemonErrorMsg) + mockStartDaemon = daemonActions.startDaemon = jest.fn( + () => () => Promise.reject(testStartDaemonErrorMsg) ); selectors.stakeTransactions = jest.fn(() => []); }); @@ -73,9 +73,8 @@ test("test remote daemon form", async () => { const rpcUsernameInput = screen.getByPlaceholderText(/rpc username/i); const rpcPasswordInput = screen.getByPlaceholderText(/rpc password/i); - const rpcCertificatePathInput = screen.getByPlaceholderText( - /rpc certificate path/i - ); + const rpcCertificatePathInput = + screen.getByPlaceholderText(/rpc certificate path/i); const rpcHostInput = screen.getByPlaceholderText(/rpc host/i); const rpcPortInput = screen.getByPlaceholderText(/rpc port/i); diff --git a/test/unit/components/views/GetStaredPage/CreateWallet.spec.js b/test/unit/components/views/GetStaredPage/CreateWallet.spec.js index 810b1caba2..ba88768eda 100644 --- a/test/unit/components/views/GetStaredPage/CreateWallet.spec.js +++ b/test/unit/components/views/GetStaredPage/CreateWallet.spec.js @@ -62,27 +62,28 @@ beforeEach(() => { selectors.getDaemonSynced = jest.fn(() => true); selectors.isSPV = jest.fn(() => false); wlActions.getSelectedWallet = jest.fn(() => () => null); - mockCreateWallet = daemonActions.createWallet = jest.fn(() => () => - Promise.resolve(testSelectedWallet) + mockCreateWallet = daemonActions.createWallet = jest.fn( + () => () => Promise.resolve(testSelectedWallet) ); - mockCreateWalletRequest = wlActions.createWalletRequest = jest.fn(() => () => - Promise.reject(testCreateWalletRequestErrorMsg) + mockCreateWalletRequest = wlActions.createWalletRequest = jest.fn( + () => () => Promise.reject(testCreateWalletRequestErrorMsg) ); - mockGenerateSeed = wlActions.generateSeed = jest.fn(() => () => - Promise.resolve({ - seedMnemonic: testSeedMnemonic - }) + mockGenerateSeed = wlActions.generateSeed = jest.fn( + () => () => + Promise.resolve({ + seedMnemonic: testSeedMnemonic + }) ); - mockCancelCreateWallet = wlActions.cancelCreateWallet = jest.fn(() => () => - Promise.resolve() + mockCancelCreateWallet = wlActions.cancelCreateWallet = jest.fn( + () => () => Promise.resolve() ); selectors.maxWalletCount = jest.fn(() => 3); mockCopySeedToClipboard = clientActions.copySeedToClipboard = jest.fn( () => () => true ); - mockDecodeSeed = wlActions.decodeSeed = jest.fn(() => () => - Promise.reject({ toString: () => "DECODE_ERROR" }) + mockDecodeSeed = wlActions.decodeSeed = jest.fn( + () => () => Promise.reject({ toString: () => "DECODE_ERROR" }) ); mockClipboardReadText = wallet.readFromClipboard.mockImplementation( () => testSeedMnemonic @@ -269,10 +270,11 @@ test("test confim seed view", async () => { expect(createWalletButton.disabled).toBeTruthy(); // fix invalid seed word, decode with success - mockDecodeSeed = wlActions.decodeSeed = jest.fn(() => () => - Promise.resolve({ - decodedSeed: testSeedArray - }) + mockDecodeSeed = wlActions.decodeSeed = jest.fn( + () => () => + Promise.resolve({ + decodedSeed: testSeedArray + }) ); await clickOnSeedButton(testSeedArray.length - 1, true); await clickOnSeedButton(testSeedArray.length - 1, false); @@ -285,21 +287,23 @@ test("test confim seed view", async () => { test("test confirm seed view in testnet mode (allows verification skip in dev)", async () => { mockIsTestNet = selectors.isTestNet = jest.fn(() => true); - mockGenerateSeed = wlActions.generateSeed = jest.fn(() => () => - Promise.resolve({ - seedMnemonic: testSeedMnemonic, - seedBytes: 1 - }) + mockGenerateSeed = wlActions.generateSeed = jest.fn( + () => () => + Promise.resolve({ + seedMnemonic: testSeedMnemonic, + seedBytes: 1 + }) ); await goToConfirmView(); const createWalletButton = screen.getByText(/create wallet/i); await testPrivatePassphraseInputs(); - mockDecodeSeed = wlActions.decodeSeed = jest.fn(() => () => - Promise.resolve({ - decodedSeed: testSeedArray - }) + mockDecodeSeed = wlActions.decodeSeed = jest.fn( + () => () => + Promise.resolve({ + decodedSeed: testSeedArray + }) ); await wait(() => expect(createWalletButton.disabled).toBe(false)); @@ -309,10 +313,11 @@ test("test confirm seed view in testnet mode (allows verification skip in dev)", }); test("test typing a valid seed word on existing seed view", async () => { - mockDecodeSeed = wlActions.decodeSeed = jest.fn(() => () => - Promise.resolve({ - decodedSeed: testSeedArray - }) + mockDecodeSeed = wlActions.decodeSeed = jest.fn( + () => () => + Promise.resolve({ + decodedSeed: testSeedArray + }) ); await goToExistingSeedView(); @@ -340,8 +345,8 @@ test("pasting just 32 seed words on existing seed view", async () => { }); test("pasting invalid seed words on existing seed view", async () => { - mockDecodeSeed = wlActions.decodeSeed = jest.fn(() => () => - Promise.reject({ toString: () => MISMATCH_ERROR }) + mockDecodeSeed = wlActions.decodeSeed = jest.fn( + () => () => Promise.reject({ toString: () => MISMATCH_ERROR }) ); await goToExistingSeedView(); @@ -350,13 +355,14 @@ test("pasting invalid seed words on existing seed view", async () => { }); test("pasting valid seed words on existing seed view and receive create wallet request error", async () => { - mockCreateWalletRequest = wlActions.createWalletRequest = jest.fn(() => () => - Promise.reject(testCreateWalletRequestErrorMsg) + mockCreateWalletRequest = wlActions.createWalletRequest = jest.fn( + () => () => Promise.reject(testCreateWalletRequestErrorMsg) ); - mockDecodeSeed = wlActions.decodeSeed = jest.fn(() => () => - Promise.resolve({ - decodedSeed: testSeedArray - }) + mockDecodeSeed = wlActions.decodeSeed = jest.fn( + () => () => + Promise.resolve({ + decodedSeed: testSeedArray + }) ); await goToExistingSeedView(); @@ -379,13 +385,14 @@ test("pasting valid seed words on existing seed view and receive create wallet r }); test("pasting valid seed words on existing seed view and successfully create wallet", async () => { - mockDecodeSeed = wlActions.decodeSeed = jest.fn(() => () => - Promise.resolve({ - decodedSeed: testSeedArray - }) + mockDecodeSeed = wlActions.decodeSeed = jest.fn( + () => () => + Promise.resolve({ + decodedSeed: testSeedArray + }) ); - mockCreateWalletRequest = wlActions.createWalletRequest = jest.fn(() => () => - Promise.resolve(true) + mockCreateWalletRequest = wlActions.createWalletRequest = jest.fn( + () => () => Promise.resolve(true) ); await goToExistingSeedView(); @@ -417,13 +424,14 @@ test("pasting valid seed words on existing seed view and successfully create wal }); test("check passphrase errors on restore view", async () => { - mockDecodeSeed = wlActions.decodeSeed = jest.fn(() => () => - Promise.resolve({ - decodedSeed: testSeedArray - }) + mockDecodeSeed = wlActions.decodeSeed = jest.fn( + () => () => + Promise.resolve({ + decodedSeed: testSeedArray + }) ); - mockCreateWalletRequest = wlActions.createWalletRequest = jest.fn(() => () => - Promise.resolve(true) + mockCreateWalletRequest = wlActions.createWalletRequest = jest.fn( + () => () => Promise.resolve(true) ); await goToExistingSeedView(); @@ -449,13 +457,14 @@ test("check passphrase errors on restore view", async () => { }); test("create wallet button must be disabled if any of the inputs are invalid", async () => { - mockDecodeSeed = wlActions.decodeSeed = jest.fn(() => () => - Promise.resolve({ - decodedSeed: testSeedArray - }) + mockDecodeSeed = wlActions.decodeSeed = jest.fn( + () => () => + Promise.resolve({ + decodedSeed: testSeedArray + }) ); - mockCreateWalletRequest = wlActions.createWalletRequest = jest.fn(() => () => - Promise.resolve(true) + mockCreateWalletRequest = wlActions.createWalletRequest = jest.fn( + () => () => Promise.resolve(true) ); await goToExistingSeedView(); @@ -481,17 +490,18 @@ test("create wallet button must be disabled if any of the inputs are invalid", a expect(createWallet.disabled).toBe(false); // enter invalid seed word into the first input, button should be disabled - mockDecodeSeed = wlActions.decodeSeed = jest.fn(() => () => - Promise.reject({}) + mockDecodeSeed = wlActions.decodeSeed = jest.fn( + () => () => Promise.reject({}) ); fillSeedWordEntryUsingEnterKey(comboboxArray[0], testSeedArray[1]); await wait(() => expect(createWallet).toHaveAttribute("disabled")); // fix, button should be enabled - mockDecodeSeed = wlActions.decodeSeed = jest.fn(() => () => - Promise.resolve({ - decodedSeed: testSeedArray - }) + mockDecodeSeed = wlActions.decodeSeed = jest.fn( + () => () => + Promise.resolve({ + decodedSeed: testSeedArray + }) ); fillSeedWordEntryUsingEnterKey(comboboxArray[0], testSeedArray[0]); await wait(() => expect(createWallet).not.toHaveAttribute("disabled")); @@ -501,8 +511,8 @@ test("test POSITION_ERROR handling on restore view (missing words)", async () => await goToExistingSeedView(); // reject with an empty error object - mockDecodeSeed = wlActions.decodeSeed = jest.fn(() => () => - Promise.reject({}) + mockDecodeSeed = wlActions.decodeSeed = jest.fn( + () => () => Promise.reject({}) ); const comboboxArray = screen.getAllByRole("combobox"); fillSeedWordEntryUsingEnterKey(comboboxArray[0], testSeedArray[0]); @@ -510,10 +520,11 @@ test("test POSITION_ERROR handling on restore view (missing words)", async () => fillSeedWordEntryUsingEnterKey(comboboxArray[1], testSeedArray[1]); expect(screen.getByText("2.").parentNode.className).toMatch(/populated/); - mockDecodeSeed = wlActions.decodeSeed = jest.fn(() => () => - Promise.reject({ - toString: () => `is ${POSITION_ERROR} 2, check for missing words` - }) + mockDecodeSeed = wlActions.decodeSeed = jest.fn( + () => () => + Promise.reject({ + toString: () => `is ${POSITION_ERROR} 2, check for missing words` + }) ); fillSeedWordEntryUsingEnterKey(comboboxArray[2], testSeedArray[2]); await wait(() => @@ -525,8 +536,8 @@ test("test POSITION_ERROR handling on restore view (mismatch error)", async () = await goToExistingSeedView(); // reject with an empty error object - mockDecodeSeed = wlActions.decodeSeed = jest.fn(() => () => - Promise.reject({}) + mockDecodeSeed = wlActions.decodeSeed = jest.fn( + () => () => Promise.reject({}) ); const comboboxArray = screen.getAllByRole("combobox"); fillSeedWordEntryUsingEnterKey(comboboxArray[0], testSeedArray[0]); @@ -534,8 +545,8 @@ test("test POSITION_ERROR handling on restore view (mismatch error)", async () = fillSeedWordEntryUsingEnterKey(comboboxArray[1], testSeedArray[1]); expect(screen.getByText("2.").parentNode.className).toMatch(/populated/); - mockDecodeSeed = wlActions.decodeSeed = jest.fn(() => () => - Promise.reject({ details: MISMATCH_ERROR }) + mockDecodeSeed = wlActions.decodeSeed = jest.fn( + () => () => Promise.reject({ details: MISMATCH_ERROR }) ); fillSeedWordEntryUsingEnterKey(comboboxArray[4], testSeedArray[4]); await wait(() => @@ -556,10 +567,11 @@ test("test POSITION_ERROR handling on restore view (mismatch error)", async () = test("test invalid POSITION_ERROR msg format handling on restore view", async () => { await goToExistingSeedView(); - mockDecodeSeed = wlActions.decodeSeed = jest.fn(() => () => - Promise.reject({ - details: `is ${POSITION_ERROR} at 4, check for missing words` - }) + mockDecodeSeed = wlActions.decodeSeed = jest.fn( + () => () => + Promise.reject({ + details: `is ${POSITION_ERROR} at 4, check for missing words` + }) ); const comboboxArray = screen.getAllByRole("combobox"); fillSeedWordEntryUsingEnterKey(comboboxArray[0], testSeedArray[0]); @@ -605,10 +617,11 @@ test("test hex input tab on restore view", async () => { expect(screen.queryByText(hexSeedWarningMsg)).not.toBeInTheDocument(); // Next tests will require some return value from the mock getDecodedSeed. - mockDecodeSeed = wlActions.decodeSeed = jest.fn(() => () => - Promise.resolve({ - decodedSeed: testCompatibleHexSeed - }) + mockDecodeSeed = wlActions.decodeSeed = jest.fn( + () => () => + Promise.resolve({ + decodedSeed: testCompatibleHexSeed + }) ); // Test valid (but short, incompatible) hex seed. @@ -639,8 +652,8 @@ test("test hex input tab on restore view", async () => { expect(screen.getByText(hexSeedWarningMsg)).toBeInTheDocument(); // The next tests all assume a failed decode. - mockDecodeSeed = wlActions.decodeSeed = jest.fn(() => () => - Promise.reject({}) + mockDecodeSeed = wlActions.decodeSeed = jest.fn( + () => () => Promise.reject({}) ); // Test too long hex seed. diff --git a/test/unit/components/views/GetStaredPage/GetStartedPage.spec.js b/test/unit/components/views/GetStaredPage/GetStartedPage.spec.js index c7210fa616..f290ae588d 100644 --- a/test/unit/components/views/GetStaredPage/GetStartedPage.spec.js +++ b/test/unit/components/views/GetStaredPage/GetStartedPage.spec.js @@ -37,8 +37,8 @@ beforeEach(() => { mockDaemonWarning = selectors.daemonWarning = jest.fn(() => null); mockIsSPV = selectors.isSPV = jest.fn(() => false); mockAppVersion = selectors.appVersion = jest.fn(() => testAppVersion); - mockGetSelectedWallet = wlActions.getSelectedWallet = jest.fn(() => () => - null + mockGetSelectedWallet = wlActions.getSelectedWallet = jest.fn( + () => () => null ); mockGetAvailableWallets = daemonActions.getAvailableWallets = jest.fn( () => () => Promise.resolve({ availableWallets: [], previousWallet: null }) @@ -61,17 +61,17 @@ beforeEach(() => { wallet.getDcrlndLogs = jest.fn(() => Promise.resolve(Buffer.from("", "utf-8")) ); - mockConnectDaemon = daemonActions.connectDaemon = jest.fn(() => () => - Promise.resolve(true) + mockConnectDaemon = daemonActions.connectDaemon = jest.fn( + () => () => Promise.resolve(true) ); - mockStartDaemon = daemonActions.startDaemon = jest.fn(() => () => - Promise.resolve(true) + mockStartDaemon = daemonActions.startDaemon = jest.fn( + () => () => Promise.resolve(true) ); - mockSyncDaemon = daemonActions.syncDaemon = jest.fn(() => () => - Promise.resolve() + mockSyncDaemon = daemonActions.syncDaemon = jest.fn( + () => () => Promise.resolve() ); - mockCheckNetworkMatch = daemonActions.checkNetworkMatch = jest.fn(() => () => - Promise.resolve() + mockCheckNetworkMatch = daemonActions.checkNetworkMatch = jest.fn( + () => () => Promise.resolve() ); selectors.stakeTransactions = jest.fn(() => []); }); @@ -273,8 +273,8 @@ test("start regular daemon and receive sync daemon error", async () => { }; }); const testSyncErrorMsg = { error: "sync-error-msg" }; - mockSyncDaemon = daemonActions.syncDaemon = jest.fn(() => () => - Promise.reject(testSyncErrorMsg) + mockSyncDaemon = daemonActions.syncDaemon = jest.fn( + () => () => Promise.reject(testSyncErrorMsg) ); mockGetDaemonSynced = selectors.getDaemonSynced = jest.fn(() => false); mockIsSPV = selectors.isSPV = jest.fn(() => false); @@ -295,8 +295,8 @@ test("start regular daemon and receive network match error", async () => { }; }); const testNetworkMatchErrorMsg = "network-match-error-msg"; - mockCheckNetworkMatch = daemonActions.checkNetworkMatch = jest.fn(() => () => - Promise.reject(testNetworkMatchErrorMsg) + mockCheckNetworkMatch = daemonActions.checkNetworkMatch = jest.fn( + () => () => Promise.reject(testNetworkMatchErrorMsg) ); mockGetDaemonSynced = selectors.getDaemonSynced = jest.fn(() => false); mockIsSPV = selectors.isSPV = jest.fn(() => false); diff --git a/test/unit/components/views/GetStaredPage/PreCreateWallet.spec.js b/test/unit/components/views/GetStaredPage/PreCreateWallet.spec.js index aecb0fa847..47df248fac 100644 --- a/test/unit/components/views/GetStaredPage/PreCreateWallet.spec.js +++ b/test/unit/components/views/GetStaredPage/PreCreateWallet.spec.js @@ -48,13 +48,14 @@ beforeEach(() => { selectors.isSPV = jest.fn(() => false); wlActions.getSelectedWallet = jest.fn(() => () => null); mockIsTestNet = selectors.isTestNet = jest.fn(() => false); - mockCreateWallet = daemonActions.createWallet = jest.fn(() => () => - Promise.reject(testWalletCreateErrorMsg) + mockCreateWallet = daemonActions.createWallet = jest.fn( + () => () => Promise.reject(testWalletCreateErrorMsg) ); - mockGenerateSeed = wlActions.generateSeed = jest.fn(() => () => - Promise.resolve({ - seedMnemonic: "" - }) + mockGenerateSeed = wlActions.generateSeed = jest.fn( + () => () => + Promise.resolve({ + seedMnemonic: "" + }) ); selectors.maxWalletCount = jest.fn(() => 3); selectors.sortedAvailableWallets = jest.fn(() => { @@ -69,9 +70,10 @@ beforeEach(() => { }); mockEnableTrezor = trezorActions.enableTrezor = jest.fn(() => () => {}); mockDisableTrezor = trezorActions.disableTrezor = jest.fn(() => () => {}); - mockGetWalletCreationMasterPubKey = trezorActions.getWalletCreationMasterPubKey = jest.fn( - () => () => Promise.resolve(testWalletCreationMasterPubKey) - ); + mockGetWalletCreationMasterPubKey = + trezorActions.getWalletCreationMasterPubKey = jest.fn( + () => () => Promise.resolve(testWalletCreationMasterPubKey) + ); mockValidateMasterPubKey = controlActions.validateMasterPubKey = jest.fn( () => () => { return { isValid: false, error: "" }; @@ -79,9 +81,10 @@ beforeEach(() => { ); mockTrezorDevice = selectors.trezorDevice = jest.fn(() => null); mockTrezorConnect = trezorActions.connect = jest.fn(() => () => {}); - mockCreateWatchOnlyWalletRequest = wlActions.createWatchOnlyWalletRequest = jest.fn( - () => () => Promise.reject("rejecting mock createWatchOnlyWalletRequest") - ); + mockCreateWatchOnlyWalletRequest = wlActions.createWatchOnlyWalletRequest = + jest.fn( + () => () => Promise.reject("rejecting mock createWatchOnlyWalletRequest") + ); selectors.stakeTransactions = jest.fn(() => []); }); @@ -115,8 +118,8 @@ test("test when createWallet has been rejected", async () => { }); test("daemon response success through createWallet function and createWalletPage has been reached", async () => { - mockCreateWallet = daemonActions.createWallet = jest.fn(() => () => - Promise.resolve(testSelectedWallet) + mockCreateWallet = daemonActions.createWallet = jest.fn( + () => () => Promise.resolve(testSelectedWallet) ); await goToCreateNewWalletView(); user.type(screen.getByPlaceholderText(/choose a name/i), testWalletName); @@ -242,13 +245,12 @@ test("test watch only control on restore wallet", async () => { await wait(() => expect(mockValidateMasterPubKey).toHaveBeenCalledWith(testValidMasterPubKey) ); - mockCreateWallet = daemonActions.createWallet = jest.fn(() => () => - Promise.resolve(true) + mockCreateWallet = daemonActions.createWallet = jest.fn( + () => () => Promise.resolve(true) ); - mockCreateWatchOnlyWalletRequest = wlActions.createWatchOnlyWalletRequest = jest.fn( - () => () => Promise.resolve() - ); + mockCreateWatchOnlyWalletRequest = wlActions.createWatchOnlyWalletRequest = + jest.fn(() => () => Promise.resolve()); user.click(continueButton); await wait(() => expect(mockCreateWallet).toHaveBeenCalledWith(testRestoreSelectedWallet) @@ -288,11 +290,10 @@ test("test create trezor-backed wallet page (trezor device is connected)", async isWatchingOnly: true }; - mockCreateWatchOnlyWalletRequest = wlActions.createWatchOnlyWalletRequest = jest.fn( - () => () => { + mockCreateWatchOnlyWalletRequest = wlActions.createWatchOnlyWalletRequest = + jest.fn(() => () => { return new Promise((resolve) => setTimeout(() => resolve(), 1)); - } - ); + }); mockCreateWallet = daemonActions.createWallet = jest.fn(() => () => { return Promise.resolve(testRestoreSelectedWallet); }); diff --git a/test/unit/components/views/GetStaredPage/PrivacyPage.spec.js b/test/unit/components/views/GetStaredPage/PrivacyPage.spec.js index 49146867bb..83ef431789 100644 --- a/test/unit/components/views/GetStaredPage/PrivacyPage.spec.js +++ b/test/unit/components/views/GetStaredPage/PrivacyPage.spec.js @@ -25,9 +25,8 @@ beforeEach(() => { mockSetupDisabledPrivacy = daemonActions.setupDisabledPrivacy = jest.fn( () => () => {} ); - mockUpdateStateSettingsChanged = settingsActions.updateStateSettingsChanged = jest.fn( - () => () => {} - ); + mockUpdateStateSettingsChanged = settingsActions.updateStateSettingsChanged = + jest.fn(() => () => {}); mockTempSettings = selectors.tempSettings = jest.fn(() => { return { allowedExternalRequests: [] diff --git a/test/unit/components/views/GetStaredPage/SetMixedAcctPage.spec.js b/test/unit/components/views/GetStaredPage/SetMixedAcctPage.spec.js index d8061e94c8..66ae3cdfe8 100644 --- a/test/unit/components/views/GetStaredPage/SetMixedAcctPage.spec.js +++ b/test/unit/components/views/GetStaredPage/SetMixedAcctPage.spec.js @@ -27,8 +27,8 @@ beforeEach(() => { mockGetCoinjoinOutputspByAcct = amActions.getCoinjoinOutputspByAcct = jest.fn( () => () => Promise.resolve(testCoinjoinSumByAcct) ); - mockSetCoinjoinCfg = amActions.setCoinjoinCfg = jest.fn(() => () => - Promise.resolve(testCoinjoinSumByAcct) + mockSetCoinjoinCfg = amActions.setCoinjoinCfg = jest.fn( + () => () => Promise.resolve(testCoinjoinSumByAcct) ); mockRenameAccountAttempt = controlActions.renameAccountAttempt = jest.fn( () => () => true @@ -53,9 +53,8 @@ test("test SetMixedAcctPage", async () => { `); const mixedAccountCheckboxes = screen.getAllByLabelText(/set mixed account/i); - const unmixedAccountCheckboxes = screen.getAllByLabelText( - /set unmixed account/i - ); + const unmixedAccountCheckboxes = + screen.getAllByLabelText(/set unmixed account/i); expect(mixedAccountCheckboxes.length).toBe(testCoinjoinSumByAcct.length - 1); expect(unmixedAccountCheckboxes.length).toBe( diff --git a/test/unit/components/views/GetStaredPage/WalletSelection.spec.js b/test/unit/components/views/GetStaredPage/WalletSelection.spec.js index 6778bbcd55..09a9401bad 100644 --- a/test/unit/components/views/GetStaredPage/WalletSelection.spec.js +++ b/test/unit/components/views/GetStaredPage/WalletSelection.spec.js @@ -87,21 +87,21 @@ beforeEach(() => { selectors.getDaemonSynced = jest.fn(() => true); mockRemoveWallet = daemonActions.removeWallet = jest.fn(() => () => {}); mockSetSelectedWallet = wlActions.setSelectedWallet = jest.fn(() => () => {}); - mockGetSelectedWallet = wlActions.getSelectedWallet = jest.fn(() => () => - null + mockGetSelectedWallet = wlActions.getSelectedWallet = jest.fn( + () => () => null ); - mockOpenWalletAttempt = wlActions.openWalletAttempt = jest.fn(() => () => - Promise.reject(OPENWALLET_FAILED_INPUT) + mockOpenWalletAttempt = wlActions.openWalletAttempt = jest.fn( + () => () => Promise.reject(OPENWALLET_FAILED_INPUT) ); wlActions.spvSyncAttempt = jest.fn(() => () => Promise.reject()); - mockStartRpcRequestFunc = wlActions.startRpcRequestFunc = jest.fn(() => () => - Promise.reject() + mockStartRpcRequestFunc = wlActions.startRpcRequestFunc = jest.fn( + () => () => Promise.reject() ); mockSetAutoWalletLaunching = wlActions.setAutoWalletLaunching = jest.fn( () => () => {} ); - mockStartWallet = daemonActions.startWallet = jest.fn(() => () => - Promise.resolve() + mockStartWallet = daemonActions.startWallet = jest.fn( + () => () => Promise.resolve() ); mockSortedAvailableWallets = selectors.sortedAvailableWallets = jest.fn( () => testAvailableWallets @@ -192,8 +192,8 @@ test("test editing wallets", async () => { const sleep = (ms) => new Promise((ok) => setTimeout(ok, ms)); const launchWallet = async (ms) => { - mockStartWallet = daemonActions.startWallet = jest.fn(() => () => - Promise.resolve(true) + mockStartWallet = daemonActions.startWallet = jest.fn( + () => () => Promise.resolve(true) ); mockStartRpcRequestFunc = wlActions.startRpcRequestFunc = jest.fn( () => async (dispatch) => { @@ -293,8 +293,8 @@ test("launch an encrypted wallet", async () => { render(); await wait(() => screen.getByText(/welcome to decrediton/i)); - mockStartWallet = daemonActions.startWallet = jest.fn(() => () => - Promise.reject(OPENWALLET_INPUT) + mockStartWallet = daemonActions.startWallet = jest.fn( + () => () => Promise.reject(OPENWALLET_INPUT) ); user.click(screen.getByText(testAvailableWallets[0].value.wallet)); await wait(() => expect(mockStartWallet).toHaveBeenCalled()); @@ -305,9 +305,8 @@ test("launch an encrypted wallet", async () => { ).toMatchInlineSnapshot( '"This wallet is encrypted, please enter the public passphrase to decrypt it."' ); - const publicPassphraseInput = screen.getByPlaceholderText( - /public passphrase/i - ); + const publicPassphraseInput = + screen.getByPlaceholderText(/public passphrase/i); const testInvalidPassphrase = "invalid-passphrase"; const testValidPassphrase = "valid-passphrase"; const openWalletButton = screen.getByText("Open Wallet"); @@ -327,8 +326,8 @@ test("launch an encrypted wallet", async () => { // invalid passphrase & unknown error const UNKNOWN_ERROR = "UNKNOWN_ERROR"; - mockOpenWalletAttempt = wlActions.openWalletAttempt = jest.fn(() => () => - Promise.reject(UNKNOWN_ERROR) + mockOpenWalletAttempt = wlActions.openWalletAttempt = jest.fn( + () => () => Promise.reject(UNKNOWN_ERROR) ); user.type(publicPassphraseInput, testInvalidPassphrase); user.click(openWalletButton); @@ -347,8 +346,8 @@ test("launch an encrypted wallet", async () => { expect(mockOpenWalletAttempt).not.toHaveBeenCalled(); // valid passphrase + submit the form by press enter - mockOpenWalletAttempt = wlActions.openWalletAttempt = jest.fn(() => () => - Promise.resolve(OPENWALLET_SUCCESS) + mockOpenWalletAttempt = wlActions.openWalletAttempt = jest.fn( + () => () => Promise.resolve(OPENWALLET_SUCCESS) ); user.type(publicPassphraseInput, testValidPassphrase + "{enter}"); await wait(() => @@ -363,8 +362,8 @@ test("ask for passphrase if account discovery is needed", async () => { render(); await wait(() => screen.getByText(/welcome to decrediton/i)); - mockStartWallet = daemonActions.startWallet = jest.fn(() => () => - Promise.reject(OPENWALLET_INPUTPRIVPASS) + mockStartWallet = daemonActions.startWallet = jest.fn( + () => () => Promise.reject(OPENWALLET_INPUTPRIVPASS) ); mockStartRpcRequestFunc = wlActions.startRpcRequestFunc = jest.fn( () => (dispatch) => { @@ -374,9 +373,8 @@ test("ask for passphrase if account discovery is needed", async () => { ); user.click(screen.getByText(testAvailableWallets[0].value.wallet)); await wait(() => expect(mockStartWallet).toHaveBeenCalled()); - let privatePassphraseInput = screen.getByPlaceholderText( - /private passphrase/i - ); + let privatePassphraseInput = + screen.getByPlaceholderText(/private passphrase/i); const testInvalidPassphrase = "invalid-passphrase"; const testValidPassphrase = "valid-passphrase"; let continueButton = screen.getByText("Continue"); @@ -409,8 +407,8 @@ test("ask for passphrase if account discovery is needed", async () => { expect(mockStartRpcRequestFunc).not.toHaveBeenCalled(); // valid passphrase + submit the form by press enter - mockStartRpcRequestFunc = wlActions.startRpcRequestFunc = jest.fn(() => () => - Promise.resolve() + mockStartRpcRequestFunc = wlActions.startRpcRequestFunc = jest.fn( + () => () => Promise.resolve() ); user.type(privatePassphraseInput, testValidPassphrase + "{enter}"); await wait(() => @@ -425,19 +423,18 @@ test("launch an encrypted wallet and ask private passphrase too if account disco render(); await wait(() => screen.getByText(/welcome to decrediton/i)); - mockStartWallet = daemonActions.startWallet = jest.fn(() => () => - Promise.reject(OPENWALLET_INPUT) + mockStartWallet = daemonActions.startWallet = jest.fn( + () => () => Promise.reject(OPENWALLET_INPUT) ); - mockOpenWalletAttempt = wlActions.openWalletAttempt = jest.fn(() => () => - Promise.reject(OPENWALLET_INPUTPRIVPASS) + mockOpenWalletAttempt = wlActions.openWalletAttempt = jest.fn( + () => () => Promise.reject(OPENWALLET_INPUTPRIVPASS) ); user.click(screen.getByText(testAvailableWallets[0].value.wallet)); await wait(() => expect(mockStartWallet).toHaveBeenCalled()); - const publicPassphraseInput = screen.getByPlaceholderText( - /public passphrase/i - ); + const publicPassphraseInput = + screen.getByPlaceholderText(/public passphrase/i); const testValidPassphrase = "valid-passphrase"; user.type(publicPassphraseInput, testValidPassphrase + "{enter}"); diff --git a/test/unit/components/views/LNPage/AdvancedTab.spec.js b/test/unit/components/views/LNPage/AdvancedTab.spec.js index 6a65a63c4b..59c7b5ea0e 100644 --- a/test/unit/components/views/LNPage/AdvancedTab.spec.js +++ b/test/unit/components/views/LNPage/AdvancedTab.spec.js @@ -131,8 +131,8 @@ beforeEach(() => { mockExportBackup = lnActions.exportBackup = jest.fn(() => () => {}); mockVerifyBackup = lnActions.verifyBackup = jest.fn(() => () => {}); mockRemoveWatchtower = lnActions.removeWatchtower = jest.fn(() => () => {}); - mockAddWatchtower = lnActions.addWatchtower = jest.fn(() => () => - Promise.resolve() + mockAddWatchtower = lnActions.addWatchtower = jest.fn( + () => () => Promise.resolve() ); mockGetNodeInfo = lnActions.getNodeInfo = jest.fn(() => () => {}); }); diff --git a/test/unit/components/views/LNPage/OverviewTab.spec.js b/test/unit/components/views/LNPage/OverviewTab.spec.js index 6a7fec5dd0..5ece1dd200 100644 --- a/test/unit/components/views/LNPage/OverviewTab.spec.js +++ b/test/unit/components/views/LNPage/OverviewTab.spec.js @@ -59,8 +59,8 @@ beforeEach(() => { selectors.lnTransactions = jest.fn(() => mockTransactions); selectors.lnDescribeGraph = jest.fn(() => mockDescribeGraph); - mockCancelInvoice = lnActions.cancelInvoice = jest.fn(() => () => - Promise.resolve() + mockCancelInvoice = lnActions.cancelInvoice = jest.fn( + () => () => Promise.resolve() ); lnActions.getNetworkInfo = jest.fn(() => () => {}); mockGoToChannelsTab = lnActions.goToChannelsTab = jest.fn(() => () => {}); diff --git a/test/unit/components/views/LNPage/ReceiveTab.spec.js b/test/unit/components/views/LNPage/ReceiveTab.spec.js index 73449f9daf..f3227c1af2 100644 --- a/test/unit/components/views/LNPage/ReceiveTab.spec.js +++ b/test/unit/components/views/LNPage/ReceiveTab.spec.js @@ -25,11 +25,11 @@ beforeEach(() => { selectors.lnChannels = jest.fn(() => mockChannels); selectors.lnChannelBalances = jest.fn(() => mockLnChannelBalance); selectors.lnInvoices = jest.fn(() => mockInvoices); - mockCancelInvoice = lnActions.cancelInvoice = jest.fn(() => () => - Promise.resolve() + mockCancelInvoice = lnActions.cancelInvoice = jest.fn( + () => () => Promise.resolve() ); - mockAddInvoice = lnActions.addInvoice = jest.fn(() => () => - Promise.resolve() + mockAddInvoice = lnActions.addInvoice = jest.fn( + () => () => Promise.resolve() ); }); diff --git a/test/unit/components/views/LNPage/SendTab.spec.js b/test/unit/components/views/LNPage/SendTab.spec.js index ce92539a05..f93fd9dbd6 100644 --- a/test/unit/components/views/LNPage/SendTab.spec.js +++ b/test/unit/components/views/LNPage/SendTab.spec.js @@ -82,11 +82,11 @@ beforeEach(() => { selectors.lnOutstandingPayments = jest.fn(() => mockOutstandingPayments); selectors.lnFailedPayments = jest.fn(() => mockFailedPayment); selectors.lnPayments = jest.fn(() => mockPayments); - mockDecodePayRequest = lnActions.decodePayRequest = jest.fn(() => () => - Promise.resolve(mockValidDecodedPayRequest) + mockDecodePayRequest = lnActions.decodePayRequest = jest.fn( + () => () => Promise.resolve(mockValidDecodedPayRequest) ); - mockSendPayment = lnActions.sendPayment = jest.fn(() => () => - Promise.resolve() + mockSendPayment = lnActions.sendPayment = jest.fn( + () => () => Promise.resolve() ); }); @@ -147,8 +147,8 @@ test("test send form with valid lightning request", async () => { }); test("test send form with expired lightning request (with empty fallbackAddr)", async () => { - mockDecodePayRequest = lnActions.decodePayRequest = jest.fn(() => () => - Promise.resolve(mockExpiredDecodedPayRequest) + mockDecodePayRequest = lnActions.decodePayRequest = jest.fn( + () => () => Promise.resolve(mockExpiredDecodedPayRequest) ); render(); @@ -180,8 +180,8 @@ test("test send form with expired lightning request (with empty fallbackAddr)", test("test send form with invalid lightning request", async () => { const mockErrorResp = "mock-error-resp"; - mockDecodePayRequest = lnActions.decodePayRequest = jest.fn(() => () => - Promise.reject(mockErrorResp) + mockDecodePayRequest = lnActions.decodePayRequest = jest.fn( + () => () => Promise.reject(mockErrorResp) ); render(); diff --git a/test/unit/components/views/PrivacyPage/PrivacyTab.spec.js b/test/unit/components/views/PrivacyPage/PrivacyTab.spec.js index 095819acb4..991840ceaf 100644 --- a/test/unit/components/views/PrivacyPage/PrivacyTab.spec.js +++ b/test/unit/components/views/PrivacyPage/PrivacyTab.spec.js @@ -126,13 +126,11 @@ beforeEach(() => { selectors.getMixedAccountBranch = jest.fn(() => mockMixedAccountBranch); selectors.getAllowSendFromUnmixed = jest.fn(() => false); - mockToggleAllowSendFromUnmixed = accountMixerActions.toggleAllowSendFromUnmixed = jest.fn( - () => () => {} - ); + mockToggleAllowSendFromUnmixed = + accountMixerActions.toggleAllowSendFromUnmixed = jest.fn(() => () => {}); controlActions.getNextAddressAttempt = jest.fn(() => () => {}); - mockConstructTransactionAttempt = controlActions.constructTransactionAttempt = jest.fn( - () => () => {} - ); + mockConstructTransactionAttempt = controlActions.constructTransactionAttempt = + jest.fn(() => () => {}); mockDispatchSingleMessage = snackbarActions.dispatchSingleMessage = jest.fn( () => () => {} ); diff --git a/test/unit/components/views/PrivacyPage/SecurityTab.spec.js b/test/unit/components/views/PrivacyPage/SecurityTab.spec.js index 74d85d2854..2baf282465 100644 --- a/test/unit/components/views/PrivacyPage/SecurityTab.spec.js +++ b/test/unit/components/views/PrivacyPage/SecurityTab.spec.js @@ -28,12 +28,10 @@ beforeEach(() => { mockSignMessageAttempt = controlActions.signMessageAttempt = jest.fn( () => () => {} ); - mockSignMessageAttemptTrezor = trezorActions.signMessageAttemptTrezor = jest.fn( - () => () => {} - ); - mockGetMessageVerificationServiceAttempt = clientAction.getMessageVerificationServiceAttempt = jest.fn( - () => () => {} - ); + mockSignMessageAttemptTrezor = trezorActions.signMessageAttemptTrezor = + jest.fn(() => () => {}); + mockGetMessageVerificationServiceAttempt = + clientAction.getMessageVerificationServiceAttempt = jest.fn(() => () => {}); mockVerifyMessageAttempt = controlActions.verifyMessageAttempt = jest.fn( () => () => {} ); @@ -77,22 +75,23 @@ test("type invalid address to validate", async () => { }); test("type valid, not owned address to validate", async () => { - controlActions.validateAddress = jest.fn(() => () => - Promise.resolve({ - accountNumber: 0, - error: null, - index: 0, - isInternal: false, - isMine: false, - isScript: false, - isValid: true, - payToAddrScript: "", - pkScriptAddrsList: [], - pubKey: "", - pubKeyAddr: "", - scriptType: 0, - sigsRequired: 0 - }) + controlActions.validateAddress = jest.fn( + () => () => + Promise.resolve({ + accountNumber: 0, + error: null, + index: 0, + isInternal: false, + isMine: false, + isScript: false, + isValid: true, + payToAddrScript: "", + pkScriptAddrsList: [], + pubKey: "", + pubKeyAddr: "", + scriptType: 0, + sigsRequired: 0 + }) ); render(); @@ -105,22 +104,23 @@ test("type valid, not owned address to validate", async () => { }); test("type valid, owned address to validate", async () => { - controlActions.validateAddress = jest.fn(() => () => - Promise.resolve({ - accountNumber: 4, - error: null, - index: 57, - isInternal: true, - isMine: true, - isScript: false, - isValid: true, - payToAddrScript: "", - pkScriptAddrsList: [], - pubKey: "", - pubKeyAddr: "", - scriptType: 0, - sigsRequired: 0 - }) + controlActions.validateAddress = jest.fn( + () => () => + Promise.resolve({ + accountNumber: 4, + error: null, + index: 57, + isInternal: true, + isMine: true, + isScript: false, + isValid: true, + payToAddrScript: "", + pkScriptAddrsList: [], + pubKey: "", + pubKeyAddr: "", + scriptType: 0, + sigsRequired: 0 + }) ); render(); @@ -138,22 +138,23 @@ test("type valid, owned address to validate", async () => { test("test signing message", async () => { const testSignature = "test-signature"; selectors.signMessageSignature = jest.fn(() => testSignature); - controlActions.validateAddress = jest.fn(() => () => - Promise.resolve({ - accountNumber: 4, - error: null, - index: 57, - isInternal: true, - isMine: true, - isScript: false, - isValid: true, - payToAddrScript: "", - pkScriptAddrsList: [], - pubKey: "", - pubKeyAddr: "", - scriptType: 0, - sigsRequired: 0 - }) + controlActions.validateAddress = jest.fn( + () => () => + Promise.resolve({ + accountNumber: 4, + error: null, + index: 57, + isInternal: true, + isMine: true, + isScript: false, + isValid: true, + payToAddrScript: "", + pkScriptAddrsList: [], + pubKey: "", + pubKeyAddr: "", + scriptType: 0, + sigsRequired: 0 + }) ); render(); const testAddress = "TsfDLrRkk9ciUuwfp2b8PawwnukYD7yAjGd"; @@ -192,22 +193,23 @@ test("test signing message", async () => { test("test signing message on a trezor-backed wallet", async () => { selectors.isTrezor = jest.fn(() => true); - controlActions.validateAddress = jest.fn(() => () => - Promise.resolve({ - accountNumber: 4, - error: null, - index: 57, - isInternal: true, - isMine: true, - isScript: false, - isValid: true, - payToAddrScript: "", - pkScriptAddrsList: [], - pubKey: "", - pubKeyAddr: "", - scriptType: 0, - sigsRequired: 0 - }) + controlActions.validateAddress = jest.fn( + () => () => + Promise.resolve({ + accountNumber: 4, + error: null, + index: 57, + isInternal: true, + isMine: true, + isScript: false, + isValid: true, + payToAddrScript: "", + pkScriptAddrsList: [], + pubKey: "", + pubKeyAddr: "", + scriptType: 0, + sigsRequired: 0 + }) ); render(); const testAddress = "TsfDLrRkk9ciUuwfp2b8PawwnukYD7yAjGd"; @@ -233,22 +235,23 @@ test("test signing message on a trezor-backed wallet", async () => { }); test("test signing message using address not owning", async () => { - controlActions.validateAddress = jest.fn(() => () => - Promise.resolve({ - accountNumber: 4, - error: null, - index: 57, - isInternal: true, - isMine: false, - isScript: false, - isValid: true, - payToAddrScript: "", - pkScriptAddrsList: [], - pubKey: "", - pubKeyAddr: "", - scriptType: 0, - sigsRequired: 0 - }) + controlActions.validateAddress = jest.fn( + () => () => + Promise.resolve({ + accountNumber: 4, + error: null, + index: 57, + isInternal: true, + isMine: false, + isScript: false, + isValid: true, + payToAddrScript: "", + pkScriptAddrsList: [], + pubKey: "", + pubKeyAddr: "", + scriptType: 0, + sigsRequired: 0 + }) ); render(); const testAddress = "TsfDLrRkk9ciUuwfp2b8PawwnukYD7yAjGd"; @@ -274,22 +277,23 @@ test("test verify message", async () => { valid: true }; }); - controlActions.validateAddress = jest.fn(() => () => - Promise.resolve({ - accountNumber: 4, - error: null, - index: 57, - isInternal: true, - isMine: true, - isScript: false, - isValid: true, - payToAddrScript: "", - pkScriptAddrsList: [], - pubKey: "", - pubKeyAddr: "", - scriptType: 0, - sigsRequired: 0 - }) + controlActions.validateAddress = jest.fn( + () => () => + Promise.resolve({ + accountNumber: 4, + error: null, + index: 57, + isInternal: true, + isMine: true, + isScript: false, + isValid: true, + payToAddrScript: "", + pkScriptAddrsList: [], + pubKey: "", + pubKeyAddr: "", + scriptType: 0, + sigsRequired: 0 + }) ); render(); user.click(getVerifyMessageToggleBt()); @@ -329,22 +333,23 @@ test("test verify invalid message", async () => { valid: false }; }); - controlActions.validateAddress = jest.fn(() => () => - Promise.resolve({ - accountNumber: 4, - error: null, - index: 57, - isInternal: true, - isMine: true, - isScript: false, - isValid: true, - payToAddrScript: "", - pkScriptAddrsList: [], - pubKey: "", - pubKeyAddr: "", - scriptType: 0, - sigsRequired: 0 - }) + controlActions.validateAddress = jest.fn( + () => () => + Promise.resolve({ + accountNumber: 4, + error: null, + index: 57, + isInternal: true, + isMine: true, + isScript: false, + isValid: true, + payToAddrScript: "", + pkScriptAddrsList: [], + pubKey: "", + pubKeyAddr: "", + scriptType: 0, + sigsRequired: 0 + }) ); render(); user.click(getVerifyMessageToggleBt()); diff --git a/test/unit/components/views/SettingsPage/SettingsPage.spec.js b/test/unit/components/views/SettingsPage/SettingsPage.spec.js index 9769c9046a..7e53d4368f 100644 --- a/test/unit/components/views/SettingsPage/SettingsPage.spec.js +++ b/test/unit/components/views/SettingsPage/SettingsPage.spec.js @@ -113,9 +113,8 @@ beforeEach(() => { mockIsTestNet = selectors.isTestNet = jest.fn(() => true); mockIsMainNet = selectors.isMainNet = jest.fn(() => false); - mockIsChangePassPhraseDisabled = selectors.isChangePassPhraseDisabled = jest.fn( - () => false - ); + mockIsChangePassPhraseDisabled = selectors.isChangePassPhraseDisabled = + jest.fn(() => false); mockWalletService = selectors.walletService = jest.fn(() => { return {}; }); @@ -138,9 +137,8 @@ beforeEach(() => { mockGetAccountMixerRunning = selectors.getAccountMixerRunning = jest.fn( () => false ); - mockPurchaseTicketsRequestAttempt = selectors.purchaseTicketsRequestAttempt = jest.fn( - () => false - ); + mockPurchaseTicketsRequestAttempt = selectors.purchaseTicketsRequestAttempt = + jest.fn(() => false); vspActions.discoverAvailableVSPs = jest.fn(() => () => {}); wallet.getVSPTicketsByFeeStatus = jest.fn(() => Promise.resolve({ @@ -260,9 +258,8 @@ test("test close wallet button (account mixer is running) ", async () => { }); test("test close wallet button (still finalizing ticket purchases) ", async () => { - mockPurchaseTicketsRequestAttempt = selectors.purchaseTicketsRequestAttempt = jest.fn( - () => true - ); + mockPurchaseTicketsRequestAttempt = selectors.purchaseTicketsRequestAttempt = + jest.fn(() => true); render(, { initialState: { settings: testSettings @@ -542,9 +539,8 @@ const testCheckBoxInputOnPrivacy = (label, configKey) => { user.click(screen.getByText("Privacy and Security")); const checkbox = screen.getByLabelText(label); - const defaultCheckedValue = testDefaultAllowedExternalRequests.includes( - configKey - ); + const defaultCheckedValue = + testDefaultAllowedExternalRequests.includes(configKey); expect(checkbox.checked).toBe(defaultCheckedValue); @@ -821,9 +817,8 @@ test("test update private passphrase, DEX is active, but dex account is empty st }); test("update private passphrase is disabled", () => { - mockIsChangePassPhraseDisabled = selectors.isChangePassPhraseDisabled = jest.fn( - () => true - ); + mockIsChangePassPhraseDisabled = selectors.isChangePassPhraseDisabled = + jest.fn(() => true); render(, { initialState: { settings: testSettings diff --git a/test/unit/components/views/TicketsPage/MyTicketsTab/MyTicketsTab.spec.js b/test/unit/components/views/TicketsPage/MyTicketsTab/MyTicketsTab.spec.js index 85ca60231d..580558bec5 100644 --- a/test/unit/components/views/TicketsPage/MyTicketsTab/MyTicketsTab.spec.js +++ b/test/unit/components/views/TicketsPage/MyTicketsTab/MyTicketsTab.spec.js @@ -106,9 +106,8 @@ beforeEach(() => { mockGetTransactions = transactionActions.getTransactions = jest.fn( () => () => {} ); - mockToggleGetTransactions = transactionActions.toggleGetTransactions = jest.fn( - () => () => {} - ); + mockToggleGetTransactions = transactionActions.toggleGetTransactions = + jest.fn(() => () => {}); selectors.startRequestHeight = jest.fn(() => 1000); selectors.currentBlockHeight = jest.fn(() => 10000); }); @@ -307,9 +306,8 @@ test("test tickets list", async () => { test("test ticket sorting", async () => { jest.useFakeTimers(); - const mockChangeTransactionsFilter = (transactionActions.changeTicketsFilter = jest.fn( - () => () => {} - )); + const mockChangeTransactionsFilter = (transactionActions.changeTicketsFilter = + jest.fn(() => () => {})); render(, { initialState: cloneDeep(initialState), diff --git a/test/unit/components/views/TicketsPage/PurchaseTab/PurchasePage.spec.js b/test/unit/components/views/TicketsPage/PurchaseTab/PurchasePage.spec.js index fa12a7595d..fb01c88b21 100644 --- a/test/unit/components/views/TicketsPage/PurchaseTab/PurchasePage.spec.js +++ b/test/unit/components/views/TicketsPage/PurchaseTab/PurchasePage.spec.js @@ -84,16 +84,14 @@ beforeEach(() => { selectors.currencyDisplay = jest.fn(() => mockCurrencyDisplay); selectors.blocksNumberToNextTicket = jest.fn(() => 13); selectors.getRememberedVspHost = jest.fn(() => null); - mockAddAllowedExternalRequest = settingsActions.addAllowedExternalRequest = jest.fn( - () => () => {} - ); + mockAddAllowedExternalRequest = settingsActions.addAllowedExternalRequest = + jest.fn(() => () => {}); mockPurchaseTicketsAttempt = controlActions.purchaseTicketsAttempt = jest.fn( () => () => {} ); - mockStartTicketBuyerAttempt = controlActions.startTicketBuyerAttempt = jest.fn( - () => () => {} - ); + mockStartTicketBuyerAttempt = controlActions.startTicketBuyerAttempt = + jest.fn(() => () => {}); mockGetTicketAutoBuyerRunning = selectors.getTicketAutoBuyerRunning = jest.fn( () => false ); diff --git a/test/unit/components/views/TransactionPage/TransactionPage.spec.js b/test/unit/components/views/TransactionPage/TransactionPage.spec.js index 9a4cae717c..17e0a0aa9d 100644 --- a/test/unit/components/views/TransactionPage/TransactionPage.spec.js +++ b/test/unit/components/views/TransactionPage/TransactionPage.spec.js @@ -62,12 +62,10 @@ beforeEach(() => { selectors.getAvailableVSPsPubkeys = jest.fn( () => mockAvailableMainnetVspsPubkeys ); - mockAbandonTransactionAttempt = clientActions.abandonTransactionAttempt = jest.fn( - () => () => {} - ); - mockPublishUnminedTransactionsAttempt = controlActions.publishUnminedTransactionsAttempt = jest.fn( - () => () => {} - ); + mockAbandonTransactionAttempt = clientActions.abandonTransactionAttempt = + jest.fn(() => () => {}); + mockPublishUnminedTransactionsAttempt = + controlActions.publishUnminedTransactionsAttempt = jest.fn(() => () => {}); mockGoBackHistory = clientActions.goBackHistory = jest.fn(() => () => {}); selectors.currentBlockHeight = jest.fn(() => testCurrentBlockHeight); wallet.getTransaction = jest.fn((_, txHash) => { diff --git a/test/unit/components/views/TransactionPage/mocks.js b/test/unit/components/views/TransactionPage/mocks.js index 3e72f0f15d..a44a9358a5 100644 --- a/test/unit/components/views/TransactionPage/mocks.js +++ b/test/unit/components/views/TransactionPage/mocks.js @@ -1039,8 +1039,7 @@ export const mockNormalizedStakeTransactionList = [ blockHash: "0000000bc17d35756d4383c27e91d83bcb5be0f8bf9943675cba87e8223eeb21", index: 0, - hash: - "1472512351262304275125239808423343934577220111166192222712233111195632030000", + hash: "1472512351262304275125239808423343934577220111166192222712233111195632030000", txHash: "843128b4209be24400f5c7452aad43c2a7592979fcce6de22695e501c6a4d3b4", txType: "vote", diff --git a/test/unit/components/views/TransactionPage/mocks_decodedTransactions.js b/test/unit/components/views/TransactionPage/mocks_decodedTransactions.js index 9a8238d8da..8e84a44efe 100644 --- a/test/unit/components/views/TransactionPage/mocks_decodedTransactions.js +++ b/test/unit/components/views/TransactionPage/mocks_decodedTransactions.js @@ -1,192 +1,190 @@ export const mockDecodedTransactions = { - "01000000020000000000000000000000000000000000000000000000000000000000000000ffffffff00ffffffff60ed215decf9ec50b50ff4477db42b1603178dab67e35d59f22b0de16cf4c1650000000001ffffffff0300000000000000000000266a24e4d5021f882b7926497679f68b14dbf77fdd2a901b24560ab297789e00000000803b0e0000000000000000000000086a0601000a0000002302b9940100000000001abb76a91499bf7a5e99c8c00e09ecef371eabd7865bcf5e1188ac0000000000000000029ef841000000000000000000ffffffff02000085097794010000007d330e00060000006a473044022038c9d8cafe8d98a904c72760e29a7f1e3942c9ef398a7384ca7b946517a3f598022016768855eae1edb7297ee52717bb4c1a247e836fce316a1d681026f4bcf9e5240121027bf4538b926d5668452965c44dbf8724b571ee6b3bae2eab59fd6969e6e87f13": { - version: 1, - serType: 0, - numInputs: 2, - inputs: [ - { - prevTxId: - "0000000000000000000000000000000000000000000000000000000000000000", - outputIndex: 4294967295, - outputTree: 0, - sequence: 4294967295, - index: 0, - valueIn: 4323486, - blockHeight: 0, - blockIndex: 4294967295, - sigScript: "0000" - }, - { - prevTxId: - "65c1f46ce10d2bf2595de367ab8d1703162bb47d47f40fb550ecf9ec5d21ed60", - outputIndex: 0, - outputTree: 1, - sequence: 4294967295, - index: 1, - valueIn: 6785796485, - blockHeight: 930685, - blockIndex: 6, - sigScript: - "473044022038c9d8cafe8d98a904c72760e29a7f1e3942c9ef398a7384ca7b946517a3f598022016768855eae1edb7297ee52717bb4c1a247e836fce316a1d681026f4bcf9e5240121027bf4538b926d5668452965c44dbf8724b571ee6b3bae2eab59fd6969e6e87f13" - } - ], - numOutputs: 3, - outputs: [ - { - value: 0, - version: 0, - script: - "6a24e4d5021f882b7926497679f68b14dbf77fdd2a901b24560ab297789e00000000803b0e00", - index: 0, - decodedScript: { - scriptClass: 0, - address: null, - requiredSig: 0, - asm: - "OP_RETURN OP_DATA_36 e4d5021f882b7926497679f68b14dbf77fdd2a901b24560ab297789e00000000803b0e00" + "01000000020000000000000000000000000000000000000000000000000000000000000000ffffffff00ffffffff60ed215decf9ec50b50ff4477db42b1603178dab67e35d59f22b0de16cf4c1650000000001ffffffff0300000000000000000000266a24e4d5021f882b7926497679f68b14dbf77fdd2a901b24560ab297789e00000000803b0e0000000000000000000000086a0601000a0000002302b9940100000000001abb76a91499bf7a5e99c8c00e09ecef371eabd7865bcf5e1188ac0000000000000000029ef841000000000000000000ffffffff02000085097794010000007d330e00060000006a473044022038c9d8cafe8d98a904c72760e29a7f1e3942c9ef398a7384ca7b946517a3f598022016768855eae1edb7297ee52717bb4c1a247e836fce316a1d681026f4bcf9e5240121027bf4538b926d5668452965c44dbf8724b571ee6b3bae2eab59fd6969e6e87f13": + { + version: 1, + serType: 0, + numInputs: 2, + inputs: [ + { + prevTxId: + "0000000000000000000000000000000000000000000000000000000000000000", + outputIndex: 4294967295, + outputTree: 0, + sequence: 4294967295, + index: 0, + valueIn: 4323486, + blockHeight: 0, + blockIndex: 4294967295, + sigScript: "0000" + }, + { + prevTxId: + "65c1f46ce10d2bf2595de367ab8d1703162bb47d47f40fb550ecf9ec5d21ed60", + outputIndex: 0, + outputTree: 1, + sequence: 4294967295, + index: 1, + valueIn: 6785796485, + blockHeight: 930685, + blockIndex: 6, + sigScript: + "473044022038c9d8cafe8d98a904c72760e29a7f1e3942c9ef398a7384ca7b946517a3f598022016768855eae1edb7297ee52717bb4c1a247e836fce316a1d681026f4bcf9e5240121027bf4538b926d5668452965c44dbf8724b571ee6b3bae2eab59fd6969e6e87f13" } - }, - { - value: 0, - version: 0, - script: "6a0601000a000000", - index: 1, - decodedScript: { - scriptClass: 0, - address: null, - requiredSig: 0, - asm: "OP_RETURN OP_DATA_6 01000a000000" + ], + numOutputs: 3, + outputs: [ + { + value: 0, + version: 0, + script: + "6a24e4d5021f882b7926497679f68b14dbf77fdd2a901b24560ab297789e00000000803b0e00", + index: 0, + decodedScript: { + scriptClass: 0, + address: null, + requiredSig: 0, + asm: "OP_RETURN OP_DATA_36 e4d5021f882b7926497679f68b14dbf77fdd2a901b24560ab297789e00000000803b0e00" + } + }, + { + value: 0, + version: 0, + script: "6a0601000a000000", + index: 1, + decodedScript: { + scriptClass: 0, + address: null, + requiredSig: 0, + asm: "OP_RETURN OP_DATA_6 01000a000000" + } + }, + { + value: 6790119971, + version: 0, + script: "bb76a91499bf7a5e99c8c00e09ecef371eabd7865bcf5e1188ac", + index: 2, + decodedScript: { + scriptClass: 7, + address: "Tsf35F2zDqv9EmDC1pTqixwNe5ytxyseRGr", + requiredSig: 1, + asm: "OP_SSGEN OP_DUP OP_HASH160 OP_DATA_20 99bf7a5e99c8c00e09ecef371eabd7865bcf5e11 OP_EQUALVERIFY OP_CHECKSIG" + } } - }, - { - value: 6790119971, - version: 0, - script: "bb76a91499bf7a5e99c8c00e09ecef371eabd7865bcf5e1188ac", - index: 2, - decodedScript: { - scriptClass: 7, - address: "Tsf35F2zDqv9EmDC1pTqixwNe5ytxyseRGr", - requiredSig: 1, - asm: - "OP_SSGEN OP_DUP OP_HASH160 OP_DATA_20 99bf7a5e99c8c00e09ecef371eabd7865bcf5e11 OP_EQUALVERIFY OP_CHECKSIG" + ], + lockTime: 0, + expiry: 0 + }, + "010000000147ecbf246e47f6e9e2616baece2a0d70c63184d09904a22eb2ca438211fc1b9a0000000001ffffffff0158f7f6810100000000001abc76a914c0e4b3a5b5a454e388c6864ae51205223a12dce488ac000000000000000001f0fff6810100000045180a00060000006b483045022100ab8406a6b9bf915b48dd251519d64a7c8cf8019adc370bdd82b8d914e128280a02204ed8d9726d3a0b8186cba70e1dfd28be1ef3d9eb4e94dd412c85bc979b49a878012102ce47d2933e9b7a2fdd867dd95716ffa7674ea15083349c9dfc2f3a29ddb28052": + { + version: 1, + serType: 0, + numInputs: 1, + inputs: [ + { + prevTxId: + "9a1bfc118243cab22ea20499d08431c6700d2aceae6b61e2e9f6476e24bfec47", + outputIndex: 0, + outputTree: 1, + sequence: 4294967295, + index: 0, + valueIn: 6475415536, + blockHeight: 661573, + blockIndex: 6, + sigScript: + "483045022100ab8406a6b9bf915b48dd251519d64a7c8cf8019adc370bdd82b8d914e128280a02204ed8d9726d3a0b8186cba70e1dfd28be1ef3d9eb4e94dd412c85bc979b49a878012102ce47d2933e9b7a2fdd867dd95716ffa7674ea15083349c9dfc2f3a29ddb28052" } - } - ], - lockTime: 0, - expiry: 0 - }, - "010000000147ecbf246e47f6e9e2616baece2a0d70c63184d09904a22eb2ca438211fc1b9a0000000001ffffffff0158f7f6810100000000001abc76a914c0e4b3a5b5a454e388c6864ae51205223a12dce488ac000000000000000001f0fff6810100000045180a00060000006b483045022100ab8406a6b9bf915b48dd251519d64a7c8cf8019adc370bdd82b8d914e128280a02204ed8d9726d3a0b8186cba70e1dfd28be1ef3d9eb4e94dd412c85bc979b49a878012102ce47d2933e9b7a2fdd867dd95716ffa7674ea15083349c9dfc2f3a29ddb28052": { - version: 1, - serType: 0, - numInputs: 1, - inputs: [ - { - prevTxId: - "9a1bfc118243cab22ea20499d08431c6700d2aceae6b61e2e9f6476e24bfec47", - outputIndex: 0, - outputTree: 1, - sequence: 4294967295, - index: 0, - valueIn: 6475415536, - blockHeight: 661573, - blockIndex: 6, - sigScript: - "483045022100ab8406a6b9bf915b48dd251519d64a7c8cf8019adc370bdd82b8d914e128280a02204ed8d9726d3a0b8186cba70e1dfd28be1ef3d9eb4e94dd412c85bc979b49a878012102ce47d2933e9b7a2fdd867dd95716ffa7674ea15083349c9dfc2f3a29ddb28052" - } - ], - numOutputs: 1, - outputs: [ - { - value: 6475413336, - version: 0, - script: "bc76a914c0e4b3a5b5a454e388c6864ae51205223a12dce488ac", - index: 0, - decodedScript: { - scriptClass: 8, - address: "Tsic4BsFzDL1jhR4LTbWS8LvGFgxjqFG3pU", - requiredSig: 1, - asm: - "OP_SSRTX OP_DUP OP_HASH160 OP_DATA_20 c0e4b3a5b5a454e388c6864ae51205223a12dce4 OP_EQUALVERIFY OP_CHECKSIG" + ], + numOutputs: 1, + outputs: [ + { + value: 6475413336, + version: 0, + script: "bc76a914c0e4b3a5b5a454e388c6864ae51205223a12dce488ac", + index: 0, + decodedScript: { + scriptClass: 8, + address: "Tsic4BsFzDL1jhR4LTbWS8LvGFgxjqFG3pU", + requiredSig: 1, + asm: "OP_SSRTX OP_DUP OP_HASH160 OP_DATA_20 c0e4b3a5b5a454e388c6864ae51205223a12dce4 OP_EQUALVERIFY OP_CHECKSIG" + } } - } - ], - lockTime: 0, - expiry: 0 - }, - "01000000020000000000000000000000000000000000000000000000000000000000000000ffffffff00ffffffff574f7189057261e0e816b09306c3dd4ae55146be8d1ce52a4d5c2475fdcf85600000000001ffffffff0300000000000000000000266a2432c8b01145a24d62ff8db613ca24a3b92e2472bac893ad0e864f1c8b00000000a8090e0000000000000000000000086a0601000a00000037fbb8db0200000000001abb76a91453b208495f9fabdfa80b4be10c4d0e488b33f29988ac0000000000000000029c0746000000000000000000ffffffff0200009bf372db0200000022090e00110000006a4730440220481a66bdf843d6fe2f41b0b5ba129cfec694f82bac72602d08998a2a8b792fb2022003b0a2c8ddfcc317fdb5fac33cc0fbff280ce4bc250caef3e94840c79ef60ee301210355174775888e14ed49e50dd0b904e6dca3f6b4595afd9248a020a4aa87ae469e": { - version: 1, - serType: 0, - numInputs: 2, - inputs: [ - { - prevTxId: - "0000000000000000000000000000000000000000000000000000000000000000", - outputIndex: 4294967295, - outputTree: 0, - sequence: 4294967295, - index: 0, - valueIn: 4589468, - blockHeight: 0, - blockIndex: 4294967295, - sigScript: "0000" - }, - { - prevTxId: - "6085cffd75245c4d2ae51c8dbe4651e54addc30693b016e8e061720589714f57", - outputIndex: 0, - outputTree: 1, - sequence: 4294967295, - index: 1, - valueIn: 12271678363, - blockHeight: 919842, - blockIndex: 17, - sigScript: - "4730440220481a66bdf843d6fe2f41b0b5ba129cfec694f82bac72602d08998a2a8b792fb2022003b0a2c8ddfcc317fdb5fac33cc0fbff280ce4bc250caef3e94840c79ef60ee301210355174775888e14ed49e50dd0b904e6dca3f6b4595afd9248a020a4aa87ae469e" - } - ], - numOutputs: 3, - outputs: [ - { - value: 0, - version: 0, - script: - "6a2432c8b01145a24d62ff8db613ca24a3b92e2472bac893ad0e864f1c8b00000000a8090e00", - index: 0, - decodedScript: { - scriptClass: 0, - address: null, - requiredSig: 0, - asm: - "OP_RETURN OP_DATA_36 32c8b01145a24d62ff8db613ca24a3b92e2472bac893ad0e864f1c8b00000000a8090e00" + ], + lockTime: 0, + expiry: 0 + }, + "01000000020000000000000000000000000000000000000000000000000000000000000000ffffffff00ffffffff574f7189057261e0e816b09306c3dd4ae55146be8d1ce52a4d5c2475fdcf85600000000001ffffffff0300000000000000000000266a2432c8b01145a24d62ff8db613ca24a3b92e2472bac893ad0e864f1c8b00000000a8090e0000000000000000000000086a0601000a00000037fbb8db0200000000001abb76a91453b208495f9fabdfa80b4be10c4d0e488b33f29988ac0000000000000000029c0746000000000000000000ffffffff0200009bf372db0200000022090e00110000006a4730440220481a66bdf843d6fe2f41b0b5ba129cfec694f82bac72602d08998a2a8b792fb2022003b0a2c8ddfcc317fdb5fac33cc0fbff280ce4bc250caef3e94840c79ef60ee301210355174775888e14ed49e50dd0b904e6dca3f6b4595afd9248a020a4aa87ae469e": + { + version: 1, + serType: 0, + numInputs: 2, + inputs: [ + { + prevTxId: + "0000000000000000000000000000000000000000000000000000000000000000", + outputIndex: 4294967295, + outputTree: 0, + sequence: 4294967295, + index: 0, + valueIn: 4589468, + blockHeight: 0, + blockIndex: 4294967295, + sigScript: "0000" + }, + { + prevTxId: + "6085cffd75245c4d2ae51c8dbe4651e54addc30693b016e8e061720589714f57", + outputIndex: 0, + outputTree: 1, + sequence: 4294967295, + index: 1, + valueIn: 12271678363, + blockHeight: 919842, + blockIndex: 17, + sigScript: + "4730440220481a66bdf843d6fe2f41b0b5ba129cfec694f82bac72602d08998a2a8b792fb2022003b0a2c8ddfcc317fdb5fac33cc0fbff280ce4bc250caef3e94840c79ef60ee301210355174775888e14ed49e50dd0b904e6dca3f6b4595afd9248a020a4aa87ae469e" } - }, - { - value: 0, - version: 0, - script: "6a0601000a000000", - index: 1, - decodedScript: { - scriptClass: 0, - address: null, - requiredSig: 0, - asm: "OP_RETURN OP_DATA_6 01000a000000" + ], + numOutputs: 3, + outputs: [ + { + value: 0, + version: 0, + script: + "6a2432c8b01145a24d62ff8db613ca24a3b92e2472bac893ad0e864f1c8b00000000a8090e00", + index: 0, + decodedScript: { + scriptClass: 0, + address: null, + requiredSig: 0, + asm: "OP_RETURN OP_DATA_36 32c8b01145a24d62ff8db613ca24a3b92e2472bac893ad0e864f1c8b00000000a8090e00" + } + }, + { + value: 0, + version: 0, + script: "6a0601000a000000", + index: 1, + decodedScript: { + scriptClass: 0, + address: null, + requiredSig: 0, + asm: "OP_RETURN OP_DATA_6 01000a000000" + } + }, + { + value: 12276267831, + version: 0, + script: "bb76a91453b208495f9fabdfa80b4be10c4d0e488b33f29988ac", + index: 2, + decodedScript: { + scriptClass: 7, + address: "TsYefqPSd4tBj2MFBaFirMhPK8hUUhMfa4n", + requiredSig: 1, + asm: "OP_SSGEN OP_DUP OP_HASH160 OP_DATA_20 53b208495f9fabdfa80b4be10c4d0e488b33f299 OP_EQUALVERIFY OP_CHECKSIG" + } } - }, - { - value: 12276267831, - version: 0, - script: "bb76a91453b208495f9fabdfa80b4be10c4d0e488b33f29988ac", - index: 2, - decodedScript: { - scriptClass: 7, - address: "TsYefqPSd4tBj2MFBaFirMhPK8hUUhMfa4n", - requiredSig: 1, - asm: - "OP_SSGEN OP_DUP OP_HASH160 OP_DATA_20 53b208495f9fabdfa80b4be10c4d0e488b33f299 OP_EQUALVERIFY OP_CHECKSIG" - } - } - ], - lockTime: 0, - expiry: 0 - } + ], + lockTime: 0, + expiry: 0 + } }; diff --git a/test/unit/components/views/TransactionPage/mocks_stakeTransactions.js b/test/unit/components/views/TransactionPage/mocks_stakeTransactions.js index 8d562318bc..6aeb13d06b 100644 --- a/test/unit/components/views/TransactionPage/mocks_stakeTransactions.js +++ b/test/unit/components/views/TransactionPage/mocks_stakeTransactions.js @@ -8,8 +8,7 @@ export const mockStakeTransactionList = [ blockHash: "21eb3e22e887ba5c674399bff8e05bcb3bd8917ec283436d75357dc10b000000", index: 0, - hash: - "1472512351262304275125239808423343934577220111166192222712233111195632030000", + hash: "1472512351262304275125239808423343934577220111166192222712233111195632030000", txHash: "843128b4209be24400f5c7452aad43c2a7592979fcce6de22695e501c6a4d3b4", txType: "vote", debitsAmount: 6785796485, diff --git a/test/unit/components/views/TransactionsPage/HistoryTab/HistoryTab.spec.js b/test/unit/components/views/TransactionsPage/HistoryTab/HistoryTab.spec.js index 6e1adfd359..46d5a169bf 100644 --- a/test/unit/components/views/TransactionsPage/HistoryTab/HistoryTab.spec.js +++ b/test/unit/components/views/TransactionsPage/HistoryTab/HistoryTab.spec.js @@ -130,8 +130,8 @@ beforeEach(() => { selectors.constructTxRequestAttempt = jest.fn(() => false); selectors.getRunningIndicator = jest.fn(() => false); selectors.currencyDisplay = jest.fn(() => DCR); - transactionActions.listUnspentOutputs = jest.fn(() => () => - Promise.resolve([]) + transactionActions.listUnspentOutputs = jest.fn( + () => () => Promise.resolve([]) ); mockWalletService = selectors.walletService = jest.fn(() => { return {}; @@ -172,7 +172,8 @@ const incAllTestTxs = (mockGetTransactionsResponse, ts) => { ts || mockGetTransactionsResponse.getRegularTxsAux.lastTransaction.timestamp ); mockGetTransactionsResponse.regularTransactions = txList; - mockGetTransactionsResponse.getRegularTxsAux.lastTransaction = lastTransaction; + mockGetTransactionsResponse.getRegularTxsAux.lastTransaction = + lastTransaction; return mockGetTransactionsResponse; }; @@ -468,9 +469,8 @@ test("show only sent txs which are coming from wallet and not from redux", async test("test tx sorting", async () => { jest.useFakeTimers(); - const mockchangeTransactionsFilter = (transactionActions.changeTransactionsFilter = jest.fn( - () => () => {} - )); + const mockchangeTransactionsFilter = + (transactionActions.changeTransactionsFilter = jest.fn(() => () => {})); render(, { initialState: cloneDeep(initialState) diff --git a/test/unit/components/views/TransactionsPage/ReceiveTab/ReceiveTab.spec.js b/test/unit/components/views/TransactionsPage/ReceiveTab/ReceiveTab.spec.js index 7b43a4e2df..8b714ae177 100644 --- a/test/unit/components/views/TransactionsPage/ReceiveTab/ReceiveTab.spec.js +++ b/test/unit/components/views/TransactionsPage/ReceiveTab/ReceiveTab.spec.js @@ -111,8 +111,8 @@ beforeEach(() => { selectors.nextAddressAccount = jest.fn(() => mockDefaultAccount); selectors.currencyDisplay = jest.fn(() => DCR); - transactionActions.listUnspentOutputs = jest.fn(() => () => - Promise.resolve(mockUnspentOutputs) + transactionActions.listUnspentOutputs = jest.fn( + () => () => Promise.resolve(mockUnspentOutputs) ); mockGenQRCodeSVG = wallet.genQRCodeSVG = jest.fn(() => {}); mockGetNextAddressAttempt = controlActions.getNextAddressAttempt = jest.fn( diff --git a/test/unit/components/views/TransactionsPage/SendTab/SendTab.spec.js b/test/unit/components/views/TransactionsPage/SendTab/SendTab.spec.js index da0423e923..3a81c40773 100644 --- a/test/unit/components/views/TransactionsPage/SendTab/SendTab.spec.js +++ b/test/unit/components/views/TransactionsPage/SendTab/SendTab.spec.js @@ -128,9 +128,8 @@ beforeEach(() => { selectors.constructTxRequestAttempt = jest.fn(() => false); selectors.getRunningIndicator = jest.fn(() => false); selectors.currencyDisplay = jest.fn(() => DCR); - mockConstructTransactionAttempt = controlActions.constructTransactionAttempt = jest.fn( - () => () => {} - ); + mockConstructTransactionAttempt = controlActions.constructTransactionAttempt = + jest.fn(() => () => {}); mockValidateAddress = controlActions.validateAddress = jest.fn(() => () => { return { error: "ERR_INVALID_ADDR_TOOSHORT", @@ -152,8 +151,8 @@ beforeEach(() => { Promise.resolve(res); } ); - transactionActions.listUnspentOutputs = jest.fn(() => () => - Promise.resolve(mockUnspentOutputs) + transactionActions.listUnspentOutputs = jest.fn( + () => () => Promise.resolve(mockUnspentOutputs) ); }); diff --git a/test/unit/components/views/TrezorPage/TrezorPage.spec.js b/test/unit/components/views/TrezorPage/TrezorPage.spec.js index 7eb46d3ab6..1f3ffa2458 100644 --- a/test/unit/components/views/TrezorPage/TrezorPage.spec.js +++ b/test/unit/components/views/TrezorPage/TrezorPage.spec.js @@ -26,15 +26,12 @@ beforeEach(() => { mockTogglePinProtection = trezorActions.togglePinProtection = jest.fn( () => () => {} ); - mockTogglePassphraseProtection = trezorActions.togglePassPhraseProtection = jest.fn( - () => () => {} - ); - mockTogglePassphraseOnDeviceProtection = trezorActions.togglePassphraseOnDevice = jest.fn( - () => () => {} - ); - mockChangeToDecredHomeScreen = trezorActions.changeToDecredHomeScreen = jest.fn( - () => () => {} - ); + mockTogglePassphraseProtection = trezorActions.togglePassPhraseProtection = + jest.fn(() => () => {}); + mockTogglePassphraseOnDeviceProtection = + trezorActions.togglePassphraseOnDevice = jest.fn(() => () => {}); + mockChangeToDecredHomeScreen = trezorActions.changeToDecredHomeScreen = + jest.fn(() => () => {}); mockWipeDevice = trezorActions.wipeDevice = jest.fn(() => () => {}); mockRecoverDevice = trezorActions.recoverDevice = jest.fn(() => () => {}); @@ -171,7 +168,8 @@ test("test passphrase on device protection switch", () => { const features = { passphrase_always_on_device: true }; - const passphraseOnDeviceProtectionLabel = getPassphraseOnDeviceProtectionToggleLabel(); + const passphraseOnDeviceProtectionLabel = + getPassphraseOnDeviceProtectionToggleLabel(); // the control is in loading state expect( diff --git a/test/unit/helpers/date.spec.js b/test/unit/helpers/date.spec.js index 3affb1b43a..b8bc563b50 100644 --- a/test/unit/helpers/date.spec.js +++ b/test/unit/helpers/date.spec.js @@ -18,77 +18,29 @@ function localTime(d) { test("endOfDay works as expected", () => { expect(localTime(endOfDay("2019-02-10 12:23"))).toEqual([ - 2019, - 2, - 10, - 23, - 59, - 59, - 999 + 2019, 2, 10, 23, 59, 59, 999 ]); expect(localTime(endOfDay("2019-02-01 23:59:40"))).toEqual([ - 2019, - 2, - 1, - 23, - 59, - 59, - 999 + 2019, 2, 1, 23, 59, 59, 999 ]); expect(localTime(endOfDay("2019-02-01 23:59:59"))).toEqual([ - 2019, - 2, - 1, - 23, - 59, - 59, - 999 + 2019, 2, 1, 23, 59, 59, 999 ]); expect(localTime(endOfDay("2019-02-02 00:00"))).toEqual([ - 2019, - 2, - 2, - 23, - 59, - 59, - 999 + 2019, 2, 2, 23, 59, 59, 999 ]); expect(localTime(endOfDay(new Date("2019-02-10 12:23")))).toEqual([ - 2019, - 2, - 10, - 23, - 59, - 59, - 999 + 2019, 2, 10, 23, 59, 59, 999 ]); expect(localTime(endOfDay(new Date("2019-02-01 23:59:40")))).toEqual([ - 2019, - 2, - 1, - 23, - 59, - 59, - 999 + 2019, 2, 1, 23, 59, 59, 999 ]); expect(localTime(endOfDay(new Date("2019-02-01 23:59:59")))).toEqual([ - 2019, - 2, - 1, - 23, - 59, - 59, - 999 + 2019, 2, 1, 23, 59, 59, 999 ]); expect(localTime(endOfDay(new Date("2019-02-02 00:00")))).toEqual([ - 2019, - 2, - 2, - 23, - 59, - 59, - 999 + 2019, 2, 2, 23, 59, 59, 999 ]); }); @@ -97,66 +49,30 @@ test("dateToLocal works as expected", () => { expect(localTime(dateToLocal(0))).toEqual([1970, 1, 1, 0, 0, 0, 0]); expect(localTime(dateToLocal(1539980438))).toEqual([ - 2018, - 10, - 19, - 20, - 20, - 38, - 0 + 2018, 10, 19, 20, 20, 38, 0 ]); expect(localTime(dateToLocal(1541708438))).toEqual([ - 2018, - 11, - 8, - 20, - 20, - 38, - 0 + 2018, 11, 8, 20, 20, 38, 0 ]); tzmock.register("Brazil/East"); expect(localTime(dateToLocal(0))).toEqual([1969, 12, 31, 21, 0, 0, 0]); expect(localTime(dateToLocal(1539980438))).toEqual([ - 2018, - 10, - 19, - 17, - 20, - 38, - 0 + 2018, 10, 19, 17, 20, 38, 0 ]); expect(localTime(dateToLocal(1541708438))).toEqual([ - 2018, - 11, - 8, - 18, - 20, - 38, - 0 + 2018, 11, 8, 18, 20, 38, 0 ]); // DST on tzmock.register("US/Pacific"); expect(localTime(dateToLocal(0))).toEqual([1969, 12, 31, 16, 0, 0, 0]); expect(localTime(dateToLocal(1539980438))).toEqual([ - 2018, - 10, - 19, - 13, - 20, - 38, - 0 + 2018, 10, 19, 13, 20, 38, 0 ]); // DST on expect(localTime(dateToLocal(1541708438))).toEqual([ - 2018, - 11, - 8, - 12, - 20, - 38, - 0 + 2018, 11, 8, 12, 20, 38, 0 ]); }); @@ -165,65 +81,29 @@ test("dateToUtc works as expected", () => { expect(localTime(dateToUTC(0))).toEqual([1970, 1, 1, 0, 0, 0, 0]); expect(localTime(dateToUTC(1539980438))).toEqual([ - 2018, - 10, - 19, - 20, - 20, - 38, - 0 + 2018, 10, 19, 20, 20, 38, 0 ]); expect(localTime(dateToUTC(1541708438))).toEqual([ - 2018, - 11, - 8, - 20, - 20, - 38, - 0 + 2018, 11, 8, 20, 20, 38, 0 ]); tzmock.register("Brazil/East"); expect(localTime(dateToUTC(0))).toEqual([1970, 1, 1, 0, 0, 0, 0]); expect(localTime(dateToUTC(1539980438))).toEqual([ - 2018, - 10, - 19, - 20, - 20, - 38, - 0 + 2018, 10, 19, 20, 20, 38, 0 ]); expect(localTime(dateToUTC(1541708438))).toEqual([ - 2018, - 11, - 8, - 20, - 20, - 38, - 0 + 2018, 11, 8, 20, 20, 38, 0 ]); tzmock.register("US/Pacific"); expect(localTime(dateToUTC(0))).toEqual([1970, 1, 1, 0, 0, 0, 0]); expect(localTime(dateToUTC(1539980438))).toEqual([ - 2018, - 10, - 19, - 20, - 20, - 38, - 0 + 2018, 10, 19, 20, 20, 38, 0 ]); expect(localTime(dateToUTC(1541708438))).toEqual([ - 2018, - 11, - 8, - 20, - 20, - 38, - 0 + 2018, 11, 8, 20, 20, 38, 0 ]); }); diff --git a/yarn.lock b/yarn.lock index 93a02ed3a8..b0e39ac326 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10692,10 +10692,10 @@ prepend-http@^2.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= -prettier@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" - integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== +prettier@2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64" + integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== pretty-error@^2.1.1: version "2.1.2"