Skip to content

Commit

Permalink
Merge branch 'develop' into fix/YOEXT-546/connector-sees-wrong-utxos
Browse files Browse the repository at this point in the history
  • Loading branch information
vsubhuman committed Mar 1, 2024
2 parents 785a504 + 62fe18b commit 8ed97c7
Show file tree
Hide file tree
Showing 89 changed files with 854 additions and 6,081 deletions.
1 change: 0 additions & 1 deletion packages/yoroi-extension/.babelrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ module.exports = function (api /*: ApiType */) /*: * */ {
'@babel/plugin-proposal-export-namespace-from',
],
env: {
cucumber: nodePlugins,
test: nodePlugins,
jest: nodePlugins,
}
Expand Down
3 changes: 0 additions & 3 deletions packages/yoroi-extension/app/actions/ada/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// @flow
import AdaWalletsActions from './ada-wallets-actions';
import PaperWalletsActions from './paper-wallets-actions';
import HWConnectActions from './hw-connect-actions';
import TrezorSendActions from './trezor-send-actions';
import LedgerSendActions from './ledger-send-actions';
Expand All @@ -10,7 +9,6 @@ import VotingActions from './voting-actions';

export type AdaActionsMap = {|
wallets: AdaWalletsActions,
paperWallets: PaperWalletsActions,
trezorConnect: HWConnectActions,
trezorSend: TrezorSendActions,
ledgerConnect: HWConnectActions,
Expand All @@ -22,7 +20,6 @@ export type AdaActionsMap = {|

const adaActionsMap: AdaActionsMap = Object.freeze({
wallets: new AdaWalletsActions(),
paperWallets: new PaperWalletsActions(),
trezorConnect: new HWConnectActions(),
trezorSend: new TrezorSendActions(),
ledgerConnect: new HWConnectActions(),
Expand Down
22 changes: 0 additions & 22 deletions packages/yoroi-extension/app/actions/ada/paper-wallets-actions.js

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ export type RestoreModeType =
| {|
type: 'bip44',
extra: void,
length:
| typeof config.wallets.WALLET_RECOVERY_PHRASE_WORD_COUNT
| typeof config.wallets.DAEDALUS_RECOVERY_PHRASE_WORD_COUNT,
length: typeof config.wallets.WALLET_RECOVERY_PHRASE_WORD_COUNT,
|}
| {|
type: 'cip1852',
Expand All @@ -31,9 +29,7 @@ export type RestoreModeType =
// but we did allow paper wallet restoration
type: 'bip44' | 'cip1852',
extra: 'paper',
length:
| typeof config.wallets.YOROI_PAPER_RECOVERY_PHRASE_WORD_COUNT
| typeof config.wallets.DAEDALUS_PAPER_RECOVERY_PHRASE_WORD_COUNT,
length: typeof config.wallets.YOROI_PAPER_RECOVERY_PHRASE_WORD_COUNT,
chain?: number,
|}
| {|
Expand Down
126 changes: 0 additions & 126 deletions packages/yoroi-extension/app/api/ada/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
HARD_DERIVATION_START,
WalletTypePurpose,
} from '../../config/numbersConfig';
import type { Network, } from '../../../config/config-types';
import { createHardwareCip1852Wallet, createStandardCip1852Wallet, } from './lib/storage/bridge/walletBuilder/shelley';
import type { ReferenceTx } from './lib/storage/bridge/updateTransactions';
import {
Expand Down Expand Up @@ -76,12 +75,6 @@ import {
import { generateAdaMnemonic, generateWalletRootKey, } from './lib/cardanoCrypto/cryptoWallet';
import { v4PublicToV2, } from './lib/cardanoCrypto/utils';
import { isValidBip39Mnemonic, } from '../common/lib/crypto/wallet';
import { generateByronPlate } from './lib/cardanoCrypto/plate';
import {
isValidEnglishAdaPaperMnemonic,
scramblePaperAdaMnemonic,
unscramblePaperAdaMnemonic,
} from './lib/cardanoCrypto/paperWallet';
import type { CardanoSignTransaction } from 'trezor-connect-flow';
import { createTrezorSignTxPayload, } from './transactions/shelley/trezorTx';
import { createLedgerSignTxPayload, } from './transactions/shelley/ledgerTx';
Expand Down Expand Up @@ -134,12 +127,9 @@ import {
multiTokenFromCardanoValue,
multiTokenFromRemote,
} from './transactions/utils';
import type { PdfGenStepType } from './paperWallet/paperWalletPdf';
import { generateAdaPaperPdf } from './paperWallet/paperWalletPdf';
import type { TransactionExportRow } from '../export';

import { RustModule } from './lib/cardanoCrypto/rustLoader';
import type { WalletChecksum } from '@emurgo/cip4-js';
import type {
CreateWalletRequest,
CreateWalletResponse,
Expand All @@ -166,36 +156,6 @@ import { derivePrivateByAddressing, derivePublicByAddressing } from './lib/carda

// ADA specific Request / Response params

// createAdaPaper

export type CreateAdaPaperRequest = {|
password: string,
numAddresses?: number,
network: $ReadOnly<NetworkRow>,
|};
export type AdaPaper = {|
addresses: Array<string>,
scrambledWords: Array<string>,
plate: WalletChecksum,
|};
export type CreateAdaPaperFunc = (
request: CreateAdaPaperRequest
) => Promise<AdaPaper>;

// createAdaPaperPdf

export type CreateAdaPaperPdfRequest = {|
paper: AdaPaper,
network: Network,
printAccountPlate?: boolean,
updateStatus?: PdfGenStepType => boolean,
|};

export type CreateAdaPaperPdfResponse = ?Blob;
export type CreateAdaPaperPdfFunc = (
request: CreateAdaPaperPdfRequest
) => Promise<CreateAdaPaperPdfResponse>;

// getAllAddressesForDisplay

export type GetAllAddressesForDisplayRequest = {|
Expand Down Expand Up @@ -460,28 +420,6 @@ export type SaveLastReceiveAddressIndexFunc = (
request: SaveLastReceiveAddressIndexRequest
) => Promise<SaveLastReceiveAddressIndexResponse>;

// isValidPaperMnemonic

export type IsValidPaperMnemonicRequest = {|
mnemonic: string,
numberOfWords: number,
|};
export type IsValidPaperMnemonicResponse = boolean;
export type IsValidPaperMnemonicFunc = (
request: IsValidPaperMnemonicRequest
) => IsValidPaperMnemonicResponse;

// unscramblePaperMnemonic

export type UnscramblePaperMnemonicRequest = {|
mnemonic: string,
numberOfWords: number,
password?: string,
|};
export type UnscramblePaperMnemonicResponse = [?string, number];
export type UnscramblePaperMnemonicFunc = (
request: UnscramblePaperMnemonicRequest
) => UnscramblePaperMnemonicResponse;

// generateWalletRecoveryPhrase

Expand Down Expand Up @@ -559,60 +497,10 @@ export type GetTransactionRowsToExportFunc = (
request: GetTransactionRowsToExportRequest
) => Promise<GetTransactionRowsToExportResponse>;

export const DEFAULT_ADDRESSES_PER_PAPER = 1;

export const FETCH_TXS_BATCH_SIZE = 20;

export default class AdaApi {

// noinspection JSMethodCanBeStatic
createAdaPaper(
request: CreateAdaPaperRequest
): AdaPaper {
const words = generateAdaMnemonic();
const rootPk = generateWalletRootKey(words.join(' '));
const scrambledWords = scramblePaperAdaMnemonic(
words.join(' '),
request.password
).split(' ');

const config = getCardanoHaskellBaseConfig(
request.network
).reduce((acc, next) => Object.assign(acc, next), {});

const { addresses, plate } = generateByronPlate(
rootPk,
0, // paper wallets always use account 0
request.numAddresses != null ? request.numAddresses : DEFAULT_ADDRESSES_PER_PAPER,
config.ByronNetworkId
);
return { addresses, scrambledWords, plate };
}

async createAdaPaperPdf(
{
paper,
network,
printAccountPlate,
updateStatus
}: CreateAdaPaperPdfRequest
): Promise<CreateAdaPaperPdfResponse> {
const { addresses, scrambledWords, plate } = paper;
// noinspection UnnecessaryLocalVariableJS
const res : Promise<CreateAdaPaperPdfResponse> = generateAdaPaperPdf({
words: scrambledWords,
addresses,
plate: printAccountPlate === true ? plate : undefined,
network,
}, s => {
Logger.info('[PaperWalletRender] ' + s);
if (updateStatus) {
updateStatus(s);
}
});
return res;
}

/**
* addresses get cutoff if there is a DisplayCutoff set
*/
Expand Down Expand Up @@ -1821,20 +1709,6 @@ export default class AdaApi {
return isValidBip39Mnemonic(request.mnemonic, request.numberOfWords);
}

// <TODO:PENDING_REMOVAL> paper
isValidPaperMnemonic(
request: IsValidPaperMnemonicRequest
): IsValidPaperMnemonicResponse {
return isValidEnglishAdaPaperMnemonic(request.mnemonic, request.numberOfWords);
}
// <TODO:PENDING_REMOVAL> paper
unscramblePaperMnemonic(
request: UnscramblePaperMnemonicRequest
): UnscramblePaperMnemonicResponse {
return unscramblePaperAdaMnemonic(request.mnemonic, request.numberOfWords, request.password);
}

generateWalletRecoveryPhrase(): Promise<GenerateWalletRecoveryPhraseResponse> {
Logger.debug(`${nameof(AdaApi)}::${nameof(this.generateWalletRecoveryPhrase)} called`);
try {
Expand Down
1 change: 0 additions & 1 deletion packages/yoroi-extension/app/api/ada/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,6 @@ test('create tx', async () => {
NetworkName: 'Cardano Legacy Testnet',
Backend: {
BackendService: 'https://testnet-backend.yoroiwallet.com',
WebSocket: 'wss://testnet-backend.yoroiwallet.com:443',
TokenInfoService: 'https://stage-cdn.yoroiwallet.com'
},
BaseConfig: [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,17 @@
// @flow

import cryptoRandomString from 'crypto-random-string';
import {
entropyToMnemonic,
mnemonicToEntropy,
wordlists,
} from 'bip39';

import { Logger, stringifyError } from '../../../../utils/logging';

import * as unorm from 'unorm';
import { pbkdf2Sync as pbkdf2 } from 'pbkdf2';

import { RustModule } from './rustLoader';
import {
isValidBip39Mnemonic
} from '../../../common/lib/crypto/wallet';
import config from '../../../../config';

/**
* Variation of the mnemonic to seed as defined by BIP39
* https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki#from-mnemonic-to-seed
*/
const mnemonicToSeedHex = (mnemonic: string, password: ?string): string => {
const mnemonicBuffer = Buffer.from(unorm.nfkd(mnemonic), 'utf8');
const salt = 'mnemonic' + (unorm.nfkd(password) || '');
const saltBuffer = Buffer.from(salt, 'utf8');
// note: we use a 32-byte key length instead of 64 like in the bip39 specification
return pbkdf2(mnemonicBuffer, saltBuffer, 2048, 32, 'sha512').toString('hex');
};

// <TODO:PENDING_REMOVAL> paper
/** Check validity of paper mnemonic (including checksum) */
export const isValidEnglishAdaPaperMnemonic = (
Expand Down Expand Up @@ -58,37 +40,6 @@ export const unscramblePaperAdaMnemonic = (
): [?string, number] => {
const words = phrase.split(' ');
if (words.length === numberOfWords) {
if (numberOfWords === config.wallets.DAEDALUS_PAPER_RECOVERY_PHRASE_WORD_COUNT) {
if (password != null) {
throw new Error(
`Password is not expected for a ${config.wallets.DAEDALUS_PAPER_RECOVERY_PHRASE_WORD_COUNT}-word paper!`
);
}
const [scrambledMnemonics, passwordMnemonics] = [words.slice(0, 18), words.slice(18)];
try {
password = mnemonicToSeedHex(passwordMnemonics.join(' '));
const entropy = mnemonicToEntropy(
scrambledMnemonics.join(' ')
);

const mnemonics = RustModule.WasmScope(Scope => {
const newEntropy = Scope.WalletV2.paper_wallet_unscramble(
Buffer.from(entropy, 'hex'),
password || ''
);

return newEntropy.to_english_mnemonics();
});

return [
mnemonics,
config.wallets.DAEDALUS_RECOVERY_PHRASE_WORD_COUNT
];
} catch (e) {
Logger.error('Failed to unscramble paper mnemonic! ' + stringifyError(e));
return [undefined, 0];
}
}
if (numberOfWords === config.wallets.YOROI_PAPER_RECOVERY_PHRASE_WORD_COUNT) {
if (password == null) {
throw new Error(
Expand Down Expand Up @@ -118,17 +69,3 @@ export const unscramblePaperAdaMnemonic = (
}
return [undefined, 0];
};

/** Scramble provided mnemonic with the provided password */
export const scramblePaperAdaMnemonic = (
phrase: string,
password: string,
): string => {
const salt = new Uint8Array(Buffer.from(cryptoRandomString({ length: 2 * 8 }), 'hex'));
const entropy = RustModule.WasmScope(Scope => {
const walletEntropy = Scope.WalletV2.Entropy.from_english_mnemonics(phrase);
const bytes = Scope.WalletV2.paper_wallet_scramble(walletEntropy, salt, password);
return Buffer.from(bytes)
});
return entropyToMnemonic(entropy, wordlists.ENGLISH);
};

0 comments on commit 8ed97c7

Please sign in to comment.