Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cspp recover wallet #2565

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 65 additions & 13 deletions app/actions/AccountMixerActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,23 +111,39 @@ export const createNeededAccounts = (
dispatch({ type: CREATEMIXERACCOUNTS_ATTEMPT });

const walletService = sel.walletService(getState());
// TODO use constants here
const walletName = sel.getWalletName(getState());
const isTestnet = sel.isTestNet(getState());
const csppPort = isTestnet ? "15760" : "5760";
const csppServer = "cspp.decred.org";

const cfg = getWalletCfg(isTestnet, walletName);
const createAccout = (pass, name) =>

const createAccount = (pass, name) =>
wallet.getNextAccount(walletService, pass, name);

try {
const mixedAccount = await createAccout(passphrase, mixedAccountName);
const changeAccount = await createAccout(passphrase, changeAccountName);
const mixedAccount = await createAccount(passphrase, mixedAccountName);
const changeAccount = await createAccount(passphrase, changeAccountName);

const mixedNumber = mixedAccount.getAccountNumber();
const changeNumber = changeAccount.getAccountNumber();

dispatch(setCoinjoinCfg(
mixedNumber,
changeNumber
));
} 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 = getWalletCfg(isTestnet, walletName);

// TODO use constants here
// On this first moment we are hard coding the cspp decred's server.
// the idea is to allow more server on upcoming releases, but we decided
// to go with this approach on this first integration.
const csppServer = "cspp.decred.org";
const csppPort = isTestnet ? "15760" : "5760";

cfg.set("csppserver", csppServer);
cfg.set("csppport", csppPort);
cfg.set("mixedaccount", mixedNumber);
Expand All @@ -142,7 +158,43 @@ export const createNeededAccounts = (
csppServer,
mixedAccountBranch: 0
});
} catch (error) {
dispatch({ type: CREATEMIXERACCOUNTS_FAILED, error });
}
};

// getCoinjoinOutputspByAcct get all possible coinjoin outputs which an account
// may have. This is used so we can recover privacy wallets and don't miss
// spend outputs. It returns all accounts, so the user also can choose the
// change account.
export const getCoinjoinOutputspByAcct = () => (dispatch, getState) =>
new Promise((resolve, reject) => {
const { balances, walletService } = getState().grpc;

wallet
.getCoinjoinOutputspByAcct(walletService)
.then((response) => {
const coinjoinSumByAcctResp = response.wrappers_[1];
const coinjoinSumByAcct = balances.reduce((allAccts, { accountNumber }) => {
// if account number is equals imported account, we ignore it.
if (accountNumber === Math.pow(2, 31) - 1) {
return allAccts;
}
const coinjoinAcct = coinjoinSumByAcctResp.find((a) => a.getAccountNumber() === accountNumber);
if (coinjoinAcct === undefined) {
allAccts.push({
acctIdx: accountNumber,
coinjoinSum: 0
});
} else {
allAccts.push({
acctIdx: accountNumber,
coinjoinSum: coinjoinAcct.getCoinjoinTxsSum()
});
}
return allAccts;
}, []);

resolve(coinjoinSumByAcct);
})
.catch((error) =>
reject(error)
);
});
23 changes: 16 additions & 7 deletions app/actions/ClientActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,15 @@ const startWalletServicesTrigger = () => (dispatch, getState) =>
await dispatch(getStartupWalletInfo());
await dispatch(transactionNtfnsStart());
await dispatch(accountNtfnsStart());
await dispatch(pushHistory("/home"));
// await dispatch(pushHistory("/home"));
};

startServicesAsync()
.then(() => resolve())
.catch((error) => reject(error));
});

export const startWalletServices = () => (dispatch, getState) => {
export const startWalletServices = () => (dispatch, getState) => new Promise((resolve, reject) => {
const { startWalletServiceAttempt } = getState().grpc;
if (startWalletServiceAttempt) {
return;
Expand All @@ -88,11 +88,13 @@ export const startWalletServices = () => (dispatch, getState) => {
dispatch(startWalletServicesTrigger())
.then(() => {
dispatch({ type: STARTWALLETSERVICE_SUCCESS });
resolve();
})
.catch((error) => {
dispatch({ type: STARTWALLETSERVICE_FAILED, error });
reject({ error });
});
};
});

export const GETSTARTUPWALLETINFO_ATTEMPT = "GETSTARTUPWALLETINFO_ATTEMPT";
export const GETSTARTUPWALLETINFO_SUCCESS = "GETSTARTUPWALLETINFO_SUCCESS";
Expand Down Expand Up @@ -268,20 +270,24 @@ export const GETBESTBLOCK_ATTEMPT = "GETBESTBLOCK_ATTEMPT";
export const GETBESTBLOCK_FAILED = "GETBESTBLOCK_FAILED";
export const GETBESTBLOCK_SUCCESS = "GETBESTBLOCK_SUCCESS";

export const getBestBlockHeightAttempt = (cb) => (dispatch, getState) => {
export const getBestBlockHeightAttempt = (cb) => (dispatch, getState) => new Promise((resolve, reject) => {
dispatch({ type: GETBESTBLOCK_ATTEMPT });
wallet
.bestBlock(sel.walletService(getState()))
.then((resp) => {
.then(async (resp) => {
dispatch({ height: resp.getHeight(), type: GETBESTBLOCK_SUCCESS });
if (cb) {
dispatch(cb());
await dispatch(cb());
return resolve();
}
return resolve();
})
.catch((error) => {
dispatch({ error, type: GETBESTBLOCK_FAILED });
reject({ error });
throw error;
});
};
});

export const GETNETWORK_ATTEMPT = "GETNETWORK_ATTEMPT";
export const GETNETWORK_FAILED = "GETNETWORK_FAILED";
Expand Down Expand Up @@ -680,3 +686,6 @@ export const getAcctSpendableBalance = (acctId) => async (dispatch, getState) =>
const acct = await wallet.getBalance(sel.walletService(getState()), acctId, 0);
return acct.getSpendable();
};

export const goToHomePage = () => (dispatch) =>
dispatch(pushHistory("/home"));
15 changes: 10 additions & 5 deletions app/actions/WalletLoaderActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,10 +288,15 @@ export const startRpcRequestFunc = (privPass, isRetry) => (
setTimeout(async () => {
const rpcSyncCall = await loader.rpcSync(request);
dispatch({ syncCall: rpcSyncCall, type: SYNC_UPDATE });
rpcSyncCall.on("data", function (response) {
dispatch(syncConsumer(response));
rpcSyncCall.on("data", async (response) => {
const synced = await dispatch(syncConsumer(response));
if (synced) {
return resolve();
}
});
rpcSyncCall.on("end", function () {
// It never gets here
// TODO investigate if this code is necessary.
dispatch({ type: SYNC_SUCCESS });
resolve({ synced: true });
});
Expand Down Expand Up @@ -496,13 +501,13 @@ export function syncCancel() {
};
}

const syncConsumer = (response) => (dispatch, getState) => {
const syncConsumer = (response) => async (dispatch, getState) => {
const { discoverAccountsComplete } = getState().walletLoader;
switch (response.getNotificationType()) {
case SyncNotificationType.SYNCED: {
dispatch(getBestBlockHeightAttempt(startWalletServices));
await dispatch(getBestBlockHeightAttempt(startWalletServices));
dispatch({ type: SYNC_SYNCED });
break;
return true;
}
case SyncNotificationType.UNSYNCED: {
dispatch({ type: SYNC_UNSYNCED });
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
import { Tooltip } from "shared";
import { FormattedMessage as T } from "react-intl";
import "style/EyeFilterMenu.less";
import "style/StakePool.less";

const WatchOnlyWalletSwitch = ({ enabled, onClick, className }) => (
const RestoreWalletSwitch = ({ enabled, onClick, className, text }) => (
<div className={className ? className : ""}>
<Tooltip
text={
enabled ? (
<T id="watchOnly.enabled" m="Watch Only" />
) : (
<T id="watchOnly.disabled" m="Normal" />
)
}>
text={text}>
<div className="autobuyer-switch">
<div
className={
Expand All @@ -32,4 +25,4 @@ const WatchOnlyWalletSwitch = ({ enabled, onClick, className }) => (
</div>
);

export default WatchOnlyWalletSwitch;
export default RestoreWalletSwitch;
35 changes: 0 additions & 35 deletions app/components/buttons/TrezorWalletSwitch.js

This file was deleted.

6 changes: 2 additions & 4 deletions app/components/buttons/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ export { default as TransactionLink } from "./TransactionLink";
export { default as EnableExternalRequestButton } from "./EnableExternalRequestButton";
export { default as SendTransactionButton } from "./SendTransactionButton";
export { default as ImportScriptIconButton } from "./ImportScriptIconButton";
export { default as TrezorWalletSwitch } from "./TrezorWalletSwitch";
export { default as RestoreWalletSwitch } from "./RestoreWalletSwitch";

import ModalButton from "./ModalButton";
import KeyBlueButton from "./KeyBlueButton";
import AutoBuyerSwitch from "./AutoBuyerSwitch";
import WatchOnlyWalletSwitch from "./WatchOnlyWalletSwitch";
import NetworkSwitch from "./NetworkSwitch";
import DangerButton from "./DangerButton";
import CloseButton from "./CloseButton";
Expand All @@ -29,8 +28,7 @@ export {
DangerButton,
CloseButton,
NetworkSwitch,
InvisibleButton,
WatchOnlyWalletSwitch
InvisibleButton
};

/***************************************************
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import { TextInput } from "inputs";
import {
KeyBlueButton,
InvisibleButton,
WatchOnlyWalletSwitch,
TrezorWalletSwitch
RestoreWalletSwitch
} from "buttons";
import { NewSeedTabMsg, RestoreTabMsg } from "../messages";
import { classNames } from "pi-ui";
Expand Down Expand Up @@ -45,6 +44,8 @@ const CreateWalletForm = ({
masterPubKeyError,
isTrezor,
toggleTrezor,
isPrivacy,
toggleIsPrivacy,
onShowTrezorConfig,
isCreateNewWallet,
creatingWallet
Expand All @@ -58,13 +59,13 @@ const CreateWalletForm = ({
</div>
</div>
) : (
<div className={styles.newWalletTitleArea}>
<div className={classNames(styles.walletIconSmall, styles.restore)} />
<div className={styles.newWalletTitle}>
<RestoreTabMsg />
<div className={styles.newWalletTitleArea}>
<div className={classNames(styles.walletIconSmall, styles.restore)} />
<div className={styles.newWalletTitle}>
<RestoreTabMsg />
</div>
</div>
</div>
)}
)}
<div className={styles.daemonRow}>
<div className={styles.daemonLabel}>
<T id="createwallet.walletname.label" m="Wallet Name" />
Expand Down Expand Up @@ -92,10 +93,17 @@ const CreateWalletForm = ({
<T id="createwallet.walletOnly.label" m="Watch only" />
</div>
<div className={styles.daemonInput}>
<WatchOnlyWalletSwitch
<RestoreWalletSwitch
className={styles.walletSwitch}
enabled={isWatchingOnly}
onClick={toggleWatchOnly}
text={
isWatchingOnly ? (
<T id="watchOnly.enabled" m="Watch Only" />
) : (
<T id="watchOnly.disabled" m="Normal" />
)
}
/>
</div>
</div>
Expand All @@ -104,16 +112,42 @@ const CreateWalletForm = ({
<T id="createwallet.isTrezor.label" m="Trezor" />
</div>
<div className={styles.daemonInput}>
<TrezorWalletSwitch
<RestoreWalletSwitch
className={styles.walletSwitch}
enabled={isTrezor}
onClick={toggleTrezor}
text={
isTrezor ? (
<T id="createWallet.restore.trezor.enabled" m="Enabled" />
) : (
<T id="createWallet.restore.trezor.disabled" m="Disabled" />
)
}
/>
<span onClick={onShowTrezorConfig} className={styles.whatsnew}>
<T id="createWallet.isTrezor.setupLink" m="(setup device)" />
</span>
</div>
</div>
<div className={styles.daemonRow}>
<div className={styles.daemonLabel}>
<T id="privacy.label" m="Privacy" />
</div>
<div className={styles.daemonInput}>
<RestoreWalletSwitch
className={styles.walletSwitch}
enabled={isPrivacy}
onClick={toggleIsPrivacy}
text={
isPrivacy ? (
<T id="privacy.label" m="Privacy" />
) : (
<T id="watchOnly.disabled" m="Normal" />
)
}
/>
</div>
</div>
{isWatchingOnly && (
<div className={styles.daemonRow}>
<div className={styles.daemonLabel}>
Expand Down
Loading