diff --git a/jsconfig.json b/jsconfig.json index f614d260..2d763433 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -1,6 +1,7 @@ { "compilerOptions": { "baseUrl": ".", + "ignoreDeprecations": "6.0", "paths": { "@BasicComponents": ["./src/components/basic/index.js"], "@ComposedComponents": ["./src/components/composed/index.js"], diff --git a/package-lock.json b/package-lock.json index c835dafc..e77c29f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,6 @@ "version": "1.5.3", "dependencies": { "@bitcoinerlab/secp256k1": "^1.2.0", - "@mintlayer/entropy-generator": "^1.0.6", "@mintlayer/sdk": "1.0.30", "@noble/secp256k1": "^3.0.0", "bip32": "^5.0.0", @@ -25,8 +24,6 @@ "decimal.js": "^10.6.0", "ecpair": "3.0.0", "konva": "^10.2.0", - "node-forge": "^1.3.3", - "pbkdf2": "^3.1.5", "process": "^0.11.10", "react": "^19.2.4", "react-dom": "^19.2.4", @@ -4726,21 +4723,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@mintlayer/entropy-generator": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@mintlayer/entropy-generator/-/entropy-generator-1.0.6.tgz", - "integrity": "sha512-TwUEQlcf3MAwBi75rnACFp/TwFhL9H6vIgC9UYolVxKvG24Np+FD8+/UmosqDPBDRZn9iSXmgE/xO1AklUY9RQ==", - "license": "MIT", - "dependencies": { - "buffer": "^6.0.3", - "crypto-shuffle": "^1.0.1", - "get-random-values": "^4.1.1" - }, - "engines": { - "node": ">=14.21.3", - "npm": ">=6.14.18" - } - }, "node_modules/@mintlayer/sdk": { "version": "1.0.30", "resolved": "https://registry.npmjs.org/@mintlayer/sdk/-/sdk-1.0.30.tgz", @@ -8080,27 +8062,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/crypto-shuffle": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/crypto-shuffle/-/crypto-shuffle-1.0.1.tgz", - "integrity": "sha512-dO6Zf2KbIjcfDGzVt+IvZnJThS/Rs0NAm9DqcuE8PdpUstEjy/DEMiHFW1a/WkfcNLqpI1543AcaCFOIyphqWw==", - "license": "MIT", - "dependencies": { - "get-random-values": "^1.2.0" - } - }, - "node_modules/crypto-shuffle/node_modules/get-random-values": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-random-values/-/get-random-values-1.2.2.tgz", - "integrity": "sha512-lMyPjQyl0cNNdDf2oR+IQ/fM3itDvpoHy45Ymo2r0L1EjazeSl13SfbKZs7KtZ/3MDCeueiaJiuOEfKqRTsSgA==", - "license": "MIT", - "dependencies": { - "global": "^4.4.0" - }, - "engines": { - "node": "10 || 12 || >=14" - } - }, "node_modules/css-loader": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.3.tgz", @@ -9050,11 +9011,6 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" - }, "node_modules/domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", @@ -10540,18 +10496,6 @@ "node": ">= 0.4" } }, - "node_modules/get-random-values": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/get-random-values/-/get-random-values-4.1.1.tgz", - "integrity": "sha512-B1Z9TN7MNsoBIaCpEsQu9gdYJ/hmMfO07KSvb/rZ0UnZACmsIcMW0ogBx44XjHWbRpRIBeF63dZ/JSCpm23qJA==", - "license": "MIT", - "dependencies": { - "window-or-global": "^1.0.1" - }, - "engines": { - "node": "20 || 22 || >=24" - } - }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -10648,16 +10592,6 @@ "dev": true, "license": "BSD-2-Clause" }, - "node_modules/global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "license": "MIT", - "dependencies": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, "node_modules/globals": { "version": "17.3.0", "resolved": "https://registry.npmjs.org/globals/-/globals-17.3.0.tgz", @@ -15289,15 +15223,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/min-document": { - "version": "2.19.2", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.2.tgz", - "integrity": "sha512-8S5I8db/uZN8r9HSLFVWPdJCvYOejMcEC82VIzNUc6Zkklf/d1gg2psfE79/vyhWOj4+J8MtwmoOz3TmvaGu5A==", - "license": "MIT", - "dependencies": { - "dom-walk": "^0.1.0" - } - }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -15526,15 +15451,6 @@ "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", "license": "MIT" }, - "node_modules/node-forge": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.3.tgz", - "integrity": "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==", - "license": "(BSD-3-Clause OR GPL-2.0)", - "engines": { - "node": ">= 6.13.0" - } - }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -19898,12 +19814,6 @@ "dev": true, "license": "MIT" }, - "node_modules/window-or-global": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/window-or-global/-/window-or-global-1.0.1.tgz", - "integrity": "sha512-tE12J/NenOv4xdVobD+AD3fT06T4KNqnzRhkv5nBIu7K+pvOH2oLCEgYP+i+5mF2jtI6FEADheOdZkA8YWET9w==", - "license": "MIT" - }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", diff --git a/package.json b/package.json index 17ab27c4..ac588341 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,6 @@ "private": true, "dependencies": { "@bitcoinerlab/secp256k1": "^1.2.0", - "@mintlayer/entropy-generator": "^1.0.6", "@mintlayer/sdk": "1.0.30", "@noble/secp256k1": "^3.0.0", "bip32": "^5.0.0", @@ -20,8 +19,6 @@ "decimal.js": "^10.6.0", "ecpair": "3.0.0", "konva": "^10.2.0", - "node-forge": "^1.3.3", - "pbkdf2": "^3.1.5", "process": "^0.11.10", "react": "^19.2.4", "react-dom": "^19.2.4", @@ -64,7 +61,6 @@ "@babel/preset-env": "^7.29.0", "@babel/preset-react": "^7.28.5", "@eslint/js": "^9.39.2", - "eslint": "^9.39.2", "@playwright/test": "^1.58.2", "@svgr/webpack": "^8.1.0", "@testing-library/dom": "^10.4.1", @@ -74,13 +70,18 @@ "@types/node": "^25.2.3", "@types/tiny-secp256k1": "^2.0.1", "babel-jest": "^30.2.0", + "babel-loader": "^10.0.0", + "copy-webpack-plugin": "^13.0.1", + "css-loader": "^7.1.3", "dotenv": "^17.2.4", "dotenv-webpack": "^8.1.1", "env-cmd": "^11.0.0", + "eslint": "^9.39.2", "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^7.0.1", "fake-indexeddb": "^6.2.5", "globals": "^17.3.0", + "html-webpack-plugin": "^5.6.6", "http-server": "^14.1.1", "husky": "^9.1.7", "identity-obj-proxy": "^3.0.0", @@ -88,21 +89,17 @@ "jest-canvas-mock": "^2.5.2", "jest-environment-jsdom": "^30.2.0", "jest-webgl-canvas-mock": "^2.5.3", + "mini-css-extract-plugin": "^2.10.0", "prettier": "^3.8.1", "pretty-quick": "^4.2.2", "style-loader": "^4.0.0", - "css-loader": "^7.1.3", - "url-loader": "^4.1.1", - "babel-loader": "^10.0.0", - "html-webpack-plugin": "^5.6.6", - "mini-css-extract-plugin": "^2.10.0", - "copy-webpack-plugin": "^13.0.1", - "webpack": "^5.105.1", - "webpack-cli": "^6.0.1", - "webpack-dev-server": "^5.2.3", "typescript": "^5.9.3", + "url-loader": "^4.1.1", "vm-browserify": "^1.1.2", "wallet-address-validator": "^0.2.4", - "webextension-polyfill": "^0.12.0" + "webextension-polyfill": "^0.12.0", + "webpack": "^5.105.1", + "webpack-cli": "^6.0.1", + "webpack-dev-server": "^5.2.3" } } diff --git a/public/background.js b/public/background.js index b044cb5d..33657fd0 100644 --- a/public/background.js +++ b/public/background.js @@ -174,6 +174,8 @@ } } + if (!message.method && message.action !== 'popupResponse') return + // Handle popup responses if (message.action === 'popupResponse') { const { requestId, origin, result, error } = message @@ -209,7 +211,7 @@ storedSendResponse({ result, error }) pendingResponses.delete(requestId) } else { - api.runtime.sendMessage({ requestId, result, error }, (response) => { + api.runtime.sendMessage({ requestId, result, error }, () => { if (api.runtime.lastError) { console.error( '[Mintlayer] Send response error:', diff --git a/src/components/basic/Button/Button.js b/src/components/basic/Button/Button.js index 22fc92c9..4bcc0eab 100644 --- a/src/components/basic/Button/Button.js +++ b/src/components/basic/Button/Button.js @@ -13,8 +13,8 @@ const Button = ({ dataTestId = 'button', onMouseEnter, onMouseLeave, + autoFocus = false, }) => { - // Вычисляем классы сразу, без useEffect const classList = ['btn', ...extraStyleClasses] if (dark) { classList.push('dark') @@ -32,6 +32,7 @@ const Button = ({ type={buttonType} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} + autoFocus={autoFocus} > {children} diff --git a/src/components/basic/Input/InputFloat.js b/src/components/basic/Input/InputFloat.js index 66e5516c..dee6b89e 100644 --- a/src/components/basic/Input/InputFloat.js +++ b/src/components/basic/Input/InputFloat.js @@ -1,6 +1,5 @@ import { AppInfo, Expressions } from '@Constants' import { NumbersHelper } from '@Helpers' -import { useEffect, useState } from 'react' import Input from './Input' const InputFloat = (props) => { @@ -12,7 +11,7 @@ const InputFloat = (props) => { const [regexIntegerPartIndex, regexDecimalPartIndex] = [1, 5] const breakersRegex = /[.,]/g - const [value, setValue] = useState(props.value || '') + const value = props.value || '' const removeBreakers = (value) => value.replaceAll(breakersRegex, '') @@ -76,10 +75,6 @@ const InputFloat = (props) => { return parsedVal.value || ev.target.value } - useEffect(() => { - setValue(props.value) - }, [props.value]) - return ( { const mask = Expressions.FIELDS.INTEGER - const [value, setValue] = useState(0) - useEffect(() => { - setValue(~~props.value) - !NumbersHelper.isInteger(props.value) && + const value = useMemo(() => { + if (!NumbersHelper.isInteger(props.value)) { console.warn( 'A non-integer value was passed to InputInteger. It has been converted to integer.', ) + } + return ~~props.value }, [props.value]) const parseValue = ({ target: { value, matchedValue } }) => { diff --git a/src/components/basic/Svg/Svg.js b/src/components/basic/Svg/Svg.js index 9331de73..faef6c9a 100644 --- a/src/components/basic/Svg/Svg.js +++ b/src/components/basic/Svg/Svg.js @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react' +import React from 'react' const Svg = ({ children, @@ -8,13 +8,8 @@ const Svg = ({ width = '100px', height = '100px', }) => { - const [viewboxWidth, setViewBoxWidth] = useState(size) - const [viewboxHeight, setViewBoxHeight] = useState(size) - - useEffect(() => { - sizeH ? setViewBoxHeight(sizeH) : setViewBoxHeight(size) - sizeW ? setViewBoxWidth(sizeW) : setViewBoxWidth(size) - }, [sizeH, sizeW, size]) + const viewboxWidth = sizeW || size + const viewboxHeight = sizeH || size return ( { - const [size, setSize] = useState({ w: 0, h: 0 }) - const [proportionalHeight, setProportionalHeight] = useState() - - useEffect(() => { - setSize({ + const size = useMemo( + () => ({ w: maxWidthPoint(points) + EXTRABOUNDARIES, h: parseInt(height) + EXTRABOUNDARIES, - }) - }, [points, height]) + }), + [points, height], + ) - useEffect(() => { - setProportionalHeight(height || getProportionalHeight(size, width)) - }, [width, height, size]) + const proportionalHeight = useMemo( + () => height || getProportionalHeight(size, width), + [width, height, size], + ) return ( { - const { lines, setLines, setEntropy } = useContext(AccountContext) - const tool = 'pen' - const isDrawing = useRef(false) - - const handleMouseDown = (e) => { - isDrawing.current = true - const pos = e.target.getStage().getPointerPosition() - setLines([...lines, { tool, points: [pos.x, pos.y] }]) - } - - const handleMouseMove = (e) => { - // no drawing - skipping - if (!isDrawing.current) { - return - } - const stage = e.target.getStage() - const point = stage.getPointerPosition() - const lastLine = lines[lines.length - 1] - // add point - lastLine.points = lastLine.points.concat([point.x, point.y]) - - // replace last - lines.splice(lines.length - 1, 1, lastLine) - setLines(lines.concat()) - } - - const handleMouseUp = () => { - isDrawing.current = false - } - - const clearButtonClickHandler = () => { - setLines([]) - setEntropy([]) - } - - return ( -
- - - {lines.map((line, i) => ( - - ))} - - - -
- ) -} - -export default DrawingBoard diff --git a/src/components/composed/Entropy/DrawingBoard.test.js b/src/components/composed/Entropy/DrawingBoard.test.js deleted file mode 100644 index bf22eb62..00000000 --- a/src/components/composed/Entropy/DrawingBoard.test.js +++ /dev/null @@ -1,69 +0,0 @@ -import React from 'react' -import { render, screen } from '@testing-library/react' -import DrawingBoard from './DrawingBoard' -import { AccountProvider } from '@Contexts' -import 'konva/lib/shapes/Line' - -// TODO: Mock the react-konva library to pass the test cause react-konva is not properly working with jest. Need to find a bettr way to test this component. -jest.mock('react-konva', () => ({ - Stage: ({ children, ...props }) => ( -
- {children} -
- ), - Layer: ({ children, ...props }) =>
{children}
, - Line: ({ ...props }) =>
, -})) - -// const setLines = jest.fn() -// const setEntropy = jest.fn() - -test('Render Drawing Board', () => { - render( - - - , - ) - - const drawingBoard = screen.getByTestId('entropy-drawing-board') - const layer = screen.getByRole('presentation') - const clearButton = screen.getByTestId('button') - - expect(drawingBoard).toBeInTheDocument() - expect(layer).toBeInTheDocument() - expect(clearButton).toBeInTheDocument() - expect(clearButton).toHaveTextContent('Clear') -}) - -// test('allows drawing on the canvas', () => { -// render( -// -// -// , -// ) -// const drawingBoard = screen.getByTestId('entropy-drawing-board') - -// fireEvent.mouseDown(drawingBoard, { clientX: 50, clientY: 50 }) -// fireEvent.mouseUp(drawingBoard) -// fireEvent.mouseDown(drawingBoard, { clientX: 60, clientY: 60 }) -// fireEvent.mouseUp(drawingBoard) - -// expect(setLines).toHaveBeenCalledTimes(2) -// }) - -// test('Clears the canvas when the Clear button is clicked', () => { -// render( -// -// -// , -// ) - -// const clearButton = screen.getByText('Clear') -// fireEvent.click(clearButton) - -// expect(setLines).toHaveBeenCalledWith([]) -// expect(setEntropy).toHaveBeenCalledWith([]) -// }) diff --git a/src/components/composed/Entropy/Entropy.css b/src/components/composed/Entropy/Entropy.css deleted file mode 100644 index 18d58301..00000000 --- a/src/components/composed/Entropy/Entropy.css +++ /dev/null @@ -1,7 +0,0 @@ -.entropy { - display: flex; - align-items: center; - width: 100%; - height: 100%; - padding: 0 5px; -} diff --git a/src/components/composed/Entropy/Entropy.js b/src/components/composed/Entropy/Entropy.js deleted file mode 100644 index c3ccbead..00000000 --- a/src/components/composed/Entropy/Entropy.js +++ /dev/null @@ -1,33 +0,0 @@ -import React from 'react' - -import EntropyDescription from './EntropyDescription' -import DrawingBoard from './DrawingBoard' -import { Error } from '@BasicComponents' - -import './Entropy.css' - -const DESCRIPTION_ITEMS = [ - 'In the blank screen aside please draw anything you want.', - 'We are going to use this drawing to generate a random seed for your wallet.', - 'The more random the drawing is, the more secure your wallet will be.', - 'Express your art.', -] - -const errorMessages = 'Your entropy is too small. Please draw more lines.' - -const Entropy = ({ isError }) => { - return ( - <> -
- - -
- {isError && } - - ) -} - -export default Entropy diff --git a/src/components/composed/Entropy/Entropy.test.js b/src/components/composed/Entropy/Entropy.test.js deleted file mode 100644 index a22b11bb..00000000 --- a/src/components/composed/Entropy/Entropy.test.js +++ /dev/null @@ -1,45 +0,0 @@ -import { render, screen } from '@testing-library/react' -import Entropy from './Entropy' -import { AccountProvider } from '@Contexts' - -// TODO: Mock the react-konva library to pass the test cause react-konva is not properly working with jest. Need to find a bettr way to test this component. -jest.mock('react-konva', () => ({ - Stage: ({ children, ...props }) =>
{children}
, - Layer: ({ children, ...props }) =>
{children}
, - Line: ({ ...props }) =>
, -})) - -test('Render Entropy', async () => { - render( - - - , - ) - - const entropy = screen.getByTestId('entropy') - const description = screen.getByTestId('entropy-description') - const drawingBoard = screen.getByTestId('entropy-drawing-board') - - expect(entropy).toBeInTheDocument() - expect(description).toBeInTheDocument() - expect(drawingBoard).toBeInTheDocument() -}) - -test('Render Entropy with error', async () => { - const errorMessages = 'Your entropy is too small. Please draw more lines.' - render( - - - , - ) - - const entropy = screen.getByTestId('entropy') - const description = screen.getByTestId('entropy-description') - const drawingBoard = screen.getByTestId('entropy-drawing-board') - const errorMessage = screen.getByTestId('error-message') - - expect(entropy).toBeInTheDocument() - expect(description).toBeInTheDocument() - expect(drawingBoard).toBeInTheDocument() - expect(errorMessage).toHaveTextContent(errorMessages) -}) diff --git a/src/components/composed/Entropy/EntropyDescription.css b/src/components/composed/Entropy/EntropyDescription.css deleted file mode 100644 index 3fc29f3d..00000000 --- a/src/components/composed/Entropy/EntropyDescription.css +++ /dev/null @@ -1,8 +0,0 @@ -.entropy-description { - width: 50%; - height: 100%; -} - -.entropy-paragraph { - font-size: 1.125rem; -} diff --git a/src/components/composed/Entropy/EntropyDescription.js b/src/components/composed/Entropy/EntropyDescription.js deleted file mode 100644 index 9d92db1c..00000000 --- a/src/components/composed/Entropy/EntropyDescription.js +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react' - -import './EntropyDescription.css' - -import { VerticalGroup } from '@LayoutComponents' - -const EntropyDescriptionItem = ({ description }) => { - return ( -

- {description} -

- ) -} - -const EntropyDescription = ({ descriptionItems }) => { - return ( -
- - {descriptionItems.map((item, index) => ( - - ))} - -
- ) -} - -export default EntropyDescription diff --git a/src/components/composed/Entropy/EntropyDescription.test.js b/src/components/composed/Entropy/EntropyDescription.test.js deleted file mode 100644 index 679d48c0..00000000 --- a/src/components/composed/Entropy/EntropyDescription.test.js +++ /dev/null @@ -1,21 +0,0 @@ -import { render, screen } from '@testing-library/react' -import EntropyDescription from './EntropyDescription' - -const DESCRIPTION_ITEMS = ['one', 'two'] - -test('Render account balance', () => { - render() - const description = screen.getByTestId('entropy-description') - const verticalContainer = screen.getByTestId('vertical-group-container') - const descriptionItems = screen.getAllByTestId('entropy-paragraph') - - expect(description).toBeInTheDocument() - expect(verticalContainer).toBeInTheDocument() - expect(description).toHaveClass('entropy-description') - - descriptionItems.forEach((item, index) => { - expect(item).toHaveTextContent(DESCRIPTION_ITEMS[index]) - }) - - expect(descriptionItems).toHaveLength(DESCRIPTION_ITEMS.length) -}) diff --git a/src/components/composed/TextField/TextField.js b/src/components/composed/TextField/TextField.js index 71b84f42..1f7a41d2 100644 --- a/src/components/composed/TextField/TextField.js +++ b/src/components/composed/TextField/TextField.js @@ -19,7 +19,6 @@ const TextField = ({ extraStyleClasses, errorMessages, pristinity = true, - reference, focus = true, bigGap = true, }) => { @@ -52,7 +51,7 @@ const TextField = ({ setIsPristine(pristinity) }, [pristinity]) - const setPristineState = (e) => setIsPristine(false) + const setPristineState = () => setIsPristine(false) return ( diff --git a/src/components/composed/index.js b/src/components/composed/index.js index 2a24006d..8fc543da 100644 --- a/src/components/composed/index.js +++ b/src/components/composed/index.js @@ -13,7 +13,6 @@ import CryptoFiatField from './CryptoFiatField/CryptoFiatField' import FeeField from './FeeField/FeeField' import FeeFieldML from './FeeField/FeeFieldML' import ConnectionErrorPopup from './ConnectionErrorPopup/ConnectionErrorPopup' -import Entropy from './Entropy/Entropy' import WalletList from './WalletList/WalletList' import AddWallet from './AddWallet/AddWallet' import CurrentStaking from './CurrentStaking/CurrentStaking' @@ -46,7 +45,6 @@ export { FeeField, FeeFieldML, ConnectionErrorPopup, - Entropy, WalletList, AddWallet, CurrentStaking, diff --git a/src/components/containers/CreateAccount/CreateAccount.js b/src/components/containers/CreateAccount/CreateAccount.js index 8e86de6b..ec3a91ca 100644 --- a/src/components/containers/CreateAccount/CreateAccount.js +++ b/src/components/containers/CreateAccount/CreateAccount.js @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useCallback, useContext } from 'react' +import React, { useState, useMemo } from 'react' import { useNavigate } from 'react-router' import { AppInfo, Expressions } from '@Constants' @@ -10,7 +10,6 @@ import { InputList, ProgressTracker, TextField, - Entropy, } from '@ComposedComponents' import { ReactComponent as IconArrowRight } from '@Assets/images/icon-arrow-right.svg' @@ -18,22 +17,19 @@ import { ReactComponent as IconArrowRight } from '@Assets/images/icon-arrow-righ import WordsDescription from './WordsListDescription' import './CreateAccount.css' -import { AccountContext } from '@Contexts' -import { generateEntropy, normalize } from '@mintlayer/entropy-generator' const CreateAccount = ({ step, setStep, words = [], onStepsFinished, + onGenerateMnemonic, validateMnemonicFn, defaultBTCWordList, }) => { - const { setEntropy, lines } = useContext(AccountContext) const inputExtraclasses = ['set-account-input'] const passwordPattern = Expressions.PASSWORD const [wordsFields, setWordsFields] = useState([]) - const [accountWordsValid, setAccountWordsValid] = useState(false) const [direction, setDirection] = useState('forward') const [accountNameValue, setAccountNameValue] = useState('') @@ -41,12 +37,13 @@ const CreateAccount = ({ const [accountNameValid, setAccountNameValid] = useState(false) const [accountPasswordValid, setAccountPasswordValid] = useState(false) - const [accountEntropyValid, setAccountEntropyValid] = useState(false) - const [accountNameErrorMessage, setAccountNameErrorMessage] = useState(null) - const [accountPasswordErrorMessage, setAccountPasswordErrorMessage] = - useState(null) - const [showEntropyError, setShowEntropyError] = useState(false) + const accountNameErrorMessage = !accountNameValid + ? AppInfo.WALLET_NAME_ERROR + : null + const accountPasswordErrorMessage = !accountPasswordValid + ? AppInfo.WALLET_PASSWORD_ERROR + : null const [accountNamePristinity, setAccountNamePristinity] = useState(true) const [accountPasswordPristinity, setAccountPasswordPristinity] = @@ -55,62 +52,10 @@ const CreateAccount = ({ const navigate = useNavigate() - const calculateEntropy = useCallback( - (size) => { - const points = lines.flatMap((line) => line.points) - const normalizedPoints = normalize( - points.map((point) => Math.round(point)), - ) - return size - ? generateEntropy(normalizedPoints, size) - : generateEntropy(normalizedPoints) - }, - [lines], - ) - - useEffect(() => { - const message = !accountNameValid - ? 'The wallet name should have at least 4 characteres.' - : null - - setAccountNameErrorMessage(message) - }, [accountNameValid]) - - useEffect(() => { - const message = !accountPasswordValid - ? [ - 'Your password should have at least 8 characteres.', - 'Also it should have a lowercase letter, an uppercase letter, a digit, and a special char like: /\\*()&^%$#@-_=+\'"?!:;<>~`', - ] - : null - - setAccountPasswordErrorMessage(message) - }, [accountPasswordValid]) - - const accountEntropyValidity = (lines) => { - const points = lines.flatMap((line) => line.points) - return points.length >= AppInfo.minEntropyLength - } - - useEffect(() => { - if (!lines) return - const isEntropyValid = accountEntropyValidity(lines) - setAccountEntropyValid(isEntropyValid) - if (step < 3 || isEntropyValid) { - setShowEntropyError(false) - } - }, [lines, step, accountEntropyValid]) - - const thirdStepSubmitHandler = () => { - if (!accountEntropyValid) { - setShowEntropyError(true) - } - setEntropy(calculateEntropy()) - } - const goToNextStep = () => { setDirection('forward') - return step < 6 + if (step === 2) onGenerateMnemonic() + return step < 5 ? setStep(step + 1) : onStepsFinished(accountNameValue, accountPasswordValue, selectedWallets) } @@ -123,27 +68,30 @@ const CreateAccount = ({ const steps = [ { value: 1, name: 'Wallet Name', active: step === 1 }, { value: 2, name: 'Wallet Password', active: step === 2 }, - { value: 3, name: 'Entropy Generation', active: step === 3 }, { - value: 4, + value: 3, name: 'Seed Phrases', - active: step > 3, + active: step > 2, }, ] + const accountWordsValid = useMemo( + () => wordsFields.every((word) => word.validity), + [wordsFields], + ) + const stepsValidations = { 1: accountNameValid, 2: accountPasswordValid, - 3: accountEntropyValid, + 3: true, 4: true, - 5: true, - 6: accountWordsValid, + 5: accountWordsValid, } const titles = { - 4: 'I understand', - 5: 'Backup done!', - 6: 'Create Wallet', + 3: 'I understand', + 4: 'Backup done!', + 5: 'Create Wallet', } const nameFieldValidity = (value) => { @@ -166,14 +114,9 @@ const CreateAccount = ({ const genButtonTitle = (currentStep) => titles[currentStep] || 'Continue' - useEffect(() => { - const wordsValidity = wordsFields.every((word) => word.validity) - setAccountWordsValid(wordsValidity) - }, [wordsFields, step]) - const handleError = (step) => { - if (step < 6) return - if (step === 6) { + if (step < 5) return + if (step === 5) { alert( 'These words do not match the previously generated mnemonic. Check if you had any typos or if you inserted them in a different order', ) @@ -192,10 +135,9 @@ const CreateAccount = ({ if (step === 1) setAccountNamePristinity(false) if (step === 2) setAccountPasswordPristinity(false) - if (step === 3) thirdStepSubmitHandler() let validForm = stepsValidations[step] - if (step === 6) validForm = validForm && isMnemonicValid() + if (step === 5) validForm = validForm && isMnemonicValid() validForm ? goToNextStep() : handleError(step) } @@ -208,14 +150,14 @@ const CreateAccount = ({ direction={direction} />
4 && 'set-account-form-words'}`} + className={`set-account-form ${step > 3 && 'set-account-form-words'}`} method="POST" data-testid="set-account-form" onSubmit={handleSubmit} > {step === 1 && ( @@ -236,7 +178,6 @@ const CreateAccount = ({ value={accountPasswordValue} onChangeHandle={accountPasswordChangeHandler} validity={accountPasswordValid} - pattern={passwordPattern} password label={'Create a password for your wallet'} placeHolder={'Password'} @@ -246,9 +187,8 @@ const CreateAccount = ({ alternate /> )} - {step === 3 && } - {step === 4 && } - {step === 5 && ( + {step === 3 && } + {step === 4 && ( )} - {step === 6 && ( + {step === 5 && (