Skip to content

Commit

Permalink
Merge pull request #3219 from Emurgo/ruslan/catalyst-ui-revert
Browse files Browse the repository at this point in the history
Revert Catalyst UI changes
  • Loading branch information
vsubhuman committed May 23, 2023
2 parents b39c14a + 06050c0 commit c89a2d2
Show file tree
Hide file tree
Showing 24 changed files with 1,200 additions and 182 deletions.
12 changes: 10 additions & 2 deletions packages/yoroi-extension/app/actions/ada/voting-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,21 @@ import { AsyncAction, Action } from '../lib/Action';
import { PublicDeriver } from '../../api/ada/lib/storage/models/PublicDeriver/index';

export default class VotingActions {
generateCatalystKey: AsyncAction<void> = new AsyncAction();
createTransaction: AsyncAction<null | string> = new AsyncAction();
signTransaction: AsyncAction<{|
password?: string,
publicDeriver: PublicDeriver<>,
|}> = new AsyncAction();
cancel: Action<void> = new Action();
finishDone: Action<void> = new Action();
submitGenerate: Action<void> = new Action();
goBackToGenerate: Action<void> = new Action();
submitConfirm: AsyncAction<void> = new AsyncAction();
submitConfirmError: Action<void> = new Action();
submitRegister: Action<void> = new Action();
submitRegisterError: Action<Error> = new Action();
goBackToRegister: Action<void> = new Action();
finishQRCode: Action<void> = new Action();
submitTransaction: Action<void> = new Action();
submitTransactionError: Action<Error> = new Action();
generatePlaceholderTransaction: AsyncAction<void> = new AsyncAction();
}
25 changes: 5 additions & 20 deletions packages/yoroi-extension/app/api/ada/lib/cardanoCrypto/catalyst.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,6 @@
import { RustModule } from './rustLoader';
import blake2b from 'blake2b';

const HARDENED = 0x80000000;

export const VoteKeyDerivationPath: Array<number> = [
1694 + HARDENED,
1815 + HARDENED,
0 + HARDENED, // acount'
0, // chain
0, // address_index
];

export const CatalystLabels = Object.freeze({
DATA: 61284,
SIG: 61285,
Expand Down Expand Up @@ -99,21 +89,16 @@ export function generateRegistrationMetadata(
}

export function generateRegistration(request: {|
stakePrivateKey: ?RustModule.WalletV4.PrivateKey,
votingPublicKey: RustModule.WalletV4.PublicKey,
stakePrivateKey: RustModule.WalletV4.PrivateKey,
catalystPrivateKey: RustModule.WalletV4.PrivateKey,
receiverAddress: string,
slotNumber: number,
|}): RustModule.WalletV4.AuxiliaryData {
return generateRegistrationMetadata(
request.votingPublicKey.to_hex(),
request.stakePrivateKey ?
Buffer.from(request.stakePrivateKey.to_public().as_bytes()).toString('hex') :
'0'.repeat(32 * 2),
Buffer.from(request.catalystPrivateKey.to_public().as_bytes()).toString('hex'),
Buffer.from(request.stakePrivateKey.to_public().as_bytes()).toString('hex'),
request.receiverAddress,
request.slotNumber,
(hashedMetadata) => (
request.stakePrivateKey?.sign(hashedMetadata).to_hex() ??
'0'.repeat(64 * 2)
),
(hashedMetadata) => request.stakePrivateKey.sign(hashedMetadata).to_hex(),
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ test('Generate Catalyst registration tx', async () => {
const nonce = 1234;
const metadata = generateRegistration({
stakePrivateKey,
votingPublicKey: catalystPrivateKey.to_public(),
catalystPrivateKey,
receiverAddress: Buffer.from(address.to_address().to_bytes()).toString('hex'),
slotNumber: nonce,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,18 @@ export function getCryptoDaedalusWalletFromMasterKey(
const wallet = RustModule.WalletV2.DaedalusWallet.new(privateKey);
return wallet;
}

/**
* Generate catalyst private key for QR code
*/

export function generatePrivateKeyForCatalyst(): RustModule.WalletV4.Bip32PrivateKey {
const mnemonic = generateMnemonic(160);
const bip39entropy = mnemonicToEntropy(mnemonic);
const EMPTY_PASSWORD = Buffer.from('');
const rootKey = RustModule.WalletV4.Bip32PrivateKey.from_bip39_entropy(
Buffer.from(bip39entropy, 'hex'),
EMPTY_PASSWORD
);
return rootKey;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// @flow
import type { Node } from 'react';
import { Component } from 'react';
import { observer } from 'mobx-react';
import classnames from 'classnames';
import { observable, action } from 'mobx';
import { defineMessages, intlShape, FormattedHTMLMessage } from 'react-intl';
import type { $npm$ReactIntl$IntlFormat } from 'react-intl';
import ReactToolboxMobxForm from '../../../utils/ReactToolboxMobxForm';
import globalMessages from '../../../i18n/global-messages';

import Dialog from '../../widgets/Dialog';
import DialogCloseButton from '../../widgets/DialogCloseButton';
import DialogBackButton from '../../widgets/DialogBackButton';
import ProgressStepBlock from './ProgressStepBlock';
import { ProgressInfo } from '../../../stores/ada/VotingStore';
import PinInput from '../../widgets/forms/PinInput';

import styles from './ConfirmPinDialog.scss';
import type { StepsList } from './types';

const messages = defineMessages({
line1: {
id: 'wallet.voting.dialog.step.confirm.line1',
defaultMessage: '!!!Please enter the PIN as you will need it <strong>every time</strong> you want to access the Catalyst Voting app.',
},
});

type Props = {|
+stepsList: StepsList,
+progressInfo: ProgressInfo,
+goBack: void => void,
+submit: void => PossiblyAsync<void>,
+error: void => PossiblyAsync<void>,
+cancel: void => void,
+classicTheme: boolean,
+pinValidation: string => boolean,
+isProcessing: boolean,
|};

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

static contextTypes: {|intl: $npm$ReactIntl$IntlFormat|} = {
intl: intlShape.isRequired
};
@observable pinForm: void | ReactToolboxMobxForm;

@action
setPinForm(form: ReactToolboxMobxForm) {
this.pinForm = form;
}

render(): Node {
const { intl } = this.context;
const {
stepsList,
progressInfo,
goBack,
cancel,
classicTheme,
pinValidation,
isProcessing,
} = this.props;

const dailogActions = [{
label: intl.formatMessage(globalMessages.stepConfirm),
primary: true,
onClick: this._submitForm,
isSubmitting: isProcessing,
disabled: isProcessing,
}];

return (
<Dialog
className={classnames([styles.dialog])}
title={intl.formatMessage(globalMessages.votingRegistrationTitle)}
actions={dailogActions}
closeOnOverlayClick={false}
closeButton={<DialogCloseButton />}
backButton={<DialogBackButton onBack={goBack} />}
onClose={cancel}
>
<ProgressStepBlock
stepsList={stepsList}
progressInfo={progressInfo}
classicTheme={classicTheme}
/>
<div className={classnames([styles.lineText, styles.firstItem])}>
<FormattedHTMLMessage {...messages.line1} />
</div>
<div className={styles.pinInputContainer}>
<PinInput
setForm={form => this.setPinForm(form)}
disabled={false}
classicTheme={classicTheme}
pinMatches={pinValidation}
fieldName="pin"
validCheck={_pin => true}
placeholder={this.context.intl.formatMessage(globalMessages.confirmPin)}
allowEmptyInput={false}
/>
</div>
</Dialog>);
}

_submitForm: void => Promise<void> = async () => {
if (this.pinForm !== undefined) {
this.pinForm.submit({
onSuccess: async () => {
await this.props.submit();
},
onError: async () => {
await this.props.error();
},
});
}
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@import './common.scss';

.pinInputContainer{
display: flex;
justify-content: center;
margin-top: 32px;
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// @flow
import type { Node } from 'react';
import { Component } from 'react';
import { observer } from 'mobx-react';
import classnames from 'classnames';
import { defineMessages, intlShape, FormattedHTMLMessage } from 'react-intl';

import globalMessages from '../../../i18n/global-messages';

import Dialog from '../../widgets/Dialog';
import DialogCloseButton from '../../widgets/DialogCloseButton';
import DialogBackButton from '../../widgets/DialogBackButton';

import ProgressStepBlock from './ProgressStepBlock';

import type { $npm$ReactIntl$IntlFormat } from 'react-intl';
import { ProgressInfo } from '../../../stores/ada/VotingStore';

import styles from './GeneratePinDialog.scss';
import type { StepsList } from './types';

const messages = defineMessages({
line1: {
id: 'wallet.voting.dialog.step.pin.line1',
defaultMessage: '!!!Please write down this PIN as you will need it <strong>every time</strong> you want to access the Catalyst Voting app.',
},
actionButton: {
id: 'wallet.voting.dialog.step.pin.actionButton',
defaultMessage: '!!!Confirm that I wrote down the PIN',
},
});

type Props = {|
+stepsList: StepsList,
+progressInfo: ProgressInfo,
+next: void => void,
+cancel: void => void,
+onBack: void => void,
+classicTheme: boolean,
+pin: Array<number>,
|};

@observer
export default class GeneratePinDialog extends Component<Props> {
static contextTypes: {| intl: $npm$ReactIntl$IntlFormat |} = {
intl: intlShape.isRequired,
};

render(): Node {
const { intl } = this.context;
const { stepsList, progressInfo, next, cancel, classicTheme, pin } = this.props;

const dialogActions = [
{
label: intl.formatMessage(messages.actionButton),
primary: true,
onClick: next,
},
];

const pinCards = (
<div className={classnames([styles.pinContainer, styles.lastItem])}>
{pin.map((value, index) => {
// eslint-disable-next-line react/no-array-index-key
return <div key={index} className={styles.pin}><span>{value}</span></div>;
})}
</div>
);

return (
<Dialog
className={classnames([styles.dialog])}
title={intl.formatMessage(globalMessages.votingRegistrationTitle)}
actions={dialogActions}
closeOnOverlayClick={false}
closeButton={<DialogCloseButton />}
backButton={<DialogBackButton onBack={this.props.onBack} />}
onClose={cancel}
>
<ProgressStepBlock
stepsList={stepsList}
progressInfo={progressInfo}
classicTheme={classicTheme}
/>

<div className={classnames([styles.lineText, styles.firstItem, styles.importantText])}>
<FormattedHTMLMessage {...messages.line1} />
</div>
{pinCards}
</Dialog>
);
}
}

0 comments on commit c89a2d2

Please sign in to comment.