diff --git a/.eslintignore b/.eslintignore index 16c0346cb7..b799c58a2e 100755 --- a/.eslintignore +++ b/.eslintignore @@ -1,3 +1,12 @@ dist release main.js +.cache-loader +logs +node_modules +translations +tests +features/support/default-wallet.json +mainnet-genesis-dryrun-with-stakeholders.json +source/renderer/app/i18n/locales +nodemon.json diff --git a/.eslintrc b/.eslintrc index 9d6f070b68..73d9c18927 100755 --- a/.eslintrc +++ b/.eslintrc @@ -8,7 +8,11 @@ "extends": [ "airbnb", "plugin:flowtype/recommended", - "plugin:react/recommended" + "plugin:react/recommended", + "prettier", + "prettier/babel", + "prettier/flowtype", + "prettier/react" ], "env": { "browser": true, @@ -16,72 +20,41 @@ "node": true }, "rules": { - "arrow-parens": ["off"], - "consistent-return": "off", - "comma-dangle": "off", - "generator-star-spacing": "off", - "import/no-unresolved": ["error", { "ignore": ["electron"] }], - "import/no-extraneous-dependencies": "off", - "import/no-dynamic-require": "off", - "import/prefer-default-export": "off", - "lines-between-class-members": 0, - "no-use-before-define": "off", - "operator-linebreak": 0, - "promise/param-names": 2, - "promise/always-return": 2, - "promise/catch-or-return": 2, - "promise/no-native": 0, - "react/button-has-type": 0, - "react/jsx-no-bind": 0, - "react/jsx-filename-extension": ["error", { "extensions": [".js", ".jsx"] }], - "react/jsx-closing-bracket-location": 1, - "react/jsx-one-expression-per-line": 0, - "react/prefer-stateless-function": "off", - "react/no-unused-prop-types": "off", - "react/prop-types": 0, - "react/sort-comp": 0, - "react/require-default-props": 0, - "react/destructuring-assignment": 0, - "react/no-access-state-in-setstate": 0, "class-methods-use-this": 0, - "no-duplicate-imports": 0, + "consistent-return": "warn", + "flowtype/generic-spacing": 0, + "jsx-a11y/alt-text": 0, + "lines-between-class-members": 0, + "global-require": 0, + "import/extensions": 0, + "import/no-dynamic-require": 0, + "import/no-extraneous-dependencies": 0, + "import/prefer-default-export": 0, + "no-await-in-loop": 0, + "no-bitwise": 0, "no-param-reassign": 0, "no-plusplus": 0, - "no-bitwise": 0, + "no-return-assign": "warn", + "no-return-await": "warn", "no-underscore-dangle": 0, - "no-console": 0, - "no-mixed-operators": 0, - "prefer-template": 0, - "no-unused-vars": 1, - "no-trailing-spaces": 1, - "padded-blocks": 0, - "no-undef": 1, - "arrow-body-style": 1, - "key-spacing": 1, - "no-empty-function": 1, - "max-len": 1, - "no-useless-escape": 1, - "prefer-const": 1, - "object-curly-spacing": 1, - "spaced-comment": 1, - "quotes": 1, - "import/imports-first": 1, - "no-multi-spaces": 1, - "no-multiple-empty-lines": 1, - "react/jsx-indent": 1, - "global-require": "off", - "prefer-destructuring": 0, - "no-return-await": 0, - "function-paren-newline": 0, - "react/no-array-index-key": 0, - "object-curly-newline": 0, - "jsx-a11y/alt-text": 0, - "no-await-in-loop": 0, + "no-unused-expressions": "warn", + "no-use-before-define": 0, "no-restricted-syntax": 0, - "no-return-assign": 0, - "prefer-promise-reject-errors": 0, - "no-unused-expressions": 0, - "import/extensions": 0 + "prefer-destructuring": "warn", + "prefer-promise-reject-errors": "warn", + "prefer-template": "warn", + "react/button-has-type": 0, + "react/destructuring-assignment": 0, + "react/jsx-no-bind": "warn", + "react/jsx-wrap-multilines": 0, + "react/jsx-filename-extension": 0, + "react/no-access-state-in-setstate": "warn", + "react/no-array-index-key": "warn", + "react/no-unused-prop-types": "warn", + "react/prefer-stateless-function": 0, + "react/prop-types": "warn", + "react/require-default-props": 0, + "react/sort-comp": 0 }, "plugins": [ "flowtype", diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000000..c6a1376dea --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +{ + "trailingComma": "es5", + "singleQuote": true +} diff --git a/CHANGELOG.md b/CHANGELOG.md index f4ce90becd..7474735e5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,11 @@ Changelog ### Chores +- Implemented `pretier` formatting tool and set up automation for basic maintainance tasks ([PR 1335](https://github.com/input-output-hk/daedalus/pull/1335)) - Replaced "Ada" with "ada" ([PR 1317](https://github.com/input-output-hk/daedalus/pull/1317), [PR 1336](https://github.com/input-output-hk/daedalus/pull/1336)) - Improved the internal IPC communication ([PR 1332](https://github.com/input-output-hk/daedalus/pull/1332)) - Improved Webpack 4 build performance ([PR 1320](https://github.com/input-output-hk/daedalus/pull/1320)) +- Introduced automated code formatting with prettier ([PR 1335](https://github.com/input-output-hk/daedalus/pull/1335)) ## 0.13.0 diff --git a/features/step_definitions/about-dialog.js b/features/step_definitions/about-dialog.js index a3077aaff1..3aba733d40 100644 --- a/features/step_definitions/about-dialog.js +++ b/features/step_definitions/about-dialog.js @@ -2,21 +2,24 @@ import { Given, When, Then } from 'cucumber'; import { expect } from 'chai'; import packageJson from '../../package.json'; -Given(/^I open the About dialog$/, async function () { +Given(/^I open the About dialog$/, async function() { this.client.execute(() => daedalus.actions.app.openAboutDialog.trigger()); }); -When(/^I close the About dialog$/, function () { +When(/^I close the About dialog$/, function() { this.client.execute(() => daedalus.actions.app.closeAboutDialog.trigger()); }); -Then(/^the About dialog is (hidden|visible)/, async function (state) { +Then(/^the About dialog is (hidden|visible)/, async function(state) { const isVisible = state === 'visible'; return this.client.waitForVisible('.About_container', null, !isVisible); }); -Then(/^the About dialog and package.json show the same Daedalus version/, async function () { - const { version: packageJsonVersion } = packageJson; - const aboutVersion = await this.client.getText('.About_daedalusVersion'); - expect(aboutVersion).to.equal(packageJsonVersion); -}); +Then( + /^the About dialog and package.json show the same Daedalus version/, + async function() { + const { version: packageJsonVersion } = packageJson; + const aboutVersion = await this.client.getText('.About_daedalusVersion'); + expect(aboutVersion).to.equal(packageJsonVersion); + } +); diff --git a/features/step_definitions/accept-terms-of-use-steps.js b/features/step_definitions/accept-terms-of-use-steps.js index 69a71b1920..e6b05766cd 100644 --- a/features/step_definitions/accept-terms-of-use-steps.js +++ b/features/step_definitions/accept-terms-of-use-steps.js @@ -4,37 +4,38 @@ import termsOfUse from '../support/helpers/terms-of-use-helpers'; const TERMS_OF_USE_FORM = '.TermsOfUseForm_component'; -Given(/^I have accepted "Terms of use"$/, async function () { +Given(/^I have accepted "Terms of use"$/, async function() { await termsOfUse.acceptTerms(this.client); }); -Given(/^I didnt accept "Terms of use"$/, async function () { +Given(/^I didnt accept "Terms of use"$/, async function() { await this.client.execute(() => { daedalus.reset(); }); }); -Given(/^I am on the "Terms of use" screen$/, function () { +Given(/^I am on the "Terms of use" screen$/, function() { return this.client.waitForVisible(TERMS_OF_USE_FORM); }); -When(/^I click on "I agree with terms of use" checkbox$/, function () { +When(/^I click on "I agree with terms of use" checkbox$/, function() { return this.waitAndClick('.TermsOfUseForm_component .SimpleCheckbox_root'); }); -When(/^I submit the "Terms of use" form$/, function () { +When(/^I submit the "Terms of use" form$/, function() { return this.waitAndClick('.TermsOfUseForm_submitButton'); }); -Then(/^I should not see the "Terms of use" screen anymore$/, function () { +Then(/^I should not see the "Terms of use" screen anymore$/, function() { return this.client.waitForVisible(TERMS_OF_USE_FORM, null, true); }); -Then(/^I should have "Terms of use" accepted$/, async function () { - const result = await this.client.executeAsync((done) => { - daedalus.stores.profile.getTermsOfUseAcceptanceRequest.execute() +Then(/^I should have "Terms of use" accepted$/, async function() { + const result = await this.client.executeAsync(done => { + daedalus.stores.profile.getTermsOfUseAcceptanceRequest + .execute() .then(done) - .catch((error) => done(error)); + .catch(error => done(error)); }); expect(result.value).to.equal(true); }); diff --git a/features/step_definitions/ada-redemption-steps.js b/features/step_definitions/ada-redemption-steps.js index ad586ef03c..07612b3a5f 100644 --- a/features/step_definitions/ada-redemption-steps.js +++ b/features/step_definitions/ada-redemption-steps.js @@ -3,122 +3,239 @@ import path from 'path'; import { navigateTo } from '../support/helpers/route-helpers'; import { environment } from '../../source/main/environment'; -const regularAdaCertificateFilePath = path.resolve(__dirname, '../support/ada_certificates/regular.pdf'); -const regularEncryptedAdaCertificateFilePath = path.resolve(__dirname, '../support/ada_certificates/regular.pdf.enc'); -const forceVendedAdaCertificateFilePath = path.resolve(__dirname, '../support/ada_certificates/force-vended.pdf'); -const forceVendedEncryptedAdaCertificateFilePath = path.resolve(__dirname, '../support/ada_certificates/force-vended.pdf.enc'); - -const CERTIFICATE_UPLOAD_BOX = '.AdaRedemptionForm_certificate .AdaCertificateUploadWidget_uploadBox input'; -const REDEMPTION_SUBMIT_BUTTON = '.AdaRedemptionForm_component .AdaRedemptionForm_submitButton'; - -Given(/^I have accepted "Daedalus Redemption Disclaimer"$/, async function () { +const regularAdaCertificateFilePath = path.resolve( + __dirname, + '../support/ada_certificates/regular.pdf' +); +const regularEncryptedAdaCertificateFilePath = path.resolve( + __dirname, + '../support/ada_certificates/regular.pdf.enc' +); +const forceVendedAdaCertificateFilePath = path.resolve( + __dirname, + '../support/ada_certificates/force-vended.pdf' +); +const forceVendedEncryptedAdaCertificateFilePath = path.resolve( + __dirname, + '../support/ada_certificates/force-vended.pdf.enc' +); + +const CERTIFICATE_UPLOAD_BOX = + '.AdaRedemptionForm_certificate .AdaCertificateUploadWidget_uploadBox input'; +const REDEMPTION_SUBMIT_BUTTON = + '.AdaRedemptionForm_component .AdaRedemptionForm_submitButton'; + +Given(/^I have accepted "Daedalus Redemption Disclaimer"$/, async function() { await this.client.execute(() => { daedalus.actions.adaRedemption.acceptRedemptionDisclaimer.trigger(); }); }); -Given(/^I am on the ada redemption screen$/, async function () { +Given(/^I am on the ada redemption screen$/, async function() { await navigateTo.call(this, '/ada-redemption'); return this.client.waitForVisible('.AdaRedemptionForm_component'); }); -Given(/^I see the "Daedalus Redemption Disclaimer" overlay$/, function () { - return environment.isMainnet || this.client.waitForVisible('.AdaRedemptionDisclaimer_component'); +Given(/^I see the "Daedalus Redemption Disclaimer" overlay$/, function() { + return ( + environment.isMainnet || + this.client.waitForVisible('.AdaRedemptionDisclaimer_component') + ); }); -When(/^I click on the "I've understood the information above" checkbox$/, function () { - return environment.isMainnet || this.waitAndClick('.AdaRedemptionDisclaimer_component .SimpleCheckbox_root'); -}); - -When(/^I click on the "Continue" button$/, function () { - return environment.isMainnet || this.waitAndClick('.AdaRedemptionDisclaimer_component button'); -}); - -Then(/^I should not see the "Daedalus Redemption Disclaimer" overlay anymore$/, function () { - return environment.isMainnet || this.client.waitForVisible('.AdaRedemptionDisclaimer_component', null, true); -}); +When( + /^I click on the "I've understood the information above" checkbox$/, + function() { + return ( + environment.isMainnet || + this.waitAndClick( + '.AdaRedemptionDisclaimer_component .SimpleCheckbox_root' + ) + ); + } +); + +When(/^I click on the "Continue" button$/, function() { + return ( + environment.isMainnet || + this.waitAndClick('.AdaRedemptionDisclaimer_component button') + ); +}); + +Then( + /^I should not see the "Daedalus Redemption Disclaimer" overlay anymore$/, + function() { + return ( + environment.isMainnet || + this.client.waitForVisible( + '.AdaRedemptionDisclaimer_component', + null, + true + ) + ); + } +); -Then(/^I should(?: still)? be on the ada redemption screen$/, function () { +Then(/^I should(?: still)? be on the ada redemption screen$/, function() { return this.client.waitForVisible('.AdaRedemptionForm_component'); }); -When(/^I click on ada redemption choices "([^"]*)" tab$/, function (tabText) { - return this.waitAndClick(`//div[@class="AdaRedemptionChoices_component"]/button[contains(text(), "${tabText}")]`); +When(/^I click on ada redemption choices "([^"]*)" tab$/, function(tabText) { + return this.waitAndClick( + `//div[@class="AdaRedemptionChoices_component"]/button[contains(text(), "${tabText}")]` + ); }); -When(/^I enter a valid "Regular" redemption key$/, function () { +When(/^I enter a valid "Regular" redemption key$/, function() { const redemptionKey = 'llVRYvW7LAyqmDMnUOvrs5ih4OHfLiLZrz5NT+iRuTw='; - return this.client.setValue('.AdaRedemptionForm_component .redemption-key input', redemptionKey); -}); - -When(/^I select a valid "Regular" PDF certificate$/, async function () { - await this.client.chooseFile(CERTIFICATE_UPLOAD_BOX, regularAdaCertificateFilePath); -}); - -When(/^I select a valid "Regular" encrypted PDF certificate$/, async function () { - await this.client.chooseFile(CERTIFICATE_UPLOAD_BOX, regularEncryptedAdaCertificateFilePath); -}); - -When(/^I enter a valid "Regular" encrypted PDF certificate passphrase$/, async function () { - const passphrase = ['uncle', 'bargain', 'pistol', 'obtain', 'amount', 'laugh', 'explain', 'type', 'learn']; - for (let i = 0; i < passphrase.length; i++) { - const word = passphrase[i]; - await this.client.setValue('.AdaRedemptionForm_component .pass-phrase input', word); - await this.client.waitForVisible(`//li[contains(text(), '${word}')]`); - await this.waitAndClick(`//li[contains(text(), '${word}')]`); - await this.client.waitForVisible(`//span[contains(text(), '${word}')]`); + return this.client.setValue( + '.AdaRedemptionForm_component .redemption-key input', + redemptionKey + ); +}); + +When(/^I select a valid "Regular" PDF certificate$/, async function() { + await this.client.chooseFile( + CERTIFICATE_UPLOAD_BOX, + regularAdaCertificateFilePath + ); +}); + +When( + /^I select a valid "Regular" encrypted PDF certificate$/, + async function() { + await this.client.chooseFile( + CERTIFICATE_UPLOAD_BOX, + regularEncryptedAdaCertificateFilePath + ); } -}); +); + +When( + /^I enter a valid "Regular" encrypted PDF certificate passphrase$/, + async function() { + const passphrase = [ + 'uncle', + 'bargain', + 'pistol', + 'obtain', + 'amount', + 'laugh', + 'explain', + 'type', + 'learn', + ]; + for (let i = 0; i < passphrase.length; i++) { + const word = passphrase[i]; + await this.client.setValue( + '.AdaRedemptionForm_component .pass-phrase input', + word + ); + await this.client.waitForVisible(`//li[contains(text(), '${word}')]`); + await this.waitAndClick(`//li[contains(text(), '${word}')]`); + await this.client.waitForVisible(`//span[contains(text(), '${word}')]`); + } + } +); -When(/^I enter a valid "Force vended" redemption key$/, function () { +When(/^I enter a valid "Force vended" redemption key$/, function() { const redemptionKey = 'LtOD4vxIqfEUYheTiHprRmvmAXHvMJbulllqHhjAGHc='; - return this.client.setValue('.AdaRedemptionForm_component .redemption-key input', redemptionKey); -}); - -When(/^I select a valid "Force vended" PDF certificate$/, async function () { - await this.client.chooseFile(CERTIFICATE_UPLOAD_BOX, forceVendedAdaCertificateFilePath); -}); - -When(/^I select a valid "Force vended" encrypted PDF certificate$/, async function () { - await this.client.chooseFile(CERTIFICATE_UPLOAD_BOX, forceVendedEncryptedAdaCertificateFilePath); -}); - -When(/^I enter a valid "Force vended" encrypted PDF certificate email, passcode and amount$/, async function () { - const email = 'nnmbsds@example.org'; - const passcode = 'uilfeet'; - const amount = '12345'; - await this.client.setValue('.AdaRedemptionForm_component .email input', email); - await this.client.setValue('.AdaRedemptionForm_component .ada-passcode input', passcode); - await this.client.setValue('.AdaRedemptionForm_component .ada-amount input', amount); -}); - -When(/^I enter a valid "Force vended" encrypted PDF certificate decryption key "([^"]*)"$/, async function (decryptionKey) { - await this.client.setValue('.AdaRedemptionForm_component .decryption-key input', decryptionKey); -}); - -When(/^I enter a valid "Paper vended" shielded vending key$/, function () { - return this.client.setValue('.AdaRedemptionForm_component .shielded-redemption-key input', '6ANn43jbzR7zZGnV3BYnna1myW5HajPgjiCPg4vpcayf'); -}); - -When(/^I enter a valid "Paper vended" shielded vending key passphrase$/, async function () { - const passphrase = ['fitness', 'engage', 'danger', 'escape', 'marriage', 'answer', 'coffee', 'develop', 'afraid']; - for (let i = 0; i < passphrase.length; i++) { - const word = passphrase[i]; - await this.client.setValue('.AdaRedemptionForm_component .pass-phrase input', word); - await this.client.waitForVisible(`//li[contains(text(), '${word}')]`); - await this.waitAndClick(`//li[contains(text(), '${word}')]`); - await this.client.waitForVisible(`//span[contains(text(), '${word}')]`); + return this.client.setValue( + '.AdaRedemptionForm_component .redemption-key input', + redemptionKey + ); +}); + +When(/^I select a valid "Force vended" PDF certificate$/, async function() { + await this.client.chooseFile( + CERTIFICATE_UPLOAD_BOX, + forceVendedAdaCertificateFilePath + ); +}); + +When( + /^I select a valid "Force vended" encrypted PDF certificate$/, + async function() { + await this.client.chooseFile( + CERTIFICATE_UPLOAD_BOX, + forceVendedEncryptedAdaCertificateFilePath + ); } -}); +); + +When( + /^I enter a valid "Force vended" encrypted PDF certificate email, passcode and amount$/, + async function() { + const email = 'nnmbsds@example.org'; + const passcode = 'uilfeet'; + const amount = '12345'; + await this.client.setValue( + '.AdaRedemptionForm_component .email input', + email + ); + await this.client.setValue( + '.AdaRedemptionForm_component .ada-passcode input', + passcode + ); + await this.client.setValue( + '.AdaRedemptionForm_component .ada-amount input', + amount + ); + } +); + +When( + /^I enter a valid "Force vended" encrypted PDF certificate decryption key "([^"]*)"$/, + async function(decryptionKey) { + await this.client.setValue( + '.AdaRedemptionForm_component .decryption-key input', + decryptionKey + ); + } +); + +When(/^I enter a valid "Paper vended" shielded vending key$/, function() { + return this.client.setValue( + '.AdaRedemptionForm_component .shielded-redemption-key input', + '6ANn43jbzR7zZGnV3BYnna1myW5HajPgjiCPg4vpcayf' + ); +}); + +When( + /^I enter a valid "Paper vended" shielded vending key passphrase$/, + async function() { + const passphrase = [ + 'fitness', + 'engage', + 'danger', + 'escape', + 'marriage', + 'answer', + 'coffee', + 'develop', + 'afraid', + ]; + for (let i = 0; i < passphrase.length; i++) { + const word = passphrase[i]; + await this.client.setValue( + '.AdaRedemptionForm_component .pass-phrase input', + word + ); + await this.client.waitForVisible(`//li[contains(text(), '${word}')]`); + await this.waitAndClick(`//li[contains(text(), '${word}')]`); + await this.client.waitForVisible(`//span[contains(text(), '${word}')]`); + } + } +); -When(/^ada redemption form submit button is no longer disabled$/, function () { +When(/^ada redemption form submit button is no longer disabled$/, function() { return this.client.waitForEnabled(REDEMPTION_SUBMIT_BUTTON); }); -When(/^I submit the ada redemption form$/, function () { +When(/^I submit the ada redemption form$/, function() { return this.waitAndClick(REDEMPTION_SUBMIT_BUTTON); }); -Then(/^I should see the "Ada Redemption Success Overlay"$/, function () { +Then(/^I should see the "Ada Redemption Success Overlay"$/, function() { return this.client.waitForVisible('.AdaRedemptionSuccessOverlay_component'); }); diff --git a/features/step_definitions/app-steps.js b/features/step_definitions/app-steps.js index a92a6e5a1c..f64d7b84ef 100644 --- a/features/step_definitions/app-steps.js +++ b/features/step_definitions/app-steps.js @@ -4,34 +4,39 @@ import { expect } from 'chai'; import type { Daedalus } from '../support/global-types'; import { waitUntilTextInSelector } from '../support/helpers/shared-helpers'; import { waitForCardanoNodeToExit } from '../support/helpers/cardano-node-helpers'; -import { refreshClient, waitForDaedalusToExit } from '../support/helpers/app-helpers'; +import { + refreshClient, + waitForDaedalusToExit, +} from '../support/helpers/app-helpers'; declare var daedalus: Daedalus; -Given(/^Daedalus is running$/, function () { +Given(/^Daedalus is running$/, function() { expect(this.app.isRunning()).to.be.true; }); -When(/^I refresh the main window$/, async function () { +When(/^I refresh the main window$/, async function() { await refreshClient(this.client); }); -When(/^I close the main window$/, async function () { +When(/^I close the main window$/, async function() { await this.client.execute(() => daedalus.stores.window.closeWindow()); }); -Then(/^Daedalus process is not running$/, async function () { +Then(/^Daedalus process is not running$/, async function() { await waitForDaedalusToExit(this.client); }); -Then(/^Daedalus should quit$/, { timeout: 70000 }, async function () { +Then(/^Daedalus should quit$/, { timeout: 70000 }, async function() { await waitForCardanoNodeToExit(this.client); await waitForDaedalusToExit(this.client); }); -Then(/^I should see the loading screen with "([^"]*)"$/, async function (message) { +Then(/^I should see the loading screen with "([^"]*)"$/, async function( + message +) { await waitUntilTextInSelector(this.client, { selector: '.Loading_connecting h1', - text: message + text: message, }); }); diff --git a/features/step_definitions/cardano-steps.js b/features/step_definitions/cardano-steps.js index 41022be8f1..55cb5d4dd6 100644 --- a/features/step_definitions/cardano-steps.js +++ b/features/step_definitions/cardano-steps.js @@ -3,15 +3,20 @@ import { Given, Then } from 'cucumber'; import { CardanoNodeStates } from '../../source/common/types/cardano-node.types'; import { getCardanoNodeState, - waitForCardanoNodeToExit + waitForCardanoNodeToExit, } from '../support/helpers/cardano-node-helpers'; -Given(/^cardano-node is running$/, async function () { - return await this.client.waitUntil(async () => ( - await getCardanoNodeState(this.client) === CardanoNodeStates.RUNNING - )); +Given(/^cardano-node is running$/, async function() { + return await this.client.waitUntil( + async () => + (await getCardanoNodeState(this.client)) === CardanoNodeStates.RUNNING + ); }); -Then(/^cardano-node process is not running$/, { timeout: 61000 }, async function () { - return waitForCardanoNodeToExit(this.client); -}); +Then( + /^cardano-node process is not running$/, + { timeout: 61000 }, + async function() { + return waitForCardanoNodeToExit(this.client); + } +); diff --git a/features/step_definitions/data-layer-migration.js b/features/step_definitions/data-layer-migration.js index 3143e4e31a..82b1f487f8 100644 --- a/features/step_definitions/data-layer-migration.js +++ b/features/step_definitions/data-layer-migration.js @@ -1,21 +1,28 @@ import { Given, When, Then } from 'cucumber'; -const DATA_LAYER_MIGRATION_ACCEPTANCE_COMPONENT = '.DataLayerMigrationForm_component'; +const DATA_LAYER_MIGRATION_ACCEPTANCE_COMPONENT = + '.DataLayerMigrationForm_component'; -Given(/^I haven't accepted the data layer migration$/, async function () { +Given(/^I haven't accepted the data layer migration$/, async function() { await this.client.execute(() => { daedalus.api.localStorage.unsetDataLayerMigrationAcceptance(); }); }); -Then(/^I should see the Data Layer Migration screen$/, function () { +Then(/^I should see the Data Layer Migration screen$/, function() { return this.client.waitForVisible(DATA_LAYER_MIGRATION_ACCEPTANCE_COMPONENT); }); -Then(/^I should not see the Data Layer Migration screen$/, function () { - return this.client.waitForVisible(DATA_LAYER_MIGRATION_ACCEPTANCE_COMPONENT, null, true); +Then(/^I should not see the Data Layer Migration screen$/, function() { + return this.client.waitForVisible( + DATA_LAYER_MIGRATION_ACCEPTANCE_COMPONENT, + null, + true + ); }); -When(/^I click the migration button$/, function () { - return this.waitAndClick(`${DATA_LAYER_MIGRATION_ACCEPTANCE_COMPONENT} .DataLayerMigrationForm_submitButton`); +When(/^I click the migration button$/, function() { + return this.waitAndClick( + `${DATA_LAYER_MIGRATION_ACCEPTANCE_COMPONENT} .DataLayerMigrationForm_submitButton` + ); }); diff --git a/features/step_definitions/general-settings-steps.js b/features/step_definitions/general-settings-steps.js index 0b5556701d..ff525996f6 100644 --- a/features/step_definitions/general-settings-steps.js +++ b/features/step_definitions/general-settings-steps.js @@ -5,40 +5,59 @@ import { waitUntilUrlEquals, } from '../support/helpers/route-helpers'; -Given(/^I am on the General Settings "([^"]*)" screen$/, async function (screen) { +Given(/^I am on the General Settings "([^"]*)" screen$/, async function( + screen +) { await navigateTo.call(this, `/settings/${screen}`); }); -When(/^I click on secondary menu (.*) item$/, async function (buttonName) { - const buttonSelector = `.SettingsMenuItem_component.${_.camelCase(buttonName)}`; +When(/^I click on secondary menu (.*) item$/, async function(buttonName) { + const buttonSelector = `.SettingsMenuItem_component.${_.camelCase( + buttonName + )}`; await this.client.waitForVisible(buttonSelector); await this.client.click(buttonSelector); }); -When(/^I select second theme$/, async function () { - await this.client.click('.DisplaySettings_themesWrapper > button:nth-child(2)'); +When(/^I select second theme$/, async function() { + await this.client.click( + '.DisplaySettings_themesWrapper > button:nth-child(2)' + ); }); -When(/^I open General Settings language selection dropdown$/, async function () { +When(/^I open General Settings language selection dropdown$/, async function() { await this.client.click('.GeneralSettings_component .SimpleInput_input'); }); -Then(/^I should see General Settings "([^"]*)" screen$/, async function (screenName) { +Then(/^I should see General Settings "([^"]*)" screen$/, async function( + screenName +) { return waitUntilUrlEquals.call(this, `/settings/${screenName}`); }); -Then(/^I should see Japanese language as selected$/, async function () { +Then(/^I should see Japanese language as selected$/, async function() { return this.client.waitUntil(async () => { - const selectedLanguage = await this.client.getValue('.GeneralSettings_component .SimpleInput_input'); + const selectedLanguage = await this.client.getValue( + '.GeneralSettings_component .SimpleInput_input' + ); const expectedLanguage = await this.intl('global.language.japanese'); return selectedLanguage === expectedLanguage; }); }); -Then(/^I should see second theme as selected$/, async function () { - await this.client.waitForVisible('.DisplaySettings_themesWrapper button:nth-child(2).DisplaySettings_active'); +Then(/^I should see second theme as selected$/, async function() { + await this.client.waitForVisible( + '.DisplaySettings_themesWrapper button:nth-child(2).DisplaySettings_active' + ); }); -Then(/^I should see the page with Frequency asked questions title$/, async function () { - return this.client.waitForVisible(await this.intl('settings.support.faq.title'), null, true); -}); +Then( + /^I should see the page with Frequency asked questions title$/, + async function() { + return this.client.waitForVisible( + await this.intl('settings.support.faq.title'), + null, + true + ); + } +); diff --git a/features/step_definitions/helper-steps.js b/features/step_definitions/helper-steps.js index 5b7e75bd73..2a79971fe4 100644 --- a/features/step_definitions/helper-steps.js +++ b/features/step_definitions/helper-steps.js @@ -1,29 +1,42 @@ import { When, Then } from 'cucumber'; -import { generateScreenshotFilePath, saveScreenshot } from '../support/helpers/screenshot'; +import { + generateScreenshotFilePath, + saveScreenshot, +} from '../support/helpers/screenshot'; const oneHour = 60 * 60 * 1000; // Helper step to pause execution for up to an hour ;) -When(/^I freeze$/, { timeout: oneHour }, (callback) => { +When(/^I freeze$/, { timeout: oneHour }, callback => { setTimeout(callback, oneHour); }); -Then(/^I should see the initial screen$/, function () { +Then(/^I should see the initial screen$/, function() { return this.client.waitForVisible('.SidebarLayout_component'); }); -When(/^I take a screenshot named "([^"]*)"$/, async function (testName) { +When(/^I take a screenshot named "([^"]*)"$/, async function(testName) { const file = generateScreenshotFilePath(testName); await saveScreenshot(this, file); }); -When(/^I inject fault named "([^"]*)"$/, async function (faultName) { +When(/^I inject fault named "([^"]*)"$/, async function(faultName) { await this.client.executeAsync((name, done) => { - daedalus.api.ada.setCardanoNodeFault([name, true]).then(done).catch(e => { throw e; }); + daedalus.api.ada + .setCardanoNodeFault([name, true]) + .then(done) + .catch(e => { + throw e; + }); }, faultName); }); -When(/^I trigger the apply-update endpoint$/, async function () { - await this.client.executeAsync((done) => { - daedalus.api.ada.applyUpdate().then(done).catch(e => { throw e; }); +When(/^I trigger the apply-update endpoint$/, async function() { + await this.client.executeAsync(done => { + daedalus.api.ada + .applyUpdate() + .then(done) + .catch(e => { + throw e; + }); }); }); diff --git a/features/step_definitions/local-time-difference-steps.js b/features/step_definitions/local-time-difference-steps.js index cbe864526d..ae689cb087 100644 --- a/features/step_definitions/local-time-difference-steps.js +++ b/features/step_definitions/local-time-difference-steps.js @@ -1,14 +1,15 @@ import { Given, Then } from 'cucumber'; -Given(/^I set wrong local time difference$/, async function () { +Given(/^I set wrong local time difference$/, async function() { await this.client.executeAsync((timeDifference, done) => { - daedalus.api.ada.setLocalTimeDifference(timeDifference) + daedalus.api.ada + .setLocalTimeDifference(timeDifference) .then(() => daedalus.stores.networkStatus._updateNetworkStatus()) .then(done) - .catch((error) => done(error)); + .catch(error => done(error)); }, 1511823600000); }); -Then(/^I should see system time error overlay$/, function () { +Then(/^I should see system time error overlay$/, function() { return this.client.waitForVisible('.SystemTimeErrorOverlay_component'); }); diff --git a/features/step_definitions/no-disk-space.js b/features/step_definitions/no-disk-space.js index f3db15ef57..b6d8617f8b 100644 --- a/features/step_definitions/no-disk-space.js +++ b/features/step_definitions/no-disk-space.js @@ -1,7 +1,7 @@ import { Given, When, Then } from 'cucumber'; let diskSpaceRequired; -const HUNDRED_TB = 100 * 1e+12; // 100 TB | unit: bytes +const HUNDRED_TB = 100 * 1e12; // 100 TB | unit: bytes const ONE_KB = 1 * 1000; // 1 KB | unit: bytes const NO_DISK_SPACE_COMPONENT = '.NoDiskSpaceErrorOverlay_component'; @@ -15,13 +15,17 @@ Given(/^I set the required space to 1 KB$/, () => { return true; }); -When(/^I check the disk space$/, function () { - this.client.execute((diskSpace) => { +When(/^I check the disk space$/, function() { + this.client.execute(diskSpace => { daedalus.stores.networkStatus._checkDiskSpace(diskSpace); }, diskSpaceRequired); }); -Then(/^The No Disk Space overlay should be (hidden|visible)$/, function (state) { +Then(/^The No Disk Space overlay should be (hidden|visible)$/, function(state) { const waitForHidden = state === 'hidden'; - return this.client.waitForVisible(NO_DISK_SPACE_COMPONENT, null, waitForHidden); + return this.client.waitForVisible( + NO_DISK_SPACE_COMPONENT, + null, + waitForHidden + ); }); diff --git a/features/step_definitions/node-update-notification-steps.js b/features/step_definitions/node-update-notification-steps.js index 041c064c00..a349ee6a5b 100644 --- a/features/step_definitions/node-update-notification-steps.js +++ b/features/step_definitions/node-update-notification-steps.js @@ -11,60 +11,78 @@ const DENY_BTN = '.NodeUpdateNotification_denyButton'; const UPDATE_VERSION = 50; -When(/^I make a node update available$/, async function () { - await this.client.executeAsync((nextVersion, done) => { - daedalus.api.ada.setNextUpdate(nextVersion) - .then(() => daedalus.stores.NodeUpdateStore.refreshNextUpdate()) - .then(done) - .catch((error) => done(error)); - }, { version: UPDATE_VERSION }); +When(/^I make a node update available$/, async function() { + await this.client.executeAsync( + (nextVersion, done) => { + daedalus.api.ada + .setNextUpdate(nextVersion) + .then(() => daedalus.stores.NodeUpdateStore.refreshNextUpdate()) + .then(done) + .catch(error => done(error)); + }, + { version: UPDATE_VERSION } + ); }); -Then(/^I should see the node update notification component$/, async function () { +Then(/^I should see the node update notification component$/, async function() { await this.client.waitForVisible(`${NODE_UPDATE_COMPONENT}`); }); -Then(/^I should see the notification's title bar$/, async function () { +Then(/^I should see the notification's title bar$/, async function() { await this.client.waitForVisible(`${NODE_UPDATE_COMPONENT} ${TITLE_BAR}`); }); -Then(/^I should see the expected update version in the notification's title bar$/, async function () { - const titleBarSelector = `${NODE_UPDATE_COMPONENT} ${TITLE_BAR}`; - await this.client.waitForText(titleBarSelector); - const versionText = await this.client.getText(titleBarSelector); - const expectedVersionText = await this.intl('cardano.node.update.notification.titleWithVersion', { version: UPDATE_VERSION }); - expect(versionText).to.equal(expectedVersionText); -}); +Then( + /^I should see the expected update version in the notification's title bar$/, + async function() { + const titleBarSelector = `${NODE_UPDATE_COMPONENT} ${TITLE_BAR}`; + await this.client.waitForText(titleBarSelector); + const versionText = await this.client.getText(titleBarSelector); + const expectedVersionText = await this.intl( + 'cardano.node.update.notification.titleWithVersion', + { version: UPDATE_VERSION } + ); + expect(versionText).to.equal(expectedVersionText); + } +); -Then(/^I should see the notification's toggle button$/, async function () { - await this.client.waitForVisible(`${NODE_UPDATE_COMPONENT} ${TITLE_BAR} ${TOGGLE_BUTTON}`); +Then(/^I should see the notification's toggle button$/, async function() { + await this.client.waitForVisible( + `${NODE_UPDATE_COMPONENT} ${TITLE_BAR} ${TOGGLE_BUTTON}` + ); }); -Then(/^I should see the notification's update message$/, async function () { - await this.client.waitForVisible(`${NODE_UPDATE_COMPONENT} ${UPDATE_MESSAGE}`); +Then(/^I should see the notification's update message$/, async function() { + await this.client.waitForVisible( + `${NODE_UPDATE_COMPONENT} ${UPDATE_MESSAGE}` + ); }); -Then(/^I should see the notification's accept button/, async function () { - await this.client.waitForVisible(`${NODE_UPDATE_COMPONENT} ${ACTIONS} ${ACCEPT_BTN}`); +Then(/^I should see the notification's accept button/, async function() { + await this.client.waitForVisible( + `${NODE_UPDATE_COMPONENT} ${ACTIONS} ${ACCEPT_BTN}` + ); }); -Then(/^I should see the notification's postpone button$/, async function () { - await this.client.waitForVisible(`${NODE_UPDATE_COMPONENT} ${ACTIONS} ${DENY_BTN}`); +Then(/^I should see the notification's postpone button$/, async function() { + await this.client.waitForVisible( + `${NODE_UPDATE_COMPONENT} ${ACTIONS} ${DENY_BTN}` + ); }); -When(/^I click the notification's postpone button$/, async function () { +When(/^I click the notification's postpone button$/, async function() { await this.waitAndClick(`${NODE_UPDATE_COMPONENT} ${ACTIONS} ${DENY_BTN}`); }); -When(/^I click the notification's accept button$/, async function () { +When(/^I click the notification's accept button$/, async function() { await this.waitAndClick(`${NODE_UPDATE_COMPONENT} ${ACTIONS} ${ACCEPT_BTN}`); }); -Then(/^I should not see the notification component anymore$/, async function () { +Then(/^I should not see the notification component anymore$/, async function() { await this.client.waitForVisible(NODE_UPDATE_COMPONENT, null, true); }); -Then(/^I should see the Daedalus window close$/, async function () { +Then(/^I should see the Daedalus window close$/, async function() { // there is latency between the window closing and this test running, so setTimeout await setTimeout(async () => { const windowCount = await this.client.getWindowCount(); diff --git a/features/step_definitions/paper-wallets-certificate-steps.js b/features/step_definitions/paper-wallets-certificate-steps.js index 8cc4964419..5ce682deea 100644 --- a/features/step_definitions/paper-wallets-certificate-steps.js +++ b/features/step_definitions/paper-wallets-certificate-steps.js @@ -4,13 +4,16 @@ import path from 'path'; import { fillOutWalletSendForm } from '../support/helpers/wallets-helpers'; import { waitUntilTextInSelector } from '../support/helpers/shared-helpers'; -const paperWalletCertificatePath = path.resolve(__dirname, '../support/paper_wallet_certificates/paper-wallet-certificate.pdf'); +const paperWalletCertificatePath = path.resolve( + __dirname, + '../support/paper_wallet_certificates/paper-wallet-certificate.pdf' +); -Given(/^I see the "Certificate Generation Instructions" dialog$/, function () { +Given(/^I see the "Certificate Generation Instructions" dialog$/, function() { return this.client.waitForVisible('.instructionsDialog'); }); -When(/^I click on the print button$/, async function () { +When(/^I click on the print button$/, async function() { /** * Clicking the real button would open the system dialog which we cannot test * easily. So we just skip that step and pretend the user picked a path @@ -26,39 +29,45 @@ When(/^I click on the print button$/, async function () { }, data); }); -When(/^I click on the continue button$/, function () { +When(/^I click on the continue button$/, function() { return this.waitAndClick('.continueButton'); }); -When(/^I see the "Certificate Generation Complete" dialog$/, function () { +When(/^I see the "Certificate Generation Complete" dialog$/, function() { return this.client.waitForVisible('.printDialog'); }); -When(/^I check all "Print Dialog" checkboxes$/, async function () { +When(/^I check all "Print Dialog" checkboxes$/, async function() { await this.waitAndClick('.printDialog .printedCheckbox'); await this.waitAndClick('.printDialog .readableCheckbox'); await this.waitAndClick('.printDialog .scannableCheckbox'); }); -When(/^I see the "Securing Additional mnemonics" dialog$/, function () { +When(/^I see the "Securing Additional mnemonics" dialog$/, function() { return this.client.waitForVisible('.SecuringPasswordDialog'); }); -When(/^I click on "I have written the remaining 9 words to the certificate." checkbox$/, function () { - return this.waitAndClick('.SecuringPasswordDialog .SimpleCheckbox_root'); -}); +When( + /^I click on "I have written the remaining 9 words to the certificate." checkbox$/, + function() { + return this.waitAndClick('.SecuringPasswordDialog .SimpleCheckbox_root'); + } +); -When(/^I see the "Verify Certificate" dialog$/, function () { +When(/^I see the "Verify Certificate" dialog$/, function() { return this.client.waitForVisible('.verificationDialog'); }); -When(/^I enter paper wallet recovery phrase$/, async function () { +When(/^I enter paper wallet recovery phrase$/, async function() { const fields = await this.client.execute(() => ({ - walletCertificateRecoveryPhrase: daedalus.stores.wallets.walletCertificateRecoveryPhrase, + walletCertificateRecoveryPhrase: + daedalus.stores.wallets.walletCertificateRecoveryPhrase, additionalMnemonicWords: daedalus.stores.wallets.additionalMnemonicWords, })); - const walletCertificateRecoveryPhrase = `${fields.value.walletCertificateRecoveryPhrase} ${fields.value.additionalMnemonicWords}`; + const walletCertificateRecoveryPhrase = `${ + fields.value.walletCertificateRecoveryPhrase + } ${fields.value.additionalMnemonicWords}`; if (!this.walletCertificateRecoveryPhrase) { this.walletCertificateRecoveryPhrase = walletCertificateRecoveryPhrase; @@ -67,99 +76,129 @@ When(/^I enter paper wallet recovery phrase$/, async function () { const recoveryPhrase = this.walletCertificateRecoveryPhrase.split(' '); for (let i = 0; i < recoveryPhrase.length; i++) { const word = recoveryPhrase[i]; - await this.client.setValue('.AutocompleteOverrides_autocompleteWrapper input', word); + await this.client.setValue( + '.AutocompleteOverrides_autocompleteWrapper input', + word + ); await this.client.waitForVisible(`//li[contains(text(), '${word}')]`); await this.waitAndClick(`//li[contains(text(), '${word}')]`); await this.client.waitForVisible(`//span[contains(text(), '${word}')]`); } }); -When(/^I enter wrong paper wallet recovery phrase:$/, async function (table) { +When(/^I enter wrong paper wallet recovery phrase:$/, async function(table) { const fields = table.hashes()[0]; const recoveryPhrase = fields.recoveryPhrase.split(' '); for (let i = 0; i < recoveryPhrase.length; i++) { const word = recoveryPhrase[i]; - await this.client.setValue('.AutocompleteOverrides_autocompleteWrapper input', word); + await this.client.setValue( + '.AutocompleteOverrides_autocompleteWrapper input', + word + ); await this.client.waitForVisible(`//li[contains(text(), '${word}')]`); await this.waitAndClick(`//li[contains(text(), '${word}')]`); await this.client.waitForVisible(`//span[contains(text(), '${word}')]`); } }); -When(/^I fill out the send form:$/, async function (table) { +When(/^I fill out the send form:$/, async function(table) { const values = table.hashes()[0]; values.address = this.certificateWalletAddress; return fillOutWalletSendForm.call(this, values); }); -When(/^I should see the following field error message:$/, async function (data) { +When(/^I should see the following field error message:$/, async function(data) { const error = data.hashes()[0]; await waitUntilTextInSelector(this.client, { selector: '.VerificationDialog_recoveryPhrase .SimpleFormField_error', - text: await this.intl(error.message) + text: await this.intl(error.message), }); }); -When(/^Verify certificate checkboxes should be disabled$/, async function () { - const chk1 = !await this.client.isEnabled('.storingUnderstandance input'); - const chk2 = !await this.client.isEnabled('.recoveringUnderstandance input'); +When(/^Verify certificate checkboxes should be disabled$/, async function() { + const chk1 = !(await this.client.isEnabled('.storingUnderstandance input')); + const chk2 = !(await this.client.isEnabled( + '.recoveringUnderstandance input' + )); expect(chk1 && chk2).to.equal(true); }); -When(/^Continue button should be disabled$/, async function () { +When(/^Continue button should be disabled$/, async function() { const isEnabled = await this.client.isEnabled('.continueButton'); expect(isEnabled).to.equal(false); }); -When(/^Verify certificate checkboxes are no longer disabled$/, async function () { - await this.client.waitForEnabled('.storingUnderstandance input'); - await this.client.waitForEnabled('.recoveringUnderstandance input'); -}); +When( + /^Verify certificate checkboxes are no longer disabled$/, + async function() { + await this.client.waitForEnabled('.storingUnderstandance input'); + await this.client.waitForEnabled('.recoveringUnderstandance input'); + } +); -When(/^I check all "Verify Certificate" checkboxes$/, async function () { +When(/^I check all "Verify Certificate" checkboxes$/, async function() { await this.waitAndClick('.storingUnderstandance'); await this.waitAndClick('.recoveringUnderstandance'); }); -When(/^I see the "Paper Wallet Certificate" dialog$/, function () { +When(/^I see the "Paper Wallet Certificate" dialog$/, function() { return this.client.waitForVisible('.completionDialog'); }); -When(/^Cardano explorer link and wallet address should be valid$/, async function () { - const visibleCardanoExplorerLink = await this.client.getText('.CompletionDialog_linkInstructionsWrapper .CompletionDialog_infoBox .CompletionDialog_link'); - const walletCertificateAddress = await this.client.execute(() => ( - daedalus.stores.wallets.walletCertificateAddress - )); - const cardanoExplorerLink = `https://cardanoexplorer.com/address/${walletCertificateAddress.value}`; - this.certificateWalletAddress = walletCertificateAddress.value; - - const visibleWalletAddress = await this.client.getText('.CompletionDialog_addressInstructionsWrapper .CompletionDialog_infoBox'); - - expect(cardanoExplorerLink).to.equal(visibleCardanoExplorerLink); - expect(walletCertificateAddress.value).to.equal(visibleWalletAddress); -}); +When( + /^Cardano explorer link and wallet address should be valid$/, + async function() { + const visibleCardanoExplorerLink = await this.client.getText( + '.CompletionDialog_linkInstructionsWrapper .CompletionDialog_infoBox .CompletionDialog_link' + ); + const walletCertificateAddress = await this.client.execute( + () => daedalus.stores.wallets.walletCertificateAddress + ); + const cardanoExplorerLink = `https://cardanoexplorer.com/address/${ + walletCertificateAddress.value + }`; + this.certificateWalletAddress = walletCertificateAddress.value; + + const visibleWalletAddress = await this.client.getText( + '.CompletionDialog_addressInstructionsWrapper .CompletionDialog_infoBox' + ); + + expect(cardanoExplorerLink).to.equal(visibleCardanoExplorerLink); + expect(walletCertificateAddress.value).to.equal(visibleWalletAddress); + } +); -When(/^I click on the finish button$/, function () { +When(/^I click on the finish button$/, function() { return this.waitAndClick('.finishButton'); }); -When(/^I should not see the create paper wallet certificate dialog anymore$/, function () { - return this.client.waitForVisible('.completionDialog', null, true); -}); +When( + /^I should not see the create paper wallet certificate dialog anymore$/, + function() { + return this.client.waitForVisible('.completionDialog', null, true); + } +); -When(/^I click "Paper wallet certificate" tab$/, function () { +When(/^I click "Paper wallet certificate" tab$/, function() { return this.waitAndClick('.certificateTab'); }); -When(/^I see "Restore wallet with certificate" form$/, function () { - return this.client.waitForVisible('.WalletRestoreDialog_dialogWithCertificateRestore'); +When(/^I see "Restore wallet with certificate" form$/, function() { + return this.client.waitForVisible( + '.WalletRestoreDialog_dialogWithCertificateRestore' + ); }); -When(/^I toggle "Spending password" switch on the restore wallet with certificate dialog$/, function () { - return this.waitAndClick('.WalletRestoreDialog_dialogWithCertificateRestore .SimpleSwitch_switch'); -}); +When( + /^I toggle "Spending password" switch on the restore wallet with certificate dialog$/, + function() { + return this.waitAndClick( + '.WalletRestoreDialog_dialogWithCertificateRestore .SimpleSwitch_switch' + ); + } +); -Then(/^I should see that address was used$/, async function () { +Then(/^I should see that address was used$/, async function() { const addressSelector = '.Address_usedWalletAddress .Address_addressId'; await this.client.waitForVisible(addressSelector); const usedAddress = await this.client.getText(addressSelector); diff --git a/features/step_definitions/receive-steps.js b/features/step_definitions/receive-steps.js index 0dae605d03..bbc2d275a0 100644 --- a/features/step_definitions/receive-steps.js +++ b/features/step_definitions/receive-steps.js @@ -1,39 +1,61 @@ import { Given, When, Then } from 'cucumber'; import { expect } from 'chai'; -import { waitAndClick, getVisibleElementsCountForSelector } from '../support/helpers/shared-helpers'; +import { + waitAndClick, + getVisibleElementsCountForSelector, +} from '../support/helpers/shared-helpers'; -Given('I generate {int} addresses', async function (numberOfAddresses) { +Given('I generate {int} addresses', async function(numberOfAddresses) { for (let i = 0; i < numberOfAddresses; i++) { - await waitAndClick(this.client, '.generateAddressButton:not(.WalletReceive_spinning)'); + await waitAndClick( + this.client, + '.generateAddressButton:not(.WalletReceive_spinning)' + ); } }); -When('I click the ShowUsed switch', async function () { +When('I click the ShowUsed switch', async function() { await waitAndClick(this.client, '.SimpleSwitch_switch'); }); -Then('I should see {int} used addresses', { timeout: 60000 }, async function (numberOfAddresses) { - const addressesFound = await getVisibleElementsCountForSelector(this.client, '.Address_usedWalletAddress', '.Address_usedWalletAddress', 60000); +Then('I should see {int} used addresses', { timeout: 60000 }, async function( + numberOfAddresses +) { + const addressesFound = await getVisibleElementsCountForSelector( + this.client, + '.Address_usedWalletAddress', + '.Address_usedWalletAddress', + 60000 + ); expect(addressesFound).to.equal(numberOfAddresses); }); -Then('I should see {int} addresses', async function (numberOfAddresses) { - const addressesFound = await getVisibleElementsCountForSelector(this.client, '.Address_component'); +Then('I should see {int} addresses', async function(numberOfAddresses) { + const addressesFound = await getVisibleElementsCountForSelector( + this.client, + '.Address_component' + ); expect(addressesFound).to.equal(numberOfAddresses); }); -Then('I should see the following addresses:', async function (table) { +Then('I should see the following addresses:', async function(table) { const expectedAdresses = table.hashes(); let addresses; await this.client.waitUntil(async () => { addresses = await this.client.getAttribute('.Address_component', 'class'); return addresses.length === expectedAdresses.length; }); - addresses.forEach((address, index) => expect(address).to.include(expectedAdresses[index].ClassName)); + addresses.forEach((address, index) => + expect(address).to.include(expectedAdresses[index].ClassName) + ); }); -Then('The active address should be the newest one', async function () { - const { value: { id: lastGeneratedAddress } } = await this.client.execute(() => daedalus.stores.addresses.lastGeneratedAddress); +Then('The active address should be the newest one', async function() { + const { + value: { id: lastGeneratedAddress }, + } = await this.client.execute( + () => daedalus.stores.addresses.lastGeneratedAddress + ); const activeAddress = await this.client.getText('.WalletReceive_hash'); expect(lastGeneratedAddress).to.equal(activeAddress); }); diff --git a/features/step_definitions/select-language-steps.js b/features/step_definitions/select-language-steps.js index 91b7e89432..57364a565d 100644 --- a/features/step_definitions/select-language-steps.js +++ b/features/step_definitions/select-language-steps.js @@ -4,41 +4,48 @@ import languageSelection from '../support/helpers/language-selection-helpers'; const LANGUAGE_SELECTION_FORM = '.LanguageSelectionForm_component'; -Given(/^I have selected English language$/, async function () { - await languageSelection.ensureLanguageIsSelected(this.client, { language: 'en-US' }); +Given(/^I have selected English language$/, async function() { + await languageSelection.ensureLanguageIsSelected(this.client, { + language: 'en-US', + }); }); -Given(/^I dont have a language set$/, async function () { +Given(/^I dont have a language set$/, async function() { await this.client.execute(() => { daedalus.reset(); }); }); -When(/^I am on the language selection screen$/, function () { +When(/^I am on the language selection screen$/, function() { return this.client.waitForVisible('.LanguageSelectionForm_component'); }); -When(/^I open language selection dropdown$/, function () { - return this.waitAndClick('.LanguageSelectionForm_component .SimpleInput_input'); +When(/^I open language selection dropdown$/, function() { + return this.waitAndClick( + '.LanguageSelectionForm_component .SimpleInput_input' + ); }); -When(/^I select Japanese language$/, function () { - return this.waitAndClick('//*[@class="SimpleOptions_label"][contains(text(), "Japanese")]'); +When(/^I select Japanese language$/, function() { + return this.waitAndClick( + '//*[@class="SimpleOptions_label"][contains(text(), "Japanese")]' + ); }); -When(/^I submit the language selection form$/, function () { +When(/^I submit the language selection form$/, function() { return this.waitAndClick('.LanguageSelectionForm_submitButton'); }); -Then(/^I should not see the language selection screen anymore$/, function () { +Then(/^I should not see the language selection screen anymore$/, function() { return this.client.waitForVisible(LANGUAGE_SELECTION_FORM, null, true); }); -Then(/^I should have Japanese language set$/, async function () { - const result = await this.client.executeAsync((done) => { - daedalus.stores.profile.getProfileLocaleRequest.execute() +Then(/^I should have Japanese language set$/, async function() { + const result = await this.client.executeAsync(done => { + daedalus.stores.profile.getProfileLocaleRequest + .execute() .then(done) - .catch((error) => done(error)); + .catch(error => done(error)); }); expect(result.value).to.equal('ja-JP'); }); diff --git a/features/step_definitions/settings-steps.js b/features/step_definitions/settings-steps.js index 7e03e5886a..00b115c7a7 100644 --- a/features/step_definitions/settings-steps.js +++ b/features/step_definitions/settings-steps.js @@ -3,98 +3,138 @@ import { expect } from 'chai'; import { navigateTo } from '../support/helpers/route-helpers'; import { waitUntilWaletNamesEqual, - getNameOfActiveWalletInSidebar + getNameOfActiveWalletInSidebar, } from '../support/helpers/wallets-helpers'; -Given(/^I am on the settings screen$/, async function () { +Given(/^I am on the settings screen$/, async function() { await navigateTo.call(this, '/settings'); return this.client.waitForVisible('.SettingsLayout_component'); }); -Given(/^I should see the "([^"]*)" wallet password dialog$/, function (dialogType) { +Given(/^I should see the "([^"]*)" wallet password dialog$/, function( + dialogType +) { const selector = '.' + dialogType + 'PasswordDialog'; return this.client.waitForVisible(selector); }); -When(/^I click on the "([^"]*)" password label$/, function (label) { +When(/^I click on the "([^"]*)" password label$/, function(label) { const selector = '.' + label + 'Label button'; return this.client.click(selector); }); -When(/^I enter wallet password:$/, async function (table) { +When(/^I enter wallet password:$/, async function(table) { const fields = table.hashes()[0]; - await this.client.setValue('.createPasswordDialog .newPassword input', fields.password); - await this.client.setValue('.createPasswordDialog .repeatedPassword input', fields.repeatedPassword); + await this.client.setValue( + '.createPasswordDialog .newPassword input', + fields.password + ); + await this.client.setValue( + '.createPasswordDialog .repeatedPassword input', + fields.repeatedPassword + ); }); -When(/^I submit the wallet password dialog$/, function () { +When(/^I submit the wallet password dialog$/, function() { return this.client.click('.confirmButton'); }); -When(/^I change wallet password:$/, async function (table) { +When(/^I change wallet password:$/, async function(table) { const fields = table.hashes()[0]; - await this.client.setValue('.changePasswordDialog .currentPassword input', fields.currentPassword); - await this.client.setValue('.changePasswordDialog .newPassword input', fields.password); - await this.client.setValue('.changePasswordDialog .repeatedPassword input', fields.repeatedPassword); -}); - -Then(/^I should not see the change password dialog anymore$/, function () { + await this.client.setValue( + '.changePasswordDialog .currentPassword input', + fields.currentPassword + ); + await this.client.setValue( + '.changePasswordDialog .newPassword input', + fields.password + ); + await this.client.setValue( + '.changePasswordDialog .repeatedPassword input', + fields.repeatedPassword + ); +}); + +Then(/^I should not see the change password dialog anymore$/, function() { return this.client.waitForVisible('.changePasswordDialog', null, true); }); -When(/^I toggle "Check to deactivate password" switch on the change wallet password dialog$/, function () { - return this.waitAndClick('.changePasswordDialog .SimpleSwitch_switch'); -}); +When( + /^I toggle "Check to deactivate password" switch on the change wallet password dialog$/, + function() { + return this.waitAndClick('.changePasswordDialog .SimpleSwitch_switch'); + } +); -When(/^I enter current wallet password:$/, async function (table) { +When(/^I enter current wallet password:$/, async function(table) { const fields = table.hashes()[0]; - await this.client.setValue('.changePasswordDialog .currentPassword input', fields.currentPassword); + await this.client.setValue( + '.changePasswordDialog .currentPassword input', + fields.currentPassword + ); }); -When(/^I click on "name" input field$/, function () { - return this.client.click('.WalletSettings_component .InlineEditingInput_component'); +When(/^I click on "name" input field$/, function() { + return this.client.click( + '.WalletSettings_component .InlineEditingInput_component' + ); }); -When(/^I enter new wallet name:$/, async function (table) { +When(/^I enter new wallet name:$/, async function(table) { const fields = table.hashes()[0]; - await this.client.setValue('.WalletSettings_component .walletName input', fields.name); + await this.client.setValue( + '.WalletSettings_component .walletName input', + fields.name + ); }); -When(/^I click outside "name" input field$/, function () { +When(/^I click outside "name" input field$/, function() { return this.client.click('.WalletSettings_component'); }); -When(/^I open "Transaction assurance security level" selection dropdown$/, function () { - return this.waitAndClick('.WalletSettings_component .walletAssuranceLevel input'); -}); - -When(/^I select "Strict" assurance level$/, function () { - return this.waitAndClick('//*[@class="SimpleOptions_label"][contains(text(), "Strict")]'); -}); - -Then(/^I should have wallet with "Strict" assurance level set$/, async function () { - const activeWalletName = await getNameOfActiveWalletInSidebar.call(this); - const wallets = await this.client.executeAsync((done) => { - daedalus.stores.wallets.walletsRequest.execute() - .then(done) - .catch((error) => done(error)); - }); - const activeWallet = wallets.value.find((w) => w.name === activeWalletName); - expect(activeWallet.assurance).to.equal('strict'); -}); - -Then(/^I should see new wallet name "([^"]*)"$/, async function (walletName) { +When( + /^I open "Transaction assurance security level" selection dropdown$/, + function() { + return this.waitAndClick( + '.WalletSettings_component .walletAssuranceLevel input' + ); + } +); + +When(/^I select "Strict" assurance level$/, function() { + return this.waitAndClick( + '//*[@class="SimpleOptions_label"][contains(text(), "Strict")]' + ); +}); + +Then( + /^I should have wallet with "Strict" assurance level set$/, + async function() { + const activeWalletName = await getNameOfActiveWalletInSidebar.call(this); + const wallets = await this.client.executeAsync(done => { + daedalus.stores.wallets.walletsRequest + .execute() + .then(done) + .catch(error => done(error)); + }); + const activeWallet = wallets.value.find(w => w.name === activeWalletName); + expect(activeWallet.assurance).to.equal('strict'); + } +); + +Then(/^I should see new wallet name "([^"]*)"$/, async function(walletName) { return waitUntilWaletNamesEqual.call(this, walletName); }); -Then(/^I should see "([^"]*)" label in password field$/, function (label) { +Then(/^I should see "([^"]*)" label in password field$/, function(label) { const selector = '.' + label + 'Label'; return this.client.waitForVisible(selector); }); -Then(/^I should see the following error messages:$/, async function (data) { +Then(/^I should see the following error messages:$/, async function(data) { const error = data.hashes()[0]; - const errorSelector = '.ChangeSpendingPasswordDialog_newPassword .SimpleFormField_error'; + const errorSelector = + '.ChangeSpendingPasswordDialog_newPassword .SimpleFormField_error'; await this.client.waitForText(errorSelector); const errorsOnScreen = await this.client.getText(errorSelector); const expectedError = await this.intl(error.message); diff --git a/features/step_definitions/setup-steps.js b/features/step_definitions/setup-steps.js index bd9dde34db..1eedde8e7a 100644 --- a/features/step_definitions/setup-steps.js +++ b/features/step_definitions/setup-steps.js @@ -3,8 +3,10 @@ import termsOfUse from '../support/helpers/terms-of-use-helpers'; import languageSelection from '../support/helpers/language-selection-helpers'; import dataLayerMigration from '../support/helpers/data-layer-migration-helpers'; -Given(/^I have completed the basic setup$/, async function () { - await languageSelection.ensureLanguageIsSelected(this.client, { language: 'en-US' }); +Given(/^I have completed the basic setup$/, async function() { + await languageSelection.ensureLanguageIsSelected(this.client, { + language: 'en-US', + }); await termsOfUse.acceptTerms(this.client); await dataLayerMigration.acceptMigration(this.client); }); diff --git a/features/step_definitions/sidebar-steps.js b/features/step_definitions/sidebar-steps.js index a6d919d40e..5e87f3fef9 100644 --- a/features/step_definitions/sidebar-steps.js +++ b/features/step_definitions/sidebar-steps.js @@ -1,7 +1,7 @@ import { Given, When, Then } from 'cucumber'; import sidebar from '../support/helpers/sidebar-helpers'; -Given(/^the sidebar submenu is (hidden|visible)/, async function (state) { +Given(/^the sidebar submenu is (hidden|visible)/, async function(state) { const isVisible = state === 'visible'; await this.client.waitForVisible('.Sidebar_component'); await this.client.executeAsync((visible, done) => { @@ -15,7 +15,10 @@ Given(/^the sidebar submenu is (hidden|visible)/, async function (state) { // Wait until the sidebar transition is finished -> otherwise webdriver click error! const sidebarElement = document.querySelectorAll('.Sidebar_component')[0]; const onTransitionFinished = () => { - sidebarElement.removeEventListener('transitioned', onTransitionFinished); + sidebarElement.removeEventListener( + 'transitioned', + onTransitionFinished + ); done(); }; sidebarElement.addEventListener('transitionend', onTransitionFinished); @@ -26,31 +29,37 @@ Given(/^the sidebar submenu is (hidden|visible)/, async function (state) { return this.client.waitForExist('.SidebarMenu_visible', null, !isVisible); }); -Given(/^The sidebar shows the "([^"]*)" category$/, function (category) { +Given(/^The sidebar shows the "([^"]*)" category$/, function(category) { return sidebar.activateCategory(this.client, { category }); }); -When(/^I click on the sidebar toggle button$/, function () { +When(/^I click on the sidebar toggle button$/, function() { return this.waitAndClick('.SidebarLayout_topbar .TopBar_leftIcon'); }); -When(/^I click on the "([^"]*)" category in the sidebar$/, function (category) { +When(/^I click on the "([^"]*)" category in the sidebar$/, function(category) { return this.waitAndClick(`.SidebarCategory_component.${category}`); }); -When(/^I click on the add wallet button in the sidebar$/, function () { +When(/^I click on the add wallet button in the sidebar$/, function() { return sidebar.clickAddWalletButton(this.client); }); -When(/^I click on the "([^"]*)" wallet in the sidebar$/, function (walletName) { - return this.waitAndClick(`//*[contains(text(), "${walletName}") and @class="SidebarWalletMenuItem_title"]`); +When(/^I click on the "([^"]*)" wallet in the sidebar$/, function(walletName) { + return this.waitAndClick( + `//*[contains(text(), "${walletName}") and @class="SidebarWalletMenuItem_title"]` + ); }); -Then(/^the sidebar submenu should be (hidden|visible)/, function (state) { +Then(/^the sidebar submenu should be (hidden|visible)/, function(state) { const waitForHidden = state === 'hidden'; - return this.client.waitForVisible('.SidebarMenu_component', null, waitForHidden); + return this.client.waitForVisible( + '.SidebarMenu_component', + null, + waitForHidden + ); }); -Then(/^The "([^"]*)" category should be active$/, function (category) { +Then(/^The "([^"]*)" category should be active$/, function(category) { return this.client.waitForVisible(`.SidebarCategory_active.${category}`); }); diff --git a/features/step_definitions/transactions-steps.js b/features/step_definitions/transactions-steps.js index 8192b5fd8d..f932d632a1 100644 --- a/features/step_definitions/transactions-steps.js +++ b/features/step_definitions/transactions-steps.js @@ -1,66 +1,96 @@ import { Given, When, Then } from 'cucumber'; import { expect } from 'chai'; import BigNumber from 'bignumber.js/bignumber'; -import { DECIMAL_PLACES_IN_ADA, LOVELACES_PER_ADA } from '../../source/renderer/app/config/numbersConfig'; +import { + DECIMAL_PLACES_IN_ADA, + LOVELACES_PER_ADA, +} from '../../source/renderer/app/config/numbersConfig'; import { getVisibleTextsForSelector } from '../support/helpers/shared-helpers'; import { getWalletByName } from '../support/helpers/wallets-helpers'; // This step ensures sequential creation of given transactions // use only when the order is important because it's slower! -Given(/^I have made the following transactions:$/, { timeout: 40000 }, async function (table) { - const txData = table.hashes().map((t) => ({ - walletId: getWalletByName.call(this, t.source).id, - destinationWalletId: getWalletByName.call(this, t.destination).id, - amount: parseInt(new BigNumber(t.amount).times(LOVELACES_PER_ADA), 10), - spendingPassword: t.password || null, - })); - this.transactions = []; - // Sequentially (and async) create transactions with for loop - for (const tx of txData) { - const txResponse = await this.client.executeAsync((transaction, done) => ( - new window.Promise((resolve) => ( - // Need to fetch the wallets data async and wait for all results - window.Promise.all([ - daedalus.stores.addresses.getAccountIndexByWalletId(transaction.walletId), - daedalus.stores.addresses.getAddressesByWalletId(transaction.destinationWalletId) - ]).then(results => ( - daedalus.api.ada.createTransaction(window.Object.assign(transaction, { - accountIndex: results[0], // Account index of sender wallet - address: results[1][0].id // First address of receiving wallet - })).then(resolve) - )) - )).then(done) - ), tx); - this.transactions.push(txResponse); +Given( + /^I have made the following transactions:$/, + { timeout: 40000 }, + async function(table) { + const txData = table.hashes().map(t => ({ + walletId: getWalletByName.call(this, t.source).id, + destinationWalletId: getWalletByName.call(this, t.destination).id, + amount: parseInt(new BigNumber(t.amount).times(LOVELACES_PER_ADA), 10), + spendingPassword: t.password || null, + })); + this.transactions = []; + // Sequentially (and async) create transactions with for loop + for (const tx of txData) { + const txResponse = await this.client.executeAsync( + (transaction, done) => + new window.Promise(resolve => + // Need to fetch the wallets data async and wait for all results + window.Promise.all([ + daedalus.stores.addresses.getAccountIndexByWalletId( + transaction.walletId + ), + daedalus.stores.addresses.getAddressesByWalletId( + transaction.destinationWalletId + ), + ]).then(results => + daedalus.api.ada + .createTransaction( + window.Object.assign(transaction, { + accountIndex: results[0], // Account index of sender wallet + address: results[1][0].id, // First address of receiving wallet + }) + ) + .then(resolve) + ) + ).then(done), + tx + ); + this.transactions.push(txResponse); + } } -}); +); -Then(/^I should not see any transactions$/, async function () { +Then(/^I should not see any transactions$/, async function() { await this.client.waitForVisible('.Transaction_component', null, true); }); -Then(/^I should see the no recent transactions message$/, async function () { +Then(/^I should see the no recent transactions message$/, async function() { await this.client.waitForVisible('.WalletNoTransactions_label'); }); -Then(/^I should see the following transactions:$/, async function (table) { +Then(/^I should see the following transactions:$/, async function(table) { // Prepare expected transaction data - const expectedTxs = await Promise.all(table.hashes().map(async (tx) => { - let title; - switch (tx.type) { - case 'income': title = 'wallet.transaction.received'; break; - case 'expend': title = 'wallet.transaction.sent'; break; - default: throw new Error('unknown transaction type'); - } - return { - title: await this.intl(title, { currency: 'ADA' }), - amount: new BigNumber(tx.amount).toFormat(DECIMAL_PLACES_IN_ADA), - }; - })); + const expectedTxs = await Promise.all( + table.hashes().map(async tx => { + let title; + switch (tx.type) { + case 'income': + title = 'wallet.transaction.received'; + break; + case 'expend': + title = 'wallet.transaction.sent'; + break; + default: + throw new Error('unknown transaction type'); + } + return { + title: await this.intl(title, { currency: 'ADA' }), + amount: new BigNumber(tx.amount).toFormat(DECIMAL_PLACES_IN_ADA), + }; + }) + ); // Collect data of visible transactions on screen - const txTitles = await getVisibleTextsForSelector(this.client, '.Transaction_title'); - const txAmounts = await getVisibleTextsForSelector(this.client, '.Transaction_amount'); + const txTitles = await getVisibleTextsForSelector( + this.client, + '.Transaction_title' + ); + const txAmounts = await getVisibleTextsForSelector( + this.client, + '.Transaction_amount' + ); const visibleTxs = txTitles.map((title, index) => ({ title, amount: txAmounts[index], @@ -69,6 +99,6 @@ Then(/^I should see the following transactions:$/, async function (table) { expect(expectedTxs).to.deep.equal(visibleTxs); }); -When(/^I click on the show more transactions button$/, async function () { +When(/^I click on the show more transactions button$/, async function() { await this.waitAndClick('.WalletTransactionsList_showMoreTransactionsButton'); }); diff --git a/features/step_definitions/wallets-limit.js b/features/step_definitions/wallets-limit.js index ddefa8ada6..8b1b2850dc 100644 --- a/features/step_definitions/wallets-limit.js +++ b/features/step_definitions/wallets-limit.js @@ -1,55 +1,79 @@ import { Given, When, Then } from 'cucumber'; import { expect } from 'chai'; -import { createWallets, getWalletByName } from '../support/helpers/wallets-helpers'; +import { + createWallets, + getWalletByName, +} from '../support/helpers/wallets-helpers'; import { MAX_ADA_WALLETS_COUNT } from '../../source/renderer/app/config/numbersConfig'; import sidebar from '../support/helpers/sidebar-helpers'; -Given('I create wallets until I reach the maximum number permitted', async function () { - const wallets = [...Array(MAX_ADA_WALLETS_COUNT)].map((x, i) => ({ - name: `Wallet ${i + 1}`, - password: '' - })); - await createWallets(wallets, this); -}); +Given( + 'I create wallets until I reach the maximum number permitted', + async function() { + const wallets = [...Array(MAX_ADA_WALLETS_COUNT)].map((x, i) => ({ + name: `Wallet ${i + 1}`, + password: '', + })); + await createWallets(wallets, this); + } +); -When('I should see maximum number of wallets in the wallets list', async function () { - const wallets = await this.client.elements('.SidebarWalletMenuItem_component'); - expect(wallets.value.length).to.equal(MAX_ADA_WALLETS_COUNT); -}); +When( + 'I should see maximum number of wallets in the wallets list', + async function() { + const wallets = await this.client.elements( + '.SidebarWalletMenuItem_component' + ); + expect(wallets.value.length).to.equal(MAX_ADA_WALLETS_COUNT); + } +); -When('I delete the last wallet', async function () { +When('I delete the last wallet', async function() { const wallet = getWalletByName.call(this, 'Wallet 20'); await this.client.execute( walletId => daedalus.actions.wallets.deleteWallet.trigger({ walletId }), wallet.id ); await this.client.waitUntil(async () => { - const wallets = await this.client.elements('.SidebarWalletMenuItem_component'); + const wallets = await this.client.elements( + '.SidebarWalletMenuItem_component' + ); return wallets.value.length < MAX_ADA_WALLETS_COUNT; }); }); -Then(/^the buttons in the Add Wallet screen should be (disabled|enabled)/, async function (state) { - const isDisabled = state === 'disabled' ? 'true' : null; +Then( + /^the buttons in the Add Wallet screen should be (disabled|enabled)/, + async function(state) { + const isDisabled = state === 'disabled' ? 'true' : null; - sidebar.clickAddWalletButton(this.client); + sidebar.clickAddWalletButton(this.client); - await this.client.waitForVisible('.WalletAdd_buttonsContainer .BigButtonForDialogs_component'); + await this.client.waitForVisible( + '.WalletAdd_buttonsContainer .BigButtonForDialogs_component' + ); - const buttonsAreDisabled = await this.client - .getAttribute('.WalletAdd_buttonsContainer .BigButtonForDialogs_component', 'disabled'); + const buttonsAreDisabled = await this.client.getAttribute( + '.WalletAdd_buttonsContainer .BigButtonForDialogs_component', + 'disabled' + ); - // Excludes the "Join shared wallet" button - buttonsAreDisabled.splice(1, 1); + // Excludes the "Join shared wallet" button + buttonsAreDisabled.splice(1, 1); - expect(buttonsAreDisabled) - .to.be.an('array') - .that.include(isDisabled) - .and.not.include(!isDisabled); + expect(buttonsAreDisabled) + .to.be.an('array') + .that.include(isDisabled) + .and.not.include(!isDisabled); + } +); -}); - -Then('I should see a disclaimer saying I have reached the maximum number of wallets', async function () { - const disclaimer = await this.client.getText('.WalletAdd_notification'); - expect(disclaimer.replace(/\n/, ' ')).to.equal(`You have reached the maximum of ${MAX_ADA_WALLETS_COUNT} wallets. No more wallets can be added.`); -}); +Then( + 'I should see a disclaimer saying I have reached the maximum number of wallets', + async function() { + const disclaimer = await this.client.getText('.WalletAdd_notification'); + expect(disclaimer.replace(/\n/, ' ')).to.equal( + `You have reached the maximum of ${MAX_ADA_WALLETS_COUNT} wallets. No more wallets can be added.` + ); + } +); diff --git a/features/step_definitions/wallets-steps.js b/features/step_definitions/wallets-steps.js index a926ae009f..02c52f7933 100644 --- a/features/step_definitions/wallets-steps.js +++ b/features/step_definitions/wallets-steps.js @@ -8,7 +8,7 @@ import { getWalletByName, waitUntilWalletIsLoaded, addOrSetWalletsForScenario, - importWalletWithFunds + importWalletWithFunds, } from '../support/helpers/wallets-helpers'; import { waitUntilUrlEquals, @@ -21,14 +21,17 @@ import importWalletDialog from '../support/helpers/dialogs/import-wallet-dialog- import i18n from '../support/helpers/i18n-helpers'; import { isActiveWalletBeingRestored, - waitForActiveRestoreNotification + waitForActiveRestoreNotification, } from '../support/helpers/notifications-helpers'; -const defaultWalletKeyFilePath = path.resolve(__dirname, '../support/default-wallet.key'); +const defaultWalletKeyFilePath = path.resolve( + __dirname, + '../support/default-wallet.key' +); // const defaultWalletJSONFilePath = path.resolve(__dirname, '../support/default-wallet.json'); // ^^ JSON wallet file import is currently not working due to missing JSON import V1 API endpoint -Given(/^I have a "Imported Wallet" with funds$/, async function () { +Given(/^I have a "Imported Wallet" with funds$/, async function() { await importWalletWithFunds(this.client, { keyFilePath: defaultWalletKeyFilePath, password: null, @@ -40,7 +43,7 @@ Given(/^I have a "Imported Wallet" with funds$/, async function () { // V1 API endpoint for importing a wallet with a spending-password is currently broken // As a temporary workaround we import the wallet without a spending-password // and then create a spending-password in a separate call -Given(/^I have a "Imported Wallet" with funds and password$/, async function () { +Given(/^I have a "Imported Wallet" with funds and password$/, async function() { await importWalletWithFunds(this.client, { keyFilePath: defaultWalletKeyFilePath, password: null, // 'Secret123', @@ -50,259 +53,352 @@ Given(/^I have a "Imported Wallet" with funds and password$/, async function () // Create a spending-password in a separate call await this.client.executeAsync((walletId, done) => { - daedalus.api.ada.updateSpendingPassword({ - walletId, - oldPassword: null, - newPassword: 'Secret123', - }) - .then(() => ( - daedalus.stores.wallets.refreshWalletsData() + daedalus.api.ada + .updateSpendingPassword({ + walletId, + oldPassword: null, + newPassword: 'Secret123', + }) + .then(() => + daedalus.stores.wallets + .refreshWalletsData() .then(done) - .catch((error) => done(error)) - )) - .catch((error) => done(error)); + .catch(error => done(error)) + ) + .catch(error => done(error)); }, wallet.id); }); -Given(/^I have the following wallets:$/, async function (table) { +Given(/^I have the following wallets:$/, async function(table) { await createWallets(table.hashes(), this); }); // Creates them sequentially -Given(/^I have created the following wallets:$/, async function (table) { +Given(/^I have created the following wallets:$/, async function(table) { await createWallets(table.hashes(), this, { sequentially: true }); }); -Given(/^I am on the "([^"]*)" wallet "([^"]*)" screen$/, async function (walletName, screen) { +Given(/^I am on the "([^"]*)" wallet "([^"]*)" screen$/, async function( + walletName, + screen +) { const wallet = getWalletByName.call(this, walletName); await navigateTo.call(this, `/wallets/${wallet.id}/${screen}`); }); -Given(/^I see the add wallet page/, function () { +Given(/^I see the add wallet page/, function() { return addWalletPage.waitForVisible(this.client); }); -Given(/^I see delete wallet dialog$/, function () { +Given(/^I see delete wallet dialog$/, function() { return this.client.waitForVisible('.DeleteWalletConfirmationDialog_dialog'); }); -Given(/^I see the create wallet dialog$/, function () { +Given(/^I see the create wallet dialog$/, function() { return this.client.waitForVisible('.WalletCreateDialog'); }); -Given(/^I see the restore wallet dialog$/, function () { +Given(/^I see the restore wallet dialog$/, function() { return this.client.waitForVisible('.WalletRestoreDialog'); }); -Given(/^I dont see the create wallet dialog(?: anymore)?$/, function () { +Given(/^I dont see the create wallet dialog(?: anymore)?$/, function() { return this.client.waitForVisible('.WalletCreateDialog', null, true); }); -Given(/^the active wallet is "([^"]*)"$/, function (walletName) { +Given(/^the active wallet is "([^"]*)"$/, function(walletName) { const wallet = getWalletByName.call(this, walletName); this.client.execute(walletId => { daedalus.actions.setActiveWallet.trigger({ walletId }); }, wallet.id); }); -When(/^I click on the create wallet button on the add wallet page/, function () { +When(/^I click on the create wallet button on the add wallet page/, function() { return this.waitAndClick('.WalletAdd .createWalletButton'); }); -When(/^I click on the import wallet button on the add wallet page/, function () { +When(/^I click on the import wallet button on the add wallet page/, function() { return addWalletPage.clickImportButton(this.client); }); -When(/^I see the import wallet dialog$/, function () { +When(/^I see the import wallet dialog$/, function() { return importWalletDialog.waitForDialog(this.client); }); -When(/^I select a valid wallet import key file$/, function () { +When(/^I select a valid wallet import key file$/, function() { // return importWalletDialog.selectFile(this.client, { filePath: defaultWalletJSONFilePath }); // ^^ JSON wallet file import is currently not working due to missing JSON import V1 API endpoint // so we have to use the KEY wallet file instead: - return importWalletDialog.selectFile(this.client, { filePath: defaultWalletKeyFilePath }); + return importWalletDialog.selectFile(this.client, { + filePath: defaultWalletKeyFilePath, + }); }); -When(/^I toggle "Activate to create password" switch on the import wallet key dialog$/, function () { - return this.waitAndClick('.WalletFileImportDialog .SimpleSwitch_switch'); -}); +When( + /^I toggle "Activate to create password" switch on the import wallet key dialog$/, + function() { + return this.waitAndClick('.WalletFileImportDialog .SimpleSwitch_switch'); + } +); -When(/^I enter wallet spending password:$/, async function (table) { +When(/^I enter wallet spending password:$/, async function(table) { const fields = table.hashes()[0]; - await this.client.setValue('.WalletFileImportDialog .spendingPassword input', fields.password); - await this.client.setValue('.WalletFileImportDialog .repeatedPassword input', fields.repeatedPassword); -}); - -When(/^I click on the import wallet button in import wallet dialog$/, function () { - return importWalletDialog.clickImport(this.client); -}); + await this.client.setValue( + '.WalletFileImportDialog .spendingPassword input', + fields.password + ); + await this.client.setValue( + '.WalletFileImportDialog .repeatedPassword input', + fields.repeatedPassword + ); +}); + +When( + /^I click on the import wallet button in import wallet dialog$/, + function() { + return importWalletDialog.clickImport(this.client); + } +); -When(/^I should see wallet spending password inputs$/, function () { - return this.client.waitForVisible('.WalletFileImportDialog .spendingPassword input'); +When(/^I should see wallet spending password inputs$/, function() { + return this.client.waitForVisible( + '.WalletFileImportDialog .spendingPassword input' + ); }); -When(/^I have one wallet address$/, function () { +When(/^I have one wallet address$/, function() { return this.client.waitForVisible('.generatedAddress-1'); }); -When(/^I enter spending password "([^"]*)"$/, function (password) { - return this.client.setValue('.WalletReceive_spendingPassword input', password); +When(/^I enter spending password "([^"]*)"$/, function(password) { + return this.client.setValue( + '.WalletReceive_spendingPassword input', + password + ); }); -When(/^I click on the "Generate new address" button$/, function () { +When(/^I click on the "Generate new address" button$/, function() { return this.client.click('.generateAddressButton'); }); -When(/^I click on the restore wallet button on the add wallet page$/, function () { - return this.waitAndClick('.WalletAdd .restoreWalletButton'); -}); +When( + /^I click on the restore wallet button on the add wallet page$/, + function() { + return this.waitAndClick('.WalletAdd .restoreWalletButton'); + } +); -When(/^I click the wallet (.*) button$/, async function (buttonName) { +When(/^I click the wallet (.*) button$/, async function(buttonName) { const buttonSelector = `.WalletNavButton_component.${buttonName}`; await this.client.waitForVisible(buttonSelector); await this.client.click(buttonSelector); }); -When(/^I can see the send form$/, function () { +When(/^I can see the send form$/, function() { return this.client.waitForVisible('.WalletSendForm'); }); -When(/^I fill out the wallet send form with:$/, function (table) { +When(/^I fill out the wallet send form with:$/, function(table) { return fillOutWalletSendForm.call(this, table.hashes()[0]); }); -When(/^I fill out the send form with a transaction to "([^"]*)" wallet:$/, async function (walletName, table) { - const values = table.hashes()[0]; - const walletId = getWalletByName.call(this, walletName).id; - const walletAddress = await this.client.executeAsync((id, done) => { - daedalus.api.ada.getAddresses({ walletId: id }) - .then((response) => ( - done(response.addresses[0].id) - )) - .catch((error) => done(error)); - }, walletId); - values.address = walletAddress.value; - return fillOutWalletSendForm.call(this, values); -}); +When( + /^I fill out the send form with a transaction to "([^"]*)" wallet:$/, + async function(walletName, table) { + const values = table.hashes()[0]; + const walletId = getWalletByName.call(this, walletName).id; + const walletAddress = await this.client.executeAsync((id, done) => { + daedalus.api.ada + .getAddresses({ walletId: id }) + .then(response => done(response.addresses[0].id)) + .catch(error => done(error)); + }, walletId); + values.address = walletAddress.value; + return fillOutWalletSendForm.call(this, values); + } +); -When(/^the transaction fees are calculated$/, async function () { +When(/^the transaction fees are calculated$/, async function() { this.fees = await this.client.waitUntil(async () => { // Expected transactionFeeText format "+ 0.000001 of fees" - const transactionFeeText = await this.client.getText('.AmountInputSkin_fees'); + const transactionFeeText = await this.client.getText( + '.AmountInputSkin_fees' + ); const transactionFeeAmount = new BigNumber(transactionFeeText.substr(2, 8)); return transactionFeeAmount.greaterThan(0) ? transactionFeeAmount : false; }); }); -When(/^I click on the next button in the wallet send form$/, async function () { +When(/^I click on the next button in the wallet send form$/, async function() { const submitButton = '.WalletSendForm_nextButton'; await this.client.waitForVisible(submitButton); return this.client.click(submitButton); }); -When(/^I see send money confirmation dialog$/, function () { +When(/^I see send money confirmation dialog$/, function() { return this.client.waitForVisible('.WalletSendConfirmationDialog_dialog'); }); -When(/^I enter wallet spending password in confirmation dialog "([^"]*)"$/, async function (password) { - await this.client.setValue('.WalletSendConfirmationDialog_spendingPassword input', password); -}); - -When(/^I submit the wallet send form$/, async function () { - await this.client.waitForEnabled('.WalletSendConfirmationDialog_dialog .confirmButton'); - return this.client.click('.WalletSendConfirmationDialog_dialog .confirmButton'); -}); - -When(/^I toggle "Spending password" switch on the create wallet dialog$/, function () { - return this.waitAndClick('.WalletCreateDialog .SimpleSwitch_switch'); -}); +When( + /^I enter wallet spending password in confirmation dialog "([^"]*)"$/, + async function(password) { + await this.client.setValue( + '.WalletSendConfirmationDialog_spendingPassword input', + password + ); + } +); -When(/^I toggle "Spending password" switch on the restore wallet dialog$/, function () { - return this.waitAndClick('.WalletRestoreDialog .SimpleSwitch_switch'); +When(/^I submit the wallet send form$/, async function() { + await this.client.waitForEnabled( + '.WalletSendConfirmationDialog_dialog .confirmButton' + ); + return this.client.click( + '.WalletSendConfirmationDialog_dialog .confirmButton' + ); }); -When(/^I submit the create wallet dialog with the following inputs:$/, async function (table) { - const fields = table.hashes()[0]; - await this.client.setValue('.WalletCreateDialog .walletName input', fields.walletName); - return this.client.click('.WalletCreateDialog .primary'); -}); +When( + /^I toggle "Spending password" switch on the create wallet dialog$/, + function() { + return this.waitAndClick('.WalletCreateDialog .SimpleSwitch_switch'); + } +); -When(/^I submit the create wallet with spending password dialog with the following inputs:$/, async function (table) { - const fields = table.hashes()[0]; - await this.client.setValue('.WalletCreateDialog .walletName input', fields.walletName); - await this.client.setValue('.WalletCreateDialog .spendingPassword input', fields.password); - await this.client.setValue('.WalletCreateDialog .repeatedPassword input', fields.repeatedPassword); - return this.client.click('.WalletCreateDialog .primary'); -}); +When( + /^I toggle "Spending password" switch on the restore wallet dialog$/, + function() { + return this.waitAndClick('.WalletRestoreDialog .SimpleSwitch_switch'); + } +); + +When( + /^I submit the create wallet dialog with the following inputs:$/, + async function(table) { + const fields = table.hashes()[0]; + await this.client.setValue( + '.WalletCreateDialog .walletName input', + fields.walletName + ); + return this.client.click('.WalletCreateDialog .primary'); + } +); + +When( + /^I submit the create wallet with spending password dialog with the following inputs:$/, + async function(table) { + const fields = table.hashes()[0]; + await this.client.setValue( + '.WalletCreateDialog .walletName input', + fields.walletName + ); + await this.client.setValue( + '.WalletCreateDialog .spendingPassword input', + fields.password + ); + await this.client.setValue( + '.WalletCreateDialog .repeatedPassword input', + fields.repeatedPassword + ); + return this.client.click('.WalletCreateDialog .primary'); + } +); -When(/^I enter wallet name "([^"]*)" in restore wallet dialog$/, async function (walletName) { - return this.client.setValue('.WalletRestoreDialog .walletName input', walletName); +When(/^I enter wallet name "([^"]*)" in restore wallet dialog$/, async function( + walletName +) { + return this.client.setValue( + '.WalletRestoreDialog .walletName input', + walletName + ); }); -When(/^I enter recovery phrase in restore wallet dialog:$/, async function (table) { +When(/^I enter recovery phrase in restore wallet dialog:$/, async function( + table +) { const fields = table.hashes()[0]; const recoveryPhrase = fields.recoveryPhrase.split(' '); for (let i = 0; i < recoveryPhrase.length; i++) { const word = recoveryPhrase[i]; - await this.client.setValue('.AutocompleteOverrides_autocompleteWrapper input', word); + await this.client.setValue( + '.AutocompleteOverrides_autocompleteWrapper input', + word + ); await this.client.waitForVisible(`//li[contains(text(), '${word}')]`); await this.waitAndClick(`//li[contains(text(), '${word}')]`); await this.client.waitForVisible(`//span[contains(text(), '${word}')]`); } }); -When(/^I enter wallet password in restore wallet dialog:$/, async function (table) { +When(/^I enter wallet password in restore wallet dialog:$/, async function( + table +) { const fields = table.hashes()[0]; - await this.client.setValue('.WalletRestoreDialog .spendingPassword input', fields.password); - await this.client.setValue('.WalletRestoreDialog .repeatedPassword input', fields.repeatedPassword); + await this.client.setValue( + '.WalletRestoreDialog .spendingPassword input', + fields.password + ); + await this.client.setValue( + '.WalletRestoreDialog .repeatedPassword input', + fields.repeatedPassword + ); }); -When(/^I submit the restore wallet dialog$/, function () { +When(/^I submit the restore wallet dialog$/, function() { return this.client.click('.WalletRestoreDialog .primary'); }); -When(/^I see the create wallet privacy dialog$/, function () { +When(/^I see the create wallet privacy dialog$/, function() { return this.client.waitForVisible('.WalletBackupPrivacyWarningDialog'); }); -When(/^I click on "Please make sure nobody looks your screen" checkbox$/, function () { - return this.waitAndClick('.WalletBackupPrivacyWarningDialog .SimpleCheckbox_root'); -}); +When( + /^I click on "Please make sure nobody looks your screen" checkbox$/, + function() { + return this.waitAndClick( + '.WalletBackupPrivacyWarningDialog .SimpleCheckbox_root' + ); + } +); -When(/^I submit the create wallet privacy dialog$/, function () { +When(/^I submit the create wallet privacy dialog$/, function() { return this.waitAndClick('.WalletBackupPrivacyWarningDialog .primary'); }); -When(/^I see the create wallet recovery phrase display dialog$/, function () { +When(/^I see the create wallet recovery phrase display dialog$/, function() { return this.client.waitForVisible('.WalletRecoveryPhraseDisplayDialog'); }); -When(/^I note down the recovery phrase$/, async function () { - const recoveryPhrase = await this.client.getText('.WalletRecoveryPhraseMnemonic_component'); +When(/^I note down the recovery phrase$/, async function() { + const recoveryPhrase = await this.client.getText( + '.WalletRecoveryPhraseMnemonic_component' + ); this.recoveryPhrase = recoveryPhrase.split(' '); }); -When(/^I submit the create wallet recovery phrase display dialog$/, function () { +When(/^I submit the create wallet recovery phrase display dialog$/, function() { return this.waitAndClick('.WalletRecoveryPhraseDisplayDialog .primary'); }); -When(/^I see the create wallet recovery phrase entry dialog$/, function () { +When(/^I see the create wallet recovery phrase entry dialog$/, function() { return this.client.waitForVisible('.WalletRecoveryPhraseEntryDialog'); }); -When(/^I click on recovery phrase mnemonics in correct order$/, async function () { - for (let i = 0; i < this.recoveryPhrase.length; i++) { - const text = this.recoveryPhrase[i]; - const selector = 'MnemonicWord_root'; - const disabledSelector = 'MnemonicWord_disabled'; - await this.waitAndClick( - `//button[contains(@class,'${selector}') and not(contains(@class, '${disabledSelector}')) and contains(text(), '${text}')]` - ); +When( + /^I click on recovery phrase mnemonics in correct order$/, + async function() { + for (let i = 0; i < this.recoveryPhrase.length; i++) { + const text = this.recoveryPhrase[i]; + const selector = 'MnemonicWord_root'; + const disabledSelector = 'MnemonicWord_disabled'; + await this.waitAndClick( + `//button[contains(@class,'${selector}') and not(contains(@class, '${disabledSelector}')) and contains(text(), '${text}')]` + ); + } } -}); +); -When(/^I click on the "Accept terms" checkboxes$/, async function () { +When(/^I click on the "Accept terms" checkboxes$/, async function() { const termsCheckboxes = await this.client.elements('.SimpleCheckbox_root'); for (let i = 0; i < termsCheckboxes.value.length; i++) { const termsCheckbox = termsCheckboxes.value[i].ELEMENT; @@ -310,27 +406,37 @@ When(/^I click on the "Accept terms" checkboxes$/, async function () { } }); -When(/^I submit the create wallet recovery phrase entry dialog$/, function () { +When(/^I submit the create wallet recovery phrase entry dialog$/, function() { return this.waitAndClick('.WalletRecoveryPhraseEntryDialog .primary'); }); -When(/^I click on delete wallet button$/, async function () { +When(/^I click on delete wallet button$/, async function() { return this.client.click('.DeleteWalletButton_button'); }); -When(/^I enter "([^"]*)" as name of the wallet to confirm$/, async function (walletName) { - return this.client.setValue('.DeleteWalletConfirmationDialog_confirmationInput input', walletName); +When(/^I enter "([^"]*)" as name of the wallet to confirm$/, async function( + walletName +) { + return this.client.setValue( + '.DeleteWalletConfirmationDialog_confirmationInput input', + walletName + ); }); -When(/^I click on the "Make sure you have access to backup before continuing" checkbox$/, function () { - return this.waitAndClick('.DeleteWalletConfirmationDialog_dialog .SimpleCheckbox_root'); -}); +When( + /^I click on the "Make sure you have access to backup before continuing" checkbox$/, + function() { + return this.waitAndClick( + '.DeleteWalletConfirmationDialog_dialog .SimpleCheckbox_root' + ); + } +); -When(/^I submit the delete wallet dialog$/, function () { +When(/^I submit the delete wallet dialog$/, function() { return this.client.click('.DeleteWalletConfirmationDialog_dialog .primary'); }); -When(/^I try to import the wallet with funds again$/, async function () { +When(/^I try to import the wallet with funds again$/, async function() { await sidebar.activateCategory(this.client, { category: 'wallets' }); await sidebar.clickAddWalletButton(this.client); await addWalletPage.waitForVisible(this.client); @@ -339,59 +445,92 @@ When(/^I try to import the wallet with funds again$/, async function () { // await importWalletDialog.selectFile(this.client, { filePath: defaultWalletJSONFilePath }); // ^^ JSON wallet file import is currently not working due to missing JSON import V1 API endpoint // so we have to use the KEY wallet file instead: - await importWalletDialog.selectFile(this.client, { filePath: defaultWalletKeyFilePath }); - return importWalletDialog.clickImport(this.client); -}); - -Then(/^I see the import wallet dialog with an error that the wallet already exists$/, async function () { - return importWalletDialog.expectError(this.client, { - error: await i18n.formatMessage(this.client, { id: 'api.errors.WalletAlreadyImportedError' }) + await importWalletDialog.selectFile(this.client, { + filePath: defaultWalletKeyFilePath, }); + return importWalletDialog.clickImport(this.client); }); -Then(/^I should not see the create wallet recovery phrase entry dialog anymore$/, function () { - return this.client.waitForVisible('.WalletRecoveryPhraseEntryDialog', null, true); -}); +Then( + /^I see the import wallet dialog with an error that the wallet already exists$/, + async function() { + return importWalletDialog.expectError(this.client, { + error: await i18n.formatMessage(this.client, { + id: 'api.errors.WalletAlreadyImportedError', + }), + }); + } +); + +Then( + /^I should not see the create wallet recovery phrase entry dialog anymore$/, + function() { + return this.client.waitForVisible( + '.WalletRecoveryPhraseEntryDialog', + null, + true + ); + } +); -Then(/^I should not see the delete wallet dialog anymore$/, function () { - return this.client.waitForVisible('.DeleteWalletConfirmationDialog_dialog', null, true); +Then(/^I should not see the delete wallet dialog anymore$/, function() { + return this.client.waitForVisible( + '.DeleteWalletConfirmationDialog_dialog', + null, + true + ); }); -Then(/^I should not see the import wallet dialog anymore$/, function () { +Then(/^I should not see the import wallet dialog anymore$/, function() { return importWalletDialog.waitForDialog(this.client, { isHidden: true }); }); -Then(/^I should not see the restore wallet dialog anymore$/, function () { +Then(/^I should not see the restore wallet dialog anymore$/, function() { return this.client.waitForVisible('.WalletRestoreDialog', null, true); }); -Then(/^I should see the restore status notification while import is running$/, async function () { - // Only check the rendered DOM if the restore is still in progress - if (await isActiveWalletBeingRestored(this.client)) { - await waitForActiveRestoreNotification(this.client); +Then( + /^I should see the restore status notification while import is running$/, + async function() { + // Only check the rendered DOM if the restore is still in progress + if (await isActiveWalletBeingRestored(this.client)) { + await waitForActiveRestoreNotification(this.client); + } } -}); - -Then(/^I should not see the restore status notification once import is finished$/, async function () { - await waitForActiveRestoreNotification(this.client, { isHidden: true }); -}); +); -Then(/^I should see the restore status notification while restore is running$/, async function () { - // Only check the rendered DOM if the restore is still in progress - if (await isActiveWalletBeingRestored(this.client)) { - await waitForActiveRestoreNotification(this.client); +Then( + /^I should not see the restore status notification once import is finished$/, + async function() { + await waitForActiveRestoreNotification(this.client, { isHidden: true }); } -}); - -Then(/^I should not see the restore status notification once restore is finished$/, async function () { - await waitForActiveRestoreNotification(this.client, { isHidden: true }); -}); +); + +Then( + /^I should see the restore status notification while restore is running$/, + async function() { + // Only check the rendered DOM if the restore is still in progress + if (await isActiveWalletBeingRestored(this.client)) { + await waitForActiveRestoreNotification(this.client); + } + } +); -Then(/^I should have newly created "([^"]*)" wallet loaded$/, async function (walletName) { - const result = await this.client.executeAsync((done) => { - daedalus.stores.wallets.walletsRequest.execute() +Then( + /^I should not see the restore status notification once restore is finished$/, + async function() { + await waitForActiveRestoreNotification(this.client, { isHidden: true }); + } +); + +Then(/^I should have newly created "([^"]*)" wallet loaded$/, async function( + walletName +) { + const result = await this.client.executeAsync(done => { + daedalus.stores.wallets.walletsRequest + .execute() .then(done) - .catch((error) => done(error)); + .catch(error => done(error)); }); // Add or set the wallets for this scenario if (this.wallets != null) { @@ -403,38 +542,46 @@ Then(/^I should have newly created "([^"]*)" wallet loaded$/, async function (wa expect(wallet).to.be.an('object'); }); -Then(/^I should be on some wallet page$/, async function () { +Then(/^I should be on some wallet page$/, async function() { return this.client.waitForVisible('.WalletNavigation_component'); }); -Then(/^I should be on the "([^"]*)" wallet "([^"]*)" screen$/, async function (walletName, screenName) { +Then(/^I should be on the "([^"]*)" wallet "([^"]*)" screen$/, async function( + walletName, + screenName +) { const wallet = getWalletByName.call(this, walletName); return waitUntilUrlEquals.call(this, `/wallets/${wallet.id}/${screenName}`); }); -Then(/^I should be on the "([^"]*)" screen$/, async function (screenName) { +Then(/^I should be on the "([^"]*)" screen$/, async function(screenName) { return waitUntilUrlEquals.call(this, `/${screenName}`); }); -Then(/^I should see the following error messages on the wallet send form:$/, async function (data) { - const errorSelector = '.WalletSendForm_component .SimpleFormField_error'; - await this.client.waitForText(errorSelector); - let errorsOnScreen = await this.client.getText(errorSelector); - if (typeof errorsOnScreen === 'string') errorsOnScreen = [errorsOnScreen]; - const errors = data.hashes(); - for (let i = 0; i < errors.length; i++) { - const expectedError = await this.intl(errors[i].message); - expect(errorsOnScreen[i]).to.equal(expectedError); +Then( + /^I should see the following error messages on the wallet send form:$/, + async function(data) { + const errorSelector = '.WalletSendForm_component .SimpleFormField_error'; + await this.client.waitForText(errorSelector); + let errorsOnScreen = await this.client.getText(errorSelector); + if (typeof errorsOnScreen === 'string') errorsOnScreen = [errorsOnScreen]; + const errors = data.hashes(); + for (let i = 0; i < errors.length; i++) { + const expectedError = await this.intl(errors[i].message); + expect(errorsOnScreen[i]).to.equal(expectedError); + } } -}); +); // TODO: refactor this to a less hackish solution (fees cannot easily be calculated atm) -Then(/^the latest transaction should show:$/, async function (table) { +Then(/^the latest transaction should show:$/, async function(table) { const expectedData = table.hashes()[0]; await this.client.waitForVisible('.Transaction_title'); let transactionTitles = await this.client.getText('.Transaction_title'); transactionTitles = [].concat(transactionTitles); - const expectedTransactionTitle = await this.intl(expectedData.title, { currency: 'Ada' }); + const expectedTransactionTitle = await this.intl(expectedData.title, { + currency: 'Ada', + }); expect(expectedTransactionTitle).to.equal(transactionTitles[0]); let transactionAmounts = await this.client.getText('.Transaction_amount'); transactionAmounts = [].concat(transactionAmounts); @@ -442,31 +589,50 @@ Then(/^the latest transaction should show:$/, async function (table) { // substract them in order to get a match with expectedData.amountWithoutFees. // NOTE: we use "add()" as this is outgoing transaction and amount is a negative value! const transactionAmount = new BigNumber(transactionAmounts[0]); - const transactionAmountWithoutFees = transactionAmount.add(this.fees).toFormat(DECIMAL_PLACES_IN_ADA); + const transactionAmountWithoutFees = transactionAmount + .add(this.fees) + .toFormat(DECIMAL_PLACES_IN_ADA); expect(expectedData.amountWithoutFees).to.equal(transactionAmountWithoutFees); }); // Extended timeout is used for this step as it takes more than DEFAULT_TIMEOUT // for the receiver wallet's balance to be updated on the backend after creating transactions -Then(/^the balance of "([^"]*)" wallet should be:$/, { timeout: 60000 }, async function (walletName, table) { - const expectedData = table.hashes()[0]; - const receiverWallet = getWalletByName.call(this, walletName); - return this.client.waitUntil(async () => { - const receiverWalletBalance = await this.client.getText(`.SidebarWalletsMenu_wallets .Wallet_${receiverWallet.id} .SidebarWalletMenuItem_info`); - return receiverWalletBalance === `${expectedData.balance} ADA`; - }, 60000); -}); - -Then(/^I should see newly generated address as active address on the wallet receive screen$/, async function () { - return this.client.waitUntil(async () => { - const activeAddress = await this.client.getText('.WalletReceive_hash'); - const generatedAddress = await this.client.getText('.generatedAddress-1 .Address_addressId'); - return generatedAddress === activeAddress; - }); -}); +Then( + /^the balance of "([^"]*)" wallet should be:$/, + { timeout: 60000 }, + async function(walletName, table) { + const expectedData = table.hashes()[0]; + const receiverWallet = getWalletByName.call(this, walletName); + return this.client.waitUntil(async () => { + const receiverWalletBalance = await this.client.getText( + `.SidebarWalletsMenu_wallets .Wallet_${ + receiverWallet.id + } .SidebarWalletMenuItem_info` + ); + return receiverWalletBalance === `${expectedData.balance} ADA`; + }, 60000); + } +); + +Then( + /^I should see newly generated address as active address on the wallet receive screen$/, + async function() { + return this.client.waitUntil(async () => { + const activeAddress = await this.client.getText('.WalletReceive_hash'); + const generatedAddress = await this.client.getText( + '.generatedAddress-1 .Address_addressId' + ); + return generatedAddress === activeAddress; + }); + } +); -Then(/^I should see the wallets in the following order:$/, async function (table) { +Then(/^I should see the wallets in the following order:$/, async function( + table +) { const expectedWallets = table.hashes(); const wallets = await this.client.getText('.SidebarWalletMenuItem_title'); - wallets.forEach((wallet, index) => expect(wallet).to.equal(expectedWallets[index].name)); + wallets.forEach((wallet, index) => + expect(wallet).to.equal(expectedWallets[index].name) + ); }); diff --git a/features/support/electron.js b/features/support/electron.js index ab609ba53a..95fc91ea20 100644 --- a/features/support/electron.js +++ b/features/support/electron.js @@ -1,24 +1,32 @@ import path from 'path'; import { Application } from 'spectron'; -import { BeforeAll, Before, After, AfterAll, setDefaultTimeout } from 'cucumber'; +import { + BeforeAll, + Before, + After, + AfterAll, + setDefaultTimeout, +} from 'cucumber'; import electronPath from 'electron'; import { TEST } from '../../source/common/types/environment.types'; -import { generateScreenshotFilePath, getTestNameFromTestFile, saveScreenshot } from './helpers/screenshot'; +import { + generateScreenshotFilePath, + getTestNameFromTestFile, + saveScreenshot, +} from './helpers/screenshot'; import { refreshClient } from './helpers/app-helpers'; const context = {}; const DEFAULT_TIMEOUT = 20000; let scenariosCount = 0; -const printMainProcessLogs = () => ( - context.app.client.getMainProcessLogs() - .then((logs) => { - console.log('========= DAEDALUS LOGS ========='); - logs.forEach((log) => console.log(log)); - console.log('================================='); - return true; - }) -); +const printMainProcessLogs = () => + context.app.client.getMainProcessLogs().then(logs => { + console.log('========= DAEDALUS LOGS ========='); + logs.forEach(log => console.log(log)); + console.log('================================='); + return true; + }); const startApp = async () => { const app = new Application({ @@ -48,7 +56,7 @@ BeforeAll({ timeout: 5 * 60 * 1000 }, async () => { }); // Make the electron app accessible in each scenario context -Before({ timeout: DEFAULT_TIMEOUT * 2 }, async function () { +Before({ timeout: DEFAULT_TIMEOUT * 2 }, async function() { this.app = context.app; this.client = context.app.client; this.browserWindow = context.app.browserWindow; @@ -63,13 +71,16 @@ Before({ timeout: DEFAULT_TIMEOUT * 2 }, async function () { // https://github.com/webdriverio/webdriverio/issues/974 // Reset backend - await this.client.executeAsync((done) => { + await this.client.executeAsync(done => { const resetBackend = () => { if (daedalus.stores.networkStatus.isConnected) { - daedalus.api.ada.testReset() + daedalus.api.ada + .testReset() .then(daedalus.api.localStorage.reset) .then(done) - .catch((error) => { throw error; }); + .catch(error => { + throw error; + }); } else { setTimeout(resetBackend, 50); } @@ -81,7 +92,7 @@ Before({ timeout: DEFAULT_TIMEOUT * 2 }, async function () { await refreshClient(this.client); // Ensure that frontend is synced and ready before test case - await this.client.executeAsync((done) => { + await this.client.executeAsync(done => { const waitUntilSyncedAndReady = () => { if (daedalus.stores.networkStatus.isSynced) { done(); @@ -96,12 +107,12 @@ Before({ timeout: DEFAULT_TIMEOUT * 2 }, async function () { // this ensures that the spectron instance of the app restarts // after the node update acceptance test shuts it down via 'kill-process' // eslint-disable-next-line prefer-arrow-callback -After({ tags: '@restartApp' }, async function () { +After({ tags: '@restartApp' }, async function() { context.app = await startApp(); }); // eslint-disable-next-line prefer-arrow-callback -After(async function ({ sourceLocation, result }) { +After(async function({ sourceLocation, result }) { scenariosCount++; if (result.status === 'failed') { const testName = getTestNameFromTestFile(sourceLocation.uri); @@ -112,14 +123,16 @@ After(async function ({ sourceLocation, result }) { }); // eslint-disable-next-line prefer-arrow-callback -AfterAll(async function () { +AfterAll(async function() { const allWindowsClosed = (await context.app.client.getWindowCount()) === 0; if (allWindowsClosed || !context.app.running) return; if (scenariosCount === 0) { await printMainProcessLogs(); } if (process.env.KEEP_APP_AFTER_TESTS === 'true') { - console.log('Keeping the app running since KEEP_APP_AFTER_TESTS env var is true'); + console.log( + 'Keeping the app running since KEEP_APP_AFTER_TESTS env var is true' + ); return; } return context.app.stop(); diff --git a/features/support/helpers/add-wallet-page-helpers.js b/features/support/helpers/add-wallet-page-helpers.js index e7b7faf582..58a956403b 100644 --- a/features/support/helpers/add-wallet-page-helpers.js +++ b/features/support/helpers/add-wallet-page-helpers.js @@ -4,10 +4,8 @@ const ADD_WALLET = '.WalletAdd'; const IMPORT_WALLET_BUTTON = '.importWalletButton'; export default { - waitForVisible: (client, { isHidden } = {}) => ( - client.waitForVisible(ADD_WALLET, null, isHidden) - ), - clickImportButton: (client) => ( - waitAndClick(client, `${ADD_WALLET} ${IMPORT_WALLET_BUTTON}`) - ), + waitForVisible: (client, { isHidden } = {}) => + client.waitForVisible(ADD_WALLET, null, isHidden), + clickImportButton: client => + waitAndClick(client, `${ADD_WALLET} ${IMPORT_WALLET_BUTTON}`), }; diff --git a/features/support/helpers/app-helpers.js b/features/support/helpers/app-helpers.js index a6610126e9..20a35e13a8 100644 --- a/features/support/helpers/app-helpers.js +++ b/features/support/helpers/app-helpers.js @@ -2,11 +2,16 @@ import type { WebdriverClient } from '../global-types'; import { getProcessesByName } from '../../../source/main/utils/processes'; -export const waitForDaedalusToExit = async (client: WebdriverClient, timeout: number = 61000) => { - const daedalusProcessName = process.platform === 'linux' ? 'electron' : 'Electron'; - return await client.waitUntil(async () => ( - (await getProcessesByName(daedalusProcessName)).length === 0 - ), timeout); +export const waitForDaedalusToExit = async ( + client: WebdriverClient, + timeout: number = 61000 +) => { + const daedalusProcessName = + process.platform === 'linux' ? 'electron' : 'Electron'; + return await client.waitUntil( + async () => (await getProcessesByName(daedalusProcessName)).length === 0, + timeout + ); }; export const refreshClient = async (client: WebdriverClient) => { diff --git a/features/support/helpers/cardano-node-helpers.js b/features/support/helpers/cardano-node-helpers.js index 1b1d0ac2ff..1dcf045dca 100644 --- a/features/support/helpers/cardano-node-helpers.js +++ b/features/support/helpers/cardano-node-helpers.js @@ -1,18 +1,15 @@ // @flow -import type { - Daedalus, - WebdriverClient -} from '../global-types'; +import type { Daedalus, WebdriverClient } from '../global-types'; import { getProcessesByName } from '../../../source/main/utils/processes'; declare var daedalus: Daedalus; -export const getCardanoNodeState = async (client: WebdriverClient) => ( - (await client.execute(() => daedalus.stores.networkStatus.cardanoNodeState)).value -); +export const getCardanoNodeState = async (client: WebdriverClient) => + (await client.execute(() => daedalus.stores.networkStatus.cardanoNodeState)) + .value; -export const waitForCardanoNodeToExit = async (client: WebdriverClient) => ( - await client.waitUntil(async () => ( - (await getProcessesByName('cardano-node')).length === 0 - ), 61000) -); +export const waitForCardanoNodeToExit = async (client: WebdriverClient) => + await client.waitUntil( + async () => (await getProcessesByName('cardano-node')).length === 0, + 61000 + ); diff --git a/features/support/helpers/data-layer-migration-helpers.js b/features/support/helpers/data-layer-migration-helpers.js index 16365291b7..0981959da1 100644 --- a/features/support/helpers/data-layer-migration-helpers.js +++ b/features/support/helpers/data-layer-migration-helpers.js @@ -1,15 +1,19 @@ -const DATA_LAYER_MIGRATION_ACCEPTANCE_COMPONENT = '.DataLayerMigrationForm_component'; +const DATA_LAYER_MIGRATION_ACCEPTANCE_COMPONENT = + '.DataLayerMigrationForm_component'; const dataLayerMigration = { - waitForVisible: async (client, { isHidden } = {}) => ( - client.waitForVisible(DATA_LAYER_MIGRATION_ACCEPTANCE_COMPONENT, null, isHidden) - ), - acceptMigration: async (client) => { + waitForVisible: async (client, { isHidden } = {}) => + client.waitForVisible( + DATA_LAYER_MIGRATION_ACCEPTANCE_COMPONENT, + null, + isHidden + ), + acceptMigration: async client => { await client.execute(() => { daedalus.actions.profile.acceptDataLayerMigration.trigger(); }); await dataLayerMigration.waitForVisible(client, { isHidden: true }); - } + }, }; export default dataLayerMigration; diff --git a/features/support/helpers/dialogs/import-wallet-dialog-helpers.js b/features/support/helpers/dialogs/import-wallet-dialog-helpers.js index 462bed41a6..f8d9afa72e 100644 --- a/features/support/helpers/dialogs/import-wallet-dialog-helpers.js +++ b/features/support/helpers/dialogs/import-wallet-dialog-helpers.js @@ -3,19 +3,18 @@ import { expectTextInSelector, waitAndClick } from '../shared-helpers'; const IMPORT_WALLET_DIALOG = '.WalletFileImportDialog'; export default { - waitForDialog: (client, { isHidden } = {}) => ( - client.waitForVisible(IMPORT_WALLET_DIALOG, null, isHidden) - ), - selectFile: (client, { filePath }) => ( - client.chooseFile(`${IMPORT_WALLET_DIALOG} .FileUploadWidget_dropZone input`, filePath) - ), - clickImport: (client) => ( - waitAndClick(client, `${IMPORT_WALLET_DIALOG} .primary`) - ), - expectError: (client, { error }) => ( + waitForDialog: (client, { isHidden } = {}) => + client.waitForVisible(IMPORT_WALLET_DIALOG, null, isHidden), + selectFile: (client, { filePath }) => + client.chooseFile( + `${IMPORT_WALLET_DIALOG} .FileUploadWidget_dropZone input`, + filePath + ), + clickImport: client => + waitAndClick(client, `${IMPORT_WALLET_DIALOG} .primary`), + expectError: (client, { error }) => expectTextInSelector(client, { selector: `${IMPORT_WALLET_DIALOG}_error`, text: error, - }) - ) + }), }; diff --git a/features/support/helpers/i18n-helpers.js b/features/support/helpers/i18n-helpers.js index f2d275ce3a..75b9857239 100644 --- a/features/support/helpers/i18n-helpers.js +++ b/features/support/helpers/i18n-helpers.js @@ -2,19 +2,26 @@ const DEFAULT_LANGUAGE = 'en-US'; export default { formatMessage: async (client, { id, values }) => { - const translation = await client.execute((translationId, translationValues) => { - const IntlProvider = require('react-intl').IntlProvider; // eslint-disable-line - const locale = daedalus.stores.profile.currentLocale; - const messages = daedalus.translations; - const intlProvider = new IntlProvider({ locale, messages: messages[locale] }, {}); - return intlProvider.getChildContext() - .intl.formatMessage({ id: translationId }, translationValues); - }, id, values || {}); + const translation = await client.execute( + (translationId, translationValues) => { + const IntlProvider = require('react-intl').IntlProvider; // eslint-disable-line + const locale = daedalus.stores.profile.currentLocale; + const messages = daedalus.translations; + const intlProvider = new IntlProvider( + { locale, messages: messages[locale] }, + {} + ); + return intlProvider + .getChildContext() + .intl.formatMessage({ id: translationId }, translationValues); + }, + id, + values || {} + ); return translation.value; }, - setActiveLanguage: async (client, { language } = {}) => ( + setActiveLanguage: async (client, { language } = {}) => await client.execute(locale => { daedalus.actions.profile.updateLocale.trigger({ locale }); - }, language || DEFAULT_LANGUAGE) - ) + }, language || DEFAULT_LANGUAGE), }; diff --git a/features/support/helpers/language-selection-helpers.js b/features/support/helpers/language-selection-helpers.js index 8d07a5d57b..f26f1b1e22 100644 --- a/features/support/helpers/language-selection-helpers.js +++ b/features/support/helpers/language-selection-helpers.js @@ -3,14 +3,13 @@ import i18n from './i18n-helpers'; const LANGUAGE_SELECTION_FORM = '.LanguageSelectionForm_component'; const languageSelection = { - waitForVisible: async (client, { isHidden } = {}) => ( - client.waitForVisible(LANGUAGE_SELECTION_FORM, null, isHidden) - ), + waitForVisible: async (client, { isHidden } = {}) => + client.waitForVisible(LANGUAGE_SELECTION_FORM, null, isHidden), ensureLanguageIsSelected: async (client, { language } = {}) => { await languageSelection.waitForVisible(client); i18n.setActiveLanguage(client, { language }); await languageSelection.waitForVisible(client, { isHidden: true }); - } + }, }; export default languageSelection; diff --git a/features/support/helpers/notifications-helpers.js b/features/support/helpers/notifications-helpers.js index 84c91a2511..41665c252f 100644 --- a/features/support/helpers/notifications-helpers.js +++ b/features/support/helpers/notifications-helpers.js @@ -1,12 +1,13 @@ import { WalletSyncStateTags } from '../../../source/renderer/app/domains/Wallet'; -export const isActiveWalletBeingRestored = async (client) => { - const result = await client.execute((expectedSyncTag) => ( - daedalus.stores.wallets.active.syncState.tag === expectedSyncTag - ), WalletSyncStateTags.RESTORING); +export const isActiveWalletBeingRestored = async client => { + const result = await client.execute( + expectedSyncTag => + daedalus.stores.wallets.active.syncState.tag === expectedSyncTag, + WalletSyncStateTags.RESTORING + ); return result.value; }; -export const waitForActiveRestoreNotification = (client, { isHidden } = {}) => ( - client.waitForVisible('.ActiveRestoreNotification', null, isHidden) -); +export const waitForActiveRestoreNotification = (client, { isHidden } = {}) => + client.waitForVisible('.ActiveRestoreNotification', null, isHidden); diff --git a/features/support/helpers/route-helpers.js b/features/support/helpers/route-helpers.js index c27a3cacfa..4da5b90c22 100644 --- a/features/support/helpers/route-helpers.js +++ b/features/support/helpers/route-helpers.js @@ -1,9 +1,9 @@ -export const getCurrentAppRoute = async function () { +export const getCurrentAppRoute = async function() { const url = (await this.client.url()).value; return url.substring(url.indexOf('#/') + 1); // return without the hash }; -export const waitUntilUrlEquals = function (expectedUrl) { +export const waitUntilUrlEquals = function(expectedUrl) { const context = this; return context.client.waitUntil(async () => { const url = await getCurrentAppRoute.call(context); @@ -11,8 +11,8 @@ export const waitUntilUrlEquals = function (expectedUrl) { }); }; -export const navigateTo = function (requestedRoute) { - return this.client.execute((route) => { +export const navigateTo = function(requestedRoute) { + return this.client.execute(route => { daedalus.actions.router.goToRoute.trigger({ route }); }, requestedRoute); }; diff --git a/features/support/helpers/screenshot.js b/features/support/helpers/screenshot.js index ae91a8ed31..e458771906 100644 --- a/features/support/helpers/screenshot.js +++ b/features/support/helpers/screenshot.js @@ -3,21 +3,21 @@ import path from 'path'; import { generateFileNameWithTimestamp } from '../../../source/common/utils/files'; import ensureDirectoryExists from '../../../source/main/utils/ensureDirectoryExists'; -export const generateScreenshotFilePath = (testName) => { +export const generateScreenshotFilePath = testName => { const filePath = path.resolve(__dirname, '../../screenshots', testName); const fileName = generateFileNameWithTimestamp(testName, 'png'); ensureDirectoryExists(filePath); return `${filePath}/${fileName}`; }; -export const getTestNameFromTestFile = (testFile) => testFile - .replace('features/', '') - .replace('.feature', ''); +export const getTestNameFromTestFile = testFile => + testFile.replace('features/', '').replace('.feature', ''); export const saveScreenshot = async (context, file) => { - await context.browserWindow.capturePage() - .then((imageBuffer) => fs.writeFile(file, imageBuffer)) - .catch((err) => { + await context.browserWindow + .capturePage() + .then(imageBuffer => fs.writeFile(file, imageBuffer)) + .catch(err => { console.log(err); }); }; diff --git a/features/support/helpers/shared-helpers.js b/features/support/helpers/shared-helpers.js index 66f31a699f..abda367b45 100644 --- a/features/support/helpers/shared-helpers.js +++ b/features/support/helpers/shared-helpers.js @@ -15,7 +15,7 @@ export const expectTextInSelector = async (client, { selector, text }) => { expect(textOnScreen[0]).to.equal(text); }; -export const waitUntilTextInSelector = async (client, { selector, text }) => ( +export const waitUntilTextInSelector = async (client, { selector, text }) => await client.waitUntil(async () => { await client.waitForText(selector); let textOnScreen = await client.getText(selector); @@ -23,16 +23,30 @@ export const waitUntilTextInSelector = async (client, { selector, text }) => ( if (typeof textOnScreen === 'string') textOnScreen = [textOnScreen]; // We only compare the first result return textOnScreen[0] === text; - }) -); + }); -export const getVisibleElementsForSelector = async (client, selectSelector, waitSelector = selectSelector, ...waitArgs) => { +export const getVisibleElementsForSelector = async ( + client, + selectSelector, + waitSelector = selectSelector, + ...waitArgs +) => { await client.waitForVisible(waitSelector, ...waitArgs); return await client.elements(selectSelector); }; -export const getVisibleElementsCountForSelector = async (client, selectSelector, waitSelector = selectSelector, ...waitArgs) => { - const elements = await getVisibleElementsForSelector(client, selectSelector, waitSelector, ...waitArgs); +export const getVisibleElementsCountForSelector = async ( + client, + selectSelector, + waitSelector = selectSelector, + ...waitArgs +) => { + const elements = await getVisibleElementsForSelector( + client, + selectSelector, + waitSelector, + ...waitArgs + ); return elements.value ? elements.value.length : 0; }; diff --git a/features/support/helpers/sidebar-helpers.js b/features/support/helpers/sidebar-helpers.js index 17aa1f2818..4981919339 100644 --- a/features/support/helpers/sidebar-helpers.js +++ b/features/support/helpers/sidebar-helpers.js @@ -2,7 +2,7 @@ import { waitAndClick } from './shared-helpers'; export default { activateCategory: async (client, { category }) => { - await client.execute((cat) => { + await client.execute(cat => { daedalus.actions.sidebar.activateSidebarCategory.trigger({ category: cat, showSubMenu: true, @@ -10,7 +10,6 @@ export default { }, `/${category}`); return client.waitForVisible(`.SidebarCategory_active.${category}`); }, - clickAddWalletButton: (client) => ( - waitAndClick(client, '.SidebarWalletsMenu_addWalletButton') - ), + clickAddWalletButton: client => + waitAndClick(client, '.SidebarWalletsMenu_addWalletButton'), }; diff --git a/features/support/helpers/terms-of-use-helpers.js b/features/support/helpers/terms-of-use-helpers.js index a68eccfcdd..966184861b 100644 --- a/features/support/helpers/terms-of-use-helpers.js +++ b/features/support/helpers/terms-of-use-helpers.js @@ -1,16 +1,15 @@ const TERMS_OF_USE_FORM = '.TermsOfUseForm_component'; const termsOfUse = { - waitForVisible: async (client, { isHidden } = {}) => ( - client.waitForVisible(TERMS_OF_USE_FORM, null, isHidden) - ), - acceptTerms: async (client) => { + waitForVisible: async (client, { isHidden } = {}) => + client.waitForVisible(TERMS_OF_USE_FORM, null, isHidden), + acceptTerms: async client => { await termsOfUse.waitForVisible(client); await client.execute(() => { daedalus.actions.profile.acceptTermsOfUse.trigger(); }); await termsOfUse.waitForVisible(client, { isHidden: true }); - } + }, }; export default termsOfUse; diff --git a/features/support/helpers/wallets-helpers.js b/features/support/helpers/wallets-helpers.js index 4326d2b913..57e8465d2e 100644 --- a/features/support/helpers/wallets-helpers.js +++ b/features/support/helpers/wallets-helpers.js @@ -1,44 +1,60 @@ import { expect } from 'chai'; -export const getNameOfActiveWalletInSidebar = async function () { +export const getNameOfActiveWalletInSidebar = async function() { await this.client.waitForVisible('.SidebarWalletMenuItem_active'); - return this.client.getText('.SidebarWalletMenuItem_active .SidebarWalletMenuItem_title'); + return this.client.getText( + '.SidebarWalletMenuItem_active .SidebarWalletMenuItem_title' + ); }; -export const expectActiveWallet = async function (walletName) { +export const expectActiveWallet = async function(walletName) { const displayedWalletName = await getNameOfActiveWalletInSidebar.call(this); - expect(displayedWalletName.toLowerCase().trim()).to.equal(walletName.toLowerCase().trim()); + expect(displayedWalletName.toLowerCase().trim()).to.equal( + walletName.toLowerCase().trim() + ); }; -export const fillOutWalletSendForm = async function (values) { +export const fillOutWalletSendForm = async function(values) { const formSelector = '.WalletSendForm_component'; - await this.client.setValue(`${formSelector} .receiver .SimpleInput_input`, values.address); - await this.client.setValue(`${formSelector} .amount .SimpleInput_input`, values.amount); + await this.client.setValue( + `${formSelector} .receiver .SimpleInput_input`, + values.address + ); + await this.client.setValue( + `${formSelector} .amount .SimpleInput_input`, + values.amount + ); if (values.spendingPassword) { - await this.client.setValue(`${formSelector} .spendingPassword .SimpleInput_input`, values.spendingPassword); + await this.client.setValue( + `${formSelector} .spendingPassword .SimpleInput_input`, + values.spendingPassword + ); } this.walletSendFormValues = values; }; -export const getWalletByName = function (walletName) { - return this.wallets.find((w) => w.name === walletName); +export const getWalletByName = function(walletName) { + return this.wallets.find(w => w.name === walletName); }; -export const waitUntilWaletNamesEqual = function (walletName) { +export const waitUntilWaletNamesEqual = function(walletName) { const context = this; return context.client.waitUntil(async () => { - const currentWalletName = await getNameOfActiveWalletInSidebar.call(context); + const currentWalletName = await getNameOfActiveWalletInSidebar.call( + context + ); return currentWalletName === walletName; }); }; -export const waitUntilWalletIsLoaded = async function (walletName) { +export const waitUntilWalletIsLoaded = async function(walletName) { let wallet = null; const context = this; await context.client.waitUntil(async () => { - const result = await context.client.execute((name) => ( - daedalus.stores.wallets.getWalletByName(name) - ), walletName); + const result = await context.client.execute( + name => daedalus.stores.wallets.getWalletByName(name), + walletName + ); if (result.value) { wallet = result.value; return true; @@ -48,7 +64,7 @@ export const waitUntilWalletIsLoaded = async function (walletName) { return wallet; }; -export const addOrSetWalletsForScenario = function (wallet) { +export const addOrSetWalletsForScenario = function(wallet) { this.wallet = wallet; if (this.wallets != null) { this.wallets.push(this.wallet); @@ -57,37 +73,49 @@ export const addOrSetWalletsForScenario = function (wallet) { } }; -export const importWalletWithFunds = async (client, { keyFilePath, password }) => ( - await client.executeAsync((filePath, spendingPassword, done) => { - daedalus.api.ada.importWalletFromKey({ filePath, spendingPassword }) - .then(() => ( - daedalus.stores.wallets.refreshWalletsData() - .then(done) - .catch((error) => done(error)) - )) - .catch((error) => done(error)); - }, keyFilePath, password) -); +export const importWalletWithFunds = async ( + client, + { keyFilePath, password } +) => + await client.executeAsync( + (filePath, spendingPassword, done) => { + daedalus.api.ada + .importWalletFromKey({ filePath, spendingPassword }) + .then(() => + daedalus.stores.wallets + .refreshWalletsData() + .then(done) + .catch(error => done(error)) + ) + .catch(error => done(error)); + }, + keyFilePath, + password + ); const createWalletsAsync = async (table, context) => { const result = await context.client.executeAsync((wallets, done) => { - window.Promise.all(wallets.map((wallet) => ( - daedalus.api.ada.createWallet({ - name: wallet.name, - mnemonic: daedalus.utils.crypto.generateMnemonic(), - spendingPassword: wallet.password || null, - }) - ))) - .then(() => ( - daedalus.stores.wallets.walletsRequest.execute() - .then((storeWallets) => ( - daedalus.stores.wallets.refreshWalletsData() + window.Promise.all( + wallets.map(wallet => + daedalus.api.ada.createWallet({ + name: wallet.name, + mnemonic: daedalus.utils.crypto.generateMnemonic(), + spendingPassword: wallet.password || null, + }) + ) + ) + .then(() => + daedalus.stores.wallets.walletsRequest + .execute() + .then(storeWallets => + daedalus.stores.wallets + .refreshWalletsData() .then(() => done(storeWallets)) - .catch((error) => done(error)) - )) - .catch((error) => done(error)) - )) - .catch((error) => done(error.stack)); + .catch(error => done(error)) + ) + .catch(error => done(error)) + ) + .catch(error => done(error.stack)); }, table); // Add or set the wallets for this scenario if (context.wallets != null) { @@ -101,19 +129,24 @@ const createWalletsSequentially = async (wallets, context) => { context.wallets = []; for (const walletData of wallets) { const result = await context.client.executeAsync((wallet, done) => { - daedalus.api.ada.createWallet({ - name: wallet.name, - mnemonic: daedalus.utils.crypto.generateMnemonic(), - spendingPassword: wallet.password || null, - }).then(() => ( - daedalus.stores.wallets.walletsRequest.execute() - .then((storeWallets) => ( - daedalus.stores.wallets.refreshWalletsData() - .then(() => done(storeWallets)) - .catch((error) => done(error)) - )) - .catch((error) => done(error)) - )).catch((error) => done(error.stack)); + daedalus.api.ada + .createWallet({ + name: wallet.name, + mnemonic: daedalus.utils.crypto.generateMnemonic(), + spendingPassword: wallet.password || null, + }) + .then(() => + daedalus.stores.wallets.walletsRequest + .execute() + .then(storeWallets => + daedalus.stores.wallets + .refreshWalletsData() + .then(() => done(storeWallets)) + .catch(error => done(error)) + ) + .catch(error => done(error)) + ) + .catch(error => done(error.stack)); }, walletData); context.wallets = result.value; } diff --git a/features/support/i18n.js b/features/support/i18n.js index e54bbccb0d..f9afc7b852 100644 --- a/features/support/i18n.js +++ b/features/support/i18n.js @@ -1,14 +1,23 @@ import { Before } from 'cucumber'; -Before(function () { +Before(function() { this.intl = async (translationId, translationValues = {}) => { - const translation = await this.client.execute((id, values) => { - const IntlProvider = require('react-intl').IntlProvider; // eslint-disable-line - const locale = daedalus.stores.profile.currentLocale; - const messages = daedalus.translations; - const intlProvider = new IntlProvider({ locale, messages: messages[locale] }, {}); - return intlProvider.getChildContext().intl.formatMessage({ id }, values); - }, translationId, translationValues); + const translation = await this.client.execute( + (id, values) => { + const IntlProvider = require('react-intl').IntlProvider; // eslint-disable-line + const locale = daedalus.stores.profile.currentLocale; + const messages = daedalus.translations; + const intlProvider = new IntlProvider( + { locale, messages: messages[locale] }, + {} + ); + return intlProvider + .getChildContext() + .intl.formatMessage({ id }, values); + }, + translationId, + translationValues + ); return translation.value; }; }); diff --git a/features/support/webdriver.js b/features/support/webdriver.js index accfaa2bc3..33d9b85225 100644 --- a/features/support/webdriver.js +++ b/features/support/webdriver.js @@ -1,6 +1,6 @@ import { Before } from 'cucumber'; -Before(function () { +Before(function() { this.waitAndClick = async (selector, ...waitArgs) => { await this.client.waitForVisible(selector, ...waitArgs); return this.client.click(selector); diff --git a/flow/declarations/File.js b/flow/declarations/File.js index 34a7b3c68d..7f4b694d8c 100644 --- a/flow/declarations/File.js +++ b/flow/declarations/File.js @@ -1,4 +1,4 @@ declare class File { - name: string, - path: string, + name: string; + path: string; } diff --git a/gulpfile.js b/gulpfile.js index c99f5bcfda..69dd31a22c 100755 --- a/gulpfile.js +++ b/gulpfile.js @@ -12,8 +12,12 @@ let electronServer; const mainInputSource = () => gulp.src('source/main/index.js'); const rendererInputSource = () => gulp.src('source/renderer/index.js'); // Webpack watch configs -const mainWebpackWatchConfig = Object.assign({}, mainWebpackConfig, { watch: true }); -const rendererWebpackWatchConfig = Object.assign({}, rendererWebpackConfig, { watch: true }); +const mainWebpackWatchConfig = Object.assign({}, mainWebpackConfig, { + watch: true, +}); +const rendererWebpackWatchConfig = Object.assign({}, rendererWebpackConfig, { + watch: true, +}); // Gulp output destinations for main and renderer compilation const mainOutputDestination = () => gulp.dest('dist/main'); const rendererOutputDestination = () => gulp.dest('dist/renderer'); @@ -29,66 +33,64 @@ const createElectronServer = (env, args = []) => { spawnOpt: { env: Object.assign({}, process.env, env), args, - } + }, }); }; -const buildMain = () => ( - () => ( - mainInputSource() - .pipe(webpackStream(mainWebpackConfig, webpack)) - .pipe(mainOutputDestination()) - ) -); +const buildMain = () => () => + mainInputSource() + .pipe(webpackStream(mainWebpackConfig, webpack)) + .pipe(mainOutputDestination()); -const buildMainWatch = () => ( - (done) => ( - mainInputSource() - .pipe(webpackStream(mainWebpackWatchConfig, webpack, () => { +const buildMainWatch = () => done => + mainInputSource() + .pipe( + webpackStream(mainWebpackWatchConfig, webpack, () => { // Restart app everytime after main script has been re-compiled electronServer.restart(); done(); - })) - .pipe(mainOutputDestination()) - ) -); - -const buildRenderer = () => ( - () => ( - rendererInputSource() - .pipe(webpackStream(rendererWebpackConfig, webpack)) - .pipe(rendererOutputDestination()) - ) -); - -const buildRendererWatch = () => ( - (done) => ( - rendererInputSource() - .pipe(webpackStream(rendererWebpackWatchConfig, webpack, () => { + }) + ) + .pipe(mainOutputDestination()); + +const buildRenderer = () => () => + rendererInputSource() + .pipe(webpackStream(rendererWebpackConfig, webpack)) + .pipe(rendererOutputDestination()); + +const buildRendererWatch = () => done => + rendererInputSource() + .pipe( + webpackStream(rendererWebpackWatchConfig, webpack, () => { // Reload app everytime after renderer script has been re-compiled electronServer.reload(); done(); - })) - .pipe(rendererOutputDestination()) - ) -); + }) + ) + .pipe(rendererOutputDestination()); -gulp.task('clear:cache', shell.task('rimraf ./node_modules/.cache && rimraf .cache-loader')); +gulp.task( + 'clear:cache', + shell.task('rimraf ./node_modules/.cache && rimraf .cache-loader') +); gulp.task('clean:dist', shell.task('rimraf ./dist')); -gulp.task('server:start', (done) => { +gulp.task('server:start', done => { electronServer.start(); done(); }); -gulp.task('server:create:dev', (done) => { +gulp.task('server:create:dev', done => { createElectronServer({ NODE_ENV: process.env.NODE_ENV || 'development' }); done(); }); -gulp.task('server:create:debug', (done) => { - createElectronServer({ NODE_ENV: process.env.NODE_ENV || 'development' }, ['--inspect', '--inspect-brk']); +gulp.task('server:create:debug', done => { + createElectronServer({ NODE_ENV: process.env.NODE_ENV || 'development' }, [ + '--inspect', + '--inspect-brk', + ]); done(); }); @@ -96,36 +98,68 @@ gulp.task('build:main', buildMain()); gulp.task('build:main:watch', buildMainWatch()); -gulp.task('build:renderer:html', () => ( +gulp.task('build:renderer:html', () => gulp.src('source/renderer/index.html').pipe(gulp.dest('dist/renderer/')) -)); +); gulp.task('build:renderer:assets', buildRenderer()); -gulp.task('build:renderer', gulp.series('build:renderer:html', 'build:renderer:assets')); +gulp.task( + 'build:renderer', + gulp.series('build:renderer:html', 'build:renderer:assets') +); gulp.task('build:renderer:watch', buildRendererWatch()); gulp.task('build', gulp.series('clean:dist', 'build:main', 'build:renderer')); -gulp.task('build:watch', gulp.series( - 'clean:dist', 'server:create:dev', 'build:renderer:html', 'build:main:watch', 'build:renderer:watch' -)); +gulp.task( + 'build:watch', + gulp.series( + 'clean:dist', + 'server:create:dev', + 'build:renderer:html', + 'build:main:watch', + 'build:renderer:watch' + ) +); gulp.task('cucumber', shell.task('npm run cucumber --')); -gulp.task('cucumber:watch', shell.task('nodemon --exec npm run cucumber:watch')); +gulp.task( + 'cucumber:watch', + shell.task('nodemon --exec npm run cucumber:watch') +); gulp.task('test', gulp.series('build', 'cucumber')); gulp.task('test:watch', gulp.series('build:watch', 'cucumber:watch')); -gulp.task('purge:translations', shell.task('rimraf ./translations/messages/source')); +gulp.task( + 'purge:translations', + shell.task('rimraf ./translations/messages/source') +); gulp.task('electron:inspector', shell.task('npm run electron:inspector')); -gulp.task('start', shell.task(`cross-env NODE_ENV=${process.env.NODE_ENV || 'production'} electron ./`)); +gulp.task( + 'start', + shell.task( + `cross-env NODE_ENV=${process.env.NODE_ENV || 'production'} electron ./` + ) +); -gulp.task('dev', gulp.series('server:create:dev', 'build:watch', 'server:start')); +gulp.task( + 'dev', + gulp.series('server:create:dev', 'build:watch', 'server:start') +); -gulp.task('debug', gulp.series('server:create:debug', 'build:watch', 'server:start', 'electron:inspector')); +gulp.task( + 'debug', + gulp.series( + 'server:create:debug', + 'build:watch', + 'server:start', + 'electron:inspector' + ) +); diff --git a/package.json b/package.json index eec4aaef1b..739fe3081b 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "cucumber:watch:debug": "KEEP_APP_AFTER_TESTS=true npm run cucumber -- --tags @watch", "lint": "eslint --format=node_modules/eslint-formatter-pretty source features storybook *.js", "flow:test": "flow; test $? -eq 0 -o $? -eq 2", + "prettier": "./node_modules/.bin/prettier --write --ignore-path .eslintignore --loglevel warn \"./**/*.{js,scss,json}\"", "manage:translations": "gulp purge:translations && gulp clear:cache && gulp build && node ./translations/translation-runner.js", "storybook": "start-storybook -p 6006 -c storybook", "clear:cache": "gulp clear:cache", @@ -73,6 +74,7 @@ "electron-rebuild": "1.8.2", "eslint": "4.19.1", "eslint-config-airbnb": "17.1.0", + "eslint-config-prettier": "4.1.0", "eslint-formatter-pretty": "2.0.0", "eslint-import-resolver-webpack": "0.10.1", "eslint-loader": "2.1.1", @@ -88,6 +90,7 @@ "gulp-shell": "0.6.5", "hash.js": "1.1.7", "html-loader": "0.5.5", + "husky": "1.3.1", "json-loader": "0.5.7", "markdown-loader": "4.0.0", "mini-css-extract-plugin": "0.5.0", @@ -99,6 +102,8 @@ "postcss": "7.0.7", "postcss-modules": "1.4.1", "postcss-modules-values": "2.0.0", + "prettier": "1.16.4", + "pretty-quick": "1.10.0", "prettysize": "1.1.0", "raw-loader": "1.0.0", "react-intl-translations-manager": "5.0.3", @@ -174,5 +179,11 @@ "devEngines": { "node": ">=8.9.4", "yarn": "1.10.0" + }, + "husky": { + "hooks": { + "pre-commit": "pretty-quick --staged --pattern \"./**/*.{js,scss,json}\"", + "pre-push": "yarn prettier && yarn lint && yarn flow:test && yarn manage:translations" + } } } diff --git a/scripts/package.js b/scripts/package.js index 19dd8fcefa..429cc1b497 100755 --- a/scripts/package.js +++ b/scripts/package.js @@ -36,7 +36,7 @@ const DEFAULT_OPTS = { /^\/tls($|\/)/, /^\/translations($|\/)/, /^\/installers\/.*exe/, - ] + ], }; const icon = argv.icon || argv.i || 'installers/icons/electron'; @@ -76,7 +76,7 @@ async function startPack() { }); }); } else if (argv.win64) { - pack("win32", "x64", log("win32", "x64")); + pack('win32', 'x64', log('win32', 'x64')); } else { // build for current platform only pack(os.platform(), os.arch(), log(os.platform(), os.arch())); @@ -86,7 +86,6 @@ async function startPack() { } } - /** * @desc * @param {String} plat @@ -98,13 +97,15 @@ function pack(plat, arch, cb) { if (plat === 'darwin' && arch === 'ia32') return; const iconObj = { - icon: DEFAULT_OPTS.icon + (() => { - let extension = '.png'; - if (plat === 'darwin') extension = '.iconset'; - if (plat === 'win32') extension = '.ico'; - - return extension; - })() + icon: + DEFAULT_OPTS.icon + + (() => { + let extension = '.png'; + if (plat === 'darwin') extension = '.iconset'; + if (plat === 'win32') extension = '.ico'; + + return extension; + })(), }; const opts = Object.assign({}, DEFAULT_OPTS, iconObj, { @@ -112,13 +113,12 @@ function pack(plat, arch, cb) { arch, prune: false, 'app-version': pkg.version || DEFAULT_OPTS.version, - out: `release/${plat}-${arch}` + out: `release/${plat}-${arch}`, }); packager(opts, cb); } - /** * @desc Log out success / error of building for given platform and architecture * @param {String} plat diff --git a/source/common/crypto/decrypt.js b/source/common/crypto/decrypt.js index 9f5e6bc9fa..70cf3b8696 100644 --- a/source/common/crypto/decrypt.js +++ b/source/common/crypto/decrypt.js @@ -7,19 +7,40 @@ import validWords from './valid-words.en'; const iv = Buffer.alloc(16); // it's iv = 0 simply function decryptWithAES(aesKey, bytes) { - return new aesjs.ModeOfOperation.ctr(aesKey, new aesjs.Counter(iv)).decrypt(bytes); // eslint-disable-line + // eslint-disable-next-line + return new aesjs.ModeOfOperation.ctr(aesKey, new aesjs.Counter(iv)).decrypt( + bytes + ); } -const hexChar = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']; +const hexChar = [ + '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', +]; -const hexToBytes = (s) => { +const hexToBytes = s => { const arr = []; - if (s.length & 1 === 1) { // eslint-disable-line + // eslint-disable-next-line + if (s.length & (1 === 1)) { throw new Error(`Wrong hex: ${s}`); } for (let i = 0; i < s.length / 2; ++i) { const c1 = s[2 * i]; - const c2 = s[(2 * i) + 1]; + const c2 = s[2 * i + 1]; const i1 = hexChar.indexOf(c1); const i2 = hexChar.indexOf(c2); if (i1 === -1 || i2 === -1) throw new Error(`Wrong hex: ${s}`); @@ -28,25 +49,32 @@ const hexToBytes = (s) => { return new Uint8Array(arr); }; -const blake2b = (data) => blakejs.blake2b(data, null, 32); +const blake2b = data => blakejs.blake2b(data, null, 32); -const fromMnemonic = (words) => hexToBytes(bip39.mnemonicToEntropy(words, validWords)); +const fromMnemonic = words => + hexToBytes(bip39.mnemonicToEntropy(words, validWords)); -export const isValidMnemonic = (phrase, numberOfWords = 9) => ( - (phrase.split(' ').length === numberOfWords && bip39.validateMnemonic(phrase, validWords)) -); +export const isValidMnemonic = (phrase, numberOfWords = 9) => + phrase.split(' ').length === numberOfWords && + bip39.validateMnemonic(phrase, validWords); -const hashData = (data) => { +const hashData = data => { const hash = crypto.createHash('sha256'); hash.update(data, 'utf8'); return hash.digest(); }; -export const decryptRegularVend = (key, data) => decryptWithAES(blake2b(fromMnemonic(key)), data); -export const decryptForceVend = (key, data) => ( - decryptWithAES(blake2b(key[0].trim().toLowerCase() + - hashData(key[1].trim()).hexSlice() + key[2].trim()), data) -); +export const decryptRegularVend = (key, data) => + decryptWithAES(blake2b(fromMnemonic(key)), data); +export const decryptForceVend = (key, data) => + decryptWithAES( + blake2b( + key[0].trim().toLowerCase() + + hashData(key[1].trim()).hexSlice() + + key[2].trim() + ), + data + ); // Recovery service certificates decryption export const decryptRecoveryRegularVend = decryptRegularVend; diff --git a/source/common/crypto/valid-words.en.js b/source/common/crypto/valid-words.en.js index f3705878dc..51dbbdf50c 100644 --- a/source/common/crypto/valid-words.en.js +++ b/source/common/crypto/valid-words.en.js @@ -1 +1,2050 @@ -export default ['abandon', 'ability', 'able', 'about', 'above', 'absent', 'absorb', 'abstract', 'absurd', 'abuse', 'access', 'accident', 'account', 'accuse', 'achieve', 'acid', 'acoustic', 'acquire', 'across', 'act', 'action', 'actor', 'actress', 'actual', 'adapt', 'add', 'addict', 'address', 'adjust', 'admit', 'adult', 'advance', 'advice', 'aerobic', 'affair', 'afford', 'afraid', 'again', 'age', 'agent', 'agree', 'ahead', 'aim', 'air', 'airport', 'aisle', 'alarm', 'album', 'alcohol', 'alert', 'alien', 'all', 'alley', 'allow', 'almost', 'alone', 'alpha', 'already', 'also', 'alter', 'always', 'amateur', 'amazing', 'among', 'amount', 'amused', 'analyst', 'anchor', 'ancient', 'anger', 'angle', 'angry', 'animal', 'ankle', 'announce', 'annual', 'another', 'answer', 'antenna', 'antique', 'anxiety', 'any', 'apart', 'apology', 'appear', 'apple', 'approve', 'april', 'arch', 'arctic', 'area', 'arena', 'argue', 'arm', 'armed', 'armor', 'army', 'around', 'arrange', 'arrest', 'arrive', 'arrow', 'art', 'artefact', 'artist', 'artwork', 'ask', 'aspect', 'assault', 'asset', 'assist', 'assume', 'asthma', 'athlete', 'atom', 'attack', 'attend', 'attitude', 'attract', 'auction', 'audit', 'august', 'aunt', 'author', 'auto', 'autumn', 'average', 'avocado', 'avoid', 'awake', 'aware', 'away', 'awesome', 'awful', 'awkward', 'axis', 'baby', 'bachelor', 'bacon', 'badge', 'bag', 'balance', 'balcony', 'ball', 'bamboo', 'banana', 'banner', 'bar', 'barely', 'bargain', 'barrel', 'base', 'basic', 'basket', 'battle', 'beach', 'bean', 'beauty', 'because', 'become', 'beef', 'before', 'begin', 'behave', 'behind', 'believe', 'below', 'belt', 'bench', 'benefit', 'best', 'betray', 'better', 'between', 'beyond', 'bicycle', 'bid', 'bike', 'bind', 'biology', 'bird', 'birth', 'bitter', 'black', 'blade', 'blame', 'blanket', 'blast', 'bleak', 'bless', 'blind', 'blood', 'blossom', 'blouse', 'blue', 'blur', 'blush', 'board', 'boat', 'body', 'boil', 'bomb', 'bone', 'bonus', 'book', 'boost', 'border', 'boring', 'borrow', 'boss', 'bottom', 'bounce', 'box', 'boy', 'bracket', 'brain', 'brand', 'brass', 'brave', 'bread', 'breeze', 'brick', 'bridge', 'brief', 'bright', 'bring', 'brisk', 'broccoli', 'broken', 'bronze', 'broom', 'brother', 'brown', 'brush', 'bubble', 'buddy', 'budget', 'buffalo', 'build', 'bulb', 'bulk', 'bullet', 'bundle', 'bunker', 'burden', 'burger', 'burst', 'bus', 'business', 'busy', 'butter', 'buyer', 'buzz', 'cabbage', 'cabin', 'cable', 'cactus', 'cage', 'cake', 'call', 'calm', 'camera', 'camp', 'can', 'canal', 'cancel', 'candy', 'cannon', 'canoe', 'canvas', 'canyon', 'capable', 'capital', 'captain', 'car', 'carbon', 'card', 'cargo', 'carpet', 'carry', 'cart', 'case', 'cash', 'casino', 'castle', 'casual', 'cat', 'catalog', 'catch', 'category', 'cattle', 'caught', 'cause', 'caution', 'cave', 'ceiling', 'celery', 'cement', 'census', 'century', 'cereal', 'certain', 'chair', 'chalk', 'champion', 'change', 'chaos', 'chapter', 'charge', 'chase', 'chat', 'cheap', 'check', 'cheese', 'chef', 'cherry', 'chest', 'chicken', 'chief', 'child', 'chimney', 'choice', 'choose', 'chronic', 'chuckle', 'chunk', 'churn', 'cigar', 'cinnamon', 'circle', 'citizen', 'city', 'civil', 'claim', 'clap', 'clarify', 'claw', 'clay', 'clean', 'clerk', 'clever', 'click', 'client', 'cliff', 'climb', 'clinic', 'clip', 'clock', 'clog', 'close', 'cloth', 'cloud', 'clown', 'club', 'clump', 'cluster', 'clutch', 'coach', 'coast', 'coconut', 'code', 'coffee', 'coil', 'coin', 'collect', 'color', 'column', 'combine', 'come', 'comfort', 'comic', 'common', 'company', 'concert', 'conduct', 'confirm', 'congress', 'connect', 'consider', 'control', 'convince', 'cook', 'cool', 'copper', 'copy', 'coral', 'core', 'corn', 'correct', 'cost', 'cotton', 'couch', 'country', 'couple', 'course', 'cousin', 'cover', 'coyote', 'crack', 'cradle', 'craft', 'cram', 'crane', 'crash', 'crater', 'crawl', 'crazy', 'cream', 'credit', 'creek', 'crew', 'cricket', 'crime', 'crisp', 'critic', 'crop', 'cross', 'crouch', 'crowd', 'crucial', 'cruel', 'cruise', 'crumble', 'crunch', 'crush', 'cry', 'crystal', 'cube', 'culture', 'cup', 'cupboard', 'curious', 'current', 'curtain', 'curve', 'cushion', 'custom', 'cute', 'cycle', 'dad', 'damage', 'damp', 'dance', 'danger', 'daring', 'dash', 'daughter', 'dawn', 'day', 'deal', 'debate', 'debris', 'decade', 'december', 'decide', 'decline', 'decorate', 'decrease', 'deer', 'defense', 'define', 'defy', 'degree', 'delay', 'deliver', 'demand', 'demise', 'denial', 'dentist', 'deny', 'depart', 'depend', 'deposit', 'depth', 'deputy', 'derive', 'describe', 'desert', 'design', 'desk', 'despair', 'destroy', 'detail', 'detect', 'develop', 'device', 'devote', 'diagram', 'dial', 'diamond', 'diary', 'dice', 'diesel', 'diet', 'differ', 'digital', 'dignity', 'dilemma', 'dinner', 'dinosaur', 'direct', 'dirt', 'disagree', 'discover', 'disease', 'dish', 'dismiss', 'disorder', 'display', 'distance', 'divert', 'divide', 'divorce', 'dizzy', 'doctor', 'document', 'dog', 'doll', 'dolphin', 'domain', 'donate', 'donkey', 'donor', 'door', 'dose', 'double', 'dove', 'draft', 'dragon', 'drama', 'drastic', 'draw', 'dream', 'dress', 'drift', 'drill', 'drink', 'drip', 'drive', 'drop', 'drum', 'dry', 'duck', 'dumb', 'dune', 'during', 'dust', 'dutch', 'duty', 'dwarf', 'dynamic', 'eager', 'eagle', 'early', 'earn', 'earth', 'easily', 'east', 'easy', 'echo', 'ecology', 'economy', 'edge', 'edit', 'educate', 'effort', 'egg', 'eight', 'either', 'elbow', 'elder', 'electric', 'elegant', 'element', 'elephant', 'elevator', 'elite', 'else', 'embark', 'embody', 'embrace', 'emerge', 'emotion', 'employ', 'empower', 'empty', 'enable', 'enact', 'end', 'endless', 'endorse', 'enemy', 'energy', 'enforce', 'engage', 'engine', 'enhance', 'enjoy', 'enlist', 'enough', 'enrich', 'enroll', 'ensure', 'enter', 'entire', 'entry', 'envelope', 'episode', 'equal', 'equip', 'era', 'erase', 'erode', 'erosion', 'error', 'erupt', 'escape', 'essay', 'essence', 'estate', 'eternal', 'ethics', 'evidence', 'evil', 'evoke', 'evolve', 'exact', 'example', 'excess', 'exchange', 'excite', 'exclude', 'excuse', 'execute', 'exercise', 'exhaust', 'exhibit', 'exile', 'exist', 'exit', 'exotic', 'expand', 'expect', 'expire', 'explain', 'expose', 'express', 'extend', 'extra', 'eye', 'eyebrow', 'fabric', 'face', 'faculty', 'fade', 'faint', 'faith', 'fall', 'false', 'fame', 'family', 'famous', 'fan', 'fancy', 'fantasy', 'farm', 'fashion', 'fat', 'fatal', 'father', 'fatigue', 'fault', 'favorite', 'feature', 'february', 'federal', 'fee', 'feed', 'feel', 'female', 'fence', 'festival', 'fetch', 'fever', 'few', 'fiber', 'fiction', 'field', 'figure', 'file', 'film', 'filter', 'final', 'find', 'fine', 'finger', 'finish', 'fire', 'firm', 'first', 'fiscal', 'fish', 'fit', 'fitness', 'fix', 'flag', 'flame', 'flash', 'flat', 'flavor', 'flee', 'flight', 'flip', 'float', 'flock', 'floor', 'flower', 'fluid', 'flush', 'fly', 'foam', 'focus', 'fog', 'foil', 'fold', 'follow', 'food', 'foot', 'force', 'forest', 'forget', 'fork', 'fortune', 'forum', 'forward', 'fossil', 'foster', 'found', 'fox', 'fragile', 'frame', 'frequent', 'fresh', 'friend', 'fringe', 'frog', 'front', 'frost', 'frown', 'frozen', 'fruit', 'fuel', 'fun', 'funny', 'furnace', 'fury', 'future', 'gadget', 'gain', 'galaxy', 'gallery', 'game', 'gap', 'garage', 'garbage', 'garden', 'garlic', 'garment', 'gas', 'gasp', 'gate', 'gather', 'gauge', 'gaze', 'general', 'genius', 'genre', 'gentle', 'genuine', 'gesture', 'ghost', 'giant', 'gift', 'giggle', 'ginger', 'giraffe', 'girl', 'give', 'glad', 'glance', 'glare', 'glass', 'glide', 'glimpse', 'globe', 'gloom', 'glory', 'glove', 'glow', 'glue', 'goat', 'goddess', 'gold', 'good', 'goose', 'gorilla', 'gospel', 'gossip', 'govern', 'gown', 'grab', 'grace', 'grain', 'grant', 'grape', 'grass', 'gravity', 'great', 'green', 'grid', 'grief', 'grit', 'grocery', 'group', 'grow', 'grunt', 'guard', 'guess', 'guide', 'guilt', 'guitar', 'gun', 'gym', 'habit', 'hair', 'half', 'hammer', 'hamster', 'hand', 'happy', 'harbor', 'hard', 'harsh', 'harvest', 'hat', 'have', 'hawk', 'hazard', 'head', 'health', 'heart', 'heavy', 'hedgehog', 'height', 'hello', 'helmet', 'help', 'hen', 'hero', 'hidden', 'high', 'hill', 'hint', 'hip', 'hire', 'history', 'hobby', 'hockey', 'hold', 'hole', 'holiday', 'hollow', 'home', 'honey', 'hood', 'hope', 'horn', 'horror', 'horse', 'hospital', 'host', 'hotel', 'hour', 'hover', 'hub', 'huge', 'human', 'humble', 'humor', 'hundred', 'hungry', 'hunt', 'hurdle', 'hurry', 'hurt', 'husband', 'hybrid', 'ice', 'icon', 'idea', 'identify', 'idle', 'ignore', 'ill', 'illegal', 'illness', 'image', 'imitate', 'immense', 'immune', 'impact', 'impose', 'improve', 'impulse', 'inch', 'include', 'income', 'increase', 'index', 'indicate', 'indoor', 'industry', 'infant', 'inflict', 'inform', 'inhale', 'inherit', 'initial', 'inject', 'injury', 'inmate', 'inner', 'innocent', 'input', 'inquiry', 'insane', 'insect', 'inside', 'inspire', 'install', 'intact', 'interest', 'into', 'invest', 'invite', 'involve', 'iron', 'island', 'isolate', 'issue', 'item', 'ivory', 'jacket', 'jaguar', 'jar', 'jazz', 'jealous', 'jeans', 'jelly', 'jewel', 'job', 'join', 'joke', 'journey', 'joy', 'judge', 'juice', 'jump', 'jungle', 'junior', 'junk', 'just', 'kangaroo', 'keen', 'keep', 'ketchup', 'key', 'kick', 'kid', 'kidney', 'kind', 'kingdom', 'kiss', 'kit', 'kitchen', 'kite', 'kitten', 'kiwi', 'knee', 'knife', 'knock', 'know', 'lab', 'label', 'labor', 'ladder', 'lady', 'lake', 'lamp', 'language', 'laptop', 'large', 'later', 'latin', 'laugh', 'laundry', 'lava', 'law', 'lawn', 'lawsuit', 'layer', 'lazy', 'leader', 'leaf', 'learn', 'leave', 'lecture', 'left', 'leg', 'legal', 'legend', 'leisure', 'lemon', 'lend', 'length', 'lens', 'leopard', 'lesson', 'letter', 'level', 'liar', 'liberty', 'library', 'license', 'life', 'lift', 'light', 'like', 'limb', 'limit', 'link', 'lion', 'liquid', 'list', 'little', 'live', 'lizard', 'load', 'loan', 'lobster', 'local', 'lock', 'logic', 'lonely', 'long', 'loop', 'lottery', 'loud', 'lounge', 'love', 'loyal', 'lucky', 'luggage', 'lumber', 'lunar', 'lunch', 'luxury', 'lyrics', 'machine', 'mad', 'magic', 'magnet', 'maid', 'mail', 'main', 'major', 'make', 'mammal', 'man', 'manage', 'mandate', 'mango', 'mansion', 'manual', 'maple', 'marble', 'march', 'margin', 'marine', 'market', 'marriage', 'mask', 'mass', 'master', 'match', 'material', 'math', 'matrix', 'matter', 'maximum', 'maze', 'meadow', 'mean', 'measure', 'meat', 'mechanic', 'medal', 'media', 'melody', 'melt', 'member', 'memory', 'mention', 'menu', 'mercy', 'merge', 'merit', 'merry', 'mesh', 'message', 'metal', 'method', 'middle', 'midnight', 'milk', 'million', 'mimic', 'mind', 'minimum', 'minor', 'minute', 'miracle', 'mirror', 'misery', 'miss', 'mistake', 'mix', 'mixed', 'mixture', 'mobile', 'model', 'modify', 'mom', 'moment', 'monitor', 'monkey', 'monster', 'month', 'moon', 'moral', 'more', 'morning', 'mosquito', 'mother', 'motion', 'motor', 'mountain', 'mouse', 'move', 'movie', 'much', 'muffin', 'mule', 'multiply', 'muscle', 'museum', 'mushroom', 'music', 'must', 'mutual', 'myself', 'mystery', 'myth', 'naive', 'name', 'napkin', 'narrow', 'nasty', 'nation', 'nature', 'near', 'neck', 'need', 'negative', 'neglect', 'neither', 'nephew', 'nerve', 'nest', 'net', 'network', 'neutral', 'never', 'news', 'next', 'nice', 'night', 'noble', 'noise', 'nominee', 'noodle', 'normal', 'north', 'nose', 'notable', 'note', 'nothing', 'notice', 'novel', 'now', 'nuclear', 'number', 'nurse', 'nut', 'oak', 'obey', 'object', 'oblige', 'obscure', 'observe', 'obtain', 'obvious', 'occur', 'ocean', 'october', 'odor', 'off', 'offer', 'office', 'often', 'oil', 'okay', 'old', 'olive', 'olympic', 'omit', 'once', 'one', 'onion', 'online', 'only', 'open', 'opera', 'opinion', 'oppose', 'option', 'orange', 'orbit', 'orchard', 'order', 'ordinary', 'organ', 'orient', 'original', 'orphan', 'ostrich', 'other', 'outdoor', 'outer', 'output', 'outside', 'oval', 'oven', 'over', 'own', 'owner', 'oxygen', 'oyster', 'ozone', 'pact', 'paddle', 'page', 'pair', 'palace', 'palm', 'panda', 'panel', 'panic', 'panther', 'paper', 'parade', 'parent', 'park', 'parrot', 'party', 'pass', 'patch', 'path', 'patient', 'patrol', 'pattern', 'pause', 'pave', 'payment', 'peace', 'peanut', 'pear', 'peasant', 'pelican', 'pen', 'penalty', 'pencil', 'people', 'pepper', 'perfect', 'permit', 'person', 'pet', 'phone', 'photo', 'phrase', 'physical', 'piano', 'picnic', 'picture', 'piece', 'pig', 'pigeon', 'pill', 'pilot', 'pink', 'pioneer', 'pipe', 'pistol', 'pitch', 'pizza', 'place', 'planet', 'plastic', 'plate', 'play', 'please', 'pledge', 'pluck', 'plug', 'plunge', 'poem', 'poet', 'point', 'polar', 'pole', 'police', 'pond', 'pony', 'pool', 'popular', 'portion', 'position', 'possible', 'post', 'potato', 'pottery', 'poverty', 'powder', 'power', 'practice', 'praise', 'predict', 'prefer', 'prepare', 'present', 'pretty', 'prevent', 'price', 'pride', 'primary', 'print', 'priority', 'prison', 'private', 'prize', 'problem', 'process', 'produce', 'profit', 'program', 'project', 'promote', 'proof', 'property', 'prosper', 'protect', 'proud', 'provide', 'public', 'pudding', 'pull', 'pulp', 'pulse', 'pumpkin', 'punch', 'pupil', 'puppy', 'purchase', 'purity', 'purpose', 'purse', 'push', 'put', 'puzzle', 'pyramid', 'quality', 'quantum', 'quarter', 'question', 'quick', 'quit', 'quiz', 'quote', 'rabbit', 'raccoon', 'race', 'rack', 'radar', 'radio', 'rail', 'rain', 'raise', 'rally', 'ramp', 'ranch', 'random', 'range', 'rapid', 'rare', 'rate', 'rather', 'raven', 'raw', 'razor', 'ready', 'real', 'reason', 'rebel', 'rebuild', 'recall', 'receive', 'recipe', 'record', 'recycle', 'reduce', 'reflect', 'reform', 'refuse', 'region', 'regret', 'regular', 'reject', 'relax', 'release', 'relief', 'rely', 'remain', 'remember', 'remind', 'remove', 'render', 'renew', 'rent', 'reopen', 'repair', 'repeat', 'replace', 'report', 'require', 'rescue', 'resemble', 'resist', 'resource', 'response', 'result', 'retire', 'retreat', 'return', 'reunion', 'reveal', 'review', 'reward', 'rhythm', 'rib', 'ribbon', 'rice', 'rich', 'ride', 'ridge', 'rifle', 'right', 'rigid', 'ring', 'riot', 'ripple', 'risk', 'ritual', 'rival', 'river', 'road', 'roast', 'robot', 'robust', 'rocket', 'romance', 'roof', 'rookie', 'room', 'rose', 'rotate', 'rough', 'round', 'route', 'royal', 'rubber', 'rude', 'rug', 'rule', 'run', 'runway', 'rural', 'sad', 'saddle', 'sadness', 'safe', 'sail', 'salad', 'salmon', 'salon', 'salt', 'salute', 'same', 'sample', 'sand', 'satisfy', 'satoshi', 'sauce', 'sausage', 'save', 'say', 'scale', 'scan', 'scare', 'scatter', 'scene', 'scheme', 'school', 'science', 'scissors', 'scorpion', 'scout', 'scrap', 'screen', 'script', 'scrub', 'sea', 'search', 'season', 'seat', 'second', 'secret', 'section', 'security', 'seed', 'seek', 'segment', 'select', 'sell', 'seminar', 'senior', 'sense', 'sentence', 'series', 'service', 'session', 'settle', 'setup', 'seven', 'shadow', 'shaft', 'shallow', 'share', 'shed', 'shell', 'sheriff', 'shield', 'shift', 'shine', 'ship', 'shiver', 'shock', 'shoe', 'shoot', 'shop', 'short', 'shoulder', 'shove', 'shrimp', 'shrug', 'shuffle', 'shy', 'sibling', 'sick', 'side', 'siege', 'sight', 'sign', 'silent', 'silk', 'silly', 'silver', 'similar', 'simple', 'since', 'sing', 'siren', 'sister', 'situate', 'six', 'size', 'skate', 'sketch', 'ski', 'skill', 'skin', 'skirt', 'skull', 'slab', 'slam', 'sleep', 'slender', 'slice', 'slide', 'slight', 'slim', 'slogan', 'slot', 'slow', 'slush', 'small', 'smart', 'smile', 'smoke', 'smooth', 'snack', 'snake', 'snap', 'sniff', 'snow', 'soap', 'soccer', 'social', 'sock', 'soda', 'soft', 'solar', 'soldier', 'solid', 'solution', 'solve', 'someone', 'song', 'soon', 'sorry', 'sort', 'soul', 'sound', 'soup', 'source', 'south', 'space', 'spare', 'spatial', 'spawn', 'speak', 'special', 'speed', 'spell', 'spend', 'sphere', 'spice', 'spider', 'spike', 'spin', 'spirit', 'split', 'spoil', 'sponsor', 'spoon', 'sport', 'spot', 'spray', 'spread', 'spring', 'spy', 'square', 'squeeze', 'squirrel', 'stable', 'stadium', 'staff', 'stage', 'stairs', 'stamp', 'stand', 'start', 'state', 'stay', 'steak', 'steel', 'stem', 'step', 'stereo', 'stick', 'still', 'sting', 'stock', 'stomach', 'stone', 'stool', 'story', 'stove', 'strategy', 'street', 'strike', 'strong', 'struggle', 'student', 'stuff', 'stumble', 'style', 'subject', 'submit', 'subway', 'success', 'such', 'sudden', 'suffer', 'sugar', 'suggest', 'suit', 'summer', 'sun', 'sunny', 'sunset', 'super', 'supply', 'supreme', 'sure', 'surface', 'surge', 'surprise', 'surround', 'survey', 'suspect', 'sustain', 'swallow', 'swamp', 'swap', 'swarm', 'swear', 'sweet', 'swift', 'swim', 'swing', 'switch', 'sword', 'symbol', 'symptom', 'syrup', 'system', 'table', 'tackle', 'tag', 'tail', 'talent', 'talk', 'tank', 'tape', 'target', 'task', 'taste', 'tattoo', 'taxi', 'teach', 'team', 'tell', 'ten', 'tenant', 'tennis', 'tent', 'term', 'test', 'text', 'thank', 'that', 'theme', 'then', 'theory', 'there', 'they', 'thing', 'this', 'thought', 'three', 'thrive', 'throw', 'thumb', 'thunder', 'ticket', 'tide', 'tiger', 'tilt', 'timber', 'time', 'tiny', 'tip', 'tired', 'tissue', 'title', 'toast', 'tobacco', 'today', 'toddler', 'toe', 'together', 'toilet', 'token', 'tomato', 'tomorrow', 'tone', 'tongue', 'tonight', 'tool', 'tooth', 'top', 'topic', 'topple', 'torch', 'tornado', 'tortoise', 'toss', 'total', 'tourist', 'toward', 'tower', 'town', 'toy', 'track', 'trade', 'traffic', 'tragic', 'train', 'transfer', 'trap', 'trash', 'travel', 'tray', 'treat', 'tree', 'trend', 'trial', 'tribe', 'trick', 'trigger', 'trim', 'trip', 'trophy', 'trouble', 'truck', 'true', 'truly', 'trumpet', 'trust', 'truth', 'try', 'tube', 'tuition', 'tumble', 'tuna', 'tunnel', 'turkey', 'turn', 'turtle', 'twelve', 'twenty', 'twice', 'twin', 'twist', 'two', 'type', 'typical', 'ugly', 'umbrella', 'unable', 'unaware', 'uncle', 'uncover', 'under', 'undo', 'unfair', 'unfold', 'unhappy', 'uniform', 'unique', 'unit', 'universe', 'unknown', 'unlock', 'until', 'unusual', 'unveil', 'update', 'upgrade', 'uphold', 'upon', 'upper', 'upset', 'urban', 'urge', 'usage', 'use', 'used', 'useful', 'useless', 'usual', 'utility', 'vacant', 'vacuum', 'vague', 'valid', 'valley', 'valve', 'van', 'vanish', 'vapor', 'various', 'vast', 'vault', 'vehicle', 'velvet', 'vendor', 'venture', 'venue', 'verb', 'verify', 'version', 'very', 'vessel', 'veteran', 'viable', 'vibrant', 'vicious', 'victory', 'video', 'view', 'village', 'vintage', 'violin', 'virtual', 'virus', 'visa', 'visit', 'visual', 'vital', 'vivid', 'vocal', 'voice', 'void', 'volcano', 'volume', 'vote', 'voyage', 'wage', 'wagon', 'wait', 'walk', 'wall', 'walnut', 'want', 'warfare', 'warm', 'warrior', 'wash', 'wasp', 'waste', 'water', 'wave', 'way', 'wealth', 'weapon', 'wear', 'weasel', 'weather', 'web', 'wedding', 'weekend', 'weird', 'welcome', 'west', 'wet', 'whale', 'what', 'wheat', 'wheel', 'when', 'where', 'whip', 'whisper', 'wide', 'width', 'wife', 'wild', 'will', 'win', 'window', 'wine', 'wing', 'wink', 'winner', 'winter', 'wire', 'wisdom', 'wise', 'wish', 'witness', 'wolf', 'woman', 'wonder', 'wood', 'wool', 'word', 'work', 'world', 'worry', 'worth', 'wrap', 'wreck', 'wrestle', 'wrist', 'write', 'wrong', 'yard', 'year', 'yellow', 'you', 'young', 'youth', 'zebra', 'zero', 'zone', 'zoo']; +export default [ + 'abandon', + 'ability', + 'able', + 'about', + 'above', + 'absent', + 'absorb', + 'abstract', + 'absurd', + 'abuse', + 'access', + 'accident', + 'account', + 'accuse', + 'achieve', + 'acid', + 'acoustic', + 'acquire', + 'across', + 'act', + 'action', + 'actor', + 'actress', + 'actual', + 'adapt', + 'add', + 'addict', + 'address', + 'adjust', + 'admit', + 'adult', + 'advance', + 'advice', + 'aerobic', + 'affair', + 'afford', + 'afraid', + 'again', + 'age', + 'agent', + 'agree', + 'ahead', + 'aim', + 'air', + 'airport', + 'aisle', + 'alarm', + 'album', + 'alcohol', + 'alert', + 'alien', + 'all', + 'alley', + 'allow', + 'almost', + 'alone', + 'alpha', + 'already', + 'also', + 'alter', + 'always', + 'amateur', + 'amazing', + 'among', + 'amount', + 'amused', + 'analyst', + 'anchor', + 'ancient', + 'anger', + 'angle', + 'angry', + 'animal', + 'ankle', + 'announce', + 'annual', + 'another', + 'answer', + 'antenna', + 'antique', + 'anxiety', + 'any', + 'apart', + 'apology', + 'appear', + 'apple', + 'approve', + 'april', + 'arch', + 'arctic', + 'area', + 'arena', + 'argue', + 'arm', + 'armed', + 'armor', + 'army', + 'around', + 'arrange', + 'arrest', + 'arrive', + 'arrow', + 'art', + 'artefact', + 'artist', + 'artwork', + 'ask', + 'aspect', + 'assault', + 'asset', + 'assist', + 'assume', + 'asthma', + 'athlete', + 'atom', + 'attack', + 'attend', + 'attitude', + 'attract', + 'auction', + 'audit', + 'august', + 'aunt', + 'author', + 'auto', + 'autumn', + 'average', + 'avocado', + 'avoid', + 'awake', + 'aware', + 'away', + 'awesome', + 'awful', + 'awkward', + 'axis', + 'baby', + 'bachelor', + 'bacon', + 'badge', + 'bag', + 'balance', + 'balcony', + 'ball', + 'bamboo', + 'banana', + 'banner', + 'bar', + 'barely', + 'bargain', + 'barrel', + 'base', + 'basic', + 'basket', + 'battle', + 'beach', + 'bean', + 'beauty', + 'because', + 'become', + 'beef', + 'before', + 'begin', + 'behave', + 'behind', + 'believe', + 'below', + 'belt', + 'bench', + 'benefit', + 'best', + 'betray', + 'better', + 'between', + 'beyond', + 'bicycle', + 'bid', + 'bike', + 'bind', + 'biology', + 'bird', + 'birth', + 'bitter', + 'black', + 'blade', + 'blame', + 'blanket', + 'blast', + 'bleak', + 'bless', + 'blind', + 'blood', + 'blossom', + 'blouse', + 'blue', + 'blur', + 'blush', + 'board', + 'boat', + 'body', + 'boil', + 'bomb', + 'bone', + 'bonus', + 'book', + 'boost', + 'border', + 'boring', + 'borrow', + 'boss', + 'bottom', + 'bounce', + 'box', + 'boy', + 'bracket', + 'brain', + 'brand', + 'brass', + 'brave', + 'bread', + 'breeze', + 'brick', + 'bridge', + 'brief', + 'bright', + 'bring', + 'brisk', + 'broccoli', + 'broken', + 'bronze', + 'broom', + 'brother', + 'brown', + 'brush', + 'bubble', + 'buddy', + 'budget', + 'buffalo', + 'build', + 'bulb', + 'bulk', + 'bullet', + 'bundle', + 'bunker', + 'burden', + 'burger', + 'burst', + 'bus', + 'business', + 'busy', + 'butter', + 'buyer', + 'buzz', + 'cabbage', + 'cabin', + 'cable', + 'cactus', + 'cage', + 'cake', + 'call', + 'calm', + 'camera', + 'camp', + 'can', + 'canal', + 'cancel', + 'candy', + 'cannon', + 'canoe', + 'canvas', + 'canyon', + 'capable', + 'capital', + 'captain', + 'car', + 'carbon', + 'card', + 'cargo', + 'carpet', + 'carry', + 'cart', + 'case', + 'cash', + 'casino', + 'castle', + 'casual', + 'cat', + 'catalog', + 'catch', + 'category', + 'cattle', + 'caught', + 'cause', + 'caution', + 'cave', + 'ceiling', + 'celery', + 'cement', + 'census', + 'century', + 'cereal', + 'certain', + 'chair', + 'chalk', + 'champion', + 'change', + 'chaos', + 'chapter', + 'charge', + 'chase', + 'chat', + 'cheap', + 'check', + 'cheese', + 'chef', + 'cherry', + 'chest', + 'chicken', + 'chief', + 'child', + 'chimney', + 'choice', + 'choose', + 'chronic', + 'chuckle', + 'chunk', + 'churn', + 'cigar', + 'cinnamon', + 'circle', + 'citizen', + 'city', + 'civil', + 'claim', + 'clap', + 'clarify', + 'claw', + 'clay', + 'clean', + 'clerk', + 'clever', + 'click', + 'client', + 'cliff', + 'climb', + 'clinic', + 'clip', + 'clock', + 'clog', + 'close', + 'cloth', + 'cloud', + 'clown', + 'club', + 'clump', + 'cluster', + 'clutch', + 'coach', + 'coast', + 'coconut', + 'code', + 'coffee', + 'coil', + 'coin', + 'collect', + 'color', + 'column', + 'combine', + 'come', + 'comfort', + 'comic', + 'common', + 'company', + 'concert', + 'conduct', + 'confirm', + 'congress', + 'connect', + 'consider', + 'control', + 'convince', + 'cook', + 'cool', + 'copper', + 'copy', + 'coral', + 'core', + 'corn', + 'correct', + 'cost', + 'cotton', + 'couch', + 'country', + 'couple', + 'course', + 'cousin', + 'cover', + 'coyote', + 'crack', + 'cradle', + 'craft', + 'cram', + 'crane', + 'crash', + 'crater', + 'crawl', + 'crazy', + 'cream', + 'credit', + 'creek', + 'crew', + 'cricket', + 'crime', + 'crisp', + 'critic', + 'crop', + 'cross', + 'crouch', + 'crowd', + 'crucial', + 'cruel', + 'cruise', + 'crumble', + 'crunch', + 'crush', + 'cry', + 'crystal', + 'cube', + 'culture', + 'cup', + 'cupboard', + 'curious', + 'current', + 'curtain', + 'curve', + 'cushion', + 'custom', + 'cute', + 'cycle', + 'dad', + 'damage', + 'damp', + 'dance', + 'danger', + 'daring', + 'dash', + 'daughter', + 'dawn', + 'day', + 'deal', + 'debate', + 'debris', + 'decade', + 'december', + 'decide', + 'decline', + 'decorate', + 'decrease', + 'deer', + 'defense', + 'define', + 'defy', + 'degree', + 'delay', + 'deliver', + 'demand', + 'demise', + 'denial', + 'dentist', + 'deny', + 'depart', + 'depend', + 'deposit', + 'depth', + 'deputy', + 'derive', + 'describe', + 'desert', + 'design', + 'desk', + 'despair', + 'destroy', + 'detail', + 'detect', + 'develop', + 'device', + 'devote', + 'diagram', + 'dial', + 'diamond', + 'diary', + 'dice', + 'diesel', + 'diet', + 'differ', + 'digital', + 'dignity', + 'dilemma', + 'dinner', + 'dinosaur', + 'direct', + 'dirt', + 'disagree', + 'discover', + 'disease', + 'dish', + 'dismiss', + 'disorder', + 'display', + 'distance', + 'divert', + 'divide', + 'divorce', + 'dizzy', + 'doctor', + 'document', + 'dog', + 'doll', + 'dolphin', + 'domain', + 'donate', + 'donkey', + 'donor', + 'door', + 'dose', + 'double', + 'dove', + 'draft', + 'dragon', + 'drama', + 'drastic', + 'draw', + 'dream', + 'dress', + 'drift', + 'drill', + 'drink', + 'drip', + 'drive', + 'drop', + 'drum', + 'dry', + 'duck', + 'dumb', + 'dune', + 'during', + 'dust', + 'dutch', + 'duty', + 'dwarf', + 'dynamic', + 'eager', + 'eagle', + 'early', + 'earn', + 'earth', + 'easily', + 'east', + 'easy', + 'echo', + 'ecology', + 'economy', + 'edge', + 'edit', + 'educate', + 'effort', + 'egg', + 'eight', + 'either', + 'elbow', + 'elder', + 'electric', + 'elegant', + 'element', + 'elephant', + 'elevator', + 'elite', + 'else', + 'embark', + 'embody', + 'embrace', + 'emerge', + 'emotion', + 'employ', + 'empower', + 'empty', + 'enable', + 'enact', + 'end', + 'endless', + 'endorse', + 'enemy', + 'energy', + 'enforce', + 'engage', + 'engine', + 'enhance', + 'enjoy', + 'enlist', + 'enough', + 'enrich', + 'enroll', + 'ensure', + 'enter', + 'entire', + 'entry', + 'envelope', + 'episode', + 'equal', + 'equip', + 'era', + 'erase', + 'erode', + 'erosion', + 'error', + 'erupt', + 'escape', + 'essay', + 'essence', + 'estate', + 'eternal', + 'ethics', + 'evidence', + 'evil', + 'evoke', + 'evolve', + 'exact', + 'example', + 'excess', + 'exchange', + 'excite', + 'exclude', + 'excuse', + 'execute', + 'exercise', + 'exhaust', + 'exhibit', + 'exile', + 'exist', + 'exit', + 'exotic', + 'expand', + 'expect', + 'expire', + 'explain', + 'expose', + 'express', + 'extend', + 'extra', + 'eye', + 'eyebrow', + 'fabric', + 'face', + 'faculty', + 'fade', + 'faint', + 'faith', + 'fall', + 'false', + 'fame', + 'family', + 'famous', + 'fan', + 'fancy', + 'fantasy', + 'farm', + 'fashion', + 'fat', + 'fatal', + 'father', + 'fatigue', + 'fault', + 'favorite', + 'feature', + 'february', + 'federal', + 'fee', + 'feed', + 'feel', + 'female', + 'fence', + 'festival', + 'fetch', + 'fever', + 'few', + 'fiber', + 'fiction', + 'field', + 'figure', + 'file', + 'film', + 'filter', + 'final', + 'find', + 'fine', + 'finger', + 'finish', + 'fire', + 'firm', + 'first', + 'fiscal', + 'fish', + 'fit', + 'fitness', + 'fix', + 'flag', + 'flame', + 'flash', + 'flat', + 'flavor', + 'flee', + 'flight', + 'flip', + 'float', + 'flock', + 'floor', + 'flower', + 'fluid', + 'flush', + 'fly', + 'foam', + 'focus', + 'fog', + 'foil', + 'fold', + 'follow', + 'food', + 'foot', + 'force', + 'forest', + 'forget', + 'fork', + 'fortune', + 'forum', + 'forward', + 'fossil', + 'foster', + 'found', + 'fox', + 'fragile', + 'frame', + 'frequent', + 'fresh', + 'friend', + 'fringe', + 'frog', + 'front', + 'frost', + 'frown', + 'frozen', + 'fruit', + 'fuel', + 'fun', + 'funny', + 'furnace', + 'fury', + 'future', + 'gadget', + 'gain', + 'galaxy', + 'gallery', + 'game', + 'gap', + 'garage', + 'garbage', + 'garden', + 'garlic', + 'garment', + 'gas', + 'gasp', + 'gate', + 'gather', + 'gauge', + 'gaze', + 'general', + 'genius', + 'genre', + 'gentle', + 'genuine', + 'gesture', + 'ghost', + 'giant', + 'gift', + 'giggle', + 'ginger', + 'giraffe', + 'girl', + 'give', + 'glad', + 'glance', + 'glare', + 'glass', + 'glide', + 'glimpse', + 'globe', + 'gloom', + 'glory', + 'glove', + 'glow', + 'glue', + 'goat', + 'goddess', + 'gold', + 'good', + 'goose', + 'gorilla', + 'gospel', + 'gossip', + 'govern', + 'gown', + 'grab', + 'grace', + 'grain', + 'grant', + 'grape', + 'grass', + 'gravity', + 'great', + 'green', + 'grid', + 'grief', + 'grit', + 'grocery', + 'group', + 'grow', + 'grunt', + 'guard', + 'guess', + 'guide', + 'guilt', + 'guitar', + 'gun', + 'gym', + 'habit', + 'hair', + 'half', + 'hammer', + 'hamster', + 'hand', + 'happy', + 'harbor', + 'hard', + 'harsh', + 'harvest', + 'hat', + 'have', + 'hawk', + 'hazard', + 'head', + 'health', + 'heart', + 'heavy', + 'hedgehog', + 'height', + 'hello', + 'helmet', + 'help', + 'hen', + 'hero', + 'hidden', + 'high', + 'hill', + 'hint', + 'hip', + 'hire', + 'history', + 'hobby', + 'hockey', + 'hold', + 'hole', + 'holiday', + 'hollow', + 'home', + 'honey', + 'hood', + 'hope', + 'horn', + 'horror', + 'horse', + 'hospital', + 'host', + 'hotel', + 'hour', + 'hover', + 'hub', + 'huge', + 'human', + 'humble', + 'humor', + 'hundred', + 'hungry', + 'hunt', + 'hurdle', + 'hurry', + 'hurt', + 'husband', + 'hybrid', + 'ice', + 'icon', + 'idea', + 'identify', + 'idle', + 'ignore', + 'ill', + 'illegal', + 'illness', + 'image', + 'imitate', + 'immense', + 'immune', + 'impact', + 'impose', + 'improve', + 'impulse', + 'inch', + 'include', + 'income', + 'increase', + 'index', + 'indicate', + 'indoor', + 'industry', + 'infant', + 'inflict', + 'inform', + 'inhale', + 'inherit', + 'initial', + 'inject', + 'injury', + 'inmate', + 'inner', + 'innocent', + 'input', + 'inquiry', + 'insane', + 'insect', + 'inside', + 'inspire', + 'install', + 'intact', + 'interest', + 'into', + 'invest', + 'invite', + 'involve', + 'iron', + 'island', + 'isolate', + 'issue', + 'item', + 'ivory', + 'jacket', + 'jaguar', + 'jar', + 'jazz', + 'jealous', + 'jeans', + 'jelly', + 'jewel', + 'job', + 'join', + 'joke', + 'journey', + 'joy', + 'judge', + 'juice', + 'jump', + 'jungle', + 'junior', + 'junk', + 'just', + 'kangaroo', + 'keen', + 'keep', + 'ketchup', + 'key', + 'kick', + 'kid', + 'kidney', + 'kind', + 'kingdom', + 'kiss', + 'kit', + 'kitchen', + 'kite', + 'kitten', + 'kiwi', + 'knee', + 'knife', + 'knock', + 'know', + 'lab', + 'label', + 'labor', + 'ladder', + 'lady', + 'lake', + 'lamp', + 'language', + 'laptop', + 'large', + 'later', + 'latin', + 'laugh', + 'laundry', + 'lava', + 'law', + 'lawn', + 'lawsuit', + 'layer', + 'lazy', + 'leader', + 'leaf', + 'learn', + 'leave', + 'lecture', + 'left', + 'leg', + 'legal', + 'legend', + 'leisure', + 'lemon', + 'lend', + 'length', + 'lens', + 'leopard', + 'lesson', + 'letter', + 'level', + 'liar', + 'liberty', + 'library', + 'license', + 'life', + 'lift', + 'light', + 'like', + 'limb', + 'limit', + 'link', + 'lion', + 'liquid', + 'list', + 'little', + 'live', + 'lizard', + 'load', + 'loan', + 'lobster', + 'local', + 'lock', + 'logic', + 'lonely', + 'long', + 'loop', + 'lottery', + 'loud', + 'lounge', + 'love', + 'loyal', + 'lucky', + 'luggage', + 'lumber', + 'lunar', + 'lunch', + 'luxury', + 'lyrics', + 'machine', + 'mad', + 'magic', + 'magnet', + 'maid', + 'mail', + 'main', + 'major', + 'make', + 'mammal', + 'man', + 'manage', + 'mandate', + 'mango', + 'mansion', + 'manual', + 'maple', + 'marble', + 'march', + 'margin', + 'marine', + 'market', + 'marriage', + 'mask', + 'mass', + 'master', + 'match', + 'material', + 'math', + 'matrix', + 'matter', + 'maximum', + 'maze', + 'meadow', + 'mean', + 'measure', + 'meat', + 'mechanic', + 'medal', + 'media', + 'melody', + 'melt', + 'member', + 'memory', + 'mention', + 'menu', + 'mercy', + 'merge', + 'merit', + 'merry', + 'mesh', + 'message', + 'metal', + 'method', + 'middle', + 'midnight', + 'milk', + 'million', + 'mimic', + 'mind', + 'minimum', + 'minor', + 'minute', + 'miracle', + 'mirror', + 'misery', + 'miss', + 'mistake', + 'mix', + 'mixed', + 'mixture', + 'mobile', + 'model', + 'modify', + 'mom', + 'moment', + 'monitor', + 'monkey', + 'monster', + 'month', + 'moon', + 'moral', + 'more', + 'morning', + 'mosquito', + 'mother', + 'motion', + 'motor', + 'mountain', + 'mouse', + 'move', + 'movie', + 'much', + 'muffin', + 'mule', + 'multiply', + 'muscle', + 'museum', + 'mushroom', + 'music', + 'must', + 'mutual', + 'myself', + 'mystery', + 'myth', + 'naive', + 'name', + 'napkin', + 'narrow', + 'nasty', + 'nation', + 'nature', + 'near', + 'neck', + 'need', + 'negative', + 'neglect', + 'neither', + 'nephew', + 'nerve', + 'nest', + 'net', + 'network', + 'neutral', + 'never', + 'news', + 'next', + 'nice', + 'night', + 'noble', + 'noise', + 'nominee', + 'noodle', + 'normal', + 'north', + 'nose', + 'notable', + 'note', + 'nothing', + 'notice', + 'novel', + 'now', + 'nuclear', + 'number', + 'nurse', + 'nut', + 'oak', + 'obey', + 'object', + 'oblige', + 'obscure', + 'observe', + 'obtain', + 'obvious', + 'occur', + 'ocean', + 'october', + 'odor', + 'off', + 'offer', + 'office', + 'often', + 'oil', + 'okay', + 'old', + 'olive', + 'olympic', + 'omit', + 'once', + 'one', + 'onion', + 'online', + 'only', + 'open', + 'opera', + 'opinion', + 'oppose', + 'option', + 'orange', + 'orbit', + 'orchard', + 'order', + 'ordinary', + 'organ', + 'orient', + 'original', + 'orphan', + 'ostrich', + 'other', + 'outdoor', + 'outer', + 'output', + 'outside', + 'oval', + 'oven', + 'over', + 'own', + 'owner', + 'oxygen', + 'oyster', + 'ozone', + 'pact', + 'paddle', + 'page', + 'pair', + 'palace', + 'palm', + 'panda', + 'panel', + 'panic', + 'panther', + 'paper', + 'parade', + 'parent', + 'park', + 'parrot', + 'party', + 'pass', + 'patch', + 'path', + 'patient', + 'patrol', + 'pattern', + 'pause', + 'pave', + 'payment', + 'peace', + 'peanut', + 'pear', + 'peasant', + 'pelican', + 'pen', + 'penalty', + 'pencil', + 'people', + 'pepper', + 'perfect', + 'permit', + 'person', + 'pet', + 'phone', + 'photo', + 'phrase', + 'physical', + 'piano', + 'picnic', + 'picture', + 'piece', + 'pig', + 'pigeon', + 'pill', + 'pilot', + 'pink', + 'pioneer', + 'pipe', + 'pistol', + 'pitch', + 'pizza', + 'place', + 'planet', + 'plastic', + 'plate', + 'play', + 'please', + 'pledge', + 'pluck', + 'plug', + 'plunge', + 'poem', + 'poet', + 'point', + 'polar', + 'pole', + 'police', + 'pond', + 'pony', + 'pool', + 'popular', + 'portion', + 'position', + 'possible', + 'post', + 'potato', + 'pottery', + 'poverty', + 'powder', + 'power', + 'practice', + 'praise', + 'predict', + 'prefer', + 'prepare', + 'present', + 'pretty', + 'prevent', + 'price', + 'pride', + 'primary', + 'print', + 'priority', + 'prison', + 'private', + 'prize', + 'problem', + 'process', + 'produce', + 'profit', + 'program', + 'project', + 'promote', + 'proof', + 'property', + 'prosper', + 'protect', + 'proud', + 'provide', + 'public', + 'pudding', + 'pull', + 'pulp', + 'pulse', + 'pumpkin', + 'punch', + 'pupil', + 'puppy', + 'purchase', + 'purity', + 'purpose', + 'purse', + 'push', + 'put', + 'puzzle', + 'pyramid', + 'quality', + 'quantum', + 'quarter', + 'question', + 'quick', + 'quit', + 'quiz', + 'quote', + 'rabbit', + 'raccoon', + 'race', + 'rack', + 'radar', + 'radio', + 'rail', + 'rain', + 'raise', + 'rally', + 'ramp', + 'ranch', + 'random', + 'range', + 'rapid', + 'rare', + 'rate', + 'rather', + 'raven', + 'raw', + 'razor', + 'ready', + 'real', + 'reason', + 'rebel', + 'rebuild', + 'recall', + 'receive', + 'recipe', + 'record', + 'recycle', + 'reduce', + 'reflect', + 'reform', + 'refuse', + 'region', + 'regret', + 'regular', + 'reject', + 'relax', + 'release', + 'relief', + 'rely', + 'remain', + 'remember', + 'remind', + 'remove', + 'render', + 'renew', + 'rent', + 'reopen', + 'repair', + 'repeat', + 'replace', + 'report', + 'require', + 'rescue', + 'resemble', + 'resist', + 'resource', + 'response', + 'result', + 'retire', + 'retreat', + 'return', + 'reunion', + 'reveal', + 'review', + 'reward', + 'rhythm', + 'rib', + 'ribbon', + 'rice', + 'rich', + 'ride', + 'ridge', + 'rifle', + 'right', + 'rigid', + 'ring', + 'riot', + 'ripple', + 'risk', + 'ritual', + 'rival', + 'river', + 'road', + 'roast', + 'robot', + 'robust', + 'rocket', + 'romance', + 'roof', + 'rookie', + 'room', + 'rose', + 'rotate', + 'rough', + 'round', + 'route', + 'royal', + 'rubber', + 'rude', + 'rug', + 'rule', + 'run', + 'runway', + 'rural', + 'sad', + 'saddle', + 'sadness', + 'safe', + 'sail', + 'salad', + 'salmon', + 'salon', + 'salt', + 'salute', + 'same', + 'sample', + 'sand', + 'satisfy', + 'satoshi', + 'sauce', + 'sausage', + 'save', + 'say', + 'scale', + 'scan', + 'scare', + 'scatter', + 'scene', + 'scheme', + 'school', + 'science', + 'scissors', + 'scorpion', + 'scout', + 'scrap', + 'screen', + 'script', + 'scrub', + 'sea', + 'search', + 'season', + 'seat', + 'second', + 'secret', + 'section', + 'security', + 'seed', + 'seek', + 'segment', + 'select', + 'sell', + 'seminar', + 'senior', + 'sense', + 'sentence', + 'series', + 'service', + 'session', + 'settle', + 'setup', + 'seven', + 'shadow', + 'shaft', + 'shallow', + 'share', + 'shed', + 'shell', + 'sheriff', + 'shield', + 'shift', + 'shine', + 'ship', + 'shiver', + 'shock', + 'shoe', + 'shoot', + 'shop', + 'short', + 'shoulder', + 'shove', + 'shrimp', + 'shrug', + 'shuffle', + 'shy', + 'sibling', + 'sick', + 'side', + 'siege', + 'sight', + 'sign', + 'silent', + 'silk', + 'silly', + 'silver', + 'similar', + 'simple', + 'since', + 'sing', + 'siren', + 'sister', + 'situate', + 'six', + 'size', + 'skate', + 'sketch', + 'ski', + 'skill', + 'skin', + 'skirt', + 'skull', + 'slab', + 'slam', + 'sleep', + 'slender', + 'slice', + 'slide', + 'slight', + 'slim', + 'slogan', + 'slot', + 'slow', + 'slush', + 'small', + 'smart', + 'smile', + 'smoke', + 'smooth', + 'snack', + 'snake', + 'snap', + 'sniff', + 'snow', + 'soap', + 'soccer', + 'social', + 'sock', + 'soda', + 'soft', + 'solar', + 'soldier', + 'solid', + 'solution', + 'solve', + 'someone', + 'song', + 'soon', + 'sorry', + 'sort', + 'soul', + 'sound', + 'soup', + 'source', + 'south', + 'space', + 'spare', + 'spatial', + 'spawn', + 'speak', + 'special', + 'speed', + 'spell', + 'spend', + 'sphere', + 'spice', + 'spider', + 'spike', + 'spin', + 'spirit', + 'split', + 'spoil', + 'sponsor', + 'spoon', + 'sport', + 'spot', + 'spray', + 'spread', + 'spring', + 'spy', + 'square', + 'squeeze', + 'squirrel', + 'stable', + 'stadium', + 'staff', + 'stage', + 'stairs', + 'stamp', + 'stand', + 'start', + 'state', + 'stay', + 'steak', + 'steel', + 'stem', + 'step', + 'stereo', + 'stick', + 'still', + 'sting', + 'stock', + 'stomach', + 'stone', + 'stool', + 'story', + 'stove', + 'strategy', + 'street', + 'strike', + 'strong', + 'struggle', + 'student', + 'stuff', + 'stumble', + 'style', + 'subject', + 'submit', + 'subway', + 'success', + 'such', + 'sudden', + 'suffer', + 'sugar', + 'suggest', + 'suit', + 'summer', + 'sun', + 'sunny', + 'sunset', + 'super', + 'supply', + 'supreme', + 'sure', + 'surface', + 'surge', + 'surprise', + 'surround', + 'survey', + 'suspect', + 'sustain', + 'swallow', + 'swamp', + 'swap', + 'swarm', + 'swear', + 'sweet', + 'swift', + 'swim', + 'swing', + 'switch', + 'sword', + 'symbol', + 'symptom', + 'syrup', + 'system', + 'table', + 'tackle', + 'tag', + 'tail', + 'talent', + 'talk', + 'tank', + 'tape', + 'target', + 'task', + 'taste', + 'tattoo', + 'taxi', + 'teach', + 'team', + 'tell', + 'ten', + 'tenant', + 'tennis', + 'tent', + 'term', + 'test', + 'text', + 'thank', + 'that', + 'theme', + 'then', + 'theory', + 'there', + 'they', + 'thing', + 'this', + 'thought', + 'three', + 'thrive', + 'throw', + 'thumb', + 'thunder', + 'ticket', + 'tide', + 'tiger', + 'tilt', + 'timber', + 'time', + 'tiny', + 'tip', + 'tired', + 'tissue', + 'title', + 'toast', + 'tobacco', + 'today', + 'toddler', + 'toe', + 'together', + 'toilet', + 'token', + 'tomato', + 'tomorrow', + 'tone', + 'tongue', + 'tonight', + 'tool', + 'tooth', + 'top', + 'topic', + 'topple', + 'torch', + 'tornado', + 'tortoise', + 'toss', + 'total', + 'tourist', + 'toward', + 'tower', + 'town', + 'toy', + 'track', + 'trade', + 'traffic', + 'tragic', + 'train', + 'transfer', + 'trap', + 'trash', + 'travel', + 'tray', + 'treat', + 'tree', + 'trend', + 'trial', + 'tribe', + 'trick', + 'trigger', + 'trim', + 'trip', + 'trophy', + 'trouble', + 'truck', + 'true', + 'truly', + 'trumpet', + 'trust', + 'truth', + 'try', + 'tube', + 'tuition', + 'tumble', + 'tuna', + 'tunnel', + 'turkey', + 'turn', + 'turtle', + 'twelve', + 'twenty', + 'twice', + 'twin', + 'twist', + 'two', + 'type', + 'typical', + 'ugly', + 'umbrella', + 'unable', + 'unaware', + 'uncle', + 'uncover', + 'under', + 'undo', + 'unfair', + 'unfold', + 'unhappy', + 'uniform', + 'unique', + 'unit', + 'universe', + 'unknown', + 'unlock', + 'until', + 'unusual', + 'unveil', + 'update', + 'upgrade', + 'uphold', + 'upon', + 'upper', + 'upset', + 'urban', + 'urge', + 'usage', + 'use', + 'used', + 'useful', + 'useless', + 'usual', + 'utility', + 'vacant', + 'vacuum', + 'vague', + 'valid', + 'valley', + 'valve', + 'van', + 'vanish', + 'vapor', + 'various', + 'vast', + 'vault', + 'vehicle', + 'velvet', + 'vendor', + 'venture', + 'venue', + 'verb', + 'verify', + 'version', + 'very', + 'vessel', + 'veteran', + 'viable', + 'vibrant', + 'vicious', + 'victory', + 'video', + 'view', + 'village', + 'vintage', + 'violin', + 'virtual', + 'virus', + 'visa', + 'visit', + 'visual', + 'vital', + 'vivid', + 'vocal', + 'voice', + 'void', + 'volcano', + 'volume', + 'vote', + 'voyage', + 'wage', + 'wagon', + 'wait', + 'walk', + 'wall', + 'walnut', + 'want', + 'warfare', + 'warm', + 'warrior', + 'wash', + 'wasp', + 'waste', + 'water', + 'wave', + 'way', + 'wealth', + 'weapon', + 'wear', + 'weasel', + 'weather', + 'web', + 'wedding', + 'weekend', + 'weird', + 'welcome', + 'west', + 'wet', + 'whale', + 'what', + 'wheat', + 'wheel', + 'when', + 'where', + 'whip', + 'whisper', + 'wide', + 'width', + 'wife', + 'wild', + 'will', + 'win', + 'window', + 'wine', + 'wing', + 'wink', + 'winner', + 'winter', + 'wire', + 'wisdom', + 'wise', + 'wish', + 'witness', + 'wolf', + 'woman', + 'wonder', + 'wood', + 'wool', + 'word', + 'work', + 'world', + 'worry', + 'worth', + 'wrap', + 'wreck', + 'wrestle', + 'wrist', + 'write', + 'wrong', + 'yard', + 'year', + 'yellow', + 'you', + 'young', + 'youth', + 'zebra', + 'zero', + 'zone', + 'zoo', +]; diff --git a/source/common/ipc/api.js b/source/common/ipc/api.js index 9dfaf026ca..9e049443c5 100644 --- a/source/common/ipc/api.js +++ b/source/common/ipc/api.js @@ -1,16 +1,19 @@ // @flow import type { BugReportRequestHttpOptions, - BugReportRequestPayload + BugReportRequestPayload, } from '../types/bug-report-request.types'; import type { GeneratePaperWalletParams } from '../types/paper-wallet-request.types'; import type { CardanoNodeState, CardanoStatus, FaultInjectionIpcRequest, - TlsConfig + TlsConfig, } from '../types/cardano-node.types'; -import type { AdaRedemptionCode, AdaRedemptionDecryptionKey } from '../types/ada-redemption.types'; +import type { + AdaRedemptionCode, + AdaRedemptionDecryptionKey, +} from '../types/ada-redemption.types'; import type { RedemptionTypeChoices } from '../../renderer/app/types/redemptionTypes'; import type { CheckDiskSpaceResponse } from '../types/no-disk-space.types'; import type { LogFiles } from '../../renderer/app/types/LogTypes'; @@ -82,11 +85,12 @@ export type OpenExternalUrlResponse = void; /** * Channel to send bug report requests */ -export const SUBMIT_BUG_REPORT_REQUEST_CHANNEL = 'SUBMIT_BUG_REPORT_REQUEST_CHANNEL'; +export const SUBMIT_BUG_REPORT_REQUEST_CHANNEL = + 'SUBMIT_BUG_REPORT_REQUEST_CHANNEL'; export type SubmitBugReportRequest = { httpOptions: BugReportRequestHttpOptions, - requestPayload?: BugReportRequestPayload -} + requestPayload?: BugReportRequestPayload, +}; export type SubmitBugReportRequestResponse = void; /** @@ -97,7 +101,8 @@ export const REBUILD_APP_MENU_CHANNEL = 'REBUILD_APP_MENU_CHANNEL'; /** * Channel to get the number of epochs consolidated */ -export const GET_CONSOLIDATED_EPOCHS_COUNT_CHANNEL = 'GET_CONSOLIDATED_EPOCHS_COUNT_CHANNEL'; +export const GET_CONSOLIDATED_EPOCHS_COUNT_CHANNEL = + 'GET_CONSOLIDATED_EPOCHS_COUNT_CHANNEL'; export type GetConsolidatedEpochsCountResponse = number; /** @@ -115,7 +120,7 @@ export const PARSE_REDEMPTION_CODE_CHANNEL = 'PARSE_REDEMPTION_CODE_CHANNEL'; export type ParseRedemptionCodeRequest = { certificateFilePath: string, decryptionKey: ?AdaRedemptionDecryptionKey, - redemptionType: RedemptionTypeChoices + redemptionType: RedemptionTypeChoices, }; export type ParseRedemptionCodeResponse = AdaRedemptionCode; @@ -164,20 +169,23 @@ export type CardanoRestartResponse = void; /** * Channel where render process can toggle cardano-node fault injections */ -export const CARDANO_FAULT_INJECTION_CHANNEL = 'CARDANO_FAULT_INJECTION_CHANNEL'; +export const CARDANO_FAULT_INJECTION_CHANNEL = + 'CARDANO_FAULT_INJECTION_CHANNEL'; export type CardanoFaultInjectionRequest = FaultInjectionIpcRequest; export type CardanoFaultInjectionResponse = void; /** * Channel where renderer can ask for the last cached cardano-node status. */ -export const GET_CACHED_CARDANO_STATUS_CHANNEL = 'GET_CACHED_CARDANO_STATUS_CHANNEL'; +export const GET_CACHED_CARDANO_STATUS_CHANNEL = + 'GET_CACHED_CARDANO_STATUS_CHANNEL'; export type GetCachedCardanoStatusRequest = void; export type GetCachedCardanoStatusResponse = ?CardanoStatus; /** * Channel where renderer and main process can exchange cardano-node status info. */ -export const SET_CACHED_CARDANO_STATUS_CHANNEL = 'SET_CACHED_CARDANO_STATUS_CHANNEL'; +export const SET_CACHED_CARDANO_STATUS_CHANNEL = + 'SET_CACHED_CARDANO_STATUS_CHANNEL'; export type SetCachedCardanoStatusRequest = ?CardanoStatus; export type SetCachedCardanoStatusResponse = void; diff --git a/source/common/ipc/lib/IpcChannel.js b/source/common/ipc/lib/IpcChannel.js index a2d5bc9fe2..e1bfe9bca1 100644 --- a/source/common/ipc/lib/IpcChannel.js +++ b/source/common/ipc/lib/IpcChannel.js @@ -2,16 +2,22 @@ import { isString } from 'lodash'; export type IpcSender = { - send: (channel: string, ...args: Array) => void + send: (channel: string, ...args: Array) => void, }; export type IpcEvent = { sender: IpcSender, -} +}; export type IpcReceiver = { - on: (channel: string, (event: IpcEvent, ...args: Array) => Promise) => void, - once: (channel: string, (event: IpcEvent, isOk: boolean, ...args: Array) => void) => void + on: ( + channel: string, + (event: IpcEvent, ...args: Array) => Promise + ) => void, + once: ( + channel: string, + (event: IpcEvent, isOk: boolean, ...args: Array) => void + ) => void, }; /** @@ -21,7 +27,6 @@ export type IpcReceiver = { * and response cycles. */ export class IpcChannel { - /** * Each ipc channel should be a singleton (based on the channelName) * Here we track the created instances. @@ -65,17 +70,24 @@ export class IpcChannel { * same channel. It returns a promise which is resolved or rejected with the response * depending on the `isOk` flag set by the respondant. */ - async send(message: Outgoing, sender: IpcSender, receiver: IpcReceiver): Promise { + async send( + message: Outgoing, + sender: IpcSender, + receiver: IpcReceiver + ): Promise { return new Promise((resolve, reject) => { sender.send(this._broadcastChannel, message); // Handle response to the sent request once - receiver.once(this._responseChannel, (event, isOk: boolean, response: Incoming) => { - if (isOk) { - resolve(response); - } else { - reject(response); + receiver.once( + this._responseChannel, + (event, isOk: boolean, response: Incoming) => { + if (isOk) { + resolve(response); + } else { + reject(response); + } } - }); + ); }); } @@ -83,17 +95,24 @@ export class IpcChannel { * Request a message from the other side. * Can be used to get the current state of some information. */ - async request(message: Outgoing, sender: IpcSender, receiver: IpcReceiver): Promise { + async request( + message: Outgoing, + sender: IpcSender, + receiver: IpcReceiver + ): Promise { return new Promise((resolve, reject) => { sender.send(this._requestChannel, message); // Handle response to the sent request once - receiver.once(this._responseChannel, (event, isOk: boolean, response: Incoming) => { - if (isOk) { - resolve(response); - } else { - reject(response); + receiver.once( + this._responseChannel, + (event, isOk: boolean, response: Incoming) => { + if (isOk) { + resolve(response); + } else { + reject(response); + } } - }); + ); }); } @@ -102,28 +121,40 @@ export class IpcChannel { * This should be used to receive messages that are broadcasted by the other end of * the ipc channel and are not responses to requests sent by this party. */ - onReceive(handler: (message: Incoming) => Promise, receiver: IpcReceiver): void { - receiver.on(this._broadcastChannel, async (event: IpcEvent, message: Incoming) => { - try { - const response = await handler(message); - event.sender.send(this._responseChannel, true, response); - } catch (error) { - event.sender.send(this._responseChannel, false, error); + onReceive( + handler: (message: Incoming) => Promise, + receiver: IpcReceiver + ): void { + receiver.on( + this._broadcastChannel, + async (event: IpcEvent, message: Incoming) => { + try { + const response = await handler(message); + event.sender.send(this._responseChannel, true, response); + } catch (error) { + event.sender.send(this._responseChannel, false, error); + } } - }); + ); } /** * Sets up a permanent handler for receiving request from the other side. */ - onRequest(handler: (Incoming) => Promise, receiver: IpcReceiver): void { - receiver.on(this._requestChannel, async (event: IpcEvent, message: Incoming) => { - try { - const response = await handler(message); - event.sender.send(this._responseChannel, true, response); - } catch (error) { - event.sender.send(this._responseChannel, false, error); + onRequest( + handler: Incoming => Promise, + receiver: IpcReceiver + ): void { + receiver.on( + this._requestChannel, + async (event: IpcEvent, message: Incoming) => { + try { + const response = await handler(message); + event.sender.send(this._responseChannel, true, response); + } catch (error) { + event.sender.send(this._responseChannel, false, error); + } } - }); + ); } } diff --git a/source/common/types/ada-redemption.types.js b/source/common/types/ada-redemption.types.js index ac9b6ec62c..e338e35d97 100644 --- a/source/common/types/ada-redemption.types.js +++ b/source/common/types/ada-redemption.types.js @@ -4,10 +4,9 @@ type Passphrase = string; type DecryptionKey = string; type ForceVendingDecryptionKey = [?string, ?string, ?string]; -export type AdaRedemptionDecryptionKey = ( - Passphrase | - DecryptionKey | - ForceVendingDecryptionKey -); +export type AdaRedemptionDecryptionKey = + | Passphrase + | DecryptionKey + | ForceVendingDecryptionKey; export type AdaRedemptionCode = string; diff --git a/source/common/types/bug-report-request.types.js b/source/common/types/bug-report-request.types.js index 6b70c14eb1..637f0e5290 100644 --- a/source/common/types/bug-report-request.types.js +++ b/source/common/types/bug-report-request.types.js @@ -25,5 +25,5 @@ export type BugReportRequestPayload = { email: string, subject: string, problem: string, - } + }, }; diff --git a/source/common/types/cardano-node.types.js b/source/common/types/cardano-node.types.js index 74c73e56ec..8a22ec7f0f 100644 --- a/source/common/types/cardano-node.types.js +++ b/source/common/types/cardano-node.types.js @@ -7,37 +7,45 @@ export type TlsConfig = { key: Uint8Array, }; -export type NetworkNames = ( - 'mainnet' | 'staging' | 'testnet' | 'development' | string -); +export type NetworkNames = + | 'mainnet' + | 'staging' + | 'testnet' + | 'development' + | string; -export type PlatformNames = ( - 'win32' | 'linux' | 'darwin' | string -); +export type PlatformNames = 'win32' | 'linux' | 'darwin' | string; export const NetworkNameOptions = { mainnet: 'mainnet', staging: 'staging', testnet: 'testnet', - development: 'development' + development: 'development', }; -export type CardanoNodeState = ( - 'stopped' | 'starting' | 'running' | 'stopping' | 'updating' | - 'updated' | 'crashed' | 'errored' | 'exiting' | 'unrecoverable' -); +export type CardanoNodeState = + | 'stopped' + | 'starting' + | 'running' + | 'stopping' + | 'updating' + | 'updated' + | 'crashed' + | 'errored' + | 'exiting' + | 'unrecoverable'; export const CardanoNodeStates: { STARTING: CardanoNodeState, - RUNNING: CardanoNodeState; - EXITING: CardanoNodeState; - STOPPING: CardanoNodeState; - STOPPED: CardanoNodeState; - UPDATING: CardanoNodeState; - UPDATED: CardanoNodeState; - CRASHED: CardanoNodeState; - ERRORED: CardanoNodeState; - UNRECOVERABLE: CardanoNodeState; + RUNNING: CardanoNodeState, + EXITING: CardanoNodeState, + STOPPING: CardanoNodeState, + STOPPED: CardanoNodeState, + UPDATING: CardanoNodeState, + UPDATED: CardanoNodeState, + CRASHED: CardanoNodeState, + ERRORED: CardanoNodeState, + UNRECOVERABLE: CardanoNodeState, } = { STARTING: 'starting', RUNNING: 'running', @@ -51,24 +59,21 @@ export const CardanoNodeStates: { UNRECOVERABLE: 'unrecoverable', }; -export type CardanoPidOptions = ( - 'mainnet-PREVIOUS-CARDANO-PID' | - 'staging-PREVIOUS-CARDANO-PID' | - 'testnet-PREVIOUS-CARDANO-PID' | - 'development-PREVIOUS-CARDANO-PID' | - string -); +export type CardanoPidOptions = + | 'mainnet-PREVIOUS-CARDANO-PID' + | 'staging-PREVIOUS-CARDANO-PID' + | 'testnet-PREVIOUS-CARDANO-PID' + | 'development-PREVIOUS-CARDANO-PID' + | string; export type CardanoNodeStorageKeys = { - PREVIOUS_CARDANO_PID: CardanoPidOptions + PREVIOUS_CARDANO_PID: CardanoPidOptions, }; -export type CardanoNodeProcessNames = ( - 'cardano-node' | 'cardano-node.exe' -); +export type CardanoNodeProcessNames = 'cardano-node' | 'cardano-node.exe'; export type ProcessNames = { - CARDANO_PROCESS_NAME: CardanoNodeProcessNames + CARDANO_PROCESS_NAME: CardanoNodeProcessNames, }; export const CardanoProcessNameOptions: { @@ -78,25 +83,24 @@ export const CardanoProcessNameOptions: { } = { win32: 'cardano-node.exe', linux: 'cardano-node', - darwin: 'cardano-node' + darwin: 'cardano-node', }; /** * Expected fault injection types that can be used to tell * cardano-node to behave faulty (useful for testing) */ -export type FaultInjection = ( - 'FInjIgnoreShutdown' | - 'FInjIgnoreAPI' | - 'FInjApplyUpdateNoExit' | - 'FInjApplyUpdateWrongExitCode' -); +export type FaultInjection = + | 'FInjIgnoreShutdown' + | 'FInjIgnoreAPI' + | 'FInjApplyUpdateNoExit' + | 'FInjApplyUpdateWrongExitCode'; export const FaultInjections: { IgnoreShutdown: FaultInjection, IgnoreApi: FaultInjection, ApplyUpdateNoExit: FaultInjection, - ApplyUpdateWrongExitCode: FaultInjection + ApplyUpdateWrongExitCode: FaultInjection, } = { IgnoreShutdown: 'FInjIgnoreShutdown', IgnoreApi: 'FInjIgnoreAPI', diff --git a/source/common/types/environment.types.js b/source/common/types/environment.types.js index 6214f11031..b06fae5335 100644 --- a/source/common/types/environment.types.js +++ b/source/common/types/environment.types.js @@ -22,7 +22,7 @@ export type Environment = { version: string, isWindows: boolean, isMacOS: boolean, - isLinux: boolean + isLinux: boolean, }; // constants export const PRODUCTION = 'production'; diff --git a/source/common/types/paper-wallet-request.types.js b/source/common/types/paper-wallet-request.types.js index b18ec4a2a5..763befacb7 100644 --- a/source/common/types/paper-wallet-request.types.js +++ b/source/common/types/paper-wallet-request.types.js @@ -10,5 +10,5 @@ export type GeneratePaperWalletParams = { recoveryPhraseLabel: string, infoTitle: string, infoAuthor: string, - } + }, }; diff --git a/source/common/utils/files.js b/source/common/utils/files.js index 1efba047fa..fa4f04cfc1 100644 --- a/source/common/utils/files.js +++ b/source/common/utils/files.js @@ -1,16 +1,23 @@ // @flow import moment from 'moment'; -export const generateFileNameWithTimestamp = (prefix: string = 'logs', fileType: string = 'zip') => ( - `${prefix}-${moment.utc().format('YYYY-MM-DDTHHmmss.0SSS')}Z.${fileType}` -); +export const generateFileNameWithTimestamp = ( + prefix: string = 'logs', + fileType: string = 'zip' +) => `${prefix}-${moment.utc().format('YYYY-MM-DDTHHmmss.0SSS')}Z.${fileType}`; -export const isFileNameWithTimestamp = (prefix: string = 'logs', fileType: string = 'zip') => (fileName: string) => ( - fileName.match(RegExp(`(${prefix}-)([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{6}.0[0-9]{3}Z)(.${fileType})`)) -); +export const isFileNameWithTimestamp = ( + prefix: string = 'logs', + fileType: string = 'zip' +) => (fileName: string) => + fileName.match( + RegExp( + `(${prefix}-)([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{6}.0[0-9]{3}Z)(.${fileType})` + ) + ); -export const getPathSlash = (path: string) => ((path.indexOf('/') > -1) ? '/' : '\\'); +export const getPathSlash = (path: string) => + path.indexOf('/') > -1 ? '/' : '\\'; -export const extractFileNameFromPath = (path: string) => ( - path.substr(path.lastIndexOf(getPathSlash(path)) + 1) -); +export const extractFileNameFromPath = (path: string) => + path.substr(path.lastIndexOf(getPathSlash(path)) + 1); diff --git a/source/common/utils/logging.js b/source/common/utils/logging.js index ab35032a99..ef2a112c5d 100644 --- a/source/common/utils/logging.js +++ b/source/common/utils/logging.js @@ -22,20 +22,26 @@ const stringifyMessageBody = (messageBody: MessageBody): string => { export const filterLogData = (data: Object): Object => { const sensitiveData = [ - 'spendingPassword', 'oldPassword', 'newPassword', - 'mnemonic', 'recoveryPhrase', 'passphrase', 'password', + 'spendingPassword', + 'oldPassword', + 'newPassword', + 'mnemonic', + 'recoveryPhrase', + 'passphrase', + 'password', ]; return pickBy(data, (value, key) => { - if (sensitiveData.includes(key)) { return false; } + if (sensitiveData.includes(key)) { + return false; + } return true; }); }; export const stringifyData = (data: any) => JSON.stringify(data, null, 2); -export const stringifyError = (error: any) => ( - JSON.stringify(error, Object.getOwnPropertyNames(error), 2) -); +export const stringifyError = (error: any) => + JSON.stringify(error, Object.getOwnPropertyNames(error), 2); export const formatContext = (context: FormatMessageContextParams): string => { const { appName, electronProcess, level, network } = context; @@ -47,7 +53,9 @@ export const formatMessageTime = (date: Date): string => { return `[${year}T${time.slice(0, -1)}Z]`; }; -export const constructMessageBody = (bodyData: ConstructMessageBodyParams): MessageBody => { +export const constructMessageBody = ( + bodyData: ConstructMessageBodyParams +): MessageBody => { let messageBody = { ...DEFAULT_MESSAGE_BODY, ...bodyData }; if (typeof messageBody.data === 'string') { messageBody = { ...messageBody, data: { response: messageBody.data } }; @@ -66,11 +74,7 @@ export const formatMessage = (loggerMessage: ElectronLoggerMessage): string => { const messageBodyParams: ConstructMessageBodyParams = { at, env: `${network}:${os}:${platformVersion}`, - ns: [ - 'daedalus', - `v${version}`, - `*${network}*`, - ], + ns: ['daedalus', `v${version}`, `*${network}*`], data, msg, pid: '', diff --git a/source/main/cardano/CardanoNode.js b/source/main/cardano/CardanoNode.js index aa0e358b66..88477d54a4 100644 --- a/source/main/cardano/CardanoNode.js +++ b/source/main/cardano/CardanoNode.js @@ -4,7 +4,11 @@ import type { ChildProcess, spawn, exec } from 'child_process'; import type { WriteStream } from 'fs'; import { toInteger } from 'lodash'; import { environment } from '../environment'; -import { deriveProcessNames, deriveStorageKeys, promisedCondition } from './utils'; +import { + deriveProcessNames, + deriveStorageKeys, + promisedCondition, +} from './utils'; import { getProcess } from '../utils/processes'; import type { CardanoNodeState, @@ -12,7 +16,7 @@ import type { FaultInjection, FaultInjectionIpcRequest, FaultInjectionIpcResponse, - TlsConfig + TlsConfig, } from '../../common/types/cardano-node.types'; import { CardanoNodeStates } from '../../common/types/cardano-node.types'; @@ -41,13 +45,13 @@ type StateTransitions = { onCrashed: (code: number, signal: string) => void, onError: (error: Error) => void, onUnrecoverable: () => void, -} +}; type CardanoNodeIpcMessage = { Started?: Array, ReplyPort?: number, FInjects?: FaultInjectionIpcResponse, -} +}; type NodeArgs = Array; @@ -213,7 +217,10 @@ export class CardanoNode { * @param isForced {boolean} * @returns {Promise} resolves if the node could be started, rejects with error otherwise. */ - start = async (config: CardanoNodeConfig, isForced: boolean = false): Promise => { + start = async ( + config: CardanoNodeConfig, + isForced: boolean = false + ): Promise => { // Guards const nodeCanBeStarted = await this._canBeStarted(); @@ -231,14 +238,22 @@ export class CardanoNode { this._startupTries++; this._changeToState(CardanoNodeStates.STARTING); - _log.info(`CardanoNode#start: trying to start cardano-node for the ${this._startupTries} time`, { startupTries: this._startupTries }); + _log.info( + `CardanoNode#start: trying to start cardano-node for the ${ + this._startupTries + } time`, + { startupTries: this._startupTries } + ); return new Promise((resolve, reject) => { const logFile = createWriteStream(config.logFilePath, { flags: 'a' }); logFile.on('open', async () => { this._cardanoLogFile = logFile; // Spawning cardano-node - _log.debug('CardanoNode path with args', { path: nodePath, args: nodeArgs }); + _log.debug('CardanoNode path with args', { + path: nodePath, + args: nodeArgs, + }); const node = this._spawnNode(nodePath, nodeArgs, logFile); this._node = node; try { @@ -249,7 +264,12 @@ export class CardanoNode { node.on('error', this._handleCardanoNodeError); // Request cardano-node to reply with port node.send({ QueryPort: [] }); - _log.info(`CardanoNode#start: cardano-node child process spawned with PID ${node.pid}`, { pid: node.pid }); + _log.info( + `CardanoNode#start: cardano-node child process spawned with PID ${ + node.pid + }`, + { pid: node.pid } + ); resolve(); } catch (_) { reject('CardanoNode#start: Error while spawning cardano-node'); @@ -280,7 +300,9 @@ export class CardanoNode { this._reset(); return Promise.resolve(); } catch (error) { - _log.error('CardanoNode#stop: cardano-node did not stop correctly', { error }); + _log.error('CardanoNode#stop: cardano-node did not stop correctly', { + error, + }); try { await this.kill(); } catch (killError) { @@ -334,11 +356,15 @@ export class CardanoNode { _log.info('CardanoNode#restart: stopping current node'); await this.stop(); } - _log.info('CardanoNode#restart: restarting node with previous config', { isForced }); + _log.info('CardanoNode#restart: restarting node with previous config', { + isForced, + }); await this._waitForCardanoToExitOrKillIt(); await this.start(_config, isForced); } catch (error) { - _log.error('CardanoNode#restart: Could not restart cardano-node', { error }); + _log.error('CardanoNode#restart: Could not restart cardano-node', { + error, + }); this._changeToState(CardanoNodeStates.ERRORED); return Promise.reject(error); } @@ -363,9 +389,10 @@ export class CardanoNode { this._changeToState(CardanoNodeStates.UPDATING); _log.info('CardanoNode: waiting for node to apply update'); try { - await promisedCondition(() => ( - this._state === CardanoNodeStates.UPDATED - ), _config.updateTimeout); + await promisedCondition( + () => this._state === CardanoNodeStates.UPDATED, + _config.updateTimeout + ); await this._waitForNodeProcessToExit(_config.updateTimeout); } catch (error) { _log.info('CardanoNode: did not apply update as expected, killing it...'); @@ -415,9 +442,9 @@ export class CardanoNode { * @private */ _spawnNode(nodePath: string, args: NodeArgs, logFile: WriteStream) { - return this._actions.spawn( - nodePath, args, { stdio: ['inherit', logFile, logFile, 'ipc'] } - ); + return this._actions.spawn(nodePath, args, { + stdio: ['inherit', logFile, logFile, 'ipc'], + }); } /** @@ -433,8 +460,10 @@ export class CardanoNode { _handleCardanoNodeMessage = (msg: CardanoNodeIpcMessage) => { if (msg == null) return; this._log.info('CardanoNode: received message', { msg }); - if (msg.ReplyPort != null) this._handleCardanoReplyPortMessage(msg.ReplyPort); - if (msg.FInjects != null) this._handleCardanoFaultInjectionResponse(msg.FInjects); + if (msg.ReplyPort != null) + this._handleCardanoReplyPortMessage(msg.ReplyPort); + if (msg.FInjects != null) + this._handleCardanoFaultInjectionResponse(msg.FInjects); }; /** @@ -470,8 +499,12 @@ export class CardanoNode { * @param response * @private */ - _handleCardanoFaultInjectionResponse = (response: FaultInjectionIpcResponse) => { - this._log.info('CardanoNode: the following injected faults are active', { injectedFaults: response }); + _handleCardanoFaultInjectionResponse = ( + response: FaultInjectionIpcResponse + ) => { + this._log.info('CardanoNode: the following injected faults are active', { + injectedFaults: response, + }); this._injectedFaults = response; }; @@ -495,11 +528,17 @@ export class CardanoNode { await this._waitForNodeProcessToExit(_config.shutdownTimeout); } catch (_) { _log.error( - `CardanoNode: sent exit code ${code} but was still running after ${_config.shutdownTimeout}ms. Killing it now.`, + `CardanoNode: sent exit code ${code} but was still running after ${ + _config.shutdownTimeout + }ms. Killing it now.`, { code, shutdownTimeout: _config.shutdownTimeout } ); try { - if (_node) await this._ensureProcessIsNotRunning(_node.pid, CARDANO_PROCESS_NAME); + if (_node) + await this._ensureProcessIsNotRunning( + _node.pid, + CARDANO_PROCESS_NAME + ); } catch (e) { _log.info('CardanoNode: did not exit correctly'); } @@ -508,7 +547,10 @@ export class CardanoNode { // Handle various exit scenarios if (this._state === CardanoNodeStates.STOPPING) { this._changeToState(CardanoNodeStates.STOPPED); - } else if (this._state === CardanoNodeStates.UPDATING && code === CARDANO_UPDATE_EXIT_CODE) { + } else if ( + this._state === CardanoNodeStates.UPDATING && + code === CARDANO_UPDATE_EXIT_CODE + ) { this._changeToState(CardanoNodeStates.UPDATED); } else if (this._isUnrecoverable(_config)) { this._changeToState(CardanoNodeStates.UNRECOVERABLE); @@ -530,14 +572,22 @@ export class CardanoNode { this._state = state; this._actions.broadcastStateChange(state); switch (state) { - case CardanoNodeStates.STARTING: return _transitionListeners.onStarting(); - case CardanoNodeStates.RUNNING: return _transitionListeners.onRunning(); - case CardanoNodeStates.STOPPING: return _transitionListeners.onStopping(); - case CardanoNodeStates.STOPPED: return _transitionListeners.onStopped(); - case CardanoNodeStates.UPDATING: return _transitionListeners.onUpdating(); - case CardanoNodeStates.UPDATED: return _transitionListeners.onUpdated(); - case CardanoNodeStates.CRASHED: return _transitionListeners.onCrashed(...args); - case CardanoNodeStates.UNRECOVERABLE: return _transitionListeners.onUnrecoverable(); + case CardanoNodeStates.STARTING: + return _transitionListeners.onStarting(); + case CardanoNodeStates.RUNNING: + return _transitionListeners.onRunning(); + case CardanoNodeStates.STOPPING: + return _transitionListeners.onStopping(); + case CardanoNodeStates.STOPPED: + return _transitionListeners.onStopped(); + case CardanoNodeStates.UPDATING: + return _transitionListeners.onUpdating(); + case CardanoNodeStates.UPDATED: + return _transitionListeners.onUpdated(); + case CardanoNodeStates.CRASHED: + return _transitionListeners.onCrashed(...args); + case CardanoNodeStates.UNRECOVERABLE: + return _transitionListeners.onUnrecoverable(); default: } } @@ -552,9 +602,8 @@ export class CardanoNode { * Checks if cardano-node child_process is not running anymore * @returns {boolean} */ - _isDead = async (): Promise => ( - !this._isConnected() && await this._isNodeProcessNotRunningAnymore() - ); + _isDead = async (): Promise => + !this._isConnected() && (await this._isNodeProcessNotRunningAnymore()); /** * Checks if current cardano-node child_process is "awake" (created, connected, stateful) @@ -565,7 +614,9 @@ export class CardanoNode { * @private */ _canBeStarted = async (): Promise => { - if (this._isConnected()) { return false; } + if (this._isConnected()) { + return false; + } try { await this._ensurePreviousCardanoNodeIsNotRunning(); return true; @@ -576,9 +627,15 @@ export class CardanoNode { _ensureProcessIsNotRunning = async (pid: number, name: string) => { const { _log } = this; - _log.info(`CardanoNode: checking if ${name} process (PID: ${pid}) is still running`, { name, pid }); + _log.info( + `CardanoNode: checking if ${name} process (PID: ${pid}) is still running`, + { name, pid } + ); if (await this._isProcessRunning(pid, name)) { - _log.info(`CardanoNode: killing ${name} process (PID: ${pid})`, { name, pid }); + _log.info(`CardanoNode: killing ${name} process (PID: ${pid})`, { + name, + pid, + }); try { await this._killProcessWithName(pid, name); return Promise.resolve(); @@ -590,33 +647,60 @@ export class CardanoNode { return Promise.reject(); } } - this._log.info(`No ${name} process (PID: ${pid}) is running`, { name, pid }); + this._log.info(`No ${name} process (PID: ${pid}) is running`, { + name, + pid, + }); }; _ensureCurrentCardanoNodeIsNotRunning = async (): Promise => { const { _log, _node } = this; - _log.info('CardanoNode: checking if current cardano-node process is still running'); - if (_node == null) { return Promise.resolve(); } - return await this._ensureProcessIsNotRunning(_node.pid, CARDANO_PROCESS_NAME); + _log.info( + 'CardanoNode: checking if current cardano-node process is still running' + ); + if (_node == null) { + return Promise.resolve(); + } + return await this._ensureProcessIsNotRunning( + _node.pid, + CARDANO_PROCESS_NAME + ); }; _ensurePreviousCardanoNodeIsNotRunning = async (): Promise => { const { _log } = this; const previousPID: ?number = await this._retrieveData(PREVIOUS_CARDANO_PID); - _log.info('CardanoNode: checking if previous cardano-node process is still running', { previousPID }); - if (previousPID == null) { return Promise.resolve(); } - return await this._ensureProcessIsNotRunning(previousPID, CARDANO_PROCESS_NAME); + _log.info( + 'CardanoNode: checking if previous cardano-node process is still running', + { previousPID } + ); + if (previousPID == null) { + return Promise.resolve(); + } + return await this._ensureProcessIsNotRunning( + previousPID, + CARDANO_PROCESS_NAME + ); }; - _isProcessRunning = async (previousPID: number, processName: string): Promise => { + _isProcessRunning = async ( + previousPID: number, + processName: string + ): Promise => { const { _log } = this; try { const previousProcess = await getProcess(previousPID, processName); if (!previousProcess) { - _log.debug(`CardanoNode: No previous ${processName} process is running anymore`, { processName }); + _log.debug( + `CardanoNode: No previous ${processName} process is running anymore`, + { processName } + ); return false; } - _log.debug(`CardanoNode: previous ${processName} process found`, { processName, previousProcess }); + _log.debug(`CardanoNode: previous ${processName} process found`, { + processName, + previousProcess, + }); return true; } catch (error) { _log.error('CardanoNode: _isProcessRunning error', { error }); @@ -629,19 +713,27 @@ export class CardanoNode { const { _config } = this; try { if (!environment.isWindows) { - this._log.info(`CardanoNode: using "process.kill(${pid})" to kill it`, { pid }); + this._log.info(`CardanoNode: using "process.kill(${pid})" to kill it`, { + pid, + }); process.kill(pid); } else { // https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/taskkill const windowsKillCmd = `taskkill /pid ${pid} /t /f`; - this._log.info('CardanoNode (Windows): using kill command to kill it', { windowsKillCmd }); + this._log.info('CardanoNode (Windows): using kill command to kill it', { + windowsKillCmd, + }); this._actions.exec(windowsKillCmd); } - await promisedCondition(async () => ( - (await this._isProcessRunning(pid, name)) === false - ), _config.killTimeout); + await promisedCondition( + async () => (await this._isProcessRunning(pid, name)) === false, + _config.killTimeout + ); - this._log.info(`CardanoNode: successfuly killed ${name} process (PID: ${pid})`, { name, pid }); + this._log.info( + `CardanoNode: successfuly killed ${name} process (PID: ${pid})`, + { name, pid } + ); return Promise.resolve(); } catch (error) { this._log.error( @@ -662,7 +754,7 @@ export class CardanoNode { } // stores the current port/pid on which cardano-node or Daedalus is running - _storeData = (identifier: string, data: number): Promise => ( + _storeData = (identifier: string, data: number): Promise => new Promise((resolve, reject) => { try { // saves current port/pid in file system @@ -670,14 +762,15 @@ export class CardanoNode { this._log.info(`CardanoNode: ${identifier} stored successfuly`); resolve(); } catch (error) { - this._log.error(`CardanoNode: failed to store ${identifier}`, { error }); + this._log.error(`CardanoNode: failed to store ${identifier}`, { + error, + }); reject(error); } - }) - ); + }); // retrieves the last known port/pid on which cardano-node or Daedalus was running - _retrieveData = (identifier: string): Promise => ( + _retrieveData = (identifier: string): Promise => new Promise((resolve, reject) => { try { // retrieves previous port/pid from file system @@ -688,24 +781,25 @@ export class CardanoNode { resolve(null); } - this._log.info(`CardanoNode: get ${identifier} success`, { [`${identifier}`]: data }); + this._log.info(`CardanoNode: get ${identifier} success`, { + [`${identifier}`]: data, + }); resolve(toInteger(data)); } catch (error) { this._log.error(`CardanoNode: get ${identifier} failed`, { error }); reject(error); } - }) - ); + }); - _isNodeProcessStillRunning = async (): Promise => ( - this._node != null && await this._isProcessRunning(this._node.pid, CARDANO_PROCESS_NAME) - ); + _isNodeProcessStillRunning = async (): Promise => + this._node != null && + (await this._isProcessRunning(this._node.pid, CARDANO_PROCESS_NAME)); - _isNodeProcessNotRunningAnymore = async () => await this._isNodeProcessStillRunning() === false; + _isNodeProcessNotRunningAnymore = async () => + (await this._isNodeProcessStillRunning()) === false; - _waitForNodeProcessToExit = async (timeout: number) => ( - await promisedCondition(this._isNodeProcessNotRunningAnymore, timeout) - ); + _waitForNodeProcessToExit = async (timeout: number) => + await promisedCondition(this._isNodeProcessNotRunningAnymore, timeout); _waitForCardanoToExitOrKillIt = async () => { const { _config } = this; @@ -717,7 +811,6 @@ export class CardanoNode { } }; - _isUnrecoverable = (config: CardanoNodeConfig) => ( - this._startupTries >= config.startupMaxRetries - ); + _isUnrecoverable = (config: CardanoNodeConfig) => + this._startupTries >= config.startupMaxRetries; } diff --git a/source/main/cardano/config.js b/source/main/cardano/config.js index a71cbb7881..c3cc254a73 100644 --- a/source/main/cardano/config.js +++ b/source/main/cardano/config.js @@ -24,10 +24,14 @@ export const prepareArgs = (config: LauncherConfig) => { if (config.nodeLogConfig) args.push('--log-config', config.nodeLogConfig); if (config.logsPrefix) args.push('--logs-prefix', config.logsPrefix); if (config.configuration) { - if (config.configuration.filePath) args.push('--configuration-file', config.configuration.filePath); - if (config.configuration.key) args.push('--configuration-key', config.configuration.key); - if (config.configuration.systemStart) args.push('--system-start', config.configuration.systemStart); - if (config.configuration.seed) args.push('--configuration-seed', config.configuration.seed); + if (config.configuration.filePath) + args.push('--configuration-file', config.configuration.filePath); + if (config.configuration.key) + args.push('--configuration-key', config.configuration.key); + if (config.configuration.systemStart) + args.push('--system-start', config.configuration.systemStart); + if (config.configuration.seed) + args.push('--configuration-seed', config.configuration.seed); } if (isDev) args.push('--wallet-doc-address', '127.0.0.1:8091'); return args; diff --git a/source/main/cardano/setup.js b/source/main/cardano/setup.js index d514056dcb..d6f397c7c9 100644 --- a/source/main/cardano/setup.js +++ b/source/main/cardano/setup.js @@ -14,7 +14,8 @@ import { setupCardanoNodeMode } from './setupCardanoNodeMode'; * @param mainWindow */ export const setupCardano = ( - launcherConfig: LauncherConfig, mainWindow: BrowserWindow + launcherConfig: LauncherConfig, + mainWindow: BrowserWindow ): ?CardanoNode => { if (frontendOnlyMode) { return setupFrontendOnlyMode(mainWindow); diff --git a/source/main/cardano/setupCardanoNodeMode.js b/source/main/cardano/setupCardanoNodeMode.js index bfd22a33e4..dac54ed1c4 100644 --- a/source/main/cardano/setupCardanoNodeMode.js +++ b/source/main/cardano/setupCardanoNodeMode.js @@ -8,20 +8,24 @@ import { NODE_KILL_TIMEOUT, NODE_SHUTDOWN_TIMEOUT, NODE_STARTUP_MAX_RETRIES, - NODE_STARTUP_TIMEOUT, NODE_UPDATE_TIMEOUT + NODE_STARTUP_TIMEOUT, + NODE_UPDATE_TIMEOUT, } from '../config'; import { Logger } from '../utils/logging'; import type { LauncherConfig } from '../config'; import type { CardanoNodeState, CardanoStatus, - TlsConfig + TlsConfig, } from '../../common/types/cardano-node.types'; import { - cardanoAwaitUpdateChannel, cardanoFaultInjectionChannel, cardanoRestartChannel, + cardanoAwaitUpdateChannel, + cardanoFaultInjectionChannel, + cardanoRestartChannel, cardanoStateChangeChannel, getCachedCardanoStatusChannel, - cardanoTlsConfigChannel, setCachedCardanoStatusChannel + cardanoTlsConfigChannel, + setCachedCardanoStatusChannel, } from '../ipc/cardano.ipc'; import { safeExitWithCode } from '../utils/safeExitWithCode'; @@ -55,50 +59,66 @@ export const setupCardanoNodeMode = ( launcherConfig: LauncherConfig, mainWindow: BrowserWindow ) => { - const cardanoNode = new CardanoNode(Logger, { - // Dependencies on node.js apis are passed as props to ease testing - spawn, - exec, - readFileSync, - createWriteStream, - broadcastTlsConfig: (config: ?TlsConfig) => { - if (!mainWindow.isDestroyed()) cardanoTlsConfigChannel.send(config, mainWindow); + const cardanoNode = new CardanoNode( + Logger, + { + // Dependencies on node.js apis are passed as props to ease testing + spawn, + exec, + readFileSync, + createWriteStream, + broadcastTlsConfig: (config: ?TlsConfig) => { + if (!mainWindow.isDestroyed()) + cardanoTlsConfigChannel.send(config, mainWindow); + }, + broadcastStateChange: (state: CardanoNodeState) => { + if (!mainWindow.isDestroyed()) + cardanoStateChangeChannel.send(state, mainWindow); + }, }, - broadcastStateChange: (state: CardanoNodeState) => { - if (!mainWindow.isDestroyed()) cardanoStateChangeChannel.send(state, mainWindow); - }, - }, { - // CardanoNode lifecycle hooks - onStarting: () => {}, - onRunning: () => {}, - onStopping: () => {}, - onStopped: () => {}, - onUpdating: () => {}, - onUpdated: () => {}, - onCrashed: (code) => { - const restartTimeout = cardanoNode.startupTries > 0 ? 30000 : 0; - Logger.info(`CardanoNode crashed with code ${code}. Restarting in ${restartTimeout}ms …`, { code, restartTimeout }); - setTimeout(() => restartCardanoNode(cardanoNode), restartTimeout); - }, - onError: () => {}, - onUnrecoverable: () => {} - }); + { + // CardanoNode lifecycle hooks + onStarting: () => {}, + onRunning: () => {}, + onStopping: () => {}, + onStopped: () => {}, + onUpdating: () => {}, + onUpdated: () => {}, + onCrashed: code => { + const restartTimeout = cardanoNode.startupTries > 0 ? 30000 : 0; + Logger.info( + `CardanoNode crashed with code ${code}. Restarting in ${restartTimeout}ms …`, + { code, restartTimeout } + ); + setTimeout(() => restartCardanoNode(cardanoNode), restartTimeout); + }, + onError: () => {}, + onUnrecoverable: () => {}, + } + ); startCardanoNode(cardanoNode, launcherConfig); getCachedCardanoStatusChannel.onRequest(() => { - Logger.info('ipcMain: Received request from renderer for cardano status', { status: cardanoNode.status }); + Logger.info('ipcMain: Received request from renderer for cardano status', { + status: cardanoNode.status, + }); return Promise.resolve(cardanoNode.status); }); setCachedCardanoStatusChannel.onReceive((status: ?CardanoStatus) => { - Logger.info('ipcMain: Received request from renderer to cache cardano status', { status }); + Logger.info( + 'ipcMain: Received request from renderer to cache cardano status', + { status } + ); cardanoNode.saveStatus(status); return Promise.resolve(); }); cardanoStateChangeChannel.onRequest(() => { - Logger.info('ipcMain: Received request from renderer for node state', { state: cardanoNode.state }); + Logger.info('ipcMain: Received request from renderer for node state', { + state: cardanoNode.state, + }); return Promise.resolve(cardanoNode.state); }); @@ -111,7 +131,9 @@ export const setupCardanoNodeMode = ( Logger.info('ipcMain: Received request from renderer to await update'); setTimeout(async () => { await cardanoNode.expectNodeUpdate(); - Logger.info('CardanoNode applied an update. Exiting Daedalus with code 20.'); + Logger.info( + 'CardanoNode applied an update. Exiting Daedalus with code 20.' + ); safeExitWithCode(20); }); return Promise.resolve(); @@ -122,8 +144,11 @@ export const setupCardanoNodeMode = ( return cardanoNode.restart(true); // forced restart }); - cardanoFaultInjectionChannel.onReceive((fault) => { - Logger.info('ipcMain: Received request to inject a fault into cardano node', { fault }); + cardanoFaultInjectionChannel.onReceive(fault => { + Logger.info( + 'ipcMain: Received request to inject a fault into cardano node', + { fault } + ); return cardanoNode.setFault(fault); }); diff --git a/source/main/cardano/setupFrontendOnlyMode.js b/source/main/cardano/setupFrontendOnlyMode.js index 81a4d82d34..88fe880f08 100644 --- a/source/main/cardano/setupFrontendOnlyMode.js +++ b/source/main/cardano/setupFrontendOnlyMode.js @@ -8,7 +8,7 @@ import { cardanoStateChangeChannel, getCachedCardanoStatusChannel, cardanoTlsConfigChannel, - setCachedCardanoStatusChannel + setCachedCardanoStatusChannel, } from '../ipc/cardano.ipc'; import { Logger } from '../utils/logging'; import { CardanoNodeStates } from '../../common/types/cardano-node.types'; @@ -39,12 +39,17 @@ export const setupFrontendOnlyMode = (mainWindow: BrowserWindow) => { }); setCachedCardanoStatusChannel.onReceive((status: ?CardanoStatus) => { - Logger.info('ipcMain: Received request from renderer to cache cardano status', { status }); + Logger.info( + 'ipcMain: Received request from renderer to cache cardano status', + { status } + ); return Promise.resolve(); }); cardanoStateChangeChannel.onRequest(() => { - Logger.info('ipcMain: Received request from renderer for node state', { state: CardanoNodeStates.RUNNING }); + Logger.info('ipcMain: Received request from renderer for node state', { + state: CardanoNodeStates.RUNNING, + }); return Promise.resolve(CardanoNodeStates.RUNNING); }); @@ -70,8 +75,11 @@ export const setupFrontendOnlyMode = (mainWindow: BrowserWindow) => { return Promise.resolve(); }); - cardanoFaultInjectionChannel.onReceive((fault) => { - Logger.info('ipcMain: Received request to inject a fault into cardano node', { fault }); + cardanoFaultInjectionChannel.onReceive(fault => { + Logger.info( + 'ipcMain: Received request to inject a fault into cardano node', + { fault } + ); return Promise.reject(fault); }); diff --git a/source/main/cardano/utils.js b/source/main/cardano/utils.js index dc4d923152..412665685e 100644 --- a/source/main/cardano/utils.js +++ b/source/main/cardano/utils.js @@ -3,11 +3,11 @@ import type { CardanoNodeStorageKeys, NetworkNames, PlatformNames, - ProcessNames + ProcessNames, } from '../../common/types/cardano-node.types'; import { CardanoProcessNameOptions, - NetworkNameOptions + NetworkNameOptions, } from '../../common/types/cardano-node.types'; export type Process = { @@ -33,26 +33,39 @@ const checkCondition = async ( } else if (timeWaited >= timeout) { reject(`Promised condition not met within ${timeout}ms.`); } else { - setTimeout(() => checkCondition( - condition, resolve, reject, timeout, retryEvery, timeWaited + retryEvery - ), retryEvery); + setTimeout( + () => + checkCondition( + condition, + resolve, + reject, + timeout, + retryEvery, + timeWaited + retryEvery + ), + retryEvery + ); } }; export const promisedCondition = ( - cond: Function, timeout: number = 5000, retryEvery: number = 1000 -): Promise => new Promise((resolve, reject) => { - checkCondition(cond, resolve, reject, timeout, retryEvery); -}); + cond: Function, + timeout: number = 5000, + retryEvery: number = 1000 +): Promise => + new Promise((resolve, reject) => { + checkCondition(cond, resolve, reject, timeout, retryEvery); + }); -const getNetworkName = (network: NetworkNames): string => ( - NetworkNameOptions[network] || NetworkNameOptions.development -); +const getNetworkName = (network: NetworkNames): string => + NetworkNameOptions[network] || NetworkNameOptions.development; -export const deriveStorageKeys = (network: NetworkNames): CardanoNodeStorageKeys => ({ - PREVIOUS_CARDANO_PID: `${getNetworkName(network)}-PREVIOUS-CARDANO-PID` +export const deriveStorageKeys = ( + network: NetworkNames +): CardanoNodeStorageKeys => ({ + PREVIOUS_CARDANO_PID: `${getNetworkName(network)}-PREVIOUS-CARDANO-PID`, }); export const deriveProcessNames = (platform: PlatformNames): ProcessNames => ({ - CARDANO_PROCESS_NAME: CardanoProcessNameOptions[platform] || 'cardano-node' + CARDANO_PROCESS_NAME: CardanoProcessNameOptions[platform] || 'cardano-node', }); diff --git a/source/main/config.js b/source/main/config.js index 13d99b6d30..bf31c895f1 100644 --- a/source/main/config.js +++ b/source/main/config.js @@ -13,11 +13,12 @@ if (!isStartedByLauncher) { const dialogTitle = 'Daedalus improperly started!'; let dialogMessage; if (isProd) { - dialogMessage = isWindows ? - 'Please start Daedalus using the icon in the Windows start menu or using Daedalus icon on your desktop.' : - 'Daedalus was launched without needed configuration. Please start Daedalus using the shortcut provided by the installer.'; + dialogMessage = isWindows + ? 'Please start Daedalus using the icon in the Windows start menu or using Daedalus icon on your desktop.' + : 'Daedalus was launched without needed configuration. Please start Daedalus using the shortcut provided by the installer.'; } else { - dialogMessage = 'Daedalus should be started using nix-shell. Find more details here: https://github.com/input-output-hk/daedalus/blob/develop/README.md'; + dialogMessage = + 'Daedalus should be started using nix-shell. Find more details here: https://github.com/input-output-hk/daedalus/blob/develop/README.md'; } try { // app may not be available at this moment so we need to use try-catch @@ -48,11 +49,13 @@ export type LauncherConfig = { key: string, systemStart: string, seed: string, - } + }, }; export const APP_NAME = 'Daedalus'; -export const launcherConfig: LauncherConfig = readLauncherConfig(LAUNCHER_CONFIG); +export const launcherConfig: LauncherConfig = readLauncherConfig( + LAUNCHER_CONFIG +); export const appLogsFolderPath = launcherConfig.logsPrefix; export const pubLogsFolderPath = path.join(appLogsFolderPath, 'pub'); export const appFolderPath = launcherConfig.workingDir; @@ -81,6 +84,8 @@ export const DISK_SPACE_REQUIRED = 2 * 1073741274; // 2 GB | unit: bytes export const DISK_SPACE_REQUIRED_MARGIN_PERCENTAGE = 10; // 10% of the available disk space export const DISK_SPACE_CHECK_LONG_INTERVAL = 10 * 60 * 1000; // 10 minutes | unit: milliseconds export const DISK_SPACE_CHECK_MEDIUM_INTERVAL = 60 * 1000; // 1 minute | unit: milliseconds -export const DISK_SPACE_CHECK_SHORT_INTERVAL = environment.isTest ? 2000 : 10 * 1000; // 10 seconds | unit: milliseconds +export const DISK_SPACE_CHECK_SHORT_INTERVAL = environment.isTest + ? 2000 + : 10 * 1000; // 10 seconds | unit: milliseconds export const DISK_SPACE_RECOMMENDED_PERCENTAGE = 15; // 15% of the total disk space /* eslint-disable max-len */ diff --git a/source/main/environment.js b/source/main/environment.js index 53729932ef..b5545c7ae3 100644 --- a/source/main/environment.js +++ b/source/main/environment.js @@ -13,7 +13,7 @@ import { STAGING, TEST, TESTNET, - WINDOWS + WINDOWS, } from '../common/types/environment.types'; // environment variables @@ -46,28 +46,32 @@ const isWindows = PLATFORM === WINDOWS; const isLinux = PLATFORM === LINUX; // compose environment -export const environment: Environment = Object.assign({}, { - network: NETWORK, - apiVersion: API_VERSION, - mobxDevTools: MOBX_DEV_TOOLS, - current: CURRENT_NODE_ENV, - isDev, - isTest, - isProduction, - isMainnet, - isStaging, - isTestnet, - isDevelopment, - isWatchMode, - build: BUILD, - buildNumber: BUILD_NUMBER, - buildLabel: BUILD_LABEL, - platform: PLATFORM, - platformVersion: PLATFORM_VERSION, - os: OS, - installerVersion: INSTALLER_VERSION, - version, - isWindows, - isMacOS, - isLinux -}, process.env); +export const environment: Environment = Object.assign( + {}, + { + network: NETWORK, + apiVersion: API_VERSION, + mobxDevTools: MOBX_DEV_TOOLS, + current: CURRENT_NODE_ENV, + isDev, + isTest, + isProduction, + isMainnet, + isStaging, + isTestnet, + isDevelopment, + isWatchMode, + build: BUILD, + buildNumber: BUILD_NUMBER, + buildLabel: BUILD_LABEL, + platform: PLATFORM, + platformVersion: PLATFORM_VERSION, + os: OS, + installerVersion: INSTALLER_VERSION, + version, + isWindows, + isMacOS, + isLinux, + }, + process.env +); diff --git a/source/main/index.js b/source/main/index.js index 23ab89d798..d737f5d053 100644 --- a/source/main/index.js +++ b/source/main/index.js @@ -28,8 +28,13 @@ let mainWindow: BrowserWindow; let cardanoNode: ?CardanoNode; const { - isDev, isWatchMode, network, current, os: osName, - version: daedalusVersion, buildNumber: cardanoVersion, + isDev, + isWatchMode, + network, + current, + os: osName, + version: daedalusVersion, + buildNumber: cardanoVersion, } = environment; const safeExit = async () => { @@ -40,12 +45,16 @@ const safeExit = async () => { if (cardanoNode.state === CardanoNodeStates.STOPPING) return; try { const pid = cardanoNode.pid || 'null'; - Logger.info(`Daedalus:safeExit: stopping cardano-node with PID: ${pid}`, { pid }); + Logger.info(`Daedalus:safeExit: stopping cardano-node with PID: ${pid}`, { + pid, + }); await cardanoNode.stop(); Logger.info('Daedalus:safeExit: exiting Daedalus with code 0', { code: 0 }); safeExitWithCode(0); } catch (error) { - Logger.error('Daedalus:safeExit: cardano-node did not exit correctly', { error }); + Logger.error('Daedalus:safeExit: cardano-node did not exit correctly', { + error, + }); safeExitWithCode(0); } }; @@ -86,7 +95,9 @@ const onAppReady = async () => { mainWindow = createMainWindow(isInSafeMode, locale); - const onCheckDiskSpace = ({ isNotEnoughDiskSpace }: CheckDiskSpaceResponse) => { + const onCheckDiskSpace = ({ + isNotEnoughDiskSpace, + }: CheckDiskSpaceResponse) => { // Daedalus is not managing cardano-node in `frontendOnlyMode` // so we don't have a way to stop it in case there is not enough disk space if (frontendOnlyMode) return; @@ -130,22 +141,25 @@ const onAppReady = async () => { getNumberOfEpochsConsolidated(); - mainWindow.on('close', async (event) => { - Logger.info('mainWindow received event. Safe exiting Daedalus now.'); + mainWindow.on('close', async event => { + Logger.info( + 'mainWindow received event. Safe exiting Daedalus now.' + ); event.preventDefault(); await safeExit(); }); buildAppMenus(mainWindow, cardanoNode, isInSafeMode, locale); - await rebuildApplicationMenu.onReceive(() => ( - new Promise(resolve => { - locale = getLocale(network); - buildAppMenus(mainWindow, cardanoNode, isInSafeMode, locale); - mainWindow.updateTitle(locale); - resolve(); - }) - )); + await rebuildApplicationMenu.onReceive( + () => + new Promise(resolve => { + locale = getLocale(network); + buildAppMenus(mainWindow, cardanoNode, isInSafeMode, locale); + mainWindow.updateTitle(locale); + resolve(); + }) + ); // Security feature: Prevent creation of new browser windows // https://github.com/electron/electron/blob/master/docs/tutorial/security.md#14-disable-or-limit-creation-of-new-windows @@ -160,7 +174,7 @@ const onAppReady = async () => { }); // Wait for controlled cardano-node shutdown before quitting the app - app.on('before-quit', async (event) => { + app.on('before-quit', async event => { Logger.info('app received event. Safe exiting Daedalus now.'); event.preventDefault(); // prevent Daedalus from quitting immediately await safeExit(); diff --git a/source/main/ipc/bugReportRequestChannel.js b/source/main/ipc/bugReportRequestChannel.js index cd1b2be02e..f0abc2fecc 100644 --- a/source/main/ipc/bugReportRequestChannel.js +++ b/source/main/ipc/bugReportRequestChannel.js @@ -7,55 +7,57 @@ import { MainIpcChannel } from './lib/MainIpcChannel'; import { SUBMIT_BUG_REPORT_REQUEST_CHANNEL } from '../../common/ipc/api'; import type { SubmitBugReportRequestResponse, - SubmitBugReportRequest + SubmitBugReportRequest, } from '../../common/ipc/api'; import { Logger } from '../utils/logging'; -export const bugReportRequestChannel: ( - // IpcChannel - MainIpcChannel -) = ( - new MainIpcChannel(SUBMIT_BUG_REPORT_REQUEST_CHANNEL) -); +export const bugReportRequestChannel: // IpcChannel +MainIpcChannel< + SubmitBugReportRequest, + SubmitBugReportRequestResponse +> = new MainIpcChannel(SUBMIT_BUG_REPORT_REQUEST_CHANNEL); export const handleBugReportRequests = () => { - bugReportRequestChannel.onReceive((request: SubmitBugReportRequest) => ( - new Promise((resolve, reject) => { - Logger.info('bugReportRequestChannel::onReceive', { request }); - const { httpOptions, requestPayload } = request; - const options = Object.assign({}, httpOptions); - const payload = Object.assign({}, requestPayload); - // Prepare multipart/form-data - const formData = new FormData(); - formData.append('payload', JSON.stringify(payload)); + bugReportRequestChannel.onReceive( + (request: SubmitBugReportRequest) => + new Promise((resolve, reject) => { + Logger.info('bugReportRequestChannel::onReceive', { request }); + const { httpOptions, requestPayload } = request; + const options = Object.assign({}, httpOptions); + const payload = Object.assign({}, requestPayload); + // Prepare multipart/form-data + const formData = new FormData(); + formData.append('payload', JSON.stringify(payload)); - // prepare file stream (attachment) - if (payload.compressedLogsFilePath) { - const stream = fs.createReadStream(payload.compressedLogsFilePath); - const fileName = extractFileNameFromPath(payload.compressedLogsFilePath); - formData.append(fileName, stream); - } + // prepare file stream (attachment) + if (payload.compressedLogsFilePath) { + const stream = fs.createReadStream(payload.compressedLogsFilePath); + const fileName = extractFileNameFromPath( + payload.compressedLogsFilePath + ); + formData.append(fileName, stream); + } - options.headers = formData.getHeaders(); + options.headers = formData.getHeaders(); - Logger.info('Sending bug report request with options', { options }); - const httpRequest = http.request(options); - httpRequest.on('response', (response) => { - if (response.statusCode !== 200) { - return reject(); - } - response.on('data', () => {}); - response.on('error', (error) => { - reject(error); - }); - response.on('end', () => { - resolve(); + Logger.info('Sending bug report request with options', { options }); + const httpRequest = http.request(options); + httpRequest.on('response', response => { + if (response.statusCode !== 200) { + return reject(); + } + response.on('data', () => {}); + response.on('error', error => { + reject(error); + }); + response.on('end', () => { + resolve(); + }); }); - }); - httpRequest.on('error', (error) => reject(error)); + httpRequest.on('error', error => reject(error)); - // Attach form-data and trigger the request - formData.pipe(httpRequest); - }) - )); + // Attach form-data and trigger the request + formData.pipe(httpRequest); + }) + ); }; diff --git a/source/main/ipc/cardano.ipc.js b/source/main/ipc/cardano.ipc.js index 93d4f0a5e7..487694c161 100644 --- a/source/main/ipc/cardano.ipc.js +++ b/source/main/ipc/cardano.ipc.js @@ -7,7 +7,7 @@ import { GET_CACHED_CARDANO_STATUS_CHANNEL, CARDANO_TLS_CONFIG_CHANNEL, CARDANO_AWAIT_UPDATE_CHANNEL, - SET_CACHED_CARDANO_STATUS_CHANNEL + SET_CACHED_CARDANO_STATUS_CHANNEL, } from '../../common/ipc/api'; import type { CardanoAwaitUpdateResponse, @@ -23,35 +23,42 @@ import type { GetCachedCardanoStatusRequest, GetCachedCardanoStatusResponse, SetCachedCardanoStatusRequest, - SetCachedCardanoStatusResponse + SetCachedCardanoStatusResponse, } from '../../common/ipc/api'; // IpcChannel -export const cardanoRestartChannel: ( - MainIpcChannel -) = new MainIpcChannel(CARDANO_RESTART_CHANNEL); +export const cardanoRestartChannel: MainIpcChannel< + CardanoRestartRequest, + CardanoRestartResponse +> = new MainIpcChannel(CARDANO_RESTART_CHANNEL); -export const cardanoTlsConfigChannel: ( - MainIpcChannel -) = new MainIpcChannel(CARDANO_TLS_CONFIG_CHANNEL); +export const cardanoTlsConfigChannel: MainIpcChannel< + CardanoTlsConfigRequest, + CardanoTlsConfigResponse +> = new MainIpcChannel(CARDANO_TLS_CONFIG_CHANNEL); -export const cardanoAwaitUpdateChannel: ( - MainIpcChannel -) = new MainIpcChannel(CARDANO_AWAIT_UPDATE_CHANNEL); +export const cardanoAwaitUpdateChannel: MainIpcChannel< + CardanoAwaitUpdateRequest, + CardanoAwaitUpdateResponse +> = new MainIpcChannel(CARDANO_AWAIT_UPDATE_CHANNEL); -export const cardanoStateChangeChannel: ( - MainIpcChannel -) = new MainIpcChannel(CARDANO_STATE_CHANNEL); +export const cardanoStateChangeChannel: MainIpcChannel< + CardanoStateRequest, + CardanoStateResponse +> = new MainIpcChannel(CARDANO_STATE_CHANNEL); -export const cardanoFaultInjectionChannel: ( - MainIpcChannel -) = new MainIpcChannel(CARDANO_FAULT_INJECTION_CHANNEL); +export const cardanoFaultInjectionChannel: MainIpcChannel< + CardanoFaultInjectionRequest, + CardanoFaultInjectionResponse +> = new MainIpcChannel(CARDANO_FAULT_INJECTION_CHANNEL); -export const getCachedCardanoStatusChannel: ( - MainIpcChannel -) = new MainIpcChannel(GET_CACHED_CARDANO_STATUS_CHANNEL); +export const getCachedCardanoStatusChannel: MainIpcChannel< + GetCachedCardanoStatusRequest, + GetCachedCardanoStatusResponse +> = new MainIpcChannel(GET_CACHED_CARDANO_STATUS_CHANNEL); -export const setCachedCardanoStatusChannel: ( - MainIpcChannel -) = new MainIpcChannel(SET_CACHED_CARDANO_STATUS_CHANNEL); +export const setCachedCardanoStatusChannel: MainIpcChannel< + SetCachedCardanoStatusRequest, + SetCachedCardanoStatusResponse +> = new MainIpcChannel(SET_CACHED_CARDANO_STATUS_CHANNEL); diff --git a/source/main/ipc/compress-logs.js b/source/main/ipc/compress-logs.js index 9ea3a7bbe5..405957bdc3 100644 --- a/source/main/ipc/compress-logs.js +++ b/source/main/ipc/compress-logs.js @@ -7,48 +7,55 @@ import { appLogsFolderPath, pubLogsFolderPath } from '../config'; import { Logger } from '../utils/logging'; import { MainIpcChannel } from './lib/MainIpcChannel'; import { COMPRESS_LOGS_CHANNEL } from '../../common/ipc/api'; -import type { CompressLogsRequest, CompressLogsResponse } from '../../common/ipc/api'; +import type { + CompressLogsRequest, + CompressLogsResponse, +} from '../../common/ipc/api'; -export const compressLogsChannel: ( - MainIpcChannel -) = new MainIpcChannel(COMPRESS_LOGS_CHANNEL); +export const compressLogsChannel: MainIpcChannel< + CompressLogsRequest, + CompressLogsResponse +> = new MainIpcChannel(COMPRESS_LOGS_CHANNEL); export default () => { - compressLogsChannel.onRequest(({ logs, compressedFileName }) => ( - new Promise((resolve, reject) => { - const outputPath = path.join(appLogsFolderPath, compressedFileName); - const output = fs.createWriteStream(outputPath); - const archive = archiver('zip', { - zlib: { level: 9 } // Sets the compression level - }); - - output.on('close', () => { - Logger.debug('COMPRESS_LOGS.SUCCESS', { outputPath }); - resolve(outputPath); - }); - - archive.on('error', (error) => { - Logger.error('COMPRESS_LOGS.ERROR', { error }); - reject(error); - }); - - Logger.debug('COMPRESS_LOGS.START'); - - // compress files - const logFiles = get(logs, ['files'], []); - for (let i = 0; i < logFiles.length; i++) { - const stream = fs.readFileSync(path.join(pubLogsFolderPath, logFiles[i])); - archive.append(stream, { name: logFiles[i] }); - } - - archive.finalize((error) => { - if (error) { + compressLogsChannel.onRequest( + ({ logs, compressedFileName }) => + new Promise((resolve, reject) => { + const outputPath = path.join(appLogsFolderPath, compressedFileName); + const output = fs.createWriteStream(outputPath); + const archive = archiver('zip', { + zlib: { level: 9 }, // Sets the compression level + }); + + output.on('close', () => { + Logger.debug('COMPRESS_LOGS.SUCCESS', { outputPath }); + resolve(outputPath); + }); + + archive.on('error', error => { Logger.error('COMPRESS_LOGS.ERROR', { error }); reject(error); + }); + + Logger.debug('COMPRESS_LOGS.START'); + + // compress files + const logFiles = get(logs, ['files'], []); + for (let i = 0; i < logFiles.length; i++) { + const stream = fs.readFileSync( + path.join(pubLogsFolderPath, logFiles[i]) + ); + archive.append(stream, { name: logFiles[i] }); } - }); - archive.pipe(output); - }) - )); + archive.finalize(error => { + if (error) { + Logger.error('COMPRESS_LOGS.ERROR', { error }); + reject(error); + } + }); + + archive.pipe(output); + }) + ); }; diff --git a/source/main/ipc/control-ui-parts.js b/source/main/ipc/control-ui-parts.js index 11365b0452..2e1546e4f1 100644 --- a/source/main/ipc/control-ui-parts.js +++ b/source/main/ipc/control-ui-parts.js @@ -1,12 +1,20 @@ // @flow import { MainIpcChannel } from './lib/MainIpcChannel'; -import type { ShowUiPartRequest, ToggleUiPartRequest } from '../../common/ipc/api'; -import { SHOW_UI_PART_CHANNEL, TOGGLE_UI_PART_CHANNEL } from '../../common/ipc/api'; +import type { + ShowUiPartRequest, + ToggleUiPartRequest, +} from '../../common/ipc/api'; +import { + SHOW_UI_PART_CHANNEL, + TOGGLE_UI_PART_CHANNEL, +} from '../../common/ipc/api'; -export const showUiPartChannel: ( - MainIpcChannel -) = new MainIpcChannel(SHOW_UI_PART_CHANNEL); +export const showUiPartChannel: MainIpcChannel< + void, + ShowUiPartRequest +> = new MainIpcChannel(SHOW_UI_PART_CHANNEL); -export const toggleUiPartChannel: ( - MainIpcChannel -) = new MainIpcChannel(TOGGLE_UI_PART_CHANNEL); +export const toggleUiPartChannel: MainIpcChannel< + void, + ToggleUiPartRequest +> = new MainIpcChannel(TOGGLE_UI_PART_CHANNEL); diff --git a/source/main/ipc/download-logs.js b/source/main/ipc/download-logs.js index 53807310ae..9cc2dc539c 100644 --- a/source/main/ipc/download-logs.js +++ b/source/main/ipc/download-logs.js @@ -7,12 +7,13 @@ import type { } from '../../common/ipc/api'; import { DOWNLOAD_LOGS_CHANNEL } from '../../common/ipc/api'; -export const downloadLogsChannel: ( - MainIpcChannel -) = new MainIpcChannel(DOWNLOAD_LOGS_CHANNEL); +export const downloadLogsChannel: MainIpcChannel< + DownloadLogsRequest, + DownloadLogsResponse +> = new MainIpcChannel(DOWNLOAD_LOGS_CHANNEL); export default () => { - downloadLogsChannel.onRequest((request) => { + downloadLogsChannel.onRequest(request => { const { compressedLogsFilePath, destinationPath } = request; if (!fs.existsSync(compressedLogsFilePath)) { diff --git a/source/main/ipc/generatePaperWalletChannel.js b/source/main/ipc/generatePaperWalletChannel.js index 3322c20411..c3069eb632 100644 --- a/source/main/ipc/generatePaperWalletChannel.js +++ b/source/main/ipc/generatePaperWalletChannel.js @@ -7,7 +7,7 @@ import { MainIpcChannel } from './lib/MainIpcChannel'; import { GENERATE_PAPER_WALLET_CHANNEL } from '../../common/ipc/api'; import type { GeneratePaperWalletResponse, - GeneratePaperWalletRequest + GeneratePaperWalletRequest, } from '../../common/ipc/api'; import paperWalletFontPath from '../../common/assets/pdf/paper-wallet-certificate-font.ttf'; import paperWalletPage1Path from '../../common/assets/pdf/paper-wallet-certificate-page-1.png'; @@ -16,129 +16,136 @@ import paperWalletPage2Path from '../../common/assets/pdf/paper-wallet-certifica import paperWalletPage2PathTestnet from '../../common/assets/pdf/paper-wallet-certificate-page-2-testnet.png'; import paperWalletCertificateBgPath from '../../common/assets/pdf/paper-wallet-certificate-background.png'; -export const generatePaperWalletChannel: ( - // IpcChannel - MainIpcChannel -) = ( - new MainIpcChannel(GENERATE_PAPER_WALLET_CHANNEL) -); +export const generatePaperWalletChannel: // IpcChannel +MainIpcChannel< + GeneratePaperWalletRequest, + GeneratePaperWalletResponse +> = new MainIpcChannel(GENERATE_PAPER_WALLET_CHANNEL); export const handlePaperWalletRequests = () => { - generatePaperWalletChannel.onReceive((request: GeneratePaperWalletRequest) => ( - new Promise((resolve, reject) => { - // Prepare params - const { address, mnemonics, buildLabel, filePath, isMainnet, messages } = request; + generatePaperWalletChannel.onReceive( + (request: GeneratePaperWalletRequest) => + new Promise((resolve, reject) => { + // Prepare params + const { + address, + mnemonics, + buildLabel, + filePath, + isMainnet, + messages, + } = request; - // Helpers - const printMnemonic = (index) => `${index + 1}. ${mnemonics[index]}`; - const readAssetSync = (p) => fs.readFileSync(path.join(__dirname, p)); + // Helpers + const printMnemonic = index => `${index + 1}. ${mnemonics[index]}`; + const readAssetSync = p => fs.readFileSync(path.join(__dirname, p)); - // Generate QR image for wallet address - const qrCodeImage = qr.imageSync(address, { - type: 'png', - size: 10, - ec_level: 'L', - margin: 0 - }); - const textColor = '#3b5c9b'; - const width = 595.28; - const height = 841.98; - const doc = new PDFDocument({ - size: [width, height], - margins: { - bottom: 0, - left: 0, - right: 0, - top: 0, - }, - info: { - Title: messages.infoTitle, - Author: messages.infoAuthor, - } - }); - try { - // font family - const fontBuffer = readAssetSync(paperWalletFontPath); - doc.font(fontBuffer); + // Generate QR image for wallet address + const qrCodeImage = qr.imageSync(address, { + type: 'png', + size: 10, + ec_level: 'L', + margin: 0, + }); + const textColor = '#3b5c9b'; + const width = 595.28; + const height = 841.98; + const doc = new PDFDocument({ + size: [width, height], + margins: { + bottom: 0, + left: 0, + right: 0, + top: 0, + }, + info: { + Title: messages.infoTitle, + Author: messages.infoAuthor, + }, + }); + try { + // font family + const fontBuffer = readAssetSync(paperWalletFontPath); + doc.font(fontBuffer); - // background images - const backgroundUri = readAssetSync(paperWalletCertificateBgPath); - doc.image(backgroundUri, 0, 0, { fit: [width, height] }); + // background images + const backgroundUri = readAssetSync(paperWalletCertificateBgPath); + doc.image(backgroundUri, 0, 0, { fit: [width, height] }); - // first page - const page1Uri = readAssetSync( - isMainnet ? paperWalletPage1Path : paperWalletPage1PathTestnet - ); + // first page + const page1Uri = readAssetSync( + isMainnet ? paperWalletPage1Path : paperWalletPage1PathTestnet + ); - doc.image(page1Uri, 0, 0, { fit: [width, height] }); - doc.rotate(180, { origin: [width / 2, height / 2] }); - doc.fillColor(textColor); - doc.fontSize(10).text(messages.walletAddressLabel, 0, 160, { - width: 595, - align: 'center' - }); - doc.image(qrCodeImage, (width / 2) - 80 / 2, 180, { fit: [80, 80] }); - doc.fontSize(8).text(address, (width - 250) / 2, 274, { - width: 250, - align: 'center', - lineGap: 2 - }); + doc.image(page1Uri, 0, 0, { fit: [width, height] }); + doc.rotate(180, { origin: [width / 2, height / 2] }); + doc.fillColor(textColor); + doc.fontSize(10).text(messages.walletAddressLabel, 0, 160, { + width: 595, + align: 'center', + }); + doc.image(qrCodeImage, width / 2 - 80 / 2, 180, { fit: [80, 80] }); + doc.fontSize(8).text(address, (width - 250) / 2, 274, { + width: 250, + align: 'center', + lineGap: 2, + }); - // revert document rotation - doc.rotate(-180, { origin: [width / 2, height / 2] }); + // revert document rotation + doc.rotate(-180, { origin: [width / 2, height / 2] }); - // second page - doc.addPage(); - const page2Uri = readAssetSync( - isMainnet ? paperWalletPage2Path : paperWalletPage2PathTestnet - ); - doc.image(page2Uri, 0, 0, { fit: [width, height] }); - doc.rotate(180, { origin: [width / 2, height / 2] }); - doc.fillColor(textColor); - doc.fontSize(10).text(messages.recoveryPhraseLabel, 0, 535, { - width: 595, - align: 'center' - }); + // second page + doc.addPage(); + const page2Uri = readAssetSync( + isMainnet ? paperWalletPage2Path : paperWalletPage2PathTestnet + ); + doc.image(page2Uri, 0, 0, { fit: [width, height] }); + doc.rotate(180, { origin: [width / 2, height / 2] }); + doc.fillColor(textColor); + doc.fontSize(10).text(messages.recoveryPhraseLabel, 0, 535, { + width: 595, + align: 'center', + }); - // mnemonics - doc.fontSize(7); - doc.text(printMnemonic(0), 168, 560); - doc.text(printMnemonic(1), 212, 560); - doc.text(printMnemonic(2), 256, 560); - doc.text(printMnemonic(3), 300, 560); - doc.text(printMnemonic(4), 344, 560); - doc.text(printMnemonic(5), 388, 560); + // mnemonics + doc.fontSize(7); + doc.text(printMnemonic(0), 168, 560); + doc.text(printMnemonic(1), 212, 560); + doc.text(printMnemonic(2), 256, 560); + doc.text(printMnemonic(3), 300, 560); + doc.text(printMnemonic(4), 344, 560); + doc.text(printMnemonic(5), 388, 560); - doc.text(printMnemonic(6), 168, 581); - doc.text(printMnemonic(7), 212, 581); - doc.text(printMnemonic(8), 256, 581); - doc.text(printMnemonic(9), 300, 581); - doc.text(printMnemonic(10), 344, 581); - doc.text(printMnemonic(11), 388, 581); + doc.text(printMnemonic(6), 168, 581); + doc.text(printMnemonic(7), 212, 581); + doc.text(printMnemonic(8), 256, 581); + doc.text(printMnemonic(9), 300, 581); + doc.text(printMnemonic(10), 344, 581); + doc.text(printMnemonic(11), 388, 581); - doc.text(printMnemonic(12), 168, 602); - doc.text(printMnemonic(13), 212, 602); - doc.text(printMnemonic(14), 256, 602); - doc.text(printMnemonic(15), 300, 602); - doc.text(printMnemonic(16), 344, 602); - doc.text(printMnemonic(17), 388, 602); + doc.text(printMnemonic(12), 168, 602); + doc.text(printMnemonic(13), 212, 602); + doc.text(printMnemonic(14), 256, 602); + doc.text(printMnemonic(15), 300, 602); + doc.text(printMnemonic(16), 344, 602); + doc.text(printMnemonic(17), 388, 602); - doc.fontSize(7).text(buildLabel, (width - 270) / 2, 705, { - width: 270, - align: 'left' - }); + doc.fontSize(7).text(buildLabel, (width - 270) / 2, 705, { + width: 270, + align: 'left', + }); - doc.rotate(-180, { origin: [width / 2, height / 2] }); - } catch (error) { - reject(error); - } + doc.rotate(-180, { origin: [width / 2, height / 2] }); + } catch (error) { + reject(error); + } - // Write file to disk - const writeStream = fs.createWriteStream(filePath); - doc.pipe(writeStream); - doc.end(); - writeStream.on('close', resolve); - writeStream.on('error', reject); - }) - )); + // Write file to disk + const writeStream = fs.createWriteStream(filePath); + doc.pipe(writeStream); + doc.end(); + writeStream.on('close', resolve); + writeStream.on('error', reject); + }) + ); }; diff --git a/source/main/ipc/get-disk-space-status.js b/source/main/ipc/get-disk-space-status.js index 95b310e5f3..929a37d892 100644 --- a/source/main/ipc/get-disk-space-status.js +++ b/source/main/ipc/get-disk-space-status.js @@ -8,8 +8,7 @@ import type { // IpcChannel -export const getDiskSpaceStatusChannel: ( - MainIpcChannel -) = ( - new MainIpcChannel(GET_DISK_SPACE_STATUS_CHANNEL) -); +export const getDiskSpaceStatusChannel: MainIpcChannel< + GetDiskSpaceStatusRendererRequest, + GetDiskSpaceStatusMainResponse +> = new MainIpcChannel(GET_DISK_SPACE_STATUS_CHANNEL); diff --git a/source/main/ipc/get-gpu-status.js b/source/main/ipc/get-gpu-status.js index fd3ab24717..2760419560 100644 --- a/source/main/ipc/get-gpu-status.js +++ b/source/main/ipc/get-gpu-status.js @@ -7,12 +7,13 @@ import type { } from '../../common/ipc/api'; import { GET_GPU_STATUS_CHANNEL } from '../../common/ipc/api'; -export const getGPUStatusChannel: ( - MainIpcChannel -) = new MainIpcChannel(GET_GPU_STATUS_CHANNEL); +export const getGPUStatusChannel: MainIpcChannel< + GetGPUStatusRequest, + GetGPUStatusResponse +> = new MainIpcChannel(GET_GPU_STATUS_CHANNEL); export default () => { - getGPUStatusChannel.onRequest(() => ( + getGPUStatusChannel.onRequest(() => Promise.resolve(app.getGPUFeatureStatus()) - )); + ); }; diff --git a/source/main/ipc/get-logs.js b/source/main/ipc/get-logs.js index 10980bdaa8..0775b8bee2 100644 --- a/source/main/ipc/get-logs.js +++ b/source/main/ipc/get-logs.js @@ -17,26 +17,25 @@ import type { LogFiles } from '../../renderer/app/types/LogTypes'; // IpcChannel -export const getLogsChannel: ( - MainIpcChannel -) = new MainIpcChannel(GET_LOGS_CHANNEL); +export const getLogsChannel: MainIpcChannel< + GetLogsRequest, + GetLogsResponse +> = new MainIpcChannel(GET_LOGS_CHANNEL); const isFileAllowed = (fileName: string) => includes(ALLOWED_LOGS, fileName); -const isFileNodeLog = (fileName: string, nodeLogsIncluded: number) => ( - ALLOWED_NODE_LOGS.test(fileName) && nodeLogsIncluded < MAX_NODE_LOGS_ALLOWED -); +const isFileNodeLog = (fileName: string, nodeLogsIncluded: number) => + ALLOWED_NODE_LOGS.test(fileName) && nodeLogsIncluded < MAX_NODE_LOGS_ALLOWED; -const isFileLauncherLog = (fileName: string, nodeLogsIncluded: number) => ( - ALLOWED_LAUNCHER_LOGS.test(fileName) && nodeLogsIncluded < MAX_LAUNCHER_LOGS_ALLOWED -); +const isFileLauncherLog = (fileName: string, nodeLogsIncluded: number) => + ALLOWED_LAUNCHER_LOGS.test(fileName) && + nodeLogsIncluded < MAX_LAUNCHER_LOGS_ALLOWED; export default () => { getLogsChannel.onRequest(() => { // check if pub folder exists and create array of log file names const logFiles: Array = []; if (fs.existsSync(pubLogsFolderPath)) { - const files = fs .readdirSync(pubLogsFolderPath) .sort() @@ -63,11 +62,14 @@ export default () => { const logs: LogFiles = { path: pubLogsFolderPath, - files: sortBy(logFiles, (log: string): string => { - // custom file sorting which enforces correct ordering (like in ALLOWED_LOGS) - const nameSegments = log.split('.'); - return nameSegments.shift() + nameSegments.join('').length; - }), + files: sortBy( + logFiles, + (log: string): string => { + // custom file sorting which enforces correct ordering (like in ALLOWED_LOGS) + const nameSegments = log.split('.'); + return nameSegments.shift() + nameSegments.join('').length; + } + ), }; return Promise.resolve(logs); diff --git a/source/main/ipc/getNumberOfEpochsConsolidated.ipc.js b/source/main/ipc/getNumberOfEpochsConsolidated.ipc.js index 36b00f09e6..db6764b6d8 100644 --- a/source/main/ipc/getNumberOfEpochsConsolidated.ipc.js +++ b/source/main/ipc/getNumberOfEpochsConsolidated.ipc.js @@ -5,8 +5,7 @@ import type { GetConsolidatedEpochsCountResponse } from '../../common/ipc/api'; // IpcChannel -export const getNumberOfEpochsConsolidatedChannel: ( - MainIpcChannel -) = ( - new MainIpcChannel(GET_CONSOLIDATED_EPOCHS_COUNT_CHANNEL) -); +export const getNumberOfEpochsConsolidatedChannel: MainIpcChannel< + void, + GetConsolidatedEpochsCountResponse +> = new MainIpcChannel(GET_CONSOLIDATED_EPOCHS_COUNT_CHANNEL); diff --git a/source/main/ipc/getSystemStartTime.ipc.js b/source/main/ipc/getSystemStartTime.ipc.js index 4a8bb310aa..9fdc24fc60 100644 --- a/source/main/ipc/getSystemStartTime.ipc.js +++ b/source/main/ipc/getSystemStartTime.ipc.js @@ -5,8 +5,7 @@ import type { GetSystemStartTimeResponse } from '../../common/ipc/api'; // IpcChannel -export const getSystemStartTimeChannel: ( - MainIpcChannel -) = ( - new MainIpcChannel(GET_SYSTEM_START_TIME_CHANNEL) -); +export const getSystemStartTimeChannel: MainIpcChannel< + void, + GetSystemStartTimeResponse +> = new MainIpcChannel(GET_SYSTEM_START_TIME_CHANNEL); diff --git a/source/main/ipc/lib/MainIpcChannel.js b/source/main/ipc/lib/MainIpcChannel.js index c28e3b141a..5e41a0ccc8 100644 --- a/source/main/ipc/lib/MainIpcChannel.js +++ b/source/main/ipc/lib/MainIpcChannel.js @@ -1,21 +1,30 @@ // @flow import { ipcMain } from 'electron'; import { IpcChannel } from '../../../common/ipc/lib/IpcChannel'; -import type { IpcReceiver, IpcSender } from '../../../common/ipc/lib/IpcChannel'; +import type { + IpcReceiver, + IpcSender, +} from '../../../common/ipc/lib/IpcChannel'; /** * Subclass of IpcChannel that uses ipcMain to receive messages. */ -export class MainIpcChannel extends IpcChannel { - +export class MainIpcChannel extends IpcChannel< + Incoming, + Outgoing +> { async send( - message: Outgoing, sender: IpcSender, receiver: IpcReceiver = ipcMain + message: Outgoing, + sender: IpcSender, + receiver: IpcReceiver = ipcMain ): Promise { return super.send(message, sender, receiver); } async request( - message: Outgoing, sender: IpcSender, receiver: IpcReceiver = ipcMain + message: Outgoing, + sender: IpcSender, + receiver: IpcReceiver = ipcMain ): Promise { return super.request(message, sender, receiver); } @@ -28,9 +37,9 @@ export class MainIpcChannel extends IpcChannel Promise, receiver: IpcReceiver = ipcMain + handler: Incoming => Promise, + receiver: IpcReceiver = ipcMain ): void { super.onRequest(handler, receiver); } - } diff --git a/source/main/ipc/load-asset.js b/source/main/ipc/load-asset.js index 866fa33d33..bf3c0e4dd7 100644 --- a/source/main/ipc/load-asset.js +++ b/source/main/ipc/load-asset.js @@ -5,18 +5,21 @@ import { MainIpcChannel } from './lib/MainIpcChannel'; import { LOAD_ASSET_CHANNEL } from '../../common/ipc/api'; import type { LoadAssetRendererRequest, - LoadAssetMainResponse + LoadAssetMainResponse, } from '../../common/ipc/api'; -const loadAssetChannel: ( - MainIpcChannel -) = (new MainIpcChannel(LOAD_ASSET_CHANNEL)); +const loadAssetChannel: MainIpcChannel< + LoadAssetRendererRequest, + LoadAssetMainResponse +> = new MainIpcChannel(LOAD_ASSET_CHANNEL); export default () => { loadAssetChannel.onRequest((request: LoadAssetRendererRequest) => { const asset = path.resolve(__dirname, `../renderer/${request.fileName}`); - return new Promise((resolve, reject) => ( - fs.readFile(asset, 'base64', (error, data) => { error ? reject(error) : resolve(data); }) - )); + return new Promise((resolve, reject) => + fs.readFile(asset, 'base64', (error, data) => { + error ? reject(error) : resolve(data); + }) + ); }); }; diff --git a/source/main/ipc/open-external-url.js b/source/main/ipc/open-external-url.js index b1b0a6afe5..e0b2395a40 100644 --- a/source/main/ipc/open-external-url.js +++ b/source/main/ipc/open-external-url.js @@ -9,12 +9,11 @@ import type { // IpcChannel -export const openExternalUrlChannel: ( - MainIpcChannel -) = ( - new MainIpcChannel(OPEN_EXTERNAL_URL_CHANNEL) -); +export const openExternalUrlChannel: MainIpcChannel< + OpenExternalUrlRequest, + OpenExternalUrlResponse +> = new MainIpcChannel(OPEN_EXTERNAL_URL_CHANNEL); -openExternalUrlChannel.onReceive((url: OpenExternalUrlRequest) => ( +openExternalUrlChannel.onReceive((url: OpenExternalUrlRequest) => shell.openExternal(url) ? Promise.resolve() : Promise.reject() -)); +); diff --git a/source/main/ipc/parse-redemption-code.js b/source/main/ipc/parse-redemption-code.js index f3d1531bf1..72ee61ed00 100644 --- a/source/main/ipc/parse-redemption-code.js +++ b/source/main/ipc/parse-redemption-code.js @@ -10,7 +10,7 @@ import { } from '../../common/crypto/decrypt'; import type { ParseRedemptionCodeRequest, - ParseRedemptionCodeResponse + ParseRedemptionCodeResponse, } from '../../common/ipc/api'; import { MainIpcChannel } from './lib/MainIpcChannel'; import { PARSE_REDEMPTION_CODE_CHANNEL } from '../../common/ipc/api'; @@ -22,17 +22,22 @@ import { ERRORS } from '../../common/ipc/constants'; const cleanupTemporaryPDF = (pdfPath, isTemporaryDecryptedPdf) => { // Remove the temporary, decrypted PDF from disk if (pdfPath && isTemporaryDecryptedPdf) { - try { fs.unlinkSync(pdfPath); } catch (e) {} // eslint-disable-line + try { + fs.unlinkSync(pdfPath); + } catch (e) {} // eslint-disable-line } }; // CHANNEL -const parseRedemptionCodeChannel: ( - MainIpcChannel -) = new MainIpcChannel(PARSE_REDEMPTION_CODE_CHANNEL); +const parseRedemptionCodeChannel: MainIpcChannel< + ParseRedemptionCodeRequest, + ParseRedemptionCodeResponse +> = new MainIpcChannel(PARSE_REDEMPTION_CODE_CHANNEL); // REQUEST HANDLER -const parseRedemptionCodeHandler = async (request: ParseRedemptionCodeRequest) => { +const parseRedemptionCodeHandler = async ( + request: ParseRedemptionCodeRequest +) => { Logger.debug('parseRedemptionCodeHandler', request); const { certificateFilePath, decryptionKey, redemptionType } = request; let pdfPath = null; @@ -48,12 +53,19 @@ const parseRedemptionCodeHandler = async (request: ParseRedemptionCodeRequest) = decryptedFile = decryptForceVend(decryptionKey, encryptedFile); break; case 'recoveryRegular': - decryptedFile = decryptRecoveryRegularVend(decryptionKey, encryptedFile); + decryptedFile = decryptRecoveryRegularVend( + decryptionKey, + encryptedFile + ); break; case 'recoveryForceVended': - decryptedFile = decryptRecoveryForceVend(decryptionKey, encryptedFile); + decryptedFile = decryptRecoveryForceVend( + decryptionKey, + encryptedFile + ); break; - default: // regular + default: + // regular decryptedFile = decryptRegularVend(decryptionKey, encryptedFile); } // Write it to disk temporarily (so pdf extract can work with it) @@ -76,8 +88,8 @@ const parseRedemptionCodeHandler = async (request: ParseRedemptionCodeRequest) = try { const redemptionKeyLabel = data.pages[0].content[9].str; if ( - redemptionKeyLabel !== 'REDEMPTION KEY' - && redemptionKeyLabel !== '—————— REDEMPTION KEY ——————' + redemptionKeyLabel !== 'REDEMPTION KEY' && + redemptionKeyLabel !== '—————— REDEMPTION KEY ——————' ) { Logger.error('Incalid redemption certificate', request); reject(ERRORS.INVALID_REDEMPTION_CERTIFICATE_ERROR); diff --git a/source/main/ipc/rebuild-application-menu.js b/source/main/ipc/rebuild-application-menu.js index 4543cf1a42..a498c46e38 100644 --- a/source/main/ipc/rebuild-application-menu.js +++ b/source/main/ipc/rebuild-application-menu.js @@ -2,9 +2,5 @@ import { MainIpcChannel } from './lib/MainIpcChannel'; import { REBUILD_APP_MENU_CHANNEL } from '../../common/ipc/api'; -export const rebuildApplicationMenu: ( - // IpcChannel - MainIpcChannel -) = ( - new MainIpcChannel(REBUILD_APP_MENU_CHANNEL) -); +export const rebuildApplicationMenu: // IpcChannel +MainIpcChannel = new MainIpcChannel(REBUILD_APP_MENU_CHANNEL); diff --git a/source/main/menus/osx.js b/source/main/menus/osx.js index b58d137305..2b38be6cd4 100644 --- a/source/main/menus/osx.js +++ b/source/main/menus/osx.js @@ -13,94 +13,111 @@ export const osxMenu = ( isInSafeMode: boolean, translations: {}, translation: Function = getTranslation(translations, id) -) => ( - [{ +) => [ + { label: translation('daedalus'), - submenu: compact([{ - label: translation('daedalus.about'), - click() { - actions.openAbout(); - }, - }, { - label: translation('daedalus.adaRedemption'), - click() { - actions.goToAdaRedemption(); - } - }, { - label: translation('daedalus.gpuSafeMode'), - type: 'checkbox', - checked: isInSafeMode, - click() { - isInSafeMode ? - actions.restartWithoutSafeMode() : - actions.restartInSafeMode(); - }, - }, { - label: translation('daedalus.blockConsolidationStatus'), - accelerator: 'Command+B', - click() { - actions.goBlockConsolidationStatus(); - }, - }, { - label: translation('daedalus.networkStatus'), - accelerator: 'Command+S', - click() { - actions.openNetworkStatus(); - }, - }, { - label: translation('daedalus.quit'), - accelerator: 'Command+Q', - click() { - app.quit(); - } - }]) - }, { + submenu: compact([ + { + label: translation('daedalus.about'), + click() { + actions.openAbout(); + }, + }, + { + label: translation('daedalus.adaRedemption'), + click() { + actions.goToAdaRedemption(); + }, + }, + { + label: translation('daedalus.gpuSafeMode'), + type: 'checkbox', + checked: isInSafeMode, + click() { + isInSafeMode + ? actions.restartWithoutSafeMode() + : actions.restartInSafeMode(); + }, + }, + { + label: translation('daedalus.blockConsolidationStatus'), + accelerator: 'Command+B', + click() { + actions.goBlockConsolidationStatus(); + }, + }, + { + label: translation('daedalus.networkStatus'), + accelerator: 'Command+S', + click() { + actions.openNetworkStatus(); + }, + }, + { + label: translation('daedalus.quit'), + accelerator: 'Command+Q', + click() { + app.quit(); + }, + }, + ]), + }, + { label: translation('edit'), - submenu: [{ - label: translation('edit.undo'), - accelerator: 'Command+Z', - role: 'undo' - }, { - label: translation('edit.redo'), - accelerator: 'Shift+Command+Z', - role: 'redo' - }, { - type: 'separator' - }, { - label: translation('edit.cut'), - accelerator: 'Command+X', - role: 'cut' - }, { - label: translation('edit.copy'), - accelerator: 'Command+C', - role: 'copy' - }, { - label: translation('edit.paste'), - accelerator: 'Command+V', - role: 'paste' - }, { - label: translation('edit.selectAll'), - accelerator: 'Command+A', - role: 'selectall' - }] - }, { + submenu: [ + { + label: translation('edit.undo'), + accelerator: 'Command+Z', + role: 'undo', + }, + { + label: translation('edit.redo'), + accelerator: 'Shift+Command+Z', + role: 'redo', + }, + { + type: 'separator', + }, + { + label: translation('edit.cut'), + accelerator: 'Command+X', + role: 'cut', + }, + { + label: translation('edit.copy'), + accelerator: 'Command+C', + role: 'copy', + }, + { + label: translation('edit.paste'), + accelerator: 'Command+V', + role: 'paste', + }, + { + label: translation('edit.selectAll'), + accelerator: 'Command+A', + role: 'selectall', + }, + ], + }, + { label: translation('view'), submenu: [ { label: translation('view.reload'), accelerator: 'Command+R', - click: () => window.webContents.reload() + click: () => window.webContents.reload(), }, { label: translation('view.toggleFullScreen'), accelerator: 'Ctrl+Command+F', - click: () => window.setFullScreen(!window.isFullScreen()) + click: () => window.setFullScreen(!window.isFullScreen()), }, { label: translation('view.toggleDeveloperTools'), accelerator: 'Alt+Command+I', - click: () => window.toggleDevTools() - } - ] - }] -); + click: () => window.toggleDevTools(), + }, + ], + }, +]; diff --git a/source/main/menus/win-linux.js b/source/main/menus/win-linux.js index 61007aafd2..9cc0e08962 100644 --- a/source/main/menus/win-linux.js +++ b/source/main/menus/win-linux.js @@ -14,104 +14,129 @@ export const winLinuxMenu = ( isInSafeMode: boolean, translations: {}, translation: Function = getTranslation(translations, id) -) => ( - [{ +) => [ + { label: translation('daedalus'), - submenu: compact([{ - label: translation('daedalus.about'), - click() { - actions.openAbout(); - } - }, { - label: translation('daedalus.adaRedemption'), - click() { - actions.goToAdaRedemption(); - } - }, { - label: translation('daedalus.gpuSafeMode'), - type: 'checkbox', - checked: isInSafeMode, - click() { - isInSafeMode ? - actions.restartWithoutSafeMode() : - actions.restartInSafeMode(); + submenu: compact([ + { + label: translation('daedalus.about'), + click() { + actions.openAbout(); + }, + }, + { + label: translation('daedalus.adaRedemption'), + click() { + actions.goToAdaRedemption(); + }, + }, + { + label: translation('daedalus.gpuSafeMode'), + type: 'checkbox', + checked: isInSafeMode, + click() { + isInSafeMode + ? actions.restartWithoutSafeMode() + : actions.restartInSafeMode(); + }, + }, + { + label: translation('daedalus.blockConsolidationStatus'), + accelerator: 'Ctrl+B', + click() { + actions.goBlockConsolidationStatus(); + }, }, - }, { - label: translation('daedalus.blockConsolidationStatus'), - accelerator: 'Ctrl+B', - click() { - actions.goBlockConsolidationStatus(); + { + label: translation('daedalus.networkStatus'), + accelerator: 'Ctrl+S', + click() { + actions.openNetworkStatus(); + }, }, - }, { - label: translation('daedalus.networkStatus'), - accelerator: 'Ctrl+S', - click() { - actions.openNetworkStatus(); + { + label: translation('daedalus.close'), + accelerator: 'Ctrl+W', + click() { + app.quit(); + }, }, - }, { - label: translation('daedalus.close'), - accelerator: 'Ctrl+W', - click() { - app.quit(); - } - }]) - }, { + ]), + }, + { label: translation('edit'), - submenu: [{ - label: translation('edit.undo'), - accelerator: 'Ctrl+Z', - role: 'undo' - }, { - label: translation('edit.redo'), - accelerator: 'Shift+Ctrl+Z', - role: 'redo' - }, { - type: 'separator' - }, { - label: translation('edit.cut'), - accelerator: 'Ctrl+X', - role: 'cut' - }, { - label: translation('edit.copy'), - accelerator: 'Ctrl+C', - role: 'copy' - }, { - label: translation('edit.paste'), - accelerator: 'Ctrl+V', - role: 'paste' - }, { - label: translation('edit.selectAll'), - accelerator: 'Ctrl+A', - role: 'selectall' - }] - }, { + submenu: [ + { + label: translation('edit.undo'), + accelerator: 'Ctrl+Z', + role: 'undo', + }, + { + label: translation('edit.redo'), + accelerator: 'Shift+Ctrl+Z', + role: 'redo', + }, + { + type: 'separator', + }, + { + label: translation('edit.cut'), + accelerator: 'Ctrl+X', + role: 'cut', + }, + { + label: translation('edit.copy'), + accelerator: 'Ctrl+C', + role: 'copy', + }, + { + label: translation('edit.paste'), + accelerator: 'Ctrl+V', + role: 'paste', + }, + { + label: translation('edit.selectAll'), + accelerator: 'Ctrl+A', + role: 'selectall', + }, + ], + }, + { label: translation('view'), submenu: [ { label: translation('view.reload'), accelerator: 'Ctrl+R', - click() { window.webContents.reload(); } - }, - environment.isWindows ? { - label: translation('view.toggleFullScreen'), - accelerator: 'F11', - click() { window.setFullScreen(!window.isFullScreen()); } - } : { - label: translation('view.toggleMaximumWindowSize'), - accelerator: 'F11', click() { - if (window.isMaximized()) { - window.unmaximize(); - } else { - window.maximize(); - } - } + window.webContents.reload(); + }, }, + environment.isWindows + ? { + label: translation('view.toggleFullScreen'), + accelerator: 'F11', + click() { + window.setFullScreen(!window.isFullScreen()); + }, + } + : { + label: translation('view.toggleMaximumWindowSize'), + accelerator: 'F11', + click() { + if (window.isMaximized()) { + window.unmaximize(); + } else { + window.maximize(); + } + }, + }, { label: translation('view.toggleDeveloperTools'), accelerator: 'Alt+Ctrl+I', - click() { window.toggleDevTools(); } - } - ] - }] -); + click() { + window.toggleDevTools(); + }, + }, + ], + }, +]; diff --git a/source/main/preload.js b/source/main/preload.js index 04b5207999..d69f2b3e6f 100644 --- a/source/main/preload.js +++ b/source/main/preload.js @@ -1,10 +1,7 @@ // @flow import os from 'os'; import _https from 'https'; -import { - ipcRenderer as _ipcRenderer, - remote as _remote -} from 'electron'; +import { ipcRenderer as _ipcRenderer, remote as _remote } from 'electron'; import _electronLog from 'electron-log'; import ElectronStore from 'electron-store'; import { environment } from './environment'; @@ -59,13 +56,20 @@ process.once('loaded', () => { if (_process.env.NODE_ENV === 'production') { // elements that can be copied using the context menu (right click), // must have a css property of user-select: 'text' or be an input element - global.document.addEventListener('contextmenu', event => { - const targetIsSelectable = getComputedStyle(event.target).userSelect === 'text'; - const targetIsInput = event.target.nodeName === 'INPUT'; + global.document.addEventListener( + 'contextmenu', + event => { + const targetIsSelectable = + getComputedStyle(event.target).userSelect === 'text'; + const targetIsInput = event.target.nodeName === 'INPUT'; - if (targetIsSelectable || targetIsInput) { return true; } + if (targetIsSelectable || targetIsInput) { + return true; + } - event.preventDefault(); - }, false); + event.preventDefault(); + }, + false + ); } }); diff --git a/source/main/utils/buildAppMenus.js b/source/main/utils/buildAppMenus.js index 7aeeeb7ce9..f25c8564f9 100644 --- a/source/main/utils/buildAppMenus.js +++ b/source/main/utils/buildAppMenus.js @@ -7,21 +7,24 @@ import { Logger } from './logging'; import { safeExitWithCode } from './safeExitWithCode'; import { CardanoNode } from '../cardano/CardanoNode'; import { DIALOGS, SCREENS } from '../../common/ipc/constants'; -import { toggleUiPartChannel, showUiPartChannel } from '../ipc/control-ui-parts'; +import { + toggleUiPartChannel, + showUiPartChannel, +} from '../ipc/control-ui-parts'; export const buildAppMenus = async ( mainWindow: BrowserWindow, cardanoNode: ?CardanoNode, isInSafeMode: boolean, - locale: string, + locale: string ) => { - const openAbout = () => { if (mainWindow) toggleUiPartChannel.send(DIALOGS.ABOUT, mainWindow); }; const openNetworkStatus = () => { - if (mainWindow) toggleUiPartChannel.send(DIALOGS.NETWORK_STATUS, mainWindow); + if (mainWindow) + toggleUiPartChannel.send(DIALOGS.NETWORK_STATUS, mainWindow); }; const goToAdaRedemption = () => { @@ -29,7 +32,8 @@ export const buildAppMenus = async ( }; const goBlockConsolidationStatus = () => { - if (mainWindow) toggleUiPartChannel.send(SCREENS.BLOCK_CONSOLIDATION, mainWindow); + if (mainWindow) + toggleUiPartChannel.send(SCREENS.BLOCK_CONSOLIDATION, mainWindow); }; const restartInSafeMode = async () => { @@ -85,5 +89,4 @@ export const buildAppMenus = async ( globalShortcut.unregister('CommandOrControl+H'); }); } - }; diff --git a/source/main/utils/config.js b/source/main/utils/config.js index b64cdb3b89..7d25ea503b 100644 --- a/source/main/utils/config.js +++ b/source/main/utils/config.js @@ -10,14 +10,12 @@ import type { LauncherConfig } from '../config'; */ export const readLauncherConfig = (configPath: ?string): LauncherConfig => { const inputYaml = configPath ? readFileSync(configPath, 'utf8') : ''; - const finalYaml = inputYaml.replace(/\${([^}]+)}/g, - (a, b) => { - if (process.env[b]) { - return process.env[b]; - } - console.log('readLauncherConfig: warning var undefined:', b); - return ''; + const finalYaml = inputYaml.replace(/\${([^}]+)}/g, (a, b) => { + if (process.env[b]) { + return process.env[b]; } - ); + console.log('readLauncherConfig: warning var undefined:', b); + return ''; + }); return yamljs.parse(finalYaml); }; diff --git a/source/main/utils/getLocale.js b/source/main/utils/getLocale.js index 30fad67350..c28162854a 100644 --- a/source/main/utils/getLocale.js +++ b/source/main/utils/getLocale.js @@ -7,7 +7,9 @@ export const getLocale = (network: string) => { const english = 'en-US'; try { const locale = store.get(`${network}-USER-LOCALE`); - if (locale) { return locale; } + if (locale) { + return locale; + } return english; } catch (error) { return english; diff --git a/source/main/utils/getNumberOfEpochsConsolidated.js b/source/main/utils/getNumberOfEpochsConsolidated.js index 5cdda166ae..c6f77580fe 100644 --- a/source/main/utils/getNumberOfEpochsConsolidated.js +++ b/source/main/utils/getNumberOfEpochsConsolidated.js @@ -6,8 +6,8 @@ import { getNumberOfEpochsConsolidatedChannel } from '../ipc/getNumberOfEpochsCo import type { GetConsolidatedEpochsCountResponse } from '../../common/ipc/api'; export const getNumberOfEpochsConsolidated = () => { - getNumberOfEpochsConsolidatedChannel - .onRequest((): Promise => { + getNumberOfEpochsConsolidatedChannel.onRequest( + (): Promise => { const epochsPath = path.join(nodeDbPath, 'epochs'); let latestConsolidatedEpoch = 0; if (fs.existsSync(epochsPath)) { @@ -15,8 +15,10 @@ export const getNumberOfEpochsConsolidated = () => { .readdirSync(epochsPath) .filter(file => file.indexOf('.epoch') > -1) .map(file => parseInt(file.split('.').shift(), 10)); - if (epochfiles.length) latestConsolidatedEpoch = Math.max(...epochfiles); + if (epochfiles.length) + latestConsolidatedEpoch = Math.max(...epochfiles); } return Promise.resolve(latestConsolidatedEpoch); - }); + } + ); }; diff --git a/source/main/utils/getTranslation.js b/source/main/utils/getTranslation.js index 7ee94d43a7..0195252b63 100644 --- a/source/main/utils/getTranslation.js +++ b/source/main/utils/getTranslation.js @@ -1,8 +1,3 @@ // @flow -export const getTranslation = -( - translations: {}, - id: string, -) => ( - key: string -) => translations[`${id}.${key}`]; +export const getTranslation = (translations: {}, id: string) => (key: string) => + translations[`${id}.${key}`]; diff --git a/source/main/utils/handleDiskSpace.js b/source/main/utils/handleDiskSpace.js index ddbe01212a..5f01ce4c77 100644 --- a/source/main/utils/handleDiskSpace.js +++ b/source/main/utils/handleDiskSpace.js @@ -11,12 +11,12 @@ import { DISK_SPACE_CHECK_LONG_INTERVAL, DISK_SPACE_CHECK_MEDIUM_INTERVAL, DISK_SPACE_CHECK_SHORT_INTERVAL, - DISK_SPACE_RECOMMENDED_PERCENTAGE + DISK_SPACE_RECOMMENDED_PERCENTAGE, } from '../config'; export const handleDiskSpace = ( mainWindow: BrowserWindow, - onCheckDiskSpace?: Function, + onCheckDiskSpace?: Function ) => { const path = environment.isWindows ? 'C:' : '/'; let diskSpaceCheckInterval; @@ -25,12 +25,19 @@ export const handleDiskSpace = ( const handleCheckDiskSpace = async (forceDiskSpaceRequired?: number) => { const diskSpaceRequired = forceDiskSpaceRequired || DISK_SPACE_REQUIRED; - const { free: diskSpaceAvailable, size: diskTotalSpace } = await checkDiskSpace(path); - const diskSpaceMissing = Math.max((diskSpaceRequired - diskSpaceAvailable), 0); + const { + free: diskSpaceAvailable, + size: diskTotalSpace, + } = await checkDiskSpace(path); + const diskSpaceMissing = Math.max( + diskSpaceRequired - diskSpaceAvailable, + 0 + ); const diskSpaceRecommended = - diskTotalSpace * DISK_SPACE_RECOMMENDED_PERCENTAGE / 100; + (diskTotalSpace * DISK_SPACE_RECOMMENDED_PERCENTAGE) / 100; const diskSpaceRequiredMargin = - diskSpaceRequired - (diskSpaceRequired * DISK_SPACE_REQUIRED_MARGIN_PERCENTAGE / 100); + diskSpaceRequired - + (diskSpaceRequired * DISK_SPACE_REQUIRED_MARGIN_PERCENTAGE) / 100; if (diskSpaceAvailable <= diskSpaceRequiredMargin) { if (!isNotEnoughDiskSpace) { @@ -39,14 +46,17 @@ export const handleDiskSpace = ( isNotEnoughDiskSpace = true; } } else if (diskSpaceAvailable >= diskSpaceRequired) { - const newDiskSpaceCheckIntervalLength = ((diskSpaceAvailable >= diskSpaceRequired * 2) ? - DISK_SPACE_CHECK_LONG_INTERVAL : DISK_SPACE_CHECK_MEDIUM_INTERVAL - ); + const newDiskSpaceCheckIntervalLength = + diskSpaceAvailable >= diskSpaceRequired * 2 + ? DISK_SPACE_CHECK_LONG_INTERVAL + : DISK_SPACE_CHECK_MEDIUM_INTERVAL; if (isNotEnoughDiskSpace) { // State change: transitioning from not-enough to enough disk space setDiskSpaceIntervalChecking(newDiskSpaceCheckIntervalLength); isNotEnoughDiskSpace = false; - } else if (newDiskSpaceCheckIntervalLength !== diskSpaceCheckIntervalLength) { + } else if ( + newDiskSpaceCheckIntervalLength !== diskSpaceCheckIntervalLength + ) { // Interval change: transitioning from medium to long interval (or vice versa) // This is a special case in which we adjust the disk space check polling interval: // - more than 2x of available space than required: LONG interval @@ -61,25 +71,27 @@ export const handleDiskSpace = ( diskSpaceMissing: prettysize(diskSpaceMissing), diskSpaceRecommended: prettysize(diskSpaceRecommended), }; - if (isNotEnoughDiskSpace) Logger.info('Not enough disk space', { response }); + if (isNotEnoughDiskSpace) + Logger.info('Not enough disk space', { response }); if (typeof onCheckDiskSpace === 'function') onCheckDiskSpace(response); getDiskSpaceStatusChannel.send(response, mainWindow.webContents); return response; }; - const setDiskSpaceIntervalChecking = (interval) => { + const setDiskSpaceIntervalChecking = interval => { clearInterval(diskSpaceCheckInterval); - diskSpaceCheckInterval = - setInterval(async () => { - handleCheckDiskSpace(); - }, interval); + diskSpaceCheckInterval = setInterval(async () => { + handleCheckDiskSpace(); + }, interval); diskSpaceCheckIntervalLength = interval; }; // Start default interval setDiskSpaceIntervalChecking(diskSpaceCheckIntervalLength); - getDiskSpaceStatusChannel.onReceive(diskSpaceRequired => handleCheckDiskSpace(diskSpaceRequired)); + getDiskSpaceStatusChannel.onReceive(diskSpaceRequired => + handleCheckDiskSpace(diskSpaceRequired) + ); return handleCheckDiskSpace; }; diff --git a/source/main/utils/installChromeExtensions.js b/source/main/utils/installChromeExtensions.js index 843ab1c021..e9e2e0ccd2 100644 --- a/source/main/utils/installChromeExtensions.js +++ b/source/main/utils/installChromeExtensions.js @@ -3,9 +3,7 @@ export const installChromeExtensions = async (isDev: boolean) => { if (isDev) { const installer = require('electron-devtools-installer'); // eslint-disable-line global-require - const extensions = [ - 'REACT_DEVELOPER_TOOLS', - ]; + const extensions = ['REACT_DEVELOPER_TOOLS']; const forceDownload = !!process.env.UPGRADE_EXTENSIONS; for (const name of extensions) { try { diff --git a/source/main/utils/logging.js b/source/main/utils/logging.js index e4c7582da2..5f79d08038 100644 --- a/source/main/utils/logging.js +++ b/source/main/utils/logging.js @@ -22,9 +22,12 @@ const environmentData = { version, }; -const logToLevel = (level: string) => (message: string, data: ?Object) => ( - log[level](formatContext({ ...messageContext, level }), { message, data, environmentData }) -); +const logToLevel = (level: string) => (message: string, data: ?Object) => + log[level](formatContext({ ...messageContext, level }), { + message, + data, + environmentData, + }); export const Logger = { debug: logToLevel('debug'), diff --git a/source/main/utils/mainErrorHandler.js b/source/main/utils/mainErrorHandler.js index cabb678bde..c810433a1a 100644 --- a/source/main/utils/mainErrorHandler.js +++ b/source/main/utils/mainErrorHandler.js @@ -9,7 +9,7 @@ export default (onError?: Function) => { unhandled({ logger: (error: any) => Logger.error('unhandledException::main', { error }), - showDialog: false + showDialog: false, }); process.on('uncaughtException', (error: any) => { @@ -19,6 +19,11 @@ export default (onError?: Function) => { }); app.on('gpu-process-crashed', (event: any, killed: boolean) => { - Logger.error(`uncaughtException::gpu-process-crashed: ${killed ? 'killed' : 'not-killed'}`, { error: event }); + Logger.error( + `uncaughtException::gpu-process-crashed: ${ + killed ? 'killed' : 'not-killed' + }`, + { error: event } + ); }); }; diff --git a/source/main/utils/processes.js b/source/main/utils/processes.js index 642acf4846..3df6ef1c5e 100644 --- a/source/main/utils/processes.js +++ b/source/main/utils/processes.js @@ -16,29 +16,35 @@ export const getProcessById = async (processId: number): Promise => { // retrieves all running processes const processes: Array = await psList(); // filters running processes against previous PID - const matches: Array = processes.filter(({ pid }) => processId === pid); + const matches: Array = processes.filter( + ({ pid }) => processId === pid + ); return matches.length > 0 ? matches[0] : Promise.reject(); }; -export const getProcessName = async (processId: number) => ( - (await getProcessById(processId)).name -); +export const getProcessName = async (processId: number) => + (await getProcessById(processId)).name; -export const getProcessesByName = async (processName: string): Promise> => { +export const getProcessesByName = async ( + processName: string +): Promise> => { // retrieves all running processes const processes: Array = await psList(); // filters running processes against previous PID return processes.filter(({ name }) => processName === name); }; -export const getProcess = async (processId: number, processName: string): Promise => { +export const getProcess = async ( + processId: number, + processName: string +): Promise => { try { // retrieves all running processes const runningProcesses: Array = await psList(); // filters running processes against given pid - const matchingProcesses: Array = runningProcesses.filter(({ pid }) => ( - pid === processId - )); + const matchingProcesses: Array = runningProcesses.filter( + ({ pid }) => pid === processId + ); // no processes exist with a matching PID if (!matchingProcesses.length) return null; // Return first matching process if names match diff --git a/source/main/utils/rendererErrorHandler.js b/source/main/utils/rendererErrorHandler.js index d3174a81bb..0f09b16324 100644 --- a/source/main/utils/rendererErrorHandler.js +++ b/source/main/utils/rendererErrorHandler.js @@ -4,8 +4,9 @@ import unhandled from 'electron-unhandled'; import { Logger } from './logging'; unhandled({ - logger: (error: any) => Logger.error('unhandledException::renderer', { error }), - showDialog: false + logger: (error: any) => + Logger.error('unhandledException::renderer', { error }), + showDialog: false, }); export default class RendererErrorHandler { diff --git a/source/main/utils/setupLogging.js b/source/main/utils/setupLogging.js index 931a0e4891..146353da5d 100644 --- a/source/main/utils/setupLogging.js +++ b/source/main/utils/setupLogging.js @@ -4,12 +4,16 @@ import path from 'path'; import log from 'electron-log'; import ensureDirectoryExists from './ensureDirectoryExists'; import { pubLogsFolderPath, appLogsFolderPath, APP_NAME } from '../config'; -import { constructMessageBody, formatMessage, stringifyData } from '../../common/utils/logging'; +import { + constructMessageBody, + formatMessage, + stringifyData, +} from '../../common/utils/logging'; import { isFileNameWithTimestamp } from '../../common/utils/files'; import type { ConstructMessageBodyParams, MessageBody, - LogSystemInfoParams + LogSystemInfoParams, } from '../../common/types/logging.types'; const isTest = process.env.NODE_ENV === 'test'; @@ -23,7 +27,8 @@ export const setupLogging = () => { log.transports.file.level = 'debug'; log.transports.file.maxSize = 20 * 1024 * 1024; log.transports.file.file = logFilePath; - log.transports.console.format = (message: Object): string => formatMessage(message); + log.transports.console.format = (message: Object): string => + formatMessage(message); log.transports.file.format = (message: Object): string => { // Debug level logging is recorded as "info" in Daedalus log files @@ -43,36 +48,40 @@ export const setupLogging = () => { if (typeof data === 'string') { messageBody = { ...messageBody, data: { response: data } }; } - return `[${year}T${time.slice(0, -1)}Z] ${context} ${stringifyData(messageBody)}`; + return `[${year}T${time.slice(0, -1)}Z] ${context} ${stringifyData( + messageBody + )}`; }; // Removes existing compressed logs fs.readdir(appLogsFolderPath, (err, files) => { - files - .filter(isFileNameWithTimestamp()) - .forEach((logFileName) => { - const logFile = path.join(appLogsFolderPath, logFileName); - try { - fs.unlinkSync(logFile); - } catch (error) { - console.error(`Compressed log file "${logFile}" deletion failed: ${error}`); - } - }); + files.filter(isFileNameWithTimestamp()).forEach(logFileName => { + const logFile = path.join(appLogsFolderPath, logFileName); + try { + fs.unlinkSync(logFile); + } catch (error) { + console.error( + `Compressed log file "${logFile}" deletion failed: ${error}` + ); + } + }); }); }; export const logSystemInfo = (props: LogSystemInfoParams): MessageBody => { const { current, ...data } = props; - const { network, osName, platformVersion, daedalusVersion, startTime: at } = data; + const { + network, + osName, + platformVersion, + daedalusVersion, + startTime: at, + } = data; const env = `${network}:${osName}:${platformVersion}:${daedalusVersion}`; const messageBodyParams: ConstructMessageBodyParams = { at, env, - ns: [ - 'daedalus', - `v${daedalusVersion}`, - `*${current}*`, - ], + ns: ['daedalus', `v${daedalusVersion}`, `*${current}*`], data, msg: 'Updating System-info.json file', pid: '', diff --git a/source/main/webpack.config.js b/source/main/webpack.config.js index 3996c86226..e1e3f1a3d3 100644 --- a/source/main/webpack.config.js +++ b/source/main/webpack.config.js @@ -37,17 +37,13 @@ module.exports = { test: /\.jsx?$/, include: /source/, exclude: /source\/renderer/, - use: (isCi ? [] : [ - 'cache-loader', - ]).concat([ - 'babel-loader' - ]), + use: (isCi ? [] : ['cache-loader']).concat(['babel-loader']), }, { test: /(pdfkit|linebreak|fontkit|unicode|brotli|png-js).*\.js$/, use: { loader: 'transform-loader?brfs', - } + }, }, { test: /\.(woff2?|eot|ttf|otf|png|jpe?g|gif|svg)(\?.*)?$/, @@ -56,22 +52,35 @@ module.exports = { loader: 'file-loader', options: { name: '[name]-[hash].[ext]', - outputPath: 'assets/' - } - } + outputPath: 'assets/', + }, + }, }, - ] + ], }, plugins: [ - new webpack.DefinePlugin(Object.assign({ - 'process.env.API_VERSION': JSON.stringify(process.env.API_VERSION || 'dev'), - 'process.env.NETWORK': JSON.stringify(process.env.NETWORK || 'development'), - 'process.env.MOBX_DEV_TOOLS': process.env.MOBX_DEV_TOOLS || 0, - 'process.env.BUILD_NUMBER': JSON.stringify(process.env.BUILD_NUMBER || 'dev'), - 'process.env.IS_WATCH_MODE': process.env.IS_WATCH_MODE === 'true' - }, process.env.NODE_ENV === 'production' ? { - // Only bake in NODE_ENV value for production builds. - 'process.env.NODE_ENV': '"production"', - } : {})), + new webpack.DefinePlugin( + Object.assign( + { + 'process.env.API_VERSION': JSON.stringify( + process.env.API_VERSION || 'dev' + ), + 'process.env.NETWORK': JSON.stringify( + process.env.NETWORK || 'development' + ), + 'process.env.MOBX_DEV_TOOLS': process.env.MOBX_DEV_TOOLS || 0, + 'process.env.BUILD_NUMBER': JSON.stringify( + process.env.BUILD_NUMBER || 'dev' + ), + 'process.env.IS_WATCH_MODE': process.env.IS_WATCH_MODE === 'true', + }, + process.env.NODE_ENV === 'production' + ? { + // Only bake in NODE_ENV value for production builds. + 'process.env.NODE_ENV': '"production"', + } + : {} + ) + ), ].filter(Boolean), }; diff --git a/source/renderer/app/App.js b/source/renderer/app/App.js index b824ff75a0..c7be602bd1 100755 --- a/source/renderer/app/App.js +++ b/source/renderer/app/App.js @@ -38,7 +38,9 @@ export default class App extends Component<{ - + {mobxDevTools} diff --git a/source/renderer/app/Routes.js b/source/renderer/app/Routes.js index 3644206df5..8e40eb80f5 100644 --- a/source/renderer/app/Routes.js +++ b/source/renderer/app/Routes.js @@ -28,16 +28,28 @@ import WalletSettingsPage from './containers/wallet/WalletSettingsPage'; export const Routes = ( - + - + {/* */} - + - + diff --git a/source/renderer/app/actions/ada-redemption-actions.js b/source/renderer/app/actions/ada-redemption-actions.js index cac04faadc..36edb0f143 100644 --- a/source/renderer/app/actions/ada-redemption-actions.js +++ b/source/renderer/app/actions/ada-redemption-actions.js @@ -5,7 +5,9 @@ import type { RedemptionTypeChoices } from '../types/redemptionTypes'; // ======= ADA REDEMPTION ACTIONS ======= export default class AdaRedemptionActions { - chooseRedemptionType: Action<{ redemptionType: RedemptionTypeChoices }> = new Action(); + chooseRedemptionType: Action<{ + redemptionType: RedemptionTypeChoices, + }> = new Action(); setCertificate: Action<{ certificate: File }> = new Action(); removeCertificate: Action = new Action(); setPassPhrase: Action<{ passPhrase: string }> = new Action(); @@ -14,10 +16,20 @@ export default class AdaRedemptionActions { setAdaPasscode: Action<{ adaPasscode: string }> = new Action(); setAdaAmount: Action<{ adaAmount: string }> = new Action(); setDecryptionKey: Action<{ decryptionKey: string }> = new Action(); - redeemAda: Action<{ walletId: string, spendingPassword: ?string }> = new Action(); + redeemAda: Action<{ + walletId: string, + spendingPassword: ?string, + }> = new Action(); // eslint-disable-next-line max-len - redeemPaperVendedAda: Action<{ walletId: string, shieldedRedemptionKey: string, spendingPassword: ?string }> = new Action(); - adaSuccessfullyRedeemed: Action<{ walletId: string, amount: number }> = new Action(); + redeemPaperVendedAda: Action<{ + walletId: string, + shieldedRedemptionKey: string, + spendingPassword: ?string, + }> = new Action(); + adaSuccessfullyRedeemed: Action<{ + walletId: string, + amount: number, + }> = new Action(); acceptRedemptionDisclaimer: Action = new Action(); // TODO: refactor dialog toggles to use dialog-actions instead closeAdaRedemptionSuccessOverlay: Action = new Action(); diff --git a/source/renderer/app/actions/addresses-actions.js b/source/renderer/app/actions/addresses-actions.js index 60eafdf2b8..f35aecf09e 100644 --- a/source/renderer/app/actions/addresses-actions.js +++ b/source/renderer/app/actions/addresses-actions.js @@ -4,6 +4,9 @@ import Action from './lib/Action'; // ======= ADDRESSES ACTIONS ======= export default class AddressesActions { - createAddress: Action<{ walletId: string, spendingPassword: ?string }> = new Action(); + createAddress: Action<{ + walletId: string, + spendingPassword: ?string, + }> = new Action(); resetErrors: Action = new Action(); } diff --git a/source/renderer/app/actions/lib/Action.js b/source/renderer/app/actions/lib/Action.js index df2783b28b..4e37abc94d 100644 --- a/source/renderer/app/actions/lib/Action.js +++ b/source/renderer/app/actions/lib/Action.js @@ -10,7 +10,6 @@ export type Listener

= (params: P) => any; * Action class with typed params */ export default class Action { - /** * Array of all defined actions in the system * @type {[Action]} diff --git a/source/renderer/app/actions/notifications-actions.js b/source/renderer/app/actions/notifications-actions.js index f75dc32cb2..991f28b254 100644 --- a/source/renderer/app/actions/notifications-actions.js +++ b/source/renderer/app/actions/notifications-actions.js @@ -6,6 +6,6 @@ import Action from './lib/Action'; export default class NotificationsActions { open: Action<{ id: string, duration?: number }> = new Action(); updateDataForActiveNotification: Action<{ data: Object }> = new Action(); - closeActiveNotification: Action<{ id: string }>= new Action(); + closeActiveNotification: Action<{ id: string }> = new Action(); resetActiveNotification: Action = new Action(); } diff --git a/source/renderer/app/actions/profile-actions.js b/source/renderer/app/actions/profile-actions.js index 490700b398..412a8f74ad 100644 --- a/source/renderer/app/actions/profile-actions.js +++ b/source/renderer/app/actions/profile-actions.js @@ -9,7 +9,11 @@ export default class ProfileActions { getLogs: Action = new Action(); getLogsAndCompress: Action = new Action(); resetBugReportDialog: Action = new Action(); - downloadLogs: Action<{ fileName: string, destination: string, fresh?: boolean }> = new Action(); + downloadLogs: Action<{ + fileName: string, + destination: string, + fresh?: boolean, + }> = new Action(); updateLocale: Action<{ locale: string }> = new Action(); updateTheme: Action<{ theme: string }> = new Action(); } diff --git a/source/renderer/app/actions/sidebar-actions.js b/source/renderer/app/actions/sidebar-actions.js index 56e7ac238a..f0f489ce71 100644 --- a/source/renderer/app/actions/sidebar-actions.js +++ b/source/renderer/app/actions/sidebar-actions.js @@ -6,6 +6,9 @@ import Action from './lib/Action'; export default class SidebarActions { showSubMenus: Action = new Action(); toggleSubMenus: Action = new Action(); - activateSidebarCategory: Action<{ category: string, showSubMenu?: boolean }> = new Action(); + activateSidebarCategory: Action<{ + category: string, + showSubMenu?: boolean, + }> = new Action(); walletSelected: Action<{ walletId: string }> = new Action(); } diff --git a/source/renderer/app/actions/wallet-backup-actions.js b/source/renderer/app/actions/wallet-backup-actions.js index 0a9c651edf..899ce0ff6d 100644 --- a/source/renderer/app/actions/wallet-backup-actions.js +++ b/source/renderer/app/actions/wallet-backup-actions.js @@ -8,7 +8,10 @@ export default class WalletBackupActions { initiateWalletBackup: Action<{ recoveryPhrase: string[] }> = new Action(); acceptPrivacyNoticeForWalletBackup: Action = new Action(); continueToRecoveryPhraseForWalletBackup: Action = new Action(); - addWordToWalletBackupVerification: Action<{ word: string, index: number }> = new Action(); + addWordToWalletBackupVerification: Action<{ + word: string, + index: number, + }> = new Action(); clearEnteredRecoveryPhrase: Action = new Action(); acceptWalletBackupTermDevice: Action = new Action(); acceptWalletBackupTermRecovery: Action = new Action(); diff --git a/source/renderer/app/actions/wallet-settings-actions.js b/source/renderer/app/actions/wallet-settings-actions.js index 92780fa907..b1da70cdbf 100644 --- a/source/renderer/app/actions/wallet-settings-actions.js +++ b/source/renderer/app/actions/wallet-settings-actions.js @@ -5,7 +5,7 @@ export type WalletExportToFileParams = { walletId: string, exportType: string, filePath: string, - password: ?string + password: ?string, }; export default class WalletSettingsActions { @@ -14,6 +14,10 @@ export default class WalletSettingsActions { stopEditingWalletField: Action = new Action(); updateWalletField: Action<{ field: string, value: string }> = new Action(); // eslint-disable-next-line max-len - updateSpendingPassword: Action<{ walletId: string, oldPassword: ?string, newPassword: ?string }> = new Action(); + updateSpendingPassword: Action<{ + walletId: string, + oldPassword: ?string, + newPassword: ?string, + }> = new Action(); exportToFile: Action = new Action(); } diff --git a/source/renderer/app/actions/wallets-actions.js b/source/renderer/app/actions/wallets-actions.js index 1987836b8f..e18ead157d 100644 --- a/source/renderer/app/actions/wallets-actions.js +++ b/source/renderer/app/actions/wallets-actions.js @@ -11,13 +11,27 @@ export type WalletImportFromFileParams = { // ======= WALLET ACTIONS ======= export default class WalletsActions { - createWallet: Action<{ name: string, spendingPassword: ?string }> = new Action(); + createWallet: Action<{ + name: string, + spendingPassword: ?string, + }> = new Action(); // eslint-disable-next-line max-len - restoreWallet: Action<{ recoveryPhrase: string, walletName: string, spendingPassword: ?string, type?: string }> = new Action(); + restoreWallet: Action<{ + recoveryPhrase: string, + walletName: string, + spendingPassword: ?string, + type?: string, + }> = new Action(); importWalletFromFile: Action = new Action(); deleteWallet: Action<{ walletId: string }> = new Action(); - sendMoney: Action<{ receiver: string, amount: string, password: ?string }> = new Action(); - chooseWalletExportType: Action<{ walletExportType: walletExportTypeChoices }> = new Action(); + sendMoney: Action<{ + receiver: string, + amount: string, + password: ?string, + }> = new Action(); + chooseWalletExportType: Action<{ + walletExportType: walletExportTypeChoices, + }> = new Action(); generateCertificate: Action<{ filePath: string }> = new Action(); updateCertificateStep: Action = new Action(); closeCertificateGeneration: Action = new Action(); diff --git a/source/renderer/app/actions/window-actions.js b/source/renderer/app/actions/window-actions.js index a9346cc54c..fb5143b81a 100644 --- a/source/renderer/app/actions/window-actions.js +++ b/source/renderer/app/actions/window-actions.js @@ -3,5 +3,5 @@ import Action from './lib/Action'; export default class WindowActions { resizeWindow: Action<{ width: number, height: number }> = new Action(); - closeWindow: Action<{ }> = new Action(); + closeWindow: Action<{}> = new Action(); } diff --git a/source/renderer/app/api/accounts/requests/getAccounts.js b/source/renderer/app/api/accounts/requests/getAccounts.js index 2c059e1328..074ee30dfc 100644 --- a/source/renderer/app/api/accounts/requests/getAccounts.js +++ b/source/renderer/app/api/accounts/requests/getAccounts.js @@ -10,10 +10,9 @@ export type GetAccountsParams = { export const getAccounts = ( config: RequestConfig, { walletId }: GetAccountsParams -): Promise => ( +): Promise => request({ method: 'GET', path: `/api/v1/wallets/${walletId}/accounts`, ...config, - }) -); + }); diff --git a/source/renderer/app/api/accounts/types.js b/source/renderer/app/api/accounts/types.js index d2036c5a3a..ccaa13cb4a 100644 --- a/source/renderer/app/api/accounts/types.js +++ b/source/renderer/app/api/accounts/types.js @@ -6,7 +6,7 @@ export type Account = { addresses: Addresses, name: string, walletId: string, - index: number + index: number, }; export type Accounts = Array; diff --git a/source/renderer/app/api/addresses/requests/createAddress.js b/source/renderer/app/api/addresses/requests/createAddress.js index d0458c981b..15f47ddf71 100644 --- a/source/renderer/app/api/addresses/requests/createAddress.js +++ b/source/renderer/app/api/addresses/requests/createAddress.js @@ -12,10 +12,13 @@ export type CreateAddressParams = { export const createAddress = ( config: RequestConfig, { spendingPassword, accountIndex, walletId }: CreateAddressParams -): Promise

=> ( - request({ - method: 'POST', - path: '/api/v1/addresses', - ...config, - }, {}, { spendingPassword, accountIndex, walletId }) -); +): Promise
=> + request( + { + method: 'POST', + path: '/api/v1/addresses', + ...config, + }, + {}, + { spendingPassword, accountIndex, walletId } + ); diff --git a/source/renderer/app/api/addresses/types.js b/source/renderer/app/api/addresses/types.js index 76f394d4bb..fcfbacb0c7 100644 --- a/source/renderer/app/api/addresses/types.js +++ b/source/renderer/app/api/addresses/types.js @@ -2,7 +2,7 @@ export type Address = { id: string, used: boolean, - changeAddress: boolean + changeAddress: boolean, }; export type Addresses = Array
; diff --git a/source/renderer/app/api/api.js b/source/renderer/app/api/api.js index 854beaf8ef..37423e3950 100644 --- a/source/renderer/app/api/api.js +++ b/source/renderer/app/api/api.js @@ -6,7 +6,10 @@ import moment from 'moment'; // domains import Wallet from '../domains/Wallet'; -import { WalletTransaction, transactionTypes } from '../domains/WalletTransaction'; +import { + WalletTransaction, + transactionTypes, +} from '../domains/WalletTransaction'; import WalletAddress from '../domains/WalletAddress'; // Accounts requests @@ -42,20 +45,23 @@ import { restoreWallet } from './wallets/requests/restoreWallet'; import { updateWallet } from './wallets/requests/updateWallet'; // utility functions -import { awaitUpdateChannel, cardanoFaultInjectionChannel } from '../ipc/cardano.ipc'; +import { + awaitUpdateChannel, + cardanoFaultInjectionChannel, +} from '../ipc/cardano.ipc'; import patchAdaApi from './utils/patchAdaApi'; import { isValidMnemonic } from '../../../common/crypto/decrypt'; import { utcStringToDate, encryptPassphrase } from './utils'; import { Logger } from '../utils/logging'; import { isValidRedemptionKey, - isValidPaperVendRedemptionKey + isValidPaperVendRedemptionKey, } from '../utils/redemption-key-validation'; import { unscrambleMnemonics, scrambleMnemonics, generateAccountMnemonics, - generateAdditionalMnemonics + generateAdditionalMnemonics, } from './utils/mnemonics'; import { filterLogData } from '../../../common/utils/logging'; @@ -64,12 +70,12 @@ import { LOVELACES_PER_ADA, MAX_TRANSACTIONS_PER_PAGE, MAX_TRANSACTION_CONFIRMATIONS, - TX_AGE_POLLING_THRESHOLD + TX_AGE_POLLING_THRESHOLD, } from '../config/numbersConfig'; import { ADA_CERTIFICATE_MNEMONIC_LENGTH, ADA_REDEMPTION_PASSPHRASE_LENGTH, - WALLET_RECOVERY_PHRASE_WORD_COUNT + WALLET_RECOVERY_PHRASE_WORD_COUNT, } from '../config/cryptoConfig'; // Accounts types @@ -80,19 +86,17 @@ import type { Address, GetAddressesRequest, CreateAddressRequest, - GetAddressesResponse + GetAddressesResponse, } from './addresses/types'; // Common Types -import type { - RequestConfig, -} from './common/types'; +import type { RequestConfig } from './common/types'; // Nodes Types import type { NodeInfo, NodeSoftware, - GetNetworkStatusResponse + GetNetworkStatusResponse, } from './nodes/types'; import type { NodeQueryParams } from './nodes/requests/getNodeInfo'; @@ -105,7 +109,7 @@ import type { TransactionFee, TransactionRequest, GetTransactionsRequest, - GetTransactionsResponse + GetTransactionsResponse, } from './transactions/types'; // Wallets Types @@ -121,7 +125,7 @@ import type { GetWalletRecoveryPhraseFromCertificateRequest, ImportWalletFromKeyRequest, ImportWalletFromFileRequest, - UpdateWalletRequest + UpdateWalletRequest, } from './wallets/types'; // Common errors @@ -129,14 +133,14 @@ import { GenericApiError, IncorrectSpendingPasswordError, InvalidMnemonicError, - ForbiddenMnemonicError + ForbiddenMnemonicError, } from './common/errors'; // Wallets errors import { WalletAlreadyRestoredError, WalletAlreadyImportedError, - WalletFileImportError + WalletFileImportError, } from './wallets/errors'; // Transactions errors @@ -152,7 +156,6 @@ import { import type { FaultInjectionIpcRequest } from '../../../common/types/cardano-node.types'; export default class AdaApi { - config: RequestConfig; constructor(isTest: boolean, config: RequestConfig) { @@ -176,19 +179,25 @@ export default class AdaApi { } }; - getAddresses = async (request: GetAddressesRequest): Promise => { - Logger.debug('AdaApi::getAddresses called', { parameters: filterLogData(request) }); + getAddresses = async ( + request: GetAddressesRequest + ): Promise => { + Logger.debug('AdaApi::getAddresses called', { + parameters: filterLogData(request), + }); const { walletId } = request; try { const accounts: Accounts = await getAccounts(this.config, { walletId }); - const response = accounts.map(account => ( + const response = accounts.map(account => Object.assign({}, account, { addresses: account.addresses.length }) - )); + ); Logger.debug('AdaApi::getAddresses success', { response }); if (!accounts || !accounts.length) { - return new Promise(resolve => resolve({ accountIndex: null, addresses: [] })); + return new Promise(resolve => + resolve({ accountIndex: null, addresses: [] }) + ); } // For now only the first wallet account is used @@ -202,14 +211,18 @@ export default class AdaApi { } }; - getTransactions = async (request: GetTransactionsRequest): Promise => { + getTransactions = async ( + request: GetTransactionsRequest + ): Promise => { const requestTimestamp = moment(); const requestStats = Object.assign({}, request, { cachedTransactions: request.cachedTransactions.length, }); Logger.debug('AdaApi::searchHistory called', { parameters: requestStats }); const { - walletId, skip, limit, + walletId, + skip, + limit, isFirstLoad, // during first load we fetch all wallet's transactions isRestoreActive, // during restoration we fetch only missing transactions isRestoreCompleted, // once restoration is done we fetch potentially missing transactions @@ -238,10 +251,12 @@ export default class AdaApi { // all subsequent multi-pages requests load the same set of transactions }; - const shouldLoadOnlyFresh = !isFirstLoad && !isRestoreActive && !isRestoreCompleted; + const shouldLoadOnlyFresh = + !isFirstLoad && !isRestoreActive && !isRestoreCompleted; if (shouldLoadOnlyFresh) { - const tenMinutesAgo = - moment.utc(Date.now() - TX_AGE_POLLING_THRESHOLD).format('YYYY-MM-DDTHH:mm:ss'); + const tenMinutesAgo = moment + .utc(Date.now() - TX_AGE_POLLING_THRESHOLD) + .format('YYYY-MM-DDTHH:mm:ss'); // Since we load all transactions in a first load, later on we only care about fresh ones Object.assign(params, { created_at: `GTE[${tenMinutesAgo}]` }); } @@ -250,41 +265,60 @@ export default class AdaApi { try { // Load first page of transactions - const response: Transactions = await getTransactionHistory(this.config, params); + const response: Transactions = await getTransactionHistory( + this.config, + params + ); const { meta, data: txHistory } = response; const { totalPages, totalEntries: totalTransactions } = meta.pagination; - let transactions = txHistory.map(tx => _createTransactionFromServerData(tx)); + let transactions = txHistory.map(tx => + _createTransactionFromServerData(tx) + ); // Load additional pages of transactions - const hasMultiplePages = (totalPages > 1 && (shouldLoadAll || limit > perPage)); + const hasMultiplePages = + totalPages > 1 && (shouldLoadAll || limit > perPage); if (hasMultiplePages) { let page = 2; const hasNextPage = () => { - const hasMorePages = (page < totalPages + 1); + const hasMorePages = page < totalPages + 1; if ((isRestoreActive || isRestoreCompleted) && hasMorePages) { - const loadedTransactions = unionBy(transactions, cachedTransactions, 'id'); - const hasMoreTransactions = (totalTransactions - loadedTransactions.length) > 0; + const loadedTransactions = unionBy( + transactions, + cachedTransactions, + 'id' + ); + const hasMoreTransactions = + totalTransactions - loadedTransactions.length > 0; return hasMoreTransactions; } return hasMorePages; }; - const shouldLoadNextPage = () => shouldLoadAll || page <= pagesToBeLoaded; + const shouldLoadNextPage = () => + shouldLoadAll || page <= pagesToBeLoaded; if (isRestoreActive || isRestoreCompleted) { const latestLoadedTransactionDate = transactions[0].date; - const latestLoadedTransactionDateString = - moment.utc(latestLoadedTransactionDate).format('YYYY-MM-DDTHH:mm:ss'); + const latestLoadedTransactionDateString = moment + .utc(latestLoadedTransactionDate) + .format('YYYY-MM-DDTHH:mm:ss'); // During restoration we need to fetch only transactions older than the latest loaded one // as this ensures that both totalPages and totalEntries remain unchanged throught out // subsequent page loads (as in the meantime new transactions can be discovered) - Object.assign(params, { created_at: `LTE[${latestLoadedTransactionDateString}]` }); + Object.assign(params, { + created_at: `LTE[${latestLoadedTransactionDateString}]`, + }); } - for (page; (hasNextPage() && shouldLoadNextPage()); page++) { - const { data: pageHistory } = - await getTransactionHistory(this.config, Object.assign(params, { page })); - transactions.push(...pageHistory.map(tx => _createTransactionFromServerData(tx))); + for (page; hasNextPage() && shouldLoadNextPage(); page++) { + const { data: pageHistory } = await getTransactionHistory( + this.config, + Object.assign(params, { page }) + ); + transactions.push( + ...pageHistory.map(tx => _createTransactionFromServerData(tx)) + ); } } @@ -308,9 +342,14 @@ export default class AdaApi { daedalusCached: cachedTransactions.length, daedalusLoaded: total - cachedTransactions.length, daedalusTotal: total, - requestDurationInMs: moment.duration(moment().diff(requestTimestamp)).as('milliseconds'), + requestDurationInMs: moment + .duration(moment().diff(requestTimestamp)) + .as('milliseconds'), }; - Logger.debug(`AdaApi::searchHistory success: ${total} transactions loaded`, { responseStats }); + Logger.debug( + `AdaApi::searchHistory success: ${total} transactions loaded`, + { responseStats } + ); return new Promise(resolve => resolve({ transactions, total })); } catch (error) { Logger.error('AdaApi::searchHistory error', { error }); @@ -319,9 +358,13 @@ export default class AdaApi { }; createWallet = async (request: CreateWalletRequest): Promise => { - Logger.debug('AdaApi::createWallet called', { parameters: filterLogData(request) }); + Logger.debug('AdaApi::createWallet called', { + parameters: filterLogData(request), + }); const { name, mnemonic, spendingPassword: passwordString } = request; - const spendingPassword = passwordString ? encryptPassphrase(passwordString) : ''; + const spendingPassword = passwordString + ? encryptPassphrase(passwordString) + : ''; const assuranceLevel = 'normal'; try { const walletInitData = { @@ -331,7 +374,9 @@ export default class AdaApi { name, spendingPassword, }; - const wallet: AdaWallet = await createWallet(this.config, { walletInitData }); + const wallet: AdaWallet = await createWallet(this.config, { + walletInitData, + }); Logger.debug('AdaApi::createWallet success', { wallet }); return _createWalletFromServerData(wallet); } catch (error) { @@ -341,7 +386,9 @@ export default class AdaApi { }; deleteWallet = async (request: DeleteWalletRequest): Promise => { - Logger.debug('AdaApi::deleteWallet called', { parameters: filterLogData(request) }); + Logger.debug('AdaApi::deleteWallet called', { + parameters: filterLogData(request), + }); try { const { walletId } = request; const response = await deleteWallet(this.config, { walletId }); @@ -356,9 +403,19 @@ export default class AdaApi { createTransaction = async ( request: TransactionRequest ): Promise => { - Logger.debug('AdaApi::createTransaction called', { parameters: filterLogData(request) }); - const { accountIndex, walletId, address, amount, spendingPassword: passwordString } = request; - const spendingPassword = passwordString ? encryptPassphrase(passwordString) : ''; + Logger.debug('AdaApi::createTransaction called', { + parameters: filterLogData(request), + }); + const { + accountIndex, + walletId, + address, + amount, + spendingPassword: passwordString, + } = request; + const spendingPassword = passwordString + ? encryptPassphrase(passwordString) + : ''; try { const data = { source: { @@ -374,8 +431,12 @@ export default class AdaApi { groupingPolicy: 'OptimizeForSecurity', spendingPassword, }; - const response: Transaction = await createTransaction(this.config, { data }); - Logger.debug('AdaApi::createTransaction success', { transaction: response }); + const response: Transaction = await createTransaction(this.config, { + data, + }); + Logger.debug('AdaApi::createTransaction success', { + transaction: response, + }); return _createTransactionFromServerData(response); } catch (error) { Logger.error('AdaApi::createTransaction error', { error }); @@ -401,12 +462,10 @@ export default class AdaApi { calculateTransactionFee = async ( request: TransactionRequest ): Promise => { - Logger.debug('AdaApi::calculateTransactionFee called', { parameters: filterLogData(request) }); - const { - accountIndex, - walletId, walletBalance, - address, amount, - } = request; + Logger.debug('AdaApi::calculateTransactionFee called', { + parameters: filterLogData(request), + }); + const { accountIndex, walletId, walletBalance, address, amount } = request; try { const data = { source: { @@ -421,8 +480,12 @@ export default class AdaApi { ], groupingPolicy: 'OptimizeForSecurity', }; - const response: TransactionFee = await getTransactionFee(this.config, { data }); - Logger.debug('AdaApi::calculateTransactionFee success', { transactionFee: response }); + const response: TransactionFee = await getTransactionFee(this.config, { + data, + }); + Logger.debug('AdaApi::calculateTransactionFee success', { + transactionFee: response, + }); return _createTransactionFeeFromServerData(response); } catch (error) { Logger.error('AdaApi::calculateTransactionFee error', { error }); @@ -436,7 +499,9 @@ export default class AdaApi { // - error.diagnostic.details.msg === 'Not enough coins to cover fee.' // = show "Not enough Ada for fees. Try sending a smaller amount." throw new NotEnoughFundsForTransactionFeesError(); - } else if (errorMessage.includes('Not enough available coins to proceed')) { + } else if ( + errorMessage.includes('Not enough available coins to proceed') + ) { const availableBalance = new BigNumber( get(error, 'diagnostic.details.availableBalance', 0) ).dividedBy(LOVELACES_PER_ADA); @@ -467,13 +532,23 @@ export default class AdaApi { }; createAddress = async (request: CreateAddressRequest): Promise
=> { - Logger.debug('AdaApi::createAddress called', { parameters: filterLogData(request) }); - const { accountIndex, walletId, spendingPassword: passwordString } = request; - const spendingPassword = passwordString ? encryptPassphrase(passwordString) : ''; + Logger.debug('AdaApi::createAddress called', { + parameters: filterLogData(request), + }); + const { + accountIndex, + walletId, + spendingPassword: passwordString, + } = request; + const spendingPassword = passwordString + ? encryptPassphrase(passwordString) + : ''; try { - const address: Address = await createAddress( - this.config, { spendingPassword, accountIndex, walletId } - ); + const address: Address = await createAddress(this.config, { + spendingPassword, + accountIndex, + walletId, + }); Logger.debug('AdaApi::createAddress success', { address }); return _createAddressFromServerData(address); } catch (error) { @@ -486,7 +561,9 @@ export default class AdaApi { }; async isValidAddress(address: string): Promise { - Logger.debug('AdaApi::isValidAdaAddress called', { parameters: { address } }); + Logger.debug('AdaApi::isValidAdaAddress called', { + parameters: { address }, + }); try { const response: Address = await getAddress(this.config, { address }); Logger.debug('AdaApi::isValidAdaAddress success', { response }); @@ -497,29 +574,26 @@ export default class AdaApi { } } - isValidMnemonic = (mnemonic: string): boolean => ( - isValidMnemonic(mnemonic, WALLET_RECOVERY_PHRASE_WORD_COUNT) - ); + isValidMnemonic = (mnemonic: string): boolean => + isValidMnemonic(mnemonic, WALLET_RECOVERY_PHRASE_WORD_COUNT); - isValidRedemptionKey = (mnemonic: string): boolean => (isValidRedemptionKey(mnemonic)); + isValidRedemptionKey = (mnemonic: string): boolean => + isValidRedemptionKey(mnemonic); - isValidPaperVendRedemptionKey = (mnemonic: string): boolean => ( - isValidPaperVendRedemptionKey(mnemonic) - ); + isValidPaperVendRedemptionKey = (mnemonic: string): boolean => + isValidPaperVendRedemptionKey(mnemonic); - isValidRedemptionMnemonic = (mnemonic: string): boolean => ( - isValidMnemonic(mnemonic, ADA_REDEMPTION_PASSPHRASE_LENGTH) - ); + isValidRedemptionMnemonic = (mnemonic: string): boolean => + isValidMnemonic(mnemonic, ADA_REDEMPTION_PASSPHRASE_LENGTH); - isValidCertificateMnemonic = (mnemonic: string): boolean => ( - mnemonic.split(' ').length === ADA_CERTIFICATE_MNEMONIC_LENGTH - ); + isValidCertificateMnemonic = (mnemonic: string): boolean => + mnemonic.split(' ').length === ADA_CERTIFICATE_MNEMONIC_LENGTH; getWalletRecoveryPhrase(): Promise> { Logger.debug('AdaApi::getWalletRecoveryPhrase called'); try { - const response: Promise> = new Promise( - (resolve) => resolve(generateAccountMnemonics()) + const response: Promise> = new Promise(resolve => + resolve(generateAccountMnemonics()) ); Logger.debug('AdaApi::getWalletRecoveryPhrase success'); return response; @@ -533,13 +607,15 @@ export default class AdaApi { getWalletCertificateAdditionalMnemonics(): Promise> { Logger.debug('AdaApi::getWalletCertificateAdditionalMnemonics called'); try { - const response: Promise> = new Promise( - (resolve) => resolve(generateAdditionalMnemonics()) + const response: Promise> = new Promise(resolve => + resolve(generateAdditionalMnemonics()) ); Logger.debug('AdaApi::getWalletCertificateAdditionalMnemonics success'); return response; } catch (error) { - Logger.error('AdaApi::getWalletCertificateAdditionalMnemonics error', { error }); + Logger.error('AdaApi::getWalletCertificateAdditionalMnemonics error', { + error, + }); throw new GenericApiError(); } } @@ -550,13 +626,15 @@ export default class AdaApi { Logger.debug('AdaApi::getWalletCertificateRecoveryPhrase called'); const { passphrase, input: scrambledInput } = request; try { - const response: Promise> = new Promise( - (resolve) => resolve(scrambleMnemonics({ passphrase, scrambledInput })) + const response: Promise> = new Promise(resolve => + resolve(scrambleMnemonics({ passphrase, scrambledInput })) ); Logger.debug('AdaApi::getWalletCertificateRecoveryPhrase success'); return response; } catch (error) { - Logger.error('AdaApi::getWalletCertificateRecoveryPhrase error', { error }); + Logger.error('AdaApi::getWalletCertificateRecoveryPhrase error', { + error, + }); throw new GenericApiError(); } } @@ -571,25 +649,37 @@ export default class AdaApi { Logger.debug('AdaApi::getWalletRecoveryPhraseFromCertificate success'); return Promise.resolve(response); } catch (error) { - Logger.error('AdaApi::getWalletRecoveryPhraseFromCertificate error', { error }); + Logger.error('AdaApi::getWalletRecoveryPhraseFromCertificate error', { + error, + }); return Promise.reject(new InvalidMnemonicError()); } } restoreWallet = async (request: RestoreWalletRequest): Promise => { - Logger.debug('AdaApi::restoreWallet called', { parameters: filterLogData(request) }); - const { recoveryPhrase, walletName, spendingPassword: passwordString } = request; - const spendingPassword = passwordString ? encryptPassphrase(passwordString) : ''; + Logger.debug('AdaApi::restoreWallet called', { + parameters: filterLogData(request), + }); + const { + recoveryPhrase, + walletName, + spendingPassword: passwordString, + } = request; + const spendingPassword = passwordString + ? encryptPassphrase(passwordString) + : ''; const assuranceLevel = 'normal'; const walletInitData = { operation: 'restore', backupPhrase: split(recoveryPhrase, ' '), assuranceLevel, name: walletName, - spendingPassword + spendingPassword, }; try { - const wallet: AdaWallet = await restoreWallet(this.config, { walletInitData }); + const wallet: AdaWallet = await restoreWallet(this.config, { + walletInitData, + }); Logger.debug('AdaApi::restoreWallet success', { wallet }); return _createWalletFromServerData(wallet); } catch (error) { @@ -599,7 +689,11 @@ export default class AdaApi { } if (error.message === 'JSONValidationFailed') { const validationError = get(error, 'diagnostic.validationError', ''); - if (validationError.includes('Forbidden Mnemonic: an example Mnemonic has been submitted')) { + if ( + validationError.includes( + 'Forbidden Mnemonic: an example Mnemonic has been submitted' + ) + ) { throw new ForbiddenMnemonicError(); } } @@ -610,13 +704,18 @@ export default class AdaApi { importWalletFromKey = async ( request: ImportWalletFromKeyRequest ): Promise => { - Logger.debug('AdaApi::importWalletFromKey called', { parameters: filterLogData(request) }); + Logger.debug('AdaApi::importWalletFromKey called', { + parameters: filterLogData(request), + }); const { filePath, spendingPassword: passwordString } = request; - const spendingPassword = passwordString ? encryptPassphrase(passwordString) : ''; + const spendingPassword = passwordString + ? encryptPassphrase(passwordString) + : ''; try { - const importedWallet: AdaWallet = await importWalletAsKey( - this.config, { filePath, spendingPassword } - ); + const importedWallet: AdaWallet = await importWalletAsKey(this.config, { + filePath, + spendingPassword, + }); Logger.debug('AdaApi::importWalletFromKey success', { importedWallet }); return _createWalletFromServerData(importedWallet); } catch (error) { @@ -631,16 +730,22 @@ export default class AdaApi { importWalletFromFile = async ( request: ImportWalletFromFileRequest ): Promise => { - Logger.debug('AdaApi::importWalletFromFile called', { parameters: filterLogData(request) }); + Logger.debug('AdaApi::importWalletFromFile called', { + parameters: filterLogData(request), + }); const { filePath, spendingPassword: passwordString } = request; - const spendingPassword = passwordString ? encryptPassphrase(passwordString) : ''; - const isKeyFile = filePath.split('.').pop().toLowerCase() === 'key'; + const spendingPassword = passwordString + ? encryptPassphrase(passwordString) + : ''; + const isKeyFile = + filePath + .split('.') + .pop() + .toLowerCase() === 'key'; try { - const importedWallet: AdaWallet = isKeyFile ? ( - await importWalletAsKey(this.config, { filePath, spendingPassword }) - ) : ( - await importWalletAsJSON(this.config, filePath) - ); + const importedWallet: AdaWallet = isKeyFile + ? await importWalletAsKey(this.config, { filePath, spendingPassword }) + : await importWalletAsJSON(this.config, filePath); Logger.debug('AdaApi::importWalletFromFile success', { importedWallet }); return _createWalletFromServerData(importedWallet); } catch (error) { @@ -652,16 +757,19 @@ export default class AdaApi { } }; - redeemAda = async ( - request: RedeemAdaParams - ): Promise => { - Logger.debug('AdaApi::redeemAda called', { parameters: filterLogData(request) }); + redeemAda = async (request: RedeemAdaParams): Promise => { + Logger.debug('AdaApi::redeemAda called', { + parameters: filterLogData(request), + }); const { spendingPassword: passwordString } = request; - const spendingPassword = passwordString ? encryptPassphrase(passwordString) : ''; + const spendingPassword = passwordString + ? encryptPassphrase(passwordString) + : ''; try { - const transaction: Transaction = await redeemAda( - this.config, { ...request, spendingPassword } - ); + const transaction: Transaction = await redeemAda(this.config, { + ...request, + spendingPassword, + }); Logger.debug('AdaApi::redeemAda success', { transaction }); return _createTransactionFromServerData(transaction); } catch (error) { @@ -676,13 +784,18 @@ export default class AdaApi { redeemPaperVendedAda = async ( request: RedeemPaperVendedAdaParams ): Promise => { - Logger.debug('AdaApi::redeemAdaPaperVend called', { parameters: filterLogData(request) }); + Logger.debug('AdaApi::redeemAdaPaperVend called', { + parameters: filterLogData(request), + }); const { spendingPassword: passwordString } = request; - const spendingPassword = passwordString ? encryptPassphrase(passwordString) : ''; + const spendingPassword = passwordString + ? encryptPassphrase(passwordString) + : ''; try { - const transaction: Transaction = await redeemPaperVendedAda( - this.config, { ...request, spendingPassword } - ); + const transaction: Transaction = await redeemPaperVendedAda(this.config, { + ...request, + spendingPassword, + }); Logger.debug('AdaApi::redeemAdaPaperVend success', { transaction }); return _createTransactionFromServerData(transaction); } catch (error) { @@ -734,12 +847,16 @@ export default class AdaApi { }; updateWallet = async (request: UpdateWalletRequest): Promise => { - Logger.debug('AdaApi::updateWallet called', { parameters: filterLogData(request) }); + Logger.debug('AdaApi::updateWallet called', { + parameters: filterLogData(request), + }); const { walletId, assuranceLevel, name } = request; try { - const wallet: AdaWallet = await updateWallet( - this.config, { walletId, assuranceLevel, name } - ); + const wallet: AdaWallet = await updateWallet(this.config, { + walletId, + assuranceLevel, + name, + }); Logger.debug('AdaApi::updateWallet success', { wallet }); return _createWalletFromServerData(wallet); } catch (error) { @@ -751,10 +868,16 @@ export default class AdaApi { updateSpendingPassword = async ( request: UpdateSpendingPasswordRequest ): Promise => { - Logger.debug('AdaApi::updateSpendingPassword called', { parameters: filterLogData(request) }); + Logger.debug('AdaApi::updateSpendingPassword called', { + parameters: filterLogData(request), + }); const { walletId, oldPassword, newPassword } = request; try { - await changeSpendingPassword(this.config, { walletId, oldPassword, newPassword }); + await changeSpendingPassword(this.config, { + walletId, + oldPassword, + newPassword, + }); Logger.debug('AdaApi::updateSpendingPassword success'); return true; } catch (error) { @@ -771,11 +894,14 @@ export default class AdaApi { request: ExportWalletToFileRequest ): Promise<[]> => { const { walletId, filePath } = request; - Logger.debug('AdaApi::exportWalletToFile called', { parameters: filterLogData(request) }); + Logger.debug('AdaApi::exportWalletToFile called', { + parameters: filterLogData(request), + }); try { - const response: Promise<[]> = await exportWalletAsJSON( - this.config, { walletId, filePath } - ); + const response: Promise<[]> = await exportWalletAsJSON(this.config, { + walletId, + filePath, + }); Logger.debug('AdaApi::exportWalletToFile success', { response }); return response; } catch (error) { @@ -800,7 +926,9 @@ export default class AdaApi { queryParams?: NodeQueryParams ): Promise => { const isForceNTPCheck = !!queryParams; - const loggerText = `AdaApi::getNetworkStatus${isForceNTPCheck ? ' (FORCE-NTP-CHECK)' : ''}`; + const loggerText = `AdaApi::getNetworkStatus${ + isForceNTPCheck ? ' (FORCE-NTP-CHECK)' : '' + }`; Logger.debug(`${loggerText} called`); try { const status: NodeInfo = await getNodeInfo(this.config, queryParams); @@ -822,7 +950,11 @@ export default class AdaApi { localBlockchainHeight: localBlockchainHeight.quantity, localTimeInformation: { status: localTimeInformation.status, - difference: get(localTimeInformation, 'localTimeDifference.quantity', null), + difference: get( + localTimeInformation, + 'localTimeDifference.quantity', + null + ), }, }; } catch (error) { @@ -839,16 +971,20 @@ export default class AdaApi { getLocalTimeDifference: Function; setLocalTimeDifference: Function; setNextUpdate: Function; - } // ========== TRANSFORM SERVER DATA INTO FRONTEND MODELS ========= const _createWalletFromServerData = action( - 'AdaApi::_createWalletFromServerData', (data: AdaWallet) => { + 'AdaApi::_createWalletFromServerData', + (data: AdaWallet) => { const { - id, balance, name, assuranceLevel, - hasSpendingPassword, spendingPasswordLastUpdate, + id, + balance, + name, + assuranceLevel, + hasSpendingPassword, + spendingPasswordLastUpdate, syncState, } = data; @@ -872,25 +1008,46 @@ const _createAddressFromServerData = action( const _conditionToTxState = (condition: string) => { switch (condition) { case 'applying': - case 'creating': return 'pending'; - case 'wontApply': return 'failed'; - default: return 'ok'; + case 'creating': + return 'pending'; + case 'wontApply': + return 'failed'; + default: + return 'ok'; // Others V0: CPtxInBlocks && CPtxNotTracked // Others V1: "inNewestBlocks" "persisted" "creating" } }; const _createTransactionFromServerData = action( - 'AdaApi::_createTransactionFromServerData', (data: Transaction) => { - const { id, direction, amount, confirmations, creationTime, inputs, outputs, status } = data; + 'AdaApi::_createTransactionFromServerData', + (data: Transaction) => { + const { + id, + direction, + amount, + confirmations, + creationTime, + inputs, + outputs, + status, + } = data; return new WalletTransaction({ id, title: direction === 'outgoing' ? 'Ada sent' : 'Ada received', - type: direction === 'outgoing' ? transactionTypes.EXPEND : transactionTypes.INCOME, - amount: new BigNumber(direction === 'outgoing' ? (amount * -1) : amount).dividedBy(LOVELACES_PER_ADA), + type: + direction === 'outgoing' + ? transactionTypes.EXPEND + : transactionTypes.INCOME, + amount: new BigNumber( + direction === 'outgoing' ? amount * -1 : amount + ).dividedBy(LOVELACES_PER_ADA), date: utcStringToDate(creationTime), description: '', - numberOfConfirmations: Math.min(confirmations, MAX_TRANSACTION_CONFIRMATIONS + 1), + numberOfConfirmations: Math.min( + confirmations, + MAX_TRANSACTION_CONFIRMATIONS + 1 + ), addresses: { from: inputs.map(({ address }) => address), to: outputs.map(({ address }) => address), @@ -901,7 +1058,7 @@ const _createTransactionFromServerData = action( ); const _createTransactionFeeFromServerData = action( - 'AdaApi::_createTransactionFeeFromServerData', (data: TransactionFee) => ( + 'AdaApi::_createTransactionFeeFromServerData', + (data: TransactionFee) => new BigNumber(data.estimatedAmount).dividedBy(LOVELACES_PER_ADA) - ) ); diff --git a/source/renderer/app/api/common/errors.js b/source/renderer/app/api/common/errors.js index ba8b50618a..ef745164d4 100644 --- a/source/renderer/app/api/common/errors.js +++ b/source/renderer/app/api/common/errors.js @@ -7,27 +7,30 @@ const messages = defineMessages({ genericApiError: { id: 'api.errors.GenericApiError', defaultMessage: '!!!An error occurred.', - description: 'Generic error message.' + description: 'Generic error message.', }, incorrectSpendingPasswordError: { id: 'api.errors.IncorrectPasswordError', defaultMessage: '!!!Incorrect wallet password.', - description: '"Incorrect wallet password." error message.' + description: '"Incorrect wallet password." error message.', }, reportRequestError: { id: 'api.errors.ReportRequestError', defaultMessage: '!!!There was a problem sending the support request.', - description: '"There was a problem sending the support request." error message' + description: + '"There was a problem sending the support request." error message', }, apiMethodNotYetImplementedError: { id: 'api.errors.ApiMethodNotYetImplementedError', defaultMessage: '!!!This API method is not yet implemented.', - description: '"This API method is not yet implemented." error message.' + description: '"This API method is not yet implemented." error message.', }, forbiddenMnemonicError: { id: 'api.errors.ForbiddenMnemonicError', - defaultMessage: '!!!Invalid recovery phrase. Submitted recovery phrase is one of the example recovery phrases from the documentation and should not be used for wallets holding funds.', - description: '"Forbidden Mnemonic: an example Mnemonic has been submitted." error message', + defaultMessage: + '!!!Invalid recovery phrase. Submitted recovery phrase is one of the example recovery phrases from the documentation and should not be used for wallets holding funds.', + description: + '"Forbidden Mnemonic: an example Mnemonic has been submitted." error message', }, }); diff --git a/source/renderer/app/api/common/types.js b/source/renderer/app/api/common/types.js index 3daf7e2d3e..770e1454a6 100644 --- a/source/renderer/app/api/common/types.js +++ b/source/renderer/app/api/common/types.js @@ -9,7 +9,7 @@ export type RequestConfig = { export type ResponseBase = { status: ResponseStatus, - meta: Pagination + meta: Pagination, }; export type ResponseStatus = 'success' | 'fail' | 'error'; @@ -19,6 +19,6 @@ export type Pagination = { totalPages: number, page: number, perPage: number, - totalEntries: number - } + totalEntries: number, + }, }; diff --git a/source/renderer/app/api/nodes/requests/applyNodeUpdate.js b/source/renderer/app/api/nodes/requests/applyNodeUpdate.js index 6574846cc9..34478f0d17 100644 --- a/source/renderer/app/api/nodes/requests/applyNodeUpdate.js +++ b/source/renderer/app/api/nodes/requests/applyNodeUpdate.js @@ -2,12 +2,9 @@ import type { RequestConfig } from '../../common/types'; import { request } from '../../utils/request'; -export const applyNodeUpdate = ( - config: RequestConfig, -): Promise => ( +export const applyNodeUpdate = (config: RequestConfig): Promise => request({ method: 'POST', path: '/api/internal/apply-update', ...config, - }) -); + }); diff --git a/source/renderer/app/api/nodes/requests/getNextNodeUpdate.js b/source/renderer/app/api/nodes/requests/getNextNodeUpdate.js index 7e145423ea..6304853009 100644 --- a/source/renderer/app/api/nodes/requests/getNextNodeUpdate.js +++ b/source/renderer/app/api/nodes/requests/getNextNodeUpdate.js @@ -2,12 +2,9 @@ import type { RequestConfig } from '../../common/types'; import { request } from '../../utils/request'; -export const getNextNodeUpdate = ( - config: RequestConfig -): Promise => ( +export const getNextNodeUpdate = (config: RequestConfig): Promise => request({ method: 'GET', path: '/api/internal/next-update', ...config, - }) -); + }); diff --git a/source/renderer/app/api/nodes/requests/getNodeInfo.js b/source/renderer/app/api/nodes/requests/getNodeInfo.js index 5f81a6cc7e..d94f9e79fd 100644 --- a/source/renderer/app/api/nodes/requests/getNodeInfo.js +++ b/source/renderer/app/api/nodes/requests/getNodeInfo.js @@ -9,11 +9,13 @@ export type NodeQueryParams = { export const getNodeInfo = ( config: RequestConfig, - queryParams?: NodeQueryParams, -): Promise => ( - request({ - method: 'GET', - path: '/api/v1/node-info', - ...config, - }, queryParams) -); + queryParams?: NodeQueryParams +): Promise => + request( + { + method: 'GET', + path: '/api/v1/node-info', + ...config, + }, + queryParams + ); diff --git a/source/renderer/app/api/nodes/requests/postponeNodeUpdate.js b/source/renderer/app/api/nodes/requests/postponeNodeUpdate.js index 50f2319ffc..0db4c334ec 100644 --- a/source/renderer/app/api/nodes/requests/postponeNodeUpdate.js +++ b/source/renderer/app/api/nodes/requests/postponeNodeUpdate.js @@ -2,12 +2,9 @@ import type { RequestConfig } from '../../common/types'; import { request } from '../../utils/request'; -export const postponeNodeUpdate = ( - config: RequestConfig -): Promise => ( +export const postponeNodeUpdate = (config: RequestConfig): Promise => request({ method: 'POST', path: '/api/internal/postpone-update', ...config, - }) -); + }); diff --git a/source/renderer/app/api/nodes/types.js b/source/renderer/app/api/nodes/types.js index 8e818f0798..ebfc0c8ab5 100644 --- a/source/renderer/app/api/nodes/types.js +++ b/source/renderer/app/api/nodes/types.js @@ -1,42 +1,45 @@ // @flow -export type LocalTimeInformationStatus = 'unavailable' | 'pending' | 'available'; +export type LocalTimeInformationStatus = + | 'unavailable' + | 'pending' + | 'available'; export type NodeInfo = { syncProgress: { quantity: number, - unit: 'percent' + unit: 'percent', }, blockchainHeight: ?{ quantity: number, - unit: ?'blocks' + unit: ?'blocks', }, localBlockchainHeight: { quantity: number, - unit: ?'blocks' + unit: ?'blocks', }, localTimeInformation: { status: LocalTimeInformationStatus, localTimeDifference?: { quantity: number, - unit: ?'microseconds' - } + unit: ?'microseconds', + }, }, - subscriptionStatus: Object + subscriptionStatus: Object, }; export type NodeSettings = { slotDuration: { quantity: number, - unit: ?'milliseconds' + unit: ?'milliseconds', }, softwareInfo: NodeSoftware, projectVersion: string, - gitRevision: string + gitRevision: string, }; export type NodeSoftware = { applicationName: string, - version: number + version: number, }; // req/res Node Types @@ -47,6 +50,6 @@ export type GetNetworkStatusResponse = { localBlockchainHeight: number, localTimeInformation: { status: LocalTimeInformationStatus, - difference: ?number - } + difference: ?number, + }, }; diff --git a/source/renderer/app/api/transactions/errors.js b/source/renderer/app/api/transactions/errors.js index 75567dfdd3..e669658984 100644 --- a/source/renderer/app/api/transactions/errors.js +++ b/source/renderer/app/api/transactions/errors.js @@ -4,58 +4,71 @@ import LocalizableError from '../../i18n/LocalizableError'; const messages = defineMessages({ notAllowedToSendMoneyToSameAddressError: { id: 'api.errors.NotAllowedToSendMoneyToSameAddressError', - defaultMessage: '!!!It\'s not allowed to send money to the same address you are sending from. Make sure you have enough addresses with money in this account or send to a different address.', - description: '"It\'s not allowed to send money to the same address you are sending from." error message.' + defaultMessage: + "!!!It's not allowed to send money to the same address you are sending from. Make sure you have enough addresses with money in this account or send to a different address.", + description: + '"It\'s not allowed to send money to the same address you are sending from." error message.', }, notAllowedToSendMoneyToRedeemAddressError: { id: 'api.errors.NotAllowedToSendMoneyToRedeemAddressError', - defaultMessage: '!!!It is not allowed to send money to ada redemption address.', - description: '"It is not allowed to send money to ada redemption address." error message.' + defaultMessage: + '!!!It is not allowed to send money to ada redemption address.', + description: + '"It is not allowed to send money to ada redemption address." error message.', }, notEnoughMoneyToSendError: { id: 'api.errors.NotEnoughMoneyToSendError', defaultMessage: '!!!Not enough money to make this transaction.', - description: '"Not enough money to make this transaction." error message.' + description: '"Not enough money to make this transaction." error message.', }, redeemAdaError: { id: 'api.errors.RedeemAdaError', defaultMessage: '!!!Your ADA could not be redeemed correctly.', - description: '"Your ADA could not be redeemed correctly." error message.' + description: '"Your ADA could not be redeemed correctly." error message.', }, allFundsAlreadyAtReceiverAddressError: { id: 'api.errors.AllFundsAlreadyAtReceiverAddressError', - defaultMessage: '!!!All your funds are already at the address you are trying send money to.', - description: '"All your funds are already at the address you are trying send money to." error message.' + defaultMessage: + '!!!All your funds are already at the address you are trying send money to.', + description: + '"All your funds are already at the address you are trying send money to." error message.', }, notEnoughFundsForTransactionFeesError: { id: 'api.errors.NotEnoughFundsForTransactionFeesError', defaultMessage: '!!!Not enough ada for fees. Try sending a smaller amount.', - description: '"Not enough ada for fees. Try sending a smaller amount." error message' + description: + '"Not enough ada for fees. Try sending a smaller amount." error message', }, notEnoughFundsForTransactionError: { id: 'api.errors.NotEnoughFundsForTransactionError', defaultMessage: '!!!Not enough ada . Try sending a smaller amount.', - description: '"Not enough ada . Try sending a smaller amount." error message' + description: + '"Not enough ada . Try sending a smaller amount." error message', }, canNotCalculateTransactionFeesError: { id: 'api.errors.CanNotCalculateTransactionFeesError', - defaultMessage: '!!!Cannot calculate fees while there are pending transactions.', - description: '"Cannot calculate fees while there are pending transactions." error message' + defaultMessage: + '!!!Cannot calculate fees while there are pending transactions.', + description: + '"Cannot calculate fees while there are pending transactions." error message', }, tooBigTransactionError: { id: 'api.errors.TooBigTransactionError', defaultMessage: '!!!Transaction too big due to too many inputs.', - description: '"Transaction too big due to too many inputs." error message.' + description: '"Transaction too big due to too many inputs." error message.', }, tooBigTransactionErrorLinkLabel: { id: 'api.errors.TooBigTransactionErrorLinkLabel', defaultMessage: '!!!Learn more.', - description: '"Transaction too big due to too many inputs." error link label.' + description: + '"Transaction too big due to too many inputs." error link label.', }, tooBigTransactionErrorLinkURL: { id: 'api.errors.TooBigTransactionErrorLinkURL', - defaultMessage: '!!!https://iohk.zendesk.com/hc/en-us/articles/360017733353', - description: '"Transaction too big due to too many inputs." error link URL.' + defaultMessage: + '!!!https://iohk.zendesk.com/hc/en-us/articles/360017733353', + description: + '"Transaction too big due to too many inputs." error link URL.', }, }); @@ -63,7 +76,8 @@ export class NotAllowedToSendMoneyToSameAddressError extends LocalizableError { constructor() { super({ id: messages.notAllowedToSendMoneyToSameAddressError.id, - defaultMessage: messages.notAllowedToSendMoneyToSameAddressError.defaultMessage, + defaultMessage: + messages.notAllowedToSendMoneyToSameAddressError.defaultMessage, }); } } @@ -72,7 +86,8 @@ export class NotAllowedToSendMoneyToRedeemAddressError extends LocalizableError constructor() { super({ id: messages.notAllowedToSendMoneyToRedeemAddressError.id, - defaultMessage: messages.notAllowedToSendMoneyToRedeemAddressError.defaultMessage, + defaultMessage: + messages.notAllowedToSendMoneyToRedeemAddressError.defaultMessage, }); } } @@ -99,7 +114,8 @@ export class AllFundsAlreadyAtReceiverAddressError extends LocalizableError { constructor() { super({ id: messages.allFundsAlreadyAtReceiverAddressError.id, - defaultMessage: messages.allFundsAlreadyAtReceiverAddressError.defaultMessage, + defaultMessage: + messages.allFundsAlreadyAtReceiverAddressError.defaultMessage, }); } } @@ -108,7 +124,8 @@ export class NotEnoughFundsForTransactionFeesError extends LocalizableError { constructor() { super({ id: messages.notEnoughFundsForTransactionFeesError.id, - defaultMessage: messages.notEnoughFundsForTransactionFeesError.defaultMessage, + defaultMessage: + messages.notEnoughFundsForTransactionFeesError.defaultMessage, }); } } @@ -126,7 +143,8 @@ export class CanNotCalculateTransactionFeesError extends LocalizableError { constructor() { super({ id: messages.canNotCalculateTransactionFeesError.id, - defaultMessage: messages.canNotCalculateTransactionFeesError.defaultMessage, + defaultMessage: + messages.canNotCalculateTransactionFeesError.defaultMessage, }); } } @@ -139,7 +157,7 @@ export class TooBigTransactionError extends LocalizableError { values: { linkLabel: messages.tooBigTransactionErrorLinkLabel, linkURL: messages.tooBigTransactionErrorLinkURL, - } + }, }); } } diff --git a/source/renderer/app/api/transactions/requests/createTransaction.js b/source/renderer/app/api/transactions/requests/createTransaction.js index 6563df4c01..b693dfbf50 100644 --- a/source/renderer/app/api/transactions/requests/createTransaction.js +++ b/source/renderer/app/api/transactions/requests/createTransaction.js @@ -18,10 +18,13 @@ export type TransactionParams = { export const createTransaction = ( config: RequestConfig, { data }: TransactionParams -): Promise => ( - request({ - method: 'POST', - path: '/api/v1/transactions', - ...config, - }, {}, data) -); +): Promise => + request( + { + method: 'POST', + path: '/api/v1/transactions', + ...config, + }, + {}, + data + ); diff --git a/source/renderer/app/api/transactions/requests/getTransactionFee.js b/source/renderer/app/api/transactions/requests/getTransactionFee.js index f45583397d..e165f5383b 100644 --- a/source/renderer/app/api/transactions/requests/getTransactionFee.js +++ b/source/renderer/app/api/transactions/requests/getTransactionFee.js @@ -7,10 +7,13 @@ import { request } from '../../utils/request'; export const getTransactionFee = ( config: RequestConfig, { data }: TransactionParams -): Promise => ( - request({ - method: 'POST', - path: '/api/v1/transactions/fees', - ...config, - }, {}, data) -); +): Promise => + request( + { + method: 'POST', + path: '/api/v1/transactions/fees', + ...config, + }, + {}, + data + ); diff --git a/source/renderer/app/api/transactions/requests/getTransactionHistory.js b/source/renderer/app/api/transactions/requests/getTransactionHistory.js index 800a8f7810..253e5d501c 100644 --- a/source/renderer/app/api/transactions/requests/getTransactionHistory.js +++ b/source/renderer/app/api/transactions/requests/getTransactionHistory.js @@ -19,10 +19,14 @@ const requestOptions = { export const getTransactionHistory = ( config: RequestConfig, { ...requestParams }: GetTxnHistoryParams -): Promise => ( - request({ - method: 'GET', - path: '/api/v1/transactions', - ...config, - }, requestParams, null, requestOptions) -); +): Promise => + request( + { + method: 'GET', + path: '/api/v1/transactions', + ...config, + }, + requestParams, + null, + requestOptions + ); diff --git a/source/renderer/app/api/transactions/requests/redeemAda.js b/source/renderer/app/api/transactions/requests/redeemAda.js index 63d67d7a56..a765d0adf7 100644 --- a/source/renderer/app/api/transactions/requests/redeemAda.js +++ b/source/renderer/app/api/transactions/requests/redeemAda.js @@ -8,16 +8,19 @@ export type RedeemAdaParams = { mnemonic: ?Array, spendingPassword?: string, walletId: string, - accountIndex: number + accountIndex: number, }; export const redeemAda = ( config: RequestConfig, redemptionParams: RedeemAdaParams -): Promise => ( - request({ - method: 'POST', - path: '/api/v1/transactions/certificates', - ...config - }, {}, redemptionParams) -); +): Promise => + request( + { + method: 'POST', + path: '/api/v1/transactions/certificates', + ...config, + }, + {}, + redemptionParams + ); diff --git a/source/renderer/app/api/transactions/requests/redeemPaperVendedAda.js b/source/renderer/app/api/transactions/requests/redeemPaperVendedAda.js index f7e6b01383..4aa6068d20 100644 --- a/source/renderer/app/api/transactions/requests/redeemPaperVendedAda.js +++ b/source/renderer/app/api/transactions/requests/redeemPaperVendedAda.js @@ -8,16 +8,19 @@ export type RedeemPaperVendedAdaParams = { mnemonic: Array, spendingPassword?: string, walletId: string, - accountIndex: number + accountIndex: number, }; export const redeemPaperVendedAda = ( config: RequestConfig, redemptionParams: RedeemPaperVendedAdaParams -): Promise => ( - request({ - method: 'POST', - path: '/api/v1/transactions/certificates', - ...config - }, {}, redemptionParams) -); +): Promise => + request( + { + method: 'POST', + path: '/api/v1/transactions/certificates', + ...config, + }, + {}, + redemptionParams + ); diff --git a/source/renderer/app/api/transactions/types.js b/source/renderer/app/api/transactions/types.js index 33592e341c..66517d23b6 100644 --- a/source/renderer/app/api/transactions/types.js +++ b/source/renderer/app/api/transactions/types.js @@ -24,7 +24,7 @@ export type Transaction = { export type PaymentDistribution = { address: string, - amount: number + amount: number, }; export type TxnAssuranceLevel = 'low' | 'medium' | 'high'; diff --git a/source/renderer/app/api/utils/apiHelpers.js b/source/renderer/app/api/utils/apiHelpers.js index 23025016ff..3fd593a9f2 100644 --- a/source/renderer/app/api/utils/apiHelpers.js +++ b/source/renderer/app/api/utils/apiHelpers.js @@ -1,11 +1,10 @@ // @flow import { ApiMethodNotYetImplementedError } from '../common/errors'; -export const notYetImplemented = async () => ( +export const notYetImplemented = async () => new Promise((resolve, reject) => { reject(new ApiMethodNotYetImplementedError()); - }) -); + }); // helper code for testing async APIs export const testAsync = async (apiMethod: Function) => { diff --git a/source/renderer/app/api/utils/index.js b/source/renderer/app/api/utils/index.js index d82ca58d71..194da06851 100644 --- a/source/renderer/app/api/utils/index.js +++ b/source/renderer/app/api/utils/index.js @@ -3,19 +3,19 @@ import moment from 'moment'; import blakejs from 'blakejs'; // time utils -export const unixTimestampToDate = (timestamp: number) => new Date(timestamp * 1000); -export const utcStringToDate = (createDate: string) => moment.utc(createDate).toDate(); +export const unixTimestampToDate = (timestamp: number) => + new Date(timestamp * 1000); +export const utcStringToDate = (createDate: string) => + moment.utc(createDate).toDate(); // passphrase utils -const bytesToB16 = (bytes) => Buffer.from(bytes).toString('hex'); -const blake2b = (data) => blakejs.blake2b(data, null, 32); +const bytesToB16 = bytes => Buffer.from(bytes).toString('hex'); +const blake2b = data => blakejs.blake2b(data, null, 32); -export const encryptPassphrase = (passphrase: ?string) => ( - bytesToB16(blake2b(passphrase)) -); +export const encryptPassphrase = (passphrase: ?string) => + bytesToB16(blake2b(passphrase)); // string utils -export const getContentLength = (content: string) => ( +export const getContentLength = (content: string) => // 'TextEncoder' is used to measure correct length of UTF-8 strings - (new TextEncoder()).encode(content).length -); + new TextEncoder().encode(content).length; diff --git a/source/renderer/app/api/utils/localStorage.js b/source/renderer/app/api/utils/localStorage.js index 33c0a711a3..d5b11b158f 100644 --- a/source/renderer/app/api/utils/localStorage.js +++ b/source/renderer/app/api/utils/localStorage.js @@ -25,109 +25,123 @@ export default class LocalStorageApi { }; } - getUserLocale = (): Promise => new Promise((resolve, reject) => { - try { - const locale = store.get(this.storageKeys.USER_LOCALE); - if (!locale) return resolve(''); - resolve(locale); - } catch (error) { - return reject(error); - } - }); - - setUserLocale = (locale: string): Promise => new Promise((resolve, reject) => { - try { - store.set(this.storageKeys.USER_LOCALE, locale); - resolve(); - } catch (error) { - return reject(error); - } - }); - - unsetUserLocale = (): Promise => new Promise((resolve) => { - try { - store.delete(this.storageKeys.USER_LOCALE); - resolve(); - } catch (error) {} // eslint-disable-line - }); - - getTermsOfUseAcceptance = (): Promise => new Promise((resolve, reject) => { - try { - const accepted = store.get(this.storageKeys.TERMS_OF_USE_ACCEPTANCE); - if (!accepted) return resolve(false); - resolve(accepted); - } catch (error) { - return reject(error); - } - }); - - setTermsOfUseAcceptance = (): Promise => new Promise((resolve, reject) => { - try { - store.set(this.storageKeys.TERMS_OF_USE_ACCEPTANCE, true); - resolve(); - } catch (error) { - return reject(error); - } - }); - - unsetTermsOfUseAcceptance = (): Promise => new Promise((resolve) => { - try { - store.delete(this.storageKeys.TERMS_OF_USE_ACCEPTANCE); - resolve(); - } catch (error) {} // eslint-disable-line - }); - - getUserTheme = (): Promise => new Promise((resolve, reject) => { - try { - const theme = store.get(this.storageKeys.THEME); - if (!theme) return resolve(''); - resolve(theme); - } catch (error) { - return reject(error); - } - }); - - setUserTheme = (theme: string): Promise => new Promise((resolve, reject) => { - try { - store.set(this.storageKeys.THEME, theme); - resolve(); - } catch (error) { - return reject(error); - } - }); - - unsetUserTheme = (): Promise => new Promise((resolve) => { - try { - store.delete(this.storageKeys.THEME); - resolve(); - } catch (error) {} // eslint-disable-line - }); - - getDataLayerMigrationAcceptance = (): Promise => new Promise((resolve, reject) => { - try { - const accepted = store.get(this.storageKeys.DATA_LAYER_MIGRATION_ACCEPTANCE); - if (!accepted) return resolve(false); - resolve(true); - } catch (error) { - return reject(error); - } - }); - - setDataLayerMigrationAcceptance = (): Promise => new Promise((resolve, reject) => { - try { - store.set(this.storageKeys.DATA_LAYER_MIGRATION_ACCEPTANCE, true); - resolve(); - } catch (error) { - return reject(error); - } - }); - - unsetDataLayerMigrationAcceptance = (): Promise => new Promise((resolve) => { - try { - store.delete(this.storageKeys.DATA_LAYER_MIGRATION_ACCEPTANCE); - resolve(); - } catch (error) {} // eslint-disable-line - }); + getUserLocale = (): Promise => + new Promise((resolve, reject) => { + try { + const locale = store.get(this.storageKeys.USER_LOCALE); + if (!locale) return resolve(''); + resolve(locale); + } catch (error) { + return reject(error); + } + }); + + setUserLocale = (locale: string): Promise => + new Promise((resolve, reject) => { + try { + store.set(this.storageKeys.USER_LOCALE, locale); + resolve(); + } catch (error) { + return reject(error); + } + }); + + unsetUserLocale = (): Promise => + new Promise(resolve => { + try { + store.delete(this.storageKeys.USER_LOCALE); + resolve(); + } catch (error) {} // eslint-disable-line + }); + + getTermsOfUseAcceptance = (): Promise => + new Promise((resolve, reject) => { + try { + const accepted = store.get(this.storageKeys.TERMS_OF_USE_ACCEPTANCE); + if (!accepted) return resolve(false); + resolve(accepted); + } catch (error) { + return reject(error); + } + }); + + setTermsOfUseAcceptance = (): Promise => + new Promise((resolve, reject) => { + try { + store.set(this.storageKeys.TERMS_OF_USE_ACCEPTANCE, true); + resolve(); + } catch (error) { + return reject(error); + } + }); + + unsetTermsOfUseAcceptance = (): Promise => + new Promise(resolve => { + try { + store.delete(this.storageKeys.TERMS_OF_USE_ACCEPTANCE); + resolve(); + } catch (error) {} // eslint-disable-line + }); + + getUserTheme = (): Promise => + new Promise((resolve, reject) => { + try { + const theme = store.get(this.storageKeys.THEME); + if (!theme) return resolve(''); + resolve(theme); + } catch (error) { + return reject(error); + } + }); + + setUserTheme = (theme: string): Promise => + new Promise((resolve, reject) => { + try { + store.set(this.storageKeys.THEME, theme); + resolve(); + } catch (error) { + return reject(error); + } + }); + + unsetUserTheme = (): Promise => + new Promise(resolve => { + try { + store.delete(this.storageKeys.THEME); + resolve(); + } catch (error) {} // eslint-disable-line + }); + + getDataLayerMigrationAcceptance = (): Promise => + new Promise((resolve, reject) => { + try { + const accepted = store.get( + this.storageKeys.DATA_LAYER_MIGRATION_ACCEPTANCE + ); + if (!accepted) return resolve(false); + resolve(true); + } catch (error) { + return reject(error); + } + }); + + setDataLayerMigrationAcceptance = (): Promise => + new Promise((resolve, reject) => { + try { + store.set(this.storageKeys.DATA_LAYER_MIGRATION_ACCEPTANCE, true); + resolve(); + } catch (error) { + return reject(error); + } + }); + + unsetDataLayerMigrationAcceptance = (): Promise => + new Promise(resolve => { + try { + store.delete(this.storageKeys.DATA_LAYER_MIGRATION_ACCEPTANCE); + resolve(); + } catch (error) {} // eslint-disable-line + }); reset = async () => { await this.unsetUserLocale(); @@ -135,5 +149,4 @@ export default class LocalStorageApi { await this.unsetUserTheme(); await this.unsetDataLayerMigrationAcceptance(); }; - } diff --git a/source/renderer/app/api/utils/mnemonics.js b/source/renderer/app/api/utils/mnemonics.js index 6240560f6c..a5be558d67 100644 --- a/source/renderer/app/api/utils/mnemonics.js +++ b/source/renderer/app/api/utils/mnemonics.js @@ -2,7 +2,7 @@ import { unscramblePaperWalletMnemonic, scramblePaperWalletMnemonic, - generateMnemonic + generateMnemonic, } from '../../utils/crypto'; import { PAPER_WALLET_WRITTEN_WORDS_COUNT } from '../../config/cryptoConfig'; @@ -11,23 +11,21 @@ type MnemonicsParams = { scrambledInput: string, // 18-word scrambled mnemonic }; -export const unscrambleMnemonics = ( - { passphrase, scrambledInput }: MnemonicsParams -): Array => ( - unscramblePaperWalletMnemonic(passphrase, scrambledInput) -); +export const unscrambleMnemonics = ({ + passphrase, + scrambledInput, +}: MnemonicsParams): Array => + unscramblePaperWalletMnemonic(passphrase, scrambledInput); -export const scrambleMnemonics = ( - { passphrase, scrambledInput }: MnemonicsParams -): Array => ( - scramblePaperWalletMnemonic(passphrase, scrambledInput) -); +export const scrambleMnemonics = ({ + passphrase, + scrambledInput, +}: MnemonicsParams): Array => + scramblePaperWalletMnemonic(passphrase, scrambledInput); -export const generateAccountMnemonics = (): Array => ( - generateMnemonic().split(' ') -); +export const generateAccountMnemonics = (): Array => + generateMnemonic().split(' '); // eslint-disable-next-line -export const generateAdditionalMnemonics = (): Array => ( - generateMnemonic(PAPER_WALLET_WRITTEN_WORDS_COUNT).split(' ') -); +export const generateAdditionalMnemonics = (): Array => + generateMnemonic(PAPER_WALLET_WRITTEN_WORDS_COUNT).split(' '); diff --git a/source/renderer/app/api/utils/patchAdaApi.js b/source/renderer/app/api/utils/patchAdaApi.js index d12d689562..d7f21e3afc 100644 --- a/source/renderer/app/api/utils/patchAdaApi.js +++ b/source/renderer/app/api/utils/patchAdaApi.js @@ -18,49 +18,60 @@ let NEXT_ADA_UPDATE = null; export default (api: AdaApi) => { // Since we cannot test ada redemption in dev mode, just resolve the requests - api.redeemAda = ( - request: RedeemAdaParams - ): Promise => new Promise((resolve) => { - try { - Logger.debug('AdaApi::redeemAda (PATCHED) called', { request }); - const { redemptionCode } = request; - const isValidRedemptionCode = api.isValidRedemptionKey(redemptionCode); - if (!isValidRedemptionCode) { - Logger.debug('AdaApi::redeemAda (PATCHED) failed: not a valid redemption key!'); + api.redeemAda = (request: RedeemAdaParams): Promise => + new Promise(resolve => { + try { + Logger.debug('AdaApi::redeemAda (PATCHED) called', { request }); + const { redemptionCode } = request; + const isValidRedemptionCode = api.isValidRedemptionKey(redemptionCode); + if (!isValidRedemptionCode) { + Logger.debug( + 'AdaApi::redeemAda (PATCHED) failed: not a valid redemption key!' + ); + throw new RedeemAdaError(); + } + Logger.debug('AdaApi::redeemAda (PATCHED) success'); + resolve({ amount: new BigNumber(1000) }); + } catch (error) { + Logger.error('AdaApi::redeemAda (PATCHED) error', { error }); throw new RedeemAdaError(); } - Logger.debug('AdaApi::redeemAda (PATCHED) success'); - resolve({ amount: new BigNumber(1000) }); - } catch (error) { - Logger.error('AdaApi::redeemAda (PATCHED) error', { error }); - throw new RedeemAdaError(); - } - }); + }); api.redeemPaperVendedAda = ( request: RedeemPaperVendedAdaParams - ): Promise => new Promise((resolve) => { - try { - Logger.debug('AdaApi::redeemPaperVendedAda (PATCHED) called', { request }); - const { redemptionCode, mnemonic } = request; - const isValidKey = api.isValidPaperVendRedemptionKey(redemptionCode); - const isValidMnemonic = api.isValidRedemptionMnemonic(mnemonic.join(' ')); - if (!isValidKey) Logger.debug('AdaApi::redeemPaperVendedAda (PATCHED) failed: not a valid redemption key!'); - if (!isValidMnemonic) Logger.debug('AdaApi::redeemPaperVendedAda (PATCHED) failed: not a valid mnemonic!'); - if (!isValidKey || !isValidMnemonic) { + ): Promise => + new Promise(resolve => { + try { + Logger.debug('AdaApi::redeemPaperVendedAda (PATCHED) called', { + request, + }); + const { redemptionCode, mnemonic } = request; + const isValidKey = api.isValidPaperVendRedemptionKey(redemptionCode); + const isValidMnemonic = api.isValidRedemptionMnemonic( + mnemonic.join(' ') + ); + if (!isValidKey) + Logger.debug( + 'AdaApi::redeemPaperVendedAda (PATCHED) failed: not a valid redemption key!' + ); + if (!isValidMnemonic) + Logger.debug( + 'AdaApi::redeemPaperVendedAda (PATCHED) failed: not a valid mnemonic!' + ); + if (!isValidKey || !isValidMnemonic) { + throw new RedeemAdaError(); + } + Logger.debug('AdaApi::redeemPaperVendedAda (PATCHED) success'); + resolve({ amount: new BigNumber(1000) }); + } catch (error) { + Logger.error('AdaApi::redeemPaperVendedAda (PATCHED) error', { error }); throw new RedeemAdaError(); } - Logger.debug('AdaApi::redeemPaperVendedAda (PATCHED) success'); - resolve({ amount: new BigNumber(1000) }); - } catch (error) { - Logger.error('AdaApi::redeemPaperVendedAda (PATCHED) error', { error }); - throw new RedeemAdaError(); - } - }); + }); - api.getLocalTimeDifference = async () => ( - Promise.resolve(LOCAL_TIME_DIFFERENCE) - ); + api.getLocalTimeDifference = async () => + Promise.resolve(LOCAL_TIME_DIFFERENCE); api.getNetworkStatus = async ( queryParams?: NodeQueryParams @@ -94,15 +105,13 @@ export default (api: AdaApi) => { } }; - api.setLocalTimeDifference = async (timeDifference) => { + api.setLocalTimeDifference = async timeDifference => { LOCAL_TIME_DIFFERENCE = timeDifference; }; - api.nextUpdate = async () => ( - Promise.resolve(NEXT_ADA_UPDATE) - ); + api.nextUpdate = async () => Promise.resolve(NEXT_ADA_UPDATE); - api.setNextUpdate = async (nextUpdate) => { + api.setNextUpdate = async nextUpdate => { NEXT_ADA_UPDATE = nextUpdate; }; }; diff --git a/source/renderer/app/api/utils/request.js b/source/renderer/app/api/utils/request.js index b5cb123616..18ccfc236d 100644 --- a/source/renderer/app/api/utils/request.js +++ b/source/renderer/app/api/utils/request.js @@ -21,7 +21,7 @@ function typedRequest( httpOptions: RequestOptions, queryParams?: {}, rawBodyParams?: any, - requestOptions?: { returnMeta: boolean }, + requestOptions?: { returnMeta: boolean } ): Promise { return new Promise((resolve, reject) => { const options: RequestOptions = Object.assign({}, httpOptions); @@ -69,12 +69,12 @@ function typedRequest( if (hasRequestBody) { httpsRequest.write(requestBody); } - httpsRequest.on('response', (response) => { + httpsRequest.on('response', response => { let body = ''; // Cardano-sl returns chunked requests, so we need to concat them - response.on('data', (chunk) => (body += chunk)); + response.on('data', chunk => (body += chunk)); // Reject errors - response.on('error', (error) => reject(error)); + response.on('error', error => reject(error)); // Resolve JSON results and handle backend errors response.on('end', () => { try { @@ -121,7 +121,7 @@ function typedRequest( } }); }); - httpsRequest.on('error', (error) => reject(error)); + httpsRequest.on('error', error => reject(error)); httpsRequest.end(); }); } diff --git a/source/renderer/app/api/utils/requestV0.js b/source/renderer/app/api/utils/requestV0.js index f739f0c3f4..e7ba262645 100644 --- a/source/renderer/app/api/utils/requestV0.js +++ b/source/renderer/app/api/utils/requestV0.js @@ -19,7 +19,9 @@ export type RequestOptions = { }; function typedRequest( - httpOptions: RequestOptions, queryParams?: {}, rawBodyParams?: any + httpOptions: RequestOptions, + queryParams?: {}, + rawBodyParams?: any ): Promise { return new Promise((resolve, reject) => { const options: RequestOptions = Object.assign({}, httpOptions); @@ -65,12 +67,12 @@ function typedRequest( if (hasRequestBody) { httpsRequest.write(requestBody); } - httpsRequest.on('response', (response) => { + httpsRequest.on('response', response => { let body = ''; // Cardano-sl returns chunked requests, so we need to concat them - response.on('data', (chunk) => (body += chunk)); + response.on('data', chunk => (body += chunk)); // Reject errors - response.on('error', (error) => reject(error)); + response.on('error', error => reject(error)); // Resolve JSON results and handle weird backend behavior // of "Left" (for errors) and "Right" (for success) properties response.on('end', () => { @@ -96,7 +98,7 @@ function typedRequest( } }); }); - httpsRequest.on('error', (error) => reject(error)); + httpsRequest.on('error', error => reject(error)); httpsRequest.end(); }); } diff --git a/source/renderer/app/api/wallets/errors.js b/source/renderer/app/api/wallets/errors.js index b22f5501fc..d0e780403e 100644 --- a/source/renderer/app/api/wallets/errors.js +++ b/source/renderer/app/api/wallets/errors.js @@ -5,17 +5,21 @@ const messages = defineMessages({ walletAlreadyRestoredError: { id: 'api.errors.WalletAlreadyRestoredError', defaultMessage: '!!!Wallet you are trying to restore already exists.', - description: '"Wallet you are trying to restore already exists." error message.' + description: + '"Wallet you are trying to restore already exists." error message.', }, walletAlreadyImportedError: { id: 'api.errors.WalletAlreadyImportedError', defaultMessage: '!!!Wallet you are trying to import already exists.', - description: '"Wallet you are trying to import already exists." error message.' + description: + '"Wallet you are trying to import already exists." error message.', }, walletFileImportError: { id: 'api.errors.WalletFileImportError', - defaultMessage: '!!!Wallet could not be imported, please make sure you are providing a correct file.', - description: '"Wallet could not be imported, please make sure you are providing a correct file." error message.' + defaultMessage: + '!!!Wallet could not be imported, please make sure you are providing a correct file.', + description: + '"Wallet could not be imported, please make sure you are providing a correct file." error message.', }, }); diff --git a/source/renderer/app/api/wallets/requests/changeSpendingPassword.js b/source/renderer/app/api/wallets/requests/changeSpendingPassword.js index 80784914a9..d090fcca04 100644 --- a/source/renderer/app/api/wallets/requests/changeSpendingPassword.js +++ b/source/renderer/app/api/wallets/requests/changeSpendingPassword.js @@ -14,11 +14,19 @@ export const changeSpendingPassword = ( config: RequestConfig, { walletId, oldPassword, newPassword }: ChangeSpendingPasswordParams ): Promise => { - const encryptedOldPassphrase = oldPassword ? encryptPassphrase(oldPassword) : ''; - const encryptedNewPassphrase = newPassword ? encryptPassphrase(newPassword) : ''; - return request({ - method: 'PUT', - path: `/api/v1/wallets/${walletId}/password`, - ...config, - }, {}, { old: encryptedOldPassphrase, new: encryptedNewPassphrase }); + const encryptedOldPassphrase = oldPassword + ? encryptPassphrase(oldPassword) + : ''; + const encryptedNewPassphrase = newPassword + ? encryptPassphrase(newPassword) + : ''; + return request( + { + method: 'PUT', + path: `/api/v1/wallets/${walletId}/password`, + ...config, + }, + {}, + { old: encryptedOldPassphrase, new: encryptedNewPassphrase } + ); }; diff --git a/source/renderer/app/api/wallets/requests/createWallet.js b/source/renderer/app/api/wallets/requests/createWallet.js index 2cf3a9c371..fb9f0bbea9 100644 --- a/source/renderer/app/api/wallets/requests/createWallet.js +++ b/source/renderer/app/api/wallets/requests/createWallet.js @@ -14,10 +14,13 @@ export type WalletInitData = { export const createWallet = ( config: RequestConfig, { walletInitData }: { walletInitData: WalletInitData } -): Promise => ( - request({ - method: 'POST', - path: '/api/v1/wallets', - ...config, - }, {}, walletInitData) -); +): Promise => + request( + { + method: 'POST', + path: '/api/v1/wallets', + ...config, + }, + {}, + walletInitData + ); diff --git a/source/renderer/app/api/wallets/requests/deleteWallet.js b/source/renderer/app/api/wallets/requests/deleteWallet.js index bfc3c6e41a..a30ea836e4 100644 --- a/source/renderer/app/api/wallets/requests/deleteWallet.js +++ b/source/renderer/app/api/wallets/requests/deleteWallet.js @@ -9,10 +9,9 @@ export type DeleteWalletParams = { export const deleteWallet = ( config: RequestConfig, { walletId }: DeleteWalletParams -): Promise<*> => ( +): Promise<*> => request({ method: 'DELETE', path: `/api/v1/wallets/${walletId}`, ...config, - }) -); + }); diff --git a/source/renderer/app/api/wallets/requests/exportWalletAsJSON.js b/source/renderer/app/api/wallets/requests/exportWalletAsJSON.js index 0b7dafdd65..344fbf97eb 100644 --- a/source/renderer/app/api/wallets/requests/exportWalletAsJSON.js +++ b/source/renderer/app/api/wallets/requests/exportWalletAsJSON.js @@ -9,11 +9,14 @@ export type ExportWalletAsJSONParams = { export const exportWalletAsJSON = ( config: RequestConfig, - { walletId, filePath }: ExportWalletAsJSONParams, -): Promise<[]> => ( - request({ - method: 'POST', - path: `/api/backup/export/${walletId}`, - ...config, - }, {}, filePath) -); + { walletId, filePath }: ExportWalletAsJSONParams +): Promise<[]> => + request( + { + method: 'POST', + path: `/api/backup/export/${walletId}`, + ...config, + }, + {}, + filePath + ); diff --git a/source/renderer/app/api/wallets/requests/getWallets.js b/source/renderer/app/api/wallets/requests/getWallets.js index 6acb52dd1f..c70ca33004 100644 --- a/source/renderer/app/api/wallets/requests/getWallets.js +++ b/source/renderer/app/api/wallets/requests/getWallets.js @@ -4,15 +4,15 @@ import type { AdaWallets } from '../types'; import { request } from '../../utils/request'; import { MAX_ADA_WALLETS_COUNT } from '../../../config/numbersConfig'; -export const getWallets = ( - config: RequestConfig -): Promise => ( - request({ - method: 'GET', - path: '/api/v1/wallets', - ...config, - }, { - per_page: MAX_ADA_WALLETS_COUNT, // 50 is the max per_page value - sort_by: 'ASC[created_at]', - }) -); +export const getWallets = (config: RequestConfig): Promise => + request( + { + method: 'GET', + path: '/api/v1/wallets', + ...config, + }, + { + per_page: MAX_ADA_WALLETS_COUNT, // 50 is the max per_page value + sort_by: 'ASC[created_at]', + } + ); diff --git a/source/renderer/app/api/wallets/requests/importWalletAsJSON.js b/source/renderer/app/api/wallets/requests/importWalletAsJSON.js index 37be1c93ee..3c8efef52a 100644 --- a/source/renderer/app/api/wallets/requests/importWalletAsJSON.js +++ b/source/renderer/app/api/wallets/requests/importWalletAsJSON.js @@ -5,11 +5,14 @@ import { request } from '../../utils/requestV0'; export const importWalletAsJSON = ( config: RequestConfig, - filePath: string, -): Promise => ( - request({ - method: 'POST', - path: '/api/backup/import', - ...config, - }, {}, filePath) -); + filePath: string +): Promise => + request( + { + method: 'POST', + path: '/api/backup/import', + ...config, + }, + {}, + filePath + ); diff --git a/source/renderer/app/api/wallets/requests/importWalletAsKey.js b/source/renderer/app/api/wallets/requests/importWalletAsKey.js index 6dcb66c815..5b80ec28dc 100644 --- a/source/renderer/app/api/wallets/requests/importWalletAsKey.js +++ b/source/renderer/app/api/wallets/requests/importWalletAsKey.js @@ -11,10 +11,13 @@ export type ImportWalletAsKey = { export const importWalletAsKey = ( config: RequestConfig, walletImportData: ImportWalletAsKey -): Promise => ( - request({ - method: 'POST', - path: '/api/internal/import-wallet', - ...config, - }, {}, walletImportData) -); +): Promise => + request( + { + method: 'POST', + path: '/api/internal/import-wallet', + ...config, + }, + {}, + walletImportData + ); diff --git a/source/renderer/app/api/wallets/requests/resetWalletState.js b/source/renderer/app/api/wallets/requests/resetWalletState.js index bb22f184d3..1fa4a55a8e 100644 --- a/source/renderer/app/api/wallets/requests/resetWalletState.js +++ b/source/renderer/app/api/wallets/requests/resetWalletState.js @@ -2,12 +2,9 @@ import type { RequestConfig } from '../../common/types'; import { request } from '../../utils/request'; -export const resetWalletState = ( - config: RequestConfig -): Promise => ( +export const resetWalletState = (config: RequestConfig): Promise => request({ method: 'DELETE', path: '/api/internal/reset-wallet-state', ...config, - }) -); + }); diff --git a/source/renderer/app/api/wallets/requests/restoreWallet.js b/source/renderer/app/api/wallets/requests/restoreWallet.js index 79243b8d89..27e32c4832 100644 --- a/source/renderer/app/api/wallets/requests/restoreWallet.js +++ b/source/renderer/app/api/wallets/requests/restoreWallet.js @@ -7,10 +7,13 @@ import { request } from '../../utils/request'; export const restoreWallet = ( config: RequestConfig, { walletInitData }: { walletInitData: WalletInitData } -): Promise => ( - request({ - method: 'POST', - path: '/api/v1/wallets', - ...config, - }, {}, walletInitData) -); +): Promise => + request( + { + method: 'POST', + path: '/api/v1/wallets', + ...config, + }, + {}, + walletInitData + ); diff --git a/source/renderer/app/api/wallets/requests/updateWallet.js b/source/renderer/app/api/wallets/requests/updateWallet.js index 2b1e715194..d139d4324c 100644 --- a/source/renderer/app/api/wallets/requests/updateWallet.js +++ b/source/renderer/app/api/wallets/requests/updateWallet.js @@ -6,16 +6,19 @@ import { request } from '../../utils/request'; export type UpdateWalletParams = { walletId: string, assuranceLevel: WalletAssuranceLevel, - name: string + name: string, }; export const updateWallet = ( config: RequestConfig, { walletId, assuranceLevel, name }: UpdateWalletParams -): Promise => ( - request({ - method: 'PUT', - path: `/api/v1/wallets/${walletId}`, - ...config, - }, {}, { assuranceLevel, name }) -); +): Promise => + request( + { + method: 'PUT', + path: `/api/v1/wallets/${walletId}`, + ...config, + }, + {}, + { assuranceLevel, name } + ); diff --git a/source/renderer/app/api/wallets/types.js b/source/renderer/app/api/wallets/types.js index eaf6c15c86..a45e1d42b0 100644 --- a/source/renderer/app/api/wallets/types.js +++ b/source/renderer/app/api/wallets/types.js @@ -62,7 +62,7 @@ export type RestoreWalletRequest = { export type UpdateWalletRequest = { walletId: string, assuranceLevel: WalletAssuranceLevel, - name: string + name: string, }; export type ImportWalletFromKeyRequest = { filePath: string, @@ -78,7 +78,7 @@ export type ImportWalletFromFileRequest = { export type ExportWalletToFileRequest = { walletId: string, filePath: string, - password: ?string + password: ?string, }; export type GetWalletCertificateRecoveryPhraseRequest = { diff --git a/source/renderer/app/components/layout/CenteredLayout.js b/source/renderer/app/components/layout/CenteredLayout.js index c9899bca80..850545ee06 100644 --- a/source/renderer/app/components/layout/CenteredLayout.js +++ b/source/renderer/app/components/layout/CenteredLayout.js @@ -10,17 +10,12 @@ type Props = { @observer export default class CenteredLayout extends Component { - static defaultProps = { - children: null + children: null, }; render() { const { children } = this.props; - return ( -
- {children} -
- ); + return
{children}
; } } diff --git a/source/renderer/app/components/layout/SidebarLayout.js b/source/renderer/app/components/layout/SidebarLayout.js index 935e3b88ac..5ae82813be 100644 --- a/source/renderer/app/components/layout/SidebarLayout.js +++ b/source/renderer/app/components/layout/SidebarLayout.js @@ -14,31 +14,27 @@ type Props = { @observer export default class SidebarLayout extends Component { - static defaultProps = { - children: null + children: null, }; render() { const { - children, sidebar, topbar, - notification, contentDialogs, + children, + sidebar, + topbar, + notification, + contentDialogs, } = this.props; return (
-
- {sidebar} -
+
{sidebar}
-
- {topbar} -
+
{topbar}
{notification}
-
- {children} -
+
{children}
{contentDialogs}
diff --git a/source/renderer/app/components/layout/TopBar.js b/source/renderer/app/components/layout/TopBar.js index 86462f5193..61b432dde3 100644 --- a/source/renderer/app/components/layout/TopBar.js +++ b/source/renderer/app/components/layout/TopBar.js @@ -17,11 +17,8 @@ type Props = { @observer export default class TopBar extends Component { - render() { - const { - onLeftIconClick, leftIcon, activeWallet, children, - } = this.props; + const { onLeftIconClick, leftIcon, activeWallet, children } = this.props; const topBarStyles = classNames([ styles.topBar, @@ -32,19 +29,14 @@ export default class TopBar extends Component {
{activeWallet.name}
- { - // show currency and use long format - formattedWalletAmount(activeWallet.amount, true) - } + {// show currency and use long format + formattedWalletAmount(activeWallet.amount, true)}
) : null; const leftIconSVG = leftIcon && ( - + ); return ( @@ -59,5 +51,4 @@ export default class TopBar extends Component { ); } - } diff --git a/source/renderer/app/components/layout/TopBar.scss b/source/renderer/app/components/layout/TopBar.scss index 9f6dcb7b16..719ff052f5 100644 --- a/source/renderer/app/components/layout/TopBar.scss +++ b/source/renderer/app/components/layout/TopBar.scss @@ -8,7 +8,8 @@ z-index: 100; &.withoutWallet { - background: var(--theme-topbar-background-color) url("../../assets/images/header-logo.svg") no-repeat center !important; + background: var(--theme-topbar-background-color) + url('../../assets/images/header-logo.svg') no-repeat center !important; background-size: 61px !important; } @@ -60,4 +61,3 @@ margin-right: 24px; } } - diff --git a/source/renderer/app/components/layout/TopBarLayout.js b/source/renderer/app/components/layout/TopBarLayout.js index 7e662127a2..ee133637ca 100644 --- a/source/renderer/app/components/layout/TopBarLayout.js +++ b/source/renderer/app/components/layout/TopBarLayout.js @@ -12,18 +12,13 @@ type Props = { @observer export default class TopBarLayout extends Component { - render() { const { children, topbar, notification } = this.props; return (
-
- {topbar} -
+
{topbar}
{notification} -
- {children} -
+
{children}
); } diff --git a/source/renderer/app/components/layout/VerticalFlexContainer.js b/source/renderer/app/components/layout/VerticalFlexContainer.js index 996b022f56..47413b1309 100644 --- a/source/renderer/app/components/layout/VerticalFlexContainer.js +++ b/source/renderer/app/components/layout/VerticalFlexContainer.js @@ -12,10 +12,6 @@ type Props = { export default class VerticalFlexContainer extends Component { render() { const { children } = this.props; - return ( -
- {children} -
- ); + return
{children}
; } } diff --git a/source/renderer/app/components/loading/Loading.js b/source/renderer/app/components/loading/Loading.js index 4f2d095948..eb3af48953 100644 --- a/source/renderer/app/components/loading/Loading.js +++ b/source/renderer/app/components/loading/Loading.js @@ -24,72 +24,75 @@ const messages = defineMessages({ starting: { id: 'loading.screen.startingCardanoMessage', defaultMessage: '!!!Starting Cardano node', - description: 'Message "Starting Cardano node" on the loading screen.' + description: 'Message "Starting Cardano node" on the loading screen.', }, stopping: { id: 'loading.screen.stoppingCardanoMessage', defaultMessage: '!!!Stopping Cardano node', - description: 'Message "Stopping Cardano node" on the loading screen.' + description: 'Message "Stopping Cardano node" on the loading screen.', }, stopped: { id: 'loading.screen.stoppedCardanoMessage', defaultMessage: '!!!Cardano node stopped', - description: 'Message "Cardano node stopped" on the loading screen.' + description: 'Message "Cardano node stopped" on the loading screen.', }, updating: { id: 'loading.screen.updatingCardanoMessage', defaultMessage: '!!!Updating Cardano node', - description: 'Message "Updating Cardano node" on the loading screen.' + description: 'Message "Updating Cardano node" on the loading screen.', }, updated: { id: 'loading.screen.updatedCardanoMessage', defaultMessage: '!!!Cardano node updated', - description: 'Message "Cardano node updated" on the loading screen.' + description: 'Message "Cardano node updated" on the loading screen.', }, crashed: { id: 'loading.screen.crashedCardanoMessage', defaultMessage: '!!!Cardano node crashed', - description: 'Message "Cardano node crashed" on the loading screen.' + description: 'Message "Cardano node crashed" on the loading screen.', }, unrecoverable: { id: 'loading.screen.unrecoverableCardanoMessage', - defaultMessage: '!!!Unable to start Cardano node. Please submit a support request.', - description: 'Message "Unable to start Cardano node. Please submit a support request." on the loading screen.' + defaultMessage: + '!!!Unable to start Cardano node. Please submit a support request.', + description: + 'Message "Unable to start Cardano node. Please submit a support request." on the loading screen.', }, connecting: { id: 'loading.screen.connectingToNetworkMessage', defaultMessage: '!!!Connecting to network', - description: 'Message "Connecting to network" on the loading screen.' + description: 'Message "Connecting to network" on the loading screen.', }, reconnecting: { id: 'loading.screen.reconnectingToNetworkMessage', defaultMessage: '!!!Network connection lost - reconnecting', - description: 'Message "Network connection lost - reconnecting" on the loading screen.' + description: + 'Message "Network connection lost - reconnecting" on the loading screen.', }, syncing: { id: 'loading.screen.syncingBlocksMessage', defaultMessage: '!!!Syncing blocks', - description: 'Message "Syncing blocks" on the loading screen.' + description: 'Message "Syncing blocks" on the loading screen.', }, reportConnectingIssueText: { id: 'loading.screen.reportIssue.connecting.text', defaultMessage: '!!!Having trouble connecting to network?', - description: 'Report connecting issue text on the loading screen.' + description: 'Report connecting issue text on the loading screen.', }, reportSyncingIssueText: { id: 'loading.screen.reportIssue.syncing.text', defaultMessage: '!!!Having trouble syncing?', - description: 'Report syncing issue text on the loading screen.' + description: 'Report syncing issue text on the loading screen.', }, reportIssueButtonLabel: { id: 'loading.screen.reportIssue.buttonLabel', defaultMessage: '!!!Open support ticket', - description: 'Open support ticket button label on the loading.' + description: 'Open support ticket button label on the loading.', }, reportIssueDownloadLogsLinkLabel: { id: 'loading.screen.reportIssue.downloadLogsLinkLabel', defaultMessage: '!!!Download logs', - description: 'Download logs button label on the loading.' + description: 'Download logs button label on the loading.', }, }); @@ -129,7 +132,6 @@ type Props = { @observer export default class Loading extends Component { - static contextTypes = { intl: intlShape.isRequired, }; @@ -152,10 +154,20 @@ export default class Loading extends Component { componentDidUpdate() { const { isConnected, isSynced, isNotEnoughDiskSpace } = this.props; - const canResetSyncing = this._syncingTimerShouldStop(isSynced, isNotEnoughDiskSpace); - const canResetConnecting = this._connectingTimerShouldStop(isConnected, isNotEnoughDiskSpace); - if (canResetSyncing) { this._resetSyncingTime(); } - if (canResetConnecting) { this._resetConnectingTime(); } + const canResetSyncing = this._syncingTimerShouldStop( + isSynced, + isNotEnoughDiskSpace + ); + const canResetConnecting = this._connectingTimerShouldStop( + isConnected, + isNotEnoughDiskSpace + ); + if (canResetSyncing) { + this._resetSyncingTime(); + } + if (canResetConnecting) { + this._resetConnectingTime(); + } } componentWillUnmount() { @@ -163,29 +175,31 @@ export default class Loading extends Component { this._resetSyncingTime(); } - _connectingTimerShouldStart = (isConnected: boolean): boolean => ( - !isConnected && connectingInterval === null - ); + _connectingTimerShouldStart = (isConnected: boolean): boolean => + !isConnected && connectingInterval === null; - _syncingTimerShouldStart = (isConnected: boolean, isSynced: boolean): boolean => ( - isConnected && !isSynced && syncingInterval === null - ); + _syncingTimerShouldStart = ( + isConnected: boolean, + isSynced: boolean + ): boolean => isConnected && !isSynced && syncingInterval === null; _syncingTimerShouldStop = ( - isSynced: boolean, isNotEnoughDiskSpace: boolean - ): boolean => ( - (isNotEnoughDiskSpace || isSynced) && syncingInterval !== null - ); + isSynced: boolean, + isNotEnoughDiskSpace: boolean + ): boolean => (isNotEnoughDiskSpace || isSynced) && syncingInterval !== null; _connectingTimerShouldStop = ( - isConnected: boolean, isNotEnoughDiskSpace: boolean - ): boolean => ( - (isNotEnoughDiskSpace || isConnected) && connectingInterval !== null - ); + isConnected: boolean, + isNotEnoughDiskSpace: boolean + ): boolean => + (isNotEnoughDiskSpace || isConnected) && connectingInterval !== null; _defensivelyStartTimers = (isConnected: boolean, isSynced: boolean) => { const needConnectingTimer = this._connectingTimerShouldStart(isConnected); - const needSyncingTimer = this._syncingTimerShouldStart(isConnected, isSynced); + const needSyncingTimer = this._syncingTimerShouldStart( + isConnected, + isSynced + ); if (needConnectingTimer) { connectingInterval = setInterval(this._incrementConnectingTime, 1000); } else if (needSyncingTimer) { @@ -252,8 +266,11 @@ export default class Loading extends Component { case CardanoNodeStates.UNRECOVERABLE: connectingMessage = messages.unrecoverable; break; - default: // also covers CardanoNodeStates.RUNNING state - connectingMessage = hasBeenConnected ? messages.reconnecting : messages.connecting; + default: + // also covers CardanoNodeStates.RUNNING state + connectingMessage = hasBeenConnected + ? messages.reconnecting + : messages.connecting; } return connectingMessage; }; @@ -277,7 +294,7 @@ export default class Loading extends Component { onContinueWithoutClockSyncCheck, isCheckingSystemTime, syncPercentage, - loadingDataForNextScreenMessage + loadingDataForNextScreenMessage, } = this.props; if (isNotEnoughDiskSpace) { @@ -382,40 +399,36 @@ export default class Loading extends Component { const currencyLoadingLogo = currencyIcon; const apiLoadingLogo = apiIcon; - const canReportConnectingIssue = ( - !isConnected && ( - connectingTime >= REPORT_ISSUE_TIME_TRIGGER || - cardanoNodeState === CardanoNodeStates.UNRECOVERABLE - ) - ); - const canReportSyncingIssue = ( - isConnected && !isSynced && syncingTime >= REPORT_ISSUE_TIME_TRIGGER - ); + const canReportConnectingIssue = + !isConnected && + (connectingTime >= REPORT_ISSUE_TIME_TRIGGER || + cardanoNodeState === CardanoNodeStates.UNRECOVERABLE); + const canReportSyncingIssue = + isConnected && !isSynced && syncingTime >= REPORT_ISSUE_TIME_TRIGGER; const showReportIssue = canReportConnectingIssue || canReportSyncingIssue; - const buttonClasses = classNames([ - 'primary', - styles.reportIssueButton, - ]); + const buttonClasses = classNames(['primary', styles.reportIssueButton]); return (
{showReportIssue && (

- {!isConnected ? - intl.formatMessage(messages.reportConnectingIssueText) : - intl.formatMessage(messages.reportSyncingIssueText) - } + {!isConnected + ? intl.formatMessage(messages.reportConnectingIssueText) + : intl.formatMessage(messages.reportSyncingIssueText)}

); } - } diff --git a/source/renderer/app/components/loading/Loading.scss b/source/renderer/app/components/loading/Loading.scss index b5797e9381..73e03bfb19 100644 --- a/source/renderer/app/components/loading/Loading.scss +++ b/source/renderer/app/components/loading/Loading.scss @@ -1,4 +1,4 @@ -@import "../../themes/mixins/animations"; +@import '../../themes/mixins/animations'; .component { height: 100%; @@ -23,15 +23,20 @@ width: 240px; &:hover { - background-color: var(--theme-report-issue-button-background-color-hover) !important; + background-color: var( + --theme-report-issue-button-background-color-hover + ) !important; } &:active { - background-color: var(--theme-report-issue-button-background-color-active) !important; + background-color: var( + --theme-report-issue-button-background-color-active + ) !important; } } .downloadLogsButton { - border-bottom: 1px solid var(--theme-report-issue-syncing-download-logs-text-color); + border-bottom: 1px solid + var(--theme-report-issue-syncing-download-logs-text-color); color: var(--theme-report-issue-syncing-download-logs-text-color); cursor: pointer; font-family: var(--font-regular); @@ -41,8 +46,11 @@ opacity: 0.8; } .downloadLogsButtonConnecting { - border-bottom: 1px solid var(--theme-report-issue-syncing-download-logs-text-color-connecting); - color: var(--theme-report-issue-syncing-download-logs-text-color-connecting); + border-bottom: 1px solid + var(--theme-report-issue-syncing-download-logs-text-color-connecting); + color: var( + --theme-report-issue-syncing-download-logs-text-color-connecting + ); } } &.is-loading-theme { @@ -149,6 +157,8 @@ $adaLogoWidth: 43px; } } -.component, .headline, .logo { +.component, +.headline, +.logo { -webkit-backface-visibility: hidden; } diff --git a/source/renderer/app/components/loading/NoDiskSpaceErrorOverlay.scss b/source/renderer/app/components/loading/NoDiskSpaceErrorOverlay.scss index 8d1ec71312..63fc2152a9 100644 --- a/source/renderer/app/components/loading/NoDiskSpaceErrorOverlay.scss +++ b/source/renderer/app/components/loading/NoDiskSpaceErrorOverlay.scss @@ -1,4 +1,4 @@ -@import "../../themes/mixins/animations"; +@import '../../themes/mixins/animations'; .component { align-items: center; @@ -35,7 +35,9 @@ } } - h1, p, button { + h1, + p, + button { font-family: var(--font-regular); } diff --git a/source/renderer/app/components/loading/NoDiskSpaceOverlay.js b/source/renderer/app/components/loading/NoDiskSpaceOverlay.js index 6d215ad234..259a6cbe91 100644 --- a/source/renderer/app/components/loading/NoDiskSpaceOverlay.js +++ b/source/renderer/app/components/loading/NoDiskSpaceOverlay.js @@ -9,13 +9,14 @@ import styles from './NoDiskSpaceErrorOverlay.scss'; const messages = defineMessages({ overlayContent: { id: 'noDiskSpace.error.overlayContent', - defaultMessage: '!!!Daedalus requires at least {diskSpaceRequired} of hard drive space to operate. Your computer is missing {diskSpaceMissing} of available space. Please delete some files to increase available hard drive space to continue using Daedalus.

It is recommended to have at least 15% of hard drive space available ({diskSpaceRecommended} in your case) for normal and stable operation of the operating system and installed programs. We strongly recommend that you free up at least that amount of space from your hard drive.', - description: 'Content of No disk space overlay' + defaultMessage: + '!!!Daedalus requires at least {diskSpaceRequired} of hard drive space to operate. Your computer is missing {diskSpaceMissing} of available space. Please delete some files to increase available hard drive space to continue using Daedalus.

It is recommended to have at least 15% of hard drive space available ({diskSpaceRecommended} in your case) for normal and stable operation of the operating system and installed programs. We strongly recommend that you free up at least that amount of space from your hard drive.', + description: 'Content of No disk space overlay', }, overlayTitle: { id: 'noDiskSpace.error.overlayTitle', defaultMessage: '!!!Daedalus requires more hard drive space', - description: 'Title of No disk space overlay' + description: 'Title of No disk space overlay', }, }); @@ -27,14 +28,17 @@ type Props = { @observer export default class NoDiskSpaceErrorOverlay extends Component { - static contextTypes = { intl: intlShape.isRequired, }; render() { const { intl } = this.context; - const { diskSpaceRequired, diskSpaceMissing, diskSpaceRecommended } = this.props; + const { + diskSpaceRequired, + diskSpaceMissing, + diskSpaceRecommended, + } = this.props; return (
@@ -44,12 +48,15 @@ export default class NoDiskSpaceErrorOverlay extends Component {

); } - } diff --git a/source/renderer/app/components/loading/SystemTimeErrorOverlay.js b/source/renderer/app/components/loading/SystemTimeErrorOverlay.js index a490d7c054..bf49666f74 100644 --- a/source/renderer/app/components/loading/SystemTimeErrorOverlay.js +++ b/source/renderer/app/components/loading/SystemTimeErrorOverlay.js @@ -12,47 +12,54 @@ const messages = defineMessages({ overlayTitle: { id: 'systemTime.error.overlayTitle', defaultMessage: '!!!Unable to sync - incorrect time', - description: 'Title of Sync error overlay' + description: 'Title of Sync error overlay', }, overlayTextP1: { id: 'systemTime.error.overlayTextP1', - defaultMessage: '!!!Attention, Daedalus is unable to sync with the blockchain because the time on your machine is different from the global time. Your time is off by 2 hours 12 minutes 54 seconds.', - description: 'First paragraph of Sync error overlay' + defaultMessage: + '!!!Attention, Daedalus is unable to sync with the blockchain because the time on your machine is different from the global time. Your time is off by 2 hours 12 minutes 54 seconds.', + description: 'First paragraph of Sync error overlay', }, overlayTextP2: { id: 'systemTime.error.overlayTextP2', - defaultMessage: '!!!To synchronise the time and fix the issue, please read our {supportPortalLink} article.', - description: 'Second paragraph of Sync error overlay' + defaultMessage: + '!!!To synchronise the time and fix the issue, please read our {supportPortalLink} article.', + description: 'Second paragraph of Sync error overlay', }, ntpUnreachableTextP1: { id: 'systemTime.error.ntpUnreachableTextP1', - defaultMessage: '!!!Attention, Daedalus is unable to check if the clock on your computer is synchronized with global time because NTP (Network Time Protocol) servers are unreachable, possibly due to firewalls on your network.', - description: 'Text of Sync error overlay when NTP service is unreachable' + defaultMessage: + '!!!Attention, Daedalus is unable to check if the clock on your computer is synchronized with global time because NTP (Network Time Protocol) servers are unreachable, possibly due to firewalls on your network.', + description: 'Text of Sync error overlay when NTP service is unreachable', }, ntpUnreachableTextP2: { id: 'systemTime.error.ntpUnreachableTextP2', - defaultMessage: '!!!If your computer clock is off by more than 15 seconds, Daedalus will be unable to connect to the network. If you have this issue, please read our Support Portal article to synchronize the time on your machine.', - description: 'Text of Sync error overlay when NTP service is unreachable' + defaultMessage: + '!!!If your computer clock is off by more than 15 seconds, Daedalus will be unable to connect to the network. If you have this issue, please read our Support Portal article to synchronize the time on your machine.', + description: 'Text of Sync error overlay when NTP service is unreachable', }, supportPortalLink: { id: 'systemTime.error.supportPortalLink', defaultMessage: '!!!Support Portal', - description: '"Support Portal" link text' + description: '"Support Portal" link text', }, supportPortalLinkUrl: { id: 'systemTime.error.supportPortalLinkUrl', - defaultMessage: '!!!https://iohk.zendesk.com/hc/en-us/articles/360010230873', - description: 'Link to "Machine clock out of sync with Cardano network" support page' + defaultMessage: + '!!!https://iohk.zendesk.com/hc/en-us/articles/360010230873', + description: + 'Link to "Machine clock out of sync with Cardano network" support page', }, onCheckTheTimeAgainLink: { id: 'systemTime.error.onCheckTheTimeAgainLink', defaultMessage: '!!!Check the time again', - description: 'Text of Check the time again button' + description: 'Text of Check the time again button', }, onContinueWithoutClockSyncCheckLink: { id: 'systemTime.error.onContinueWithoutClockSyncCheckLink', defaultMessage: '!!!Continue without clock synchronization checks', - description: 'Text of "Continue without clock synchronization checks" button' + description: + 'Text of "Continue without clock synchronization checks" button', }, }); @@ -67,7 +74,6 @@ type Props = { @observer export default class SystemTimeErrorOverlay extends Component { - static contextTypes = { intl: intlShape.isRequired, }; @@ -75,12 +81,17 @@ export default class SystemTimeErrorOverlay extends Component { render() { const { intl } = this.context; const { - localTimeDifference, currentLocale, isCheckingSystemTime, - onCheckTheTimeAgain, onContinueWithoutClockSyncCheck, - onExternalLinkClick + localTimeDifference, + currentLocale, + isCheckingSystemTime, + onCheckTheTimeAgain, + onContinueWithoutClockSyncCheck, + onExternalLinkClick, } = this.props; - const supportPortalLinkUrl = intl.formatMessage(messages.supportPortalLinkUrl); + const supportPortalLinkUrl = intl.formatMessage( + messages.supportPortalLinkUrl + ); const supportPortalLink = ( { return (
- {isNTPServiceReachable ? ( @@ -169,9 +179,7 @@ export default class SystemTimeErrorOverlay extends Component {
)} -
); } - } diff --git a/source/renderer/app/components/loading/SystemTimeErrorOverlay.scss b/source/renderer/app/components/loading/SystemTimeErrorOverlay.scss index 7bf41867f8..9c615f41ac 100644 --- a/source/renderer/app/components/loading/SystemTimeErrorOverlay.scss +++ b/source/renderer/app/components/loading/SystemTimeErrorOverlay.scss @@ -1,4 +1,4 @@ -@import "../../themes/mixins/animations"; +@import '../../themes/mixins/animations'; .component { align-items: center; @@ -34,7 +34,9 @@ } } - h1, p, button { + h1, + p, + button { font-family: var(--font-regular); } @@ -72,5 +74,4 @@ @include animated-ellipsis($width: 16px); } } - } diff --git a/source/renderer/app/components/notifications/NodeUpdateNotification.js b/source/renderer/app/components/notifications/NodeUpdateNotification.js index 13fe9f2dbe..243111c247 100644 --- a/source/renderer/app/components/notifications/NodeUpdateNotification.js +++ b/source/renderer/app/components/notifications/NodeUpdateNotification.js @@ -13,27 +13,31 @@ const messages = defineMessages({ acceptLabel: { id: 'cardano.node.update.notification.accept.button.label', defaultMessage: '!!!Update and restart', - description: 'Label "Update and restart" on the Cardano node update notification.' + description: + 'Label "Update and restart" on the Cardano node update notification.', }, denyLabel: { id: 'cardano.node.update.notification.postpone.button.label', defaultMessage: '!!!Postpone until restart', - description: 'Label "Postpone until restart" on the Cardano node update notification.' + description: + 'Label "Postpone until restart" on the Cardano node update notification.', }, titleWithVersion: { id: 'cardano.node.update.notification.titleWithVersion', defaultMessage: '!!!Cardano-Core update v{version} is available', - description: 'Cardano-Core update notification with version.' + description: 'Cardano-Core update notification with version.', }, titleWithoutVersion: { id: 'cardano.node.update.notification.titleWithoutVersion', defaultMessage: '!!!Cardano-Core update is available', - description: 'Cardano-Core update notification without version.' + description: 'Cardano-Core update notification without version.', }, updateMessage: { id: 'cardano.node.update.notification.message', - defaultMessage: '!!!Daedalus and Cardano node update is available. Would you like to install the update?', - description: 'Message shown when there is a Daedalus and Cardano node update available.' + defaultMessage: + '!!!Daedalus and Cardano node update is available. Would you like to install the update?', + description: + 'Message shown when there is a Daedalus and Cardano node update available.', }, }); @@ -48,45 +52,49 @@ type Props = { @observer export default class NodeUpdateNotification extends Component { - static contextTypes = { intl: intlShape.isRequired, }; render() { const { intl } = this.context; - const { version, message, onAccept, onPostpone, onToggleExpanded, isExpanded } = this.props; + const { + version, + message, + onAccept, + onPostpone, + onToggleExpanded, + isExpanded, + } = this.props; const arrowClasses = classnames([ - isExpanded ? styles.arrow : styles.arrowCollapsed + isExpanded ? styles.arrow : styles.arrowCollapsed, ]); - const title = version ? - intl.formatMessage(messages.titleWithVersion, { version }) : - intl.formatMessage(messages.titleWithoutVersion); + const title = version + ? intl.formatMessage(messages.titleWithVersion, { version }) + : intl.formatMessage(messages.titleWithoutVersion); return (
{title}
-
- {isExpanded && ( - message ? ( - // eslint-disable-next-line react/no-danger -
+ {isExpanded && + (message ? ( +
) : (
{intl.formatMessage(messages.updateMessage)}
- ) - )} + ))} {isExpanded && (
-
)} -
); } diff --git a/source/renderer/app/components/notifications/NodeUpdateNotification.scss b/source/renderer/app/components/notifications/NodeUpdateNotification.scss index 4bd0798efb..ecba275474 100644 --- a/source/renderer/app/components/notifications/NodeUpdateNotification.scss +++ b/source/renderer/app/components/notifications/NodeUpdateNotification.scss @@ -28,10 +28,14 @@ background-color: var(--theme-node-update-accept-button-background-color); &:hover { - background-color: var(--theme-node-update-accept-button-background-color-hover) !important; + background-color: var( + --theme-node-update-accept-button-background-color-hover + ) !important; } &:active { - background-color: var(--theme-node-update-accept-button-background-color-active) !important; + background-color: var( + --theme-node-update-accept-button-background-color-active + ) !important; } } @@ -40,10 +44,14 @@ background-color: var(--theme-node-update-deny-button-background-color); &:hover { - background-color: var(--theme-node-update-deny-button-background-color-hover) !important; + background-color: var( + --theme-node-update-deny-button-background-color-hover + ) !important; } &:active { - background-color: var(--theme-node-update-deny-button-background-color-active) !important; + background-color: var( + --theme-node-update-deny-button-background-color-active + ) !important; } } } diff --git a/source/renderer/app/components/notifications/RestoreNotification.js b/source/renderer/app/components/notifications/RestoreNotification.js index 44850f3660..aa3e97f222 100644 --- a/source/renderer/app/components/notifications/RestoreNotification.js +++ b/source/renderer/app/components/notifications/RestoreNotification.js @@ -12,7 +12,8 @@ const messages = defineMessages({ activeRestoreMessage: { id: 'wallet.statusMessages.activeRestore', defaultMessage: '!!!Wallet restore in progress', - description: 'Status message "Wallet restore in progress" shown while wallet is being restored.' + description: + 'Status message "Wallet restore in progress" shown while wallet is being restored.', }, }); @@ -24,7 +25,6 @@ type Props = { @observer export default class RestoreNotification extends Component { - static contextTypes = { intl: intlShape.isRequired, }; @@ -64,8 +64,8 @@ export default class RestoreNotification extends Component { return (
- {intl.formatMessage(messages.activeRestoreMessage)}: {restoreProgress}% - ({estimatedCompletionTime}) + {intl.formatMessage(messages.activeRestoreMessage)}: {restoreProgress} + % ({estimatedCompletionTime})
diff --git a/source/renderer/app/components/profile/data-layer-migration/DataLayerMigrationForm.js b/source/renderer/app/components/profile/data-layer-migration/DataLayerMigrationForm.js index 1eef219873..9b45f49635 100644 --- a/source/renderer/app/components/profile/data-layer-migration/DataLayerMigrationForm.js +++ b/source/renderer/app/components/profile/data-layer-migration/DataLayerMigrationForm.js @@ -11,27 +11,30 @@ const messages = defineMessages({ title: { id: 'profile.dataLayerMigration.title', defaultMessage: '!!!Wallet data migration', - description: 'Title for the Data Layer Migration screen.' + description: 'Title for the Data Layer Migration screen.', }, content1: { id: 'profile.dataLayerMigration.content1', - defaultMessage: '!!!You have installed a version of Daedalus that changes how wallet data is stored and managed. Because of this, all of your wallets need to be restored and synchronized with the complete history of the Cardano blockchain.', - description: 'Content for the Data Layer Migration screen.' + defaultMessage: + '!!!You have installed a version of Daedalus that changes how wallet data is stored and managed. Because of this, all of your wallets need to be restored and synchronized with the complete history of the Cardano blockchain.', + description: 'Content for the Data Layer Migration screen.', }, content2: { id: 'profile.dataLayerMigration.content2', - defaultMessage: '!!!This is an automatic process and does not require any action on your behalf.', - description: 'Content for the Data Layer Migration screen.' + defaultMessage: + '!!!This is an automatic process and does not require any action on your behalf.', + description: 'Content for the Data Layer Migration screen.', }, content3: { id: 'profile.dataLayerMigration.content3', - defaultMessage: '!!!Your transaction history and used addresses will appear in your wallets as they are recovered during the restoration process. Addresses that were not used will not be recovered because they are not recorded on the blockchain. If funds were sent to those addresses you will receive the funds and those addresses will appear in your wallet.', - description: 'Content for the Data Layer Migration screen.' + defaultMessage: + '!!!Your transaction history and used addresses will appear in your wallets as they are recovered during the restoration process. Addresses that were not used will not be recovered because they are not recorded on the blockchain. If funds were sent to those addresses you will receive the funds and those addresses will appear in your wallet.', + description: 'Content for the Data Layer Migration screen.', }, submitLabel: { id: 'profile.dataLayerMigration.submitLabel', defaultMessage: '!!!Start migration', - description: 'Submit label for the Data Layer Migration screen.' + description: 'Submit label for the Data Layer Migration screen.', }, }); @@ -42,7 +45,6 @@ type Props = { @observer export default class DataLayerMigrationForm extends Component { - static contextTypes = { intl: intlShape.isRequired, }; @@ -57,14 +59,11 @@ export default class DataLayerMigrationForm extends Component { return (
-

{intl.formatMessage(messages.title)}

{/* intl.formatMessage(messages.content1) */} - +

{intl.formatMessage(messages.content2)} @@ -81,9 +80,7 @@ export default class DataLayerMigrationForm extends Component { onClick={this.submit} skin={ButtonSkin} /> -

); } - } diff --git a/source/renderer/app/components/profile/data-layer-migration/DataLayerMigrationForm.scss b/source/renderer/app/components/profile/data-layer-migration/DataLayerMigrationForm.scss index 25f69a95fd..0586efdb15 100644 --- a/source/renderer/app/components/profile/data-layer-migration/DataLayerMigrationForm.scss +++ b/source/renderer/app/components/profile/data-layer-migration/DataLayerMigrationForm.scss @@ -28,7 +28,9 @@ text-align: center; } -.content1, .content2, .content3 { +.content1, +.content2, +.content3 { color: var(--theme-data-migration-layer-text-color); cursor: default; font-family: var(--font-light); @@ -55,10 +57,15 @@ color: var(--theme-data-migration-layer-text-color) !important; line-height: 1.36 !important; margin-bottom: 30px; - transition: box-shadow 0.2s cubic-bezier(0.4, 0, 1, 1), background-color 0.2s cubic-bezier(0.4, 0, 0.2, 1), color 0.2s cubic-bezier(0.4, 0, 0.2, 1); + transition: box-shadow 0.2s cubic-bezier(0.4, 0, 1, 1), + background-color 0.2s cubic-bezier(0.4, 0, 0.2, 1), + color 0.2s cubic-bezier(0.4, 0, 0.2, 1); - &:hover, &:active { - background: var(--theme-data-migration-layer-button-background-color-hover) !important; + &:hover, + &:active { + background: var( + --theme-data-migration-layer-button-background-color-hover + ) !important; color: var(--theme-data-migration-layer-background-color) !important; } } diff --git a/source/renderer/app/components/profile/language-selection/LanguageSelectionForm.js b/source/renderer/app/components/profile/language-selection/LanguageSelectionForm.js index 6a93575a83..9c820a7dd1 100644 --- a/source/renderer/app/components/profile/language-selection/LanguageSelectionForm.js +++ b/source/renderer/app/components/profile/language-selection/LanguageSelectionForm.js @@ -16,12 +16,12 @@ const messages = defineMessages({ languageSelectLabel: { id: 'profile.languageSelect.form.languageSelectLabel', defaultMessage: '!!!Select your language', - description: 'Label for the language select.' + description: 'Label for the language select.', }, submitLabel: { id: 'profile.languageSelect.form.submitLabel', defaultMessage: '!!!Continue', - description: 'Label for the "Language select" form submit button.' + description: 'Label for the "Language select" form submit button.', }, }); @@ -34,7 +34,6 @@ type Props = { @observer export default class LanguageSelectionForm extends Component { - static defaultProps = { error: null, }; @@ -45,26 +44,29 @@ export default class LanguageSelectionForm extends Component { submit = () => { this.form.submit({ - onSuccess: (form) => { + onSuccess: form => { const { languageId } = form.values(); this.props.onSubmit({ locale: languageId }); }, - onError: () => {} + onError: () => {}, }); }; - form = new ReactToolboxMobxForm({ - fields: { - languageId: { - label: this.context.intl.formatMessage(messages.languageSelectLabel), - value: this.props.languages[0].value, - } - } - }, { - options: { - validateOnChange: false, + form = new ReactToolboxMobxForm( + { + fields: { + languageId: { + label: this.context.intl.formatMessage(messages.languageSelectLabel), + value: this.props.languages[0].value, + }, + }, }, - }); + { + options: { + validateOnChange: false, + }, + } + ); render() { const { intl } = this.context; @@ -73,12 +75,11 @@ export default class LanguageSelectionForm extends Component { const languageId = form.$('languageId'); const languageOptions = languages.map(language => ({ value: language.value, - label: intl.formatMessage(language.label) + label: intl.formatMessage(language.label), })); return (
- { /> {error &&

{error}

} -
); } - } diff --git a/source/renderer/app/components/settings/categories/SupportSettings.js b/source/renderer/app/components/settings/categories/SupportSettings.js index 1b955e18da..6fb6132825 100644 --- a/source/renderer/app/components/settings/categories/SupportSettings.js +++ b/source/renderer/app/components/settings/categories/SupportSettings.js @@ -13,13 +13,16 @@ const messages = defineMessages({ }, faqContent: { id: 'settings.support.faq.content', - defaultMessage: '!!!If you are experiencing issues, for guidance please see the {faqLink} article in the Support Portal.', - description: 'Content for the "Help and support" section on the support settings page.', + defaultMessage: + '!!!If you are experiencing issues, for guidance please see the {faqLink} article in the Support Portal.', + description: + 'Content for the "Help and support" section on the support settings page.', }, faqLink: { id: 'settings.support.faq.faqLink', defaultMessage: '!!!Known Issues', - description: '"Known Issues" link in the "Help and support" section on the support settings page', + description: + '"Known Issues" link in the "Help and support" section on the support settings page', }, reportProblemTitle: { id: 'settings.support.reportProblem.title', @@ -28,13 +31,16 @@ const messages = defineMessages({ }, reportProblemContent: { id: 'settings.support.reportProblem.content', - defaultMessage: '!!!If you are still experiencing an issue, please submit a support request.', - description: 'Content for the "Reporting a problem" section on the support settings page.', + defaultMessage: + '!!!If you are still experiencing an issue, please submit a support request.', + description: + 'Content for the "Reporting a problem" section on the support settings page.', }, supportRequestLink: { id: 'settings.support.reportProblem.link', defaultMessage: '!!!submit a support request', - description: '"submit a support request" link in the "Report a problem" section on the support settings page.', + description: + '"submit a support request" link in the "Report a problem" section on the support settings page.', }, logsTitle: { id: 'settings.support.logs.title', @@ -43,13 +49,15 @@ const messages = defineMessages({ }, logsContent: { id: 'settings.support.logs.content', - defaultMessage: '!!!Please download your logs here and attach the downloaded file when submitting a support ticket to help the support team investigate the issue. Logs do not contain sensitive information.', + defaultMessage: + '!!!Please download your logs here and attach the downloaded file when submitting a support ticket to help the support team investigate the issue. Logs do not contain sensitive information.', description: 'Content for the "Logs" section on the support settings page.', }, downloadLogsLink: { id: 'settings.support.logs.downloadLogsLink', defaultMessage: '!!!download your logs here', - description: '"download your logs here" link in the Logs section on the support settings page', + description: + '"download your logs here" link in the Logs section on the support settings page', }, }); @@ -61,13 +69,16 @@ type Props = { @observer export default class SupportSettings extends Component { - static contextTypes = { intl: intlShape.isRequired, }; render() { - const { onExternalLinkClick, onSupportRequestClick, onDownloadLogs } = this.props; + const { + onExternalLinkClick, + onSupportRequestClick, + onDownloadLogs, + } = this.props; const { intl } = this.context; const faqLinkUrl = intl.formatMessage(globalMessages.faqLinkUrl); @@ -94,23 +105,30 @@ export default class SupportSettings extends Component { return (
-

{intl.formatMessage(messages.faqTitle)}

-

+

+ +

{intl.formatMessage(messages.reportProblemTitle)}

- +

{intl.formatMessage(messages.logsTitle)}

-

- +

+ +

); } - } diff --git a/source/renderer/app/components/settings/categories/SupportSettings.scss b/source/renderer/app/components/settings/categories/SupportSettings.scss index 0352ae7bbc..e64a26d7fc 100644 --- a/source/renderer/app/components/settings/categories/SupportSettings.scss +++ b/source/renderer/app/components/settings/categories/SupportSettings.scss @@ -38,4 +38,3 @@ margin-bottom: 10px; } } - diff --git a/source/renderer/app/components/settings/categories/TermsOfUseSettings.js b/source/renderer/app/components/settings/categories/TermsOfUseSettings.js index 0fc4fb5b6a..08c7938f3e 100644 --- a/source/renderer/app/components/settings/categories/TermsOfUseSettings.js +++ b/source/renderer/app/components/settings/categories/TermsOfUseSettings.js @@ -18,5 +18,4 @@ export default class TermsOfUseSettings extends Component {
); } - } diff --git a/source/renderer/app/components/settings/menu/SettingsMenu.js b/source/renderer/app/components/settings/menu/SettingsMenu.js index feab14b149..c8ae0a9725 100644 --- a/source/renderer/app/components/settings/menu/SettingsMenu.js +++ b/source/renderer/app/components/settings/menu/SettingsMenu.js @@ -36,7 +36,6 @@ type Props = { @observer export default class SettingsMenu extends Component { - static contextTypes = { intl: intlShape.isRequired, }; @@ -77,5 +76,4 @@ export default class SettingsMenu extends Component {
); } - } diff --git a/source/renderer/app/components/settings/menu/SettingsMenu.scss b/source/renderer/app/components/settings/menu/SettingsMenu.scss index 8154163961..105f08cc60 100644 --- a/source/renderer/app/components/settings/menu/SettingsMenu.scss +++ b/source/renderer/app/components/settings/menu/SettingsMenu.scss @@ -1,4 +1,4 @@ -@import "../settingsConfig"; +@import '../settingsConfig'; .component { background-color: var(--theme-settings-menu-box-background-color); diff --git a/source/renderer/app/components/settings/menu/SettingsMenuItem.js b/source/renderer/app/components/settings/menu/SettingsMenuItem.js index f93126fe6a..6acbf8c3b2 100644 --- a/source/renderer/app/components/settings/menu/SettingsMenuItem.js +++ b/source/renderer/app/components/settings/menu/SettingsMenuItem.js @@ -24,8 +24,9 @@ export default class SettingsMenuItem extends Component { } const componentClasses = classNames([styles.component, state, className]); return ( - + ); } - } diff --git a/source/renderer/app/components/settings/menu/SettingsMenuItem.scss b/source/renderer/app/components/settings/menu/SettingsMenuItem.scss index 6b44211e4a..ed88288bc7 100644 --- a/source/renderer/app/components/settings/menu/SettingsMenuItem.scss +++ b/source/renderer/app/components/settings/menu/SettingsMenuItem.scss @@ -12,7 +12,8 @@ .active { color: var(--theme-settings-menu-item-text-color-active); background-color: var(--theme-settings-menu-item-background-color-active); - border-left: 4px solid var(--theme-settings-menu-item-left-border-color-active); + border-left: 4px solid + var(--theme-settings-menu-item-left-border-color-active); font-family: var(--font-bold); padding-left: 16px; } diff --git a/source/renderer/app/components/sidebar/Sidebar.js b/source/renderer/app/components/sidebar/Sidebar.js index 630181f441..f28d541676 100644 --- a/source/renderer/app/components/sidebar/Sidebar.js +++ b/source/renderer/app/components/sidebar/Sidebar.js @@ -30,8 +30,8 @@ export type SidebarMenus = ?{ activeWalletId: ?string, actions: { onWalletItemClick: Function, - } - } + }, + }, }; export type SidebarCategories = Array<{ @@ -42,20 +42,24 @@ export type SidebarCategories = Array<{ @observer export default class Sidebar extends Component { - static defaultProps = { isShowingSubMenus: false, }; render() { const { - menus, categories, activeSidebarCategory, pathname, - isShowingSubMenus, onAddWallet, onSubmitSupportRequest, + menus, + categories, + activeSidebarCategory, + pathname, + isShowingSubMenus, + onAddWallet, + onSubmitSupportRequest, } = this.props; let subMenu = null; const walletsCategory = find(categories, { - name: CATEGORIES_BY_NAME.WALLETS.name + name: CATEGORIES_BY_NAME.WALLETS.name, }).route; if (menus && activeSidebarCategory === walletsCategory) { @@ -73,7 +77,7 @@ export default class Sidebar extends Component { const sidebarStyles = classNames([ styles.component, - !isShowingSubMenus || subMenu == null ? styles.minimized : null + !isShowingSubMenus || subMenu == null ? styles.minimized : null, ]); return ( diff --git a/source/renderer/app/components/sidebar/SidebarCategory.js b/source/renderer/app/components/sidebar/SidebarCategory.js index 04c45f8dcb..86a62c8a10 100644 --- a/source/renderer/app/components/sidebar/SidebarCategory.js +++ b/source/renderer/app/components/sidebar/SidebarCategory.js @@ -24,7 +24,7 @@ export default class SidebarCategory extends Component { ]); const iconStyles = classNames([ - className === 'supportRequest' ? styles.supportRequestIcon : styles.icon + className === 'supportRequest' ? styles.supportRequestIcon : styles.icon, ]); return ( diff --git a/source/renderer/app/components/sidebar/SidebarMenu.js b/source/renderer/app/components/sidebar/SidebarMenu.js index ee969f6222..68571f443b 100644 --- a/source/renderer/app/components/sidebar/SidebarMenu.js +++ b/source/renderer/app/components/sidebar/SidebarMenu.js @@ -16,13 +16,8 @@ export default class SidebarMenu extends Component { const { children, visible } = this.props; const componentStyles = classNames([ styles.component, - visible ? styles.visible : null + visible ? styles.visible : null, ]); - return ( -
- {children} -
- ); + return
{children}
; } - } diff --git a/source/renderer/app/components/sidebar/wallets/SidebarWalletMenuItem.js b/source/renderer/app/components/sidebar/wallets/SidebarWalletMenuItem.js index 588de4e872..4e3b9c38ee 100644 --- a/source/renderer/app/components/sidebar/wallets/SidebarWalletMenuItem.js +++ b/source/renderer/app/components/sidebar/wallets/SidebarWalletMenuItem.js @@ -19,8 +19,13 @@ type Props = { export default class SidebarWalletMenuItem extends Component { render() { const { - title, info, active, className, - onClick, isRestoreActive, restoreProgress, + title, + info, + active, + className, + onClick, + isRestoreActive, + restoreProgress, } = this.props; const componentStyles = classNames([ @@ -34,12 +39,9 @@ export default class SidebarWalletMenuItem extends Component { {title} {info} - {isRestoreActive ? ( - - ) : null} + {isRestoreActive ? : null} ); } - } diff --git a/source/renderer/app/components/sidebar/wallets/SidebarWalletsMenu.js b/source/renderer/app/components/sidebar/wallets/SidebarWalletsMenu.js index 474bed2936..69c7ccf086 100644 --- a/source/renderer/app/components/sidebar/wallets/SidebarWalletsMenu.js +++ b/source/renderer/app/components/sidebar/wallets/SidebarWalletsMenu.js @@ -29,15 +29,18 @@ type Props = { @observer export default class SidebarWalletsMenu extends Component { - static contextTypes = { - intl: intlShape.isRequired + intl: intlShape.isRequired, }; render() { const { intl } = this.context; const { - wallets, onAddWallet, isActiveWallet, onWalletItemClick, isAddWalletButtonActive + wallets, + onAddWallet, + isActiveWallet, + onWalletItemClick, + isAddWalletButtonActive, } = this.props; const addWalletButtonStyles = classNames([ @@ -48,7 +51,7 @@ export default class SidebarWalletsMenu extends Component { return (
- {wallets.map((wallet) => ( + {wallets.map(wallet => ( { ); } - } diff --git a/source/renderer/app/components/sidebar/wallets/SidebarWalletsMenu.scss b/source/renderer/app/components/sidebar/wallets/SidebarWalletsMenu.scss index e79b5424ba..4782639e19 100644 --- a/source/renderer/app/components/sidebar/wallets/SidebarWalletsMenu.scss +++ b/source/renderer/app/components/sidebar/wallets/SidebarWalletsMenu.scss @@ -19,7 +19,9 @@ width: $sidebar-width - $sidebar-minimized-category-width; &:hover { - background-color: var(--theme-sidebar-menu-add-button-background-color-hover); + background-color: var( + --theme-sidebar-menu-add-button-background-color-hover + ); } .icon { @@ -41,7 +43,8 @@ &.active { cursor: default; - background-color: var(--theme-sidebar-menu-add-button-background-color-active); + background-color: var( + --theme-sidebar-menu-add-button-background-color-active + ); } } - diff --git a/source/renderer/app/components/staking/BlockGenerationInfo.js b/source/renderer/app/components/staking/BlockGenerationInfo.js index b3f7be088c..07e8db453d 100644 --- a/source/renderer/app/components/staking/BlockGenerationInfo.js +++ b/source/renderer/app/components/staking/BlockGenerationInfo.js @@ -5,22 +5,18 @@ import styles from './BlockGenerationInfo.scss'; @observer export default class BlockGenerationInfo extends Component { - render() { return (
You will be generating next block in
-
- 3 hours 10 minutes -
+
3 hours 10 minutes
- be online and you will be rewarded - or you can delegate this process to the pool + be online and you will be rewarded or you can{' '} + delegate this process to the pool
); } - } diff --git a/source/renderer/app/components/staking/BlockGenerationInfo.scss b/source/renderer/app/components/staking/BlockGenerationInfo.scss index c6d20c7a43..d11033ee70 100644 --- a/source/renderer/app/components/staking/BlockGenerationInfo.scss +++ b/source/renderer/app/components/staking/BlockGenerationInfo.scss @@ -1,4 +1,4 @@ -@import "./stakingConfig"; +@import './stakingConfig'; .component { margin: 30px; @@ -26,4 +26,3 @@ color: var(--theme-block-generation-info-color); } } - diff --git a/source/renderer/app/components/staking/Staking.js b/source/renderer/app/components/staking/Staking.js index e2359be95d..3a9525091b 100644 --- a/source/renderer/app/components/staking/Staking.js +++ b/source/renderer/app/components/staking/Staking.js @@ -8,7 +8,6 @@ import styles from './Staking.scss'; @observer export default class Settings extends Component { - render() { return (
@@ -24,5 +23,4 @@ export default class Settings extends Component {
); } - } diff --git a/source/renderer/app/components/staking/Staking.scss b/source/renderer/app/components/staking/Staking.scss index 1ae4770ded..56174efa64 100644 --- a/source/renderer/app/components/staking/Staking.scss +++ b/source/renderer/app/components/staking/Staking.scss @@ -1,4 +1,4 @@ -@import "./stakingConfig"; +@import './stakingConfig'; .component { height: 100%; diff --git a/source/renderer/app/components/staking/StakingChart.js b/source/renderer/app/components/staking/StakingChart.js index 04b0272461..413aac2ec1 100644 --- a/source/renderer/app/components/staking/StakingChart.js +++ b/source/renderer/app/components/staking/StakingChart.js @@ -34,11 +34,10 @@ type State = { @observer export default class StakingChart extends Component { - state = { isHovered: false, hoveredBarData: null, - tooltipPos: null + tooltipPos: null, }; onMouseMove(event: MouseEvent) { @@ -46,8 +45,8 @@ export default class StakingChart extends Component { this.setState({ tooltipPos: { left: event.pageX + 10, - top: event.pageY - } + top: event.pageY, + }, }); } } @@ -60,7 +59,11 @@ export default class StakingChart extends Component { let tooltip = null; // TODO: find better way to represent the data records that are behind the reference line // for now this is the easiest way to ignore zero-bars in the chart - if (isHovered && hoveredBarData && hoveredBarData.numberOfTransactions > 0) { + if ( + isHovered && + hoveredBarData && + hoveredBarData.numberOfTransactions > 0 + ) { tooltip = (
@@ -69,7 +72,10 @@ export default class StakingChart extends Component { } return ( -
+
{ barCategoryGap={2} barGap={2} > - + { ticks={ticks.slice()} domain={['dataMin', 'dataMax + 10']} /> - + this.setState({ isHovered: true, hoveredBarData: barData })} - onMouseLeave={() => this.setState({ isHovered: false, hoveredBarData: null })} + onMouseEnter={barData => + this.setState({ isHovered: true, hoveredBarData: barData }) + } + onMouseLeave={() => + this.setState({ isHovered: false, hoveredBarData: null }) + } minPointSize={2} isAnimationActive={false} > - { - data.slice().map((entry, index) => { - let fillColor = '#c2cad4'; - let cursor = 'pointer'; - if (index === activeIndex) fillColor = '#445b7c'; - if (entry.numberOfTransactions === 0) { - fillColor = '#e7eaee'; - cursor = 'default'; - } - return ( - - ); - }) - } + {data.slice().map((entry, index) => { + let fillColor = '#c2cad4'; + let cursor = 'pointer'; + if (index === activeIndex) fillColor = '#445b7c'; + if (entry.numberOfTransactions === 0) { + fillColor = '#e7eaee'; + cursor = 'default'; + } + return ( + + ); + })} {tooltip}
); } - } diff --git a/source/renderer/app/components/staking/StakingChartTooltip.js b/source/renderer/app/components/staking/StakingChartTooltip.js index 4d6ebaa8ab..eebf5959b3 100644 --- a/source/renderer/app/components/staking/StakingChartTooltip.js +++ b/source/renderer/app/components/staking/StakingChartTooltip.js @@ -12,32 +12,32 @@ const messages = defineMessages({ slot: { id: 'staking.chart.tooltip.slot.label', defaultMessage: '!!!slot', - description: '"slot" label on staking chart tooltip.' + description: '"slot" label on staking chart tooltip.', }, transactions: { id: 'staking.chart.tooltip.transactions.label', defaultMessage: '!!!transactions', - description: '"transactions" label on staking chart tooltip.' + description: '"transactions" label on staking chart tooltip.', }, mpcPhase: { id: 'staking.chart.tooltip.mpc.phase.label', defaultMessage: '!!!MPC phase', - description: '"MPC phase" label on staking chart tooltip.' + description: '"MPC phase" label on staking chart tooltip.', }, commitments: { id: 'staking.chart.tooltip.commitments.label', defaultMessage: '!!!commitments', - description: '"commitments" label on staking chart tooltip.' + description: '"commitments" label on staking chart tooltip.', }, openings: { id: 'staking.chart.tooltip.openings.label', defaultMessage: '!!!openings', - description: '"openings" label on staking chart tooltip.' + description: '"openings" label on staking chart tooltip.', }, shares: { id: 'staking.chart.tooltip.shares.label', defaultMessage: '!!!shares', - description: '"shares" label on staking chart tooltip.' + description: '"shares" label on staking chart tooltip.', }, }); @@ -49,12 +49,11 @@ type Props = { mpcPhase: string, commitments: string, openings: string, - shares: string + shares: string, }; @observer export default class StakingChartTooltip extends Component { - static contextTypes = { intl: intlShape.isRequired, }; @@ -69,11 +68,13 @@ export default class StakingChartTooltip extends Component { mpcPhase, commitments, openings, - shares + shares, } = this.props; return (
-
{`#${slot}`} {intl.formatMessage(messages.slot)}
+
+ {`#${slot}`} {intl.formatMessage(messages.slot)} +
{moment(time).format(dateFormat)}
{hash}
{
); } - } diff --git a/source/renderer/app/components/staking/StakingChartTooltip.scss b/source/renderer/app/components/staking/StakingChartTooltip.scss index a31c362535..2adb3298ea 100644 --- a/source/renderer/app/components/staking/StakingChartTooltip.scss +++ b/source/renderer/app/components/staking/StakingChartTooltip.scss @@ -1,4 +1,4 @@ -@import "stakingConfig"; +@import 'stakingConfig'; .component { width: 330px; diff --git a/source/renderer/app/components/staking/StakingChartTooltipItem.js b/source/renderer/app/components/staking/StakingChartTooltipItem.js index 2bde8479eb..64e0d49df1 100644 --- a/source/renderer/app/components/staking/StakingChartTooltipItem.js +++ b/source/renderer/app/components/staking/StakingChartTooltipItem.js @@ -5,12 +5,11 @@ import styles from './StakingChartTooltipItem.scss'; type Props = { value: string, - label: string + label: string, }; @observer export default class StakingChartTooltipItem extends Component { - render() { const { value, label } = this.props; return ( @@ -19,5 +18,4 @@ export default class StakingChartTooltipItem extends Component {
); } - } diff --git a/source/renderer/app/components/staking/StakingChartTooltipItem.scss b/source/renderer/app/components/staking/StakingChartTooltipItem.scss index 2fceab81fe..796663b9d5 100644 --- a/source/renderer/app/components/staking/StakingChartTooltipItem.scss +++ b/source/renderer/app/components/staking/StakingChartTooltipItem.scss @@ -1,4 +1,4 @@ -@import "./stakingConfig"; +@import './stakingConfig'; .component { @extend %regularText; diff --git a/source/renderer/app/components/staking/StakingSwitch.js b/source/renderer/app/components/staking/StakingSwitch.js index a774110089..873d0c04ff 100644 --- a/source/renderer/app/components/staking/StakingSwitch.js +++ b/source/renderer/app/components/staking/StakingSwitch.js @@ -12,7 +12,6 @@ type Props = { @observer export default class StakingSwitch extends Component { - handleChange = () => {}; render() { @@ -29,5 +28,4 @@ export default class StakingSwitch extends Component {
); } - } diff --git a/source/renderer/app/components/staking/StakingSwitch.scss b/source/renderer/app/components/staking/StakingSwitch.scss index a94b57d056..3cb14acb80 100644 --- a/source/renderer/app/components/staking/StakingSwitch.scss +++ b/source/renderer/app/components/staking/StakingSwitch.scss @@ -1,4 +1,4 @@ -@import "./stakingConfig"; +@import './stakingConfig'; .component { @extend %contentBorderAndBackground; diff --git a/source/renderer/app/components/staking/StakingSystemState.js b/source/renderer/app/components/staking/StakingSystemState.js index b2c6cec0c4..bb61edec7f 100644 --- a/source/renderer/app/components/staking/StakingSystemState.js +++ b/source/renderer/app/components/staking/StakingSystemState.js @@ -6,7 +6,6 @@ import styles from './StakingSystemState.scss'; @observer export default class StakingSystemState extends Component { - render() { return (
@@ -21,5 +20,4 @@ export default class StakingSystemState extends Component {
); } - } diff --git a/source/renderer/app/components/staking/StakingSystemState.scss b/source/renderer/app/components/staking/StakingSystemState.scss index 7aaf70a023..d4cba3a777 100644 --- a/source/renderer/app/components/staking/StakingSystemState.scss +++ b/source/renderer/app/components/staking/StakingSystemState.scss @@ -1,4 +1,4 @@ -@import "./stakingConfig"; +@import './stakingConfig'; .component { @extend %contentBorderAndBackground; diff --git a/source/renderer/app/components/staking/StakingSystemStateElement.js b/source/renderer/app/components/staking/StakingSystemStateElement.js index 01dd6c3495..03fceedf47 100644 --- a/source/renderer/app/components/staking/StakingSystemStateElement.js +++ b/source/renderer/app/components/staking/StakingSystemStateElement.js @@ -18,5 +18,4 @@ export default class StakingSystemState extends Component {
); } - } diff --git a/source/renderer/app/components/staking/StakingSystemStateElement.scss b/source/renderer/app/components/staking/StakingSystemStateElement.scss index f6f83d6c7d..3c4ff652d3 100644 --- a/source/renderer/app/components/staking/StakingSystemStateElement.scss +++ b/source/renderer/app/components/staking/StakingSystemStateElement.scss @@ -1,4 +1,4 @@ -@import "./stakingConfig"; +@import './stakingConfig'; .component { padding: 14px 0 0 0; diff --git a/source/renderer/app/components/static/About.js b/source/renderer/app/components/static/About.js index ab288095fb..ff4eb3c8b2 100644 --- a/source/renderer/app/components/static/About.js +++ b/source/renderer/app/components/static/About.js @@ -25,12 +25,14 @@ const messages = defineMessages({ }, aboutContentDaedalusMembers: { id: 'static.about.content.daedalus.members', - defaultMessage: '!!!Alexander Rukin, Charles Hoskinson, Clemens Helm, Darko Mijić, Dominik Guzei, Jeremy Wood, Nikola Glumac, Richard Wild, Stefan Malzner, Tomislav Horaček', + defaultMessage: + '!!!Alexander Rukin, Charles Hoskinson, Clemens Helm, Darko Mijić, Dominik Guzei, Jeremy Wood, Nikola Glumac, Richard Wild, Stefan Malzner, Tomislav Horaček', description: 'About page daedalus team members', }, aboutContentCardanoMembers: { id: 'static.about.content.cardano.members', - defaultMessage: '!!!Alexander Sukhoverkhov, Alexander Vieth, Alexandre Rodrigues Baldé, Alfredo Di Napoli, Anastasiya Besman, Andrzej Rybczak, Ante Kegalj, Anton Belyy, Anupam Jain, Arseniy Seroka, Artyom Kazak, Carlos D\'Agostino, Charles Hoskinson, Dan Friedman, Denis Shevchenko, Dmitry Kovanikov, Dmitry Mukhutdinov, Dmitry Nikulin, Domen Kožar, Duncan Coutts, Edsko de Vries, Eileen Fitzgerald, George Agapov, Hiroto Shioi, Ilya Lubimov, Ilya Peresadin, Ivan Gromakovskii, Jake Mitchell, Jane Wild, Jens Krause, Jeremy Wood, Joel Mislov Kunst, Jonn Mostovoy, Konstantin Ivanov, Kristijan Šarić, Lars Brünjes, Laurie Wang, Lionel Miller, Michael Bishop, Mikhail Volkhov, Niklas Hambüchen, Peter Gaži, Philipp Kant, Serge Kosyrev, Vincent Hanquez', + defaultMessage: + "!!!Alexander Sukhoverkhov, Alexander Vieth, Alexandre Rodrigues Baldé, Alfredo Di Napoli, Anastasiya Besman, Andrzej Rybczak, Ante Kegalj, Anton Belyy, Anupam Jain, Arseniy Seroka, Artyom Kazak, Carlos D'Agostino, Charles Hoskinson, Dan Friedman, Denis Shevchenko, Dmitry Kovanikov, Dmitry Mukhutdinov, Dmitry Nikulin, Domen Kožar, Duncan Coutts, Edsko de Vries, Eileen Fitzgerald, George Agapov, Hiroto Shioi, Ilya Lubimov, Ilya Peresadin, Ivan Gromakovskii, Jake Mitchell, Jane Wild, Jens Krause, Jeremy Wood, Joel Mislov Kunst, Jonn Mostovoy, Konstantin Ivanov, Kristijan Šarić, Lars Brünjes, Laurie Wang, Lionel Miller, Michael Bishop, Mikhail Volkhov, Niklas Hambüchen, Peter Gaži, Philipp Kant, Serge Kosyrev, Vincent Hanquez", description: 'About page cardano team members', }, aboutCopyright: { @@ -55,11 +57,10 @@ type Props = { build: string, onOpenExternalLink: Function, os: string, - version: string + version: string, }; export default class About extends Component { - static contextTypes = { intl: intlShape.isRequired, }; @@ -70,22 +71,20 @@ export default class About extends Component { const apiName = intl.formatMessage(globalMessages.apiName); const apiIcon = cardanoIcon; - const apiHeadline = intl.formatMessage(messages.aboutContentCardanoHeadline); + const apiHeadline = intl.formatMessage( + messages.aboutContentCardanoHeadline + ); const apiMembers = intl.formatMessage(messages.aboutContentCardanoMembers); return (
-
-
{intl.formatMessage(messages.aboutTitle)} - - {version} - + {version}
{

{apiHeadline}

-
- {apiMembers} -
+
{apiMembers}
@@ -124,7 +121,11 @@ export default class About extends Component {
{intl.formatMessage(messages.aboutCopyright)}  onOpenExternalLink('https://github.com/input-output-hk/daedalus/blob/master/LICENSE')} + onClick={() => + onOpenExternalLink( + 'https://github.com/input-output-hk/daedalus/blob/master/LICENSE' + ) + } className={styles.link} role="link" aria-hidden @@ -133,7 +134,6 @@ export default class About extends Component {
-
); } diff --git a/source/renderer/app/components/static/About.scss b/source/renderer/app/components/static/About.scss index d7c8185d54..c5cd181d01 100644 --- a/source/renderer/app/components/static/About.scss +++ b/source/renderer/app/components/static/About.scss @@ -7,7 +7,8 @@ user-select: text; .headerWrapper { - border-bottom: 1px solid var(--theme-about-window-header-bottom-border-color); + border-bottom: 1px solid + var(--theme-about-window-header-bottom-border-color); display: flex; padding-bottom: 20px; @@ -74,7 +75,8 @@ } .contentText { - border-bottom: 1px solid var(--theme-about-window-content-bottom-border-color); + border-bottom: 1px solid + var(--theme-about-window-content-bottom-border-color); color: var(--theme-about-window-content-text-color); flex: 1; font-family: var(--font-regular); diff --git a/source/renderer/app/components/status/BlockConsolidationStatus.js b/source/renderer/app/components/status/BlockConsolidationStatus.js index 62e394ca71..da25511531 100644 --- a/source/renderer/app/components/status/BlockConsolidationStatus.js +++ b/source/renderer/app/components/status/BlockConsolidationStatus.js @@ -13,57 +13,62 @@ const messages = defineMessages({ title: { id: 'blockConsolidationStatus.title', defaultMessage: '!!!Block storage consolidation status', - description: 'Title of "Block consolidation status" page.' + description: 'Title of "Block consolidation status" page.', }, description1: { id: 'blockConsolidationStatus.description1', defaultMessage: '!!!Block storage is being consolidated.', - description: 'Description 1 of "Block consolidation status" page.' + description: 'Description 1 of "Block consolidation status" page.', }, description2: { id: 'blockConsolidationStatus.description2', - defaultMessage: '!!!Blocks for the current epoch ({currentEpoch}) and the previous epoch ({currentEpochBehind}) are stored as one file per block. All previous epochs will be consolidated to two files per epoch.', - description: 'Description 2 of "Block consolidation status" page.' + defaultMessage: + '!!!Blocks for the current epoch ({currentEpoch}) and the previous epoch ({currentEpochBehind}) are stored as one file per block. All previous epochs will be consolidated to two files per epoch.', + description: 'Description 2 of "Block consolidation status" page.', }, description3: { id: 'blockConsolidationStatus.description3', - defaultMessage: '!!!This reduces the number of files and the amount of hard drive space required to store the blockchain on your machine.', - description: 'Description 3 of "Block consolidation status" page.' + defaultMessage: + '!!!This reduces the number of files and the amount of hard drive space required to store the blockchain on your machine.', + description: 'Description 3 of "Block consolidation status" page.', }, epochsConsolidatedOfTotal: { id: 'blockConsolidationStatus.epochsConsolidatedOfTotal', - defaultMessage: '!!!{consolidated} of {downloaded} epochs consolidated', - description: 'Epochs Consolidated Of Total on "Block consolidation status" page.' + defaultMessage: + '!!!{consolidated} of {downloaded} epochs consolidated', + description: + 'Epochs Consolidated Of Total on "Block consolidation status" page.', }, epoch: { id: 'blockConsolidationStatus.epoch', defaultMessage: '!!!epoch', - description: 'Singular Epoch on "Block consolidation status" page.' + description: 'Singular Epoch on "Block consolidation status" page.', }, epochs: { id: 'blockConsolidationStatus.epochs', defaultMessage: '!!!epochs', - description: 'Plural Epochs on "Block consolidation status" page.' + description: 'Plural Epochs on "Block consolidation status" page.', }, epochsConsolidated: { id: 'blockConsolidationStatus.epochsConsolidated', defaultMessage: '!!!epochs consolidated', - description: 'Epochs consolidated on "Block consolidation status" page.' + description: 'Epochs consolidated on "Block consolidation status" page.', }, synced: { id: 'blockConsolidationStatus.synced', defaultMessage: '!!!{epochsSynced}% blocks synced', - description: 'synced on "Block consolidation status" page.' + description: 'synced on "Block consolidation status" page.', }, supportButton: { id: 'blockConsolidationStatus.supportButton', defaultMessage: '!!!Support', - description: 'Support Button on "Block consolidation status" page.' + description: 'Support Button on "Block consolidation status" page.', }, supportButtonURL: { id: 'blockConsolidationStatus.supportButtonURL', - defaultMessage: '!!!https://iohk.zendesk.com/hc/en-us/articles/360016060314', - description: 'URL of Support Button on "Block consolidation status" page.' + defaultMessage: + '!!!https://iohk.zendesk.com/hc/en-us/articles/360016060314', + description: 'URL of Support Button on "Block consolidation status" page.', }, }); @@ -77,26 +82,26 @@ type Props = { @observer export default class BlockConsolidationStatus extends Component { - static contextTypes = { intl: intlShape.isRequired, }; getWidthOfEpochsConsolidated = ( epochsConsolidated: number, - currentEpoch: number, + currentEpoch: number ) => { - const widthOfEpochsConsolidated = epochsConsolidated * 100 / (currentEpoch - 2); + const widthOfEpochsConsolidated = + (epochsConsolidated * 100) / (currentEpoch - 2); return Math.min(widthOfEpochsConsolidated, 100); }; - getPositionOfEpochsConsolidated = (widthOfEpochsConsolidated: number) => ( - (widthOfEpochsConsolidated > 32) ? { right: 8 } : { left: 0, textAlign: 'left' } - ); + getPositionOfEpochsConsolidated = (widthOfEpochsConsolidated: number) => + widthOfEpochsConsolidated > 32 + ? { right: 8 } + : { left: 0, textAlign: 'left' }; - getPositionOfEpochsSynced = (widthOfEpochsSynced: number) => ( - (widthOfEpochsSynced > 20) ? { right: 0 } : { left: 0 } - ); + getPositionOfEpochsSynced = (widthOfEpochsSynced: number) => + widthOfEpochsSynced > 20 ? { right: 0 } : { left: 0 }; render() { const { @@ -107,15 +112,14 @@ export default class BlockConsolidationStatus extends Component { onClose, } = this.props; const { formatMessage } = this.context.intl; - const widthOfEpochsConsolidated = - this.getWidthOfEpochsConsolidated(epochsConsolidated, currentEpoch); + const widthOfEpochsConsolidated = this.getWidthOfEpochsConsolidated( + epochsConsolidated, + currentEpoch + ); return (
- +
@@ -142,7 +146,7 @@ export default class BlockConsolidationStatus extends Component { {...messages.epochsConsolidatedOfTotal} values={{ consolidated: epochsConsolidated, - downloaded: currentEpoch + downloaded: currentEpoch, }} />

@@ -151,9 +155,14 @@ export default class BlockConsolidationStatus extends Component {
-

{formatMessage(messages.epoch)} 0

+

+ {formatMessage(messages.epoch)} 0 +

-

{formatMessage(messages.epoch)} {Math.max(currentEpoch - 2, 0)}

+

+ {formatMessage(messages.epoch)}{' '} + {Math.max(currentEpoch - 2, 0)} +

{ className={styles.indicatorEpochsConsolidated} style={{ width: `${widthOfEpochsConsolidated}%` }} > -

- {epochsConsolidated} {formatMessage(messages.epochsConsolidated)} +

+ {epochsConsolidated}{' '} + {formatMessage(messages.epochsConsolidated)}

@@ -184,7 +198,9 @@ export default class BlockConsolidationStatus extends Component {
diff --git a/source/renderer/app/components/status/BlockConsolidationStatus.scss b/source/renderer/app/components/status/BlockConsolidationStatus.scss index 7a0ade4b45..d284eb14f0 100644 --- a/source/renderer/app/components/status/BlockConsolidationStatus.scss +++ b/source/renderer/app/components/status/BlockConsolidationStatus.scss @@ -57,7 +57,6 @@ } } - .epochs { height: 149px; margin: 0 auto 60px; @@ -74,7 +73,7 @@ width: 118px; em { - font-size: 16px + font-size: 16px; } b { @@ -98,7 +97,9 @@ } .indicatorContainer { - background-color: var(--theme-block-consolidation-indicator-container-background-color); + background-color: var( + --theme-block-consolidation-indicator-container-background-color + ); border-radius: 5px; height: 24px; margin: 0 auto; diff --git a/source/renderer/app/components/status/NetworkStatus.js b/source/renderer/app/components/status/NetworkStatus.js index 30e20a6ba6..6ef03408b6 100644 --- a/source/renderer/app/components/status/NetworkStatus.js +++ b/source/renderer/app/components/status/NetworkStatus.js @@ -6,8 +6,13 @@ import moment from 'moment'; import classNames from 'classnames'; import SVGInline from 'react-svg-inline'; import { - LineChart, YAxis, XAxis, Line, - CartesianGrid, Tooltip, Legend, + LineChart, + YAxis, + XAxis, + Line, + CartesianGrid, + Tooltip, + Legend, ResponsiveContainer, } from 'recharts'; import { @@ -65,7 +70,6 @@ type State = { @observer export default class NetworkStatus extends Component { - constructor(props: Props) { super(props); let { localBlockHeight, networkBlockHeight } = props; @@ -73,16 +77,56 @@ export default class NetworkStatus extends Component { networkBlockHeight = networkBlockHeight || null; this.state = { data: [ - { localBlockHeight, networkBlockHeight, time: moment(Date.now() - 20000).format('HH:mm:ss') }, - { localBlockHeight, networkBlockHeight, time: moment(Date.now() - 18000).format('HH:mm:ss') }, - { localBlockHeight, networkBlockHeight, time: moment(Date.now() - 16000).format('HH:mm:ss') }, - { localBlockHeight, networkBlockHeight, time: moment(Date.now() - 14000).format('HH:mm:ss') }, - { localBlockHeight, networkBlockHeight, time: moment(Date.now() - 12000).format('HH:mm:ss') }, - { localBlockHeight, networkBlockHeight, time: moment(Date.now() - 10000).format('HH:mm:ss') }, - { localBlockHeight, networkBlockHeight, time: moment(Date.now() - 8000).format('HH:mm:ss') }, - { localBlockHeight, networkBlockHeight, time: moment(Date.now() - 6000).format('HH:mm:ss') }, - { localBlockHeight, networkBlockHeight, time: moment(Date.now() - 4000).format('HH:mm:ss') }, - { localBlockHeight, networkBlockHeight, time: moment(Date.now() - 2000).format('HH:mm:ss') }, + { + localBlockHeight, + networkBlockHeight, + time: moment(Date.now() - 20000).format('HH:mm:ss'), + }, + { + localBlockHeight, + networkBlockHeight, + time: moment(Date.now() - 18000).format('HH:mm:ss'), + }, + { + localBlockHeight, + networkBlockHeight, + time: moment(Date.now() - 16000).format('HH:mm:ss'), + }, + { + localBlockHeight, + networkBlockHeight, + time: moment(Date.now() - 14000).format('HH:mm:ss'), + }, + { + localBlockHeight, + networkBlockHeight, + time: moment(Date.now() - 12000).format('HH:mm:ss'), + }, + { + localBlockHeight, + networkBlockHeight, + time: moment(Date.now() - 10000).format('HH:mm:ss'), + }, + { + localBlockHeight, + networkBlockHeight, + time: moment(Date.now() - 8000).format('HH:mm:ss'), + }, + { + localBlockHeight, + networkBlockHeight, + time: moment(Date.now() - 6000).format('HH:mm:ss'), + }, + { + localBlockHeight, + networkBlockHeight, + time: moment(Date.now() - 4000).format('HH:mm:ss'), + }, + { + localBlockHeight, + networkBlockHeight, + time: moment(Date.now() - 2000).format('HH:mm:ss'), + }, ], isNodeRestarting: false, }; @@ -102,7 +146,7 @@ export default class NetworkStatus extends Component { CardanoNodeStates.UPDATED, CardanoNodeStates.CRASHED, CardanoNodeStates.ERRORED, - CardanoNodeStates.UNRECOVERABLE + CardanoNodeStates.UNRECOVERABLE, ]; if ( isNodeRestarting && @@ -119,12 +163,32 @@ export default class NetworkStatus extends Component { render() { const { - cardanoNodeState, isNodeResponding, isNodeSubscribed, isNodeSyncing, isNodeInSync, - isNodeTimeCorrect, isConnected, isSynced, syncPercentage, hasBeenConnected, - localTimeDifference, isSystemTimeCorrect, isForceCheckingNodeTime, - localBlockHeight, networkBlockHeight, latestLocalBlockTimestamp, latestNetworkBlockTimestamp, - onForceCheckLocalTimeDifference, onClose, nodeConnectionError, isSystemTimeIgnored, - onOpenExternalLink, isDev, isTestnet, isStaging, isMainnet, + cardanoNodeState, + isNodeResponding, + isNodeSubscribed, + isNodeSyncing, + isNodeInSync, + isNodeTimeCorrect, + isConnected, + isSynced, + syncPercentage, + hasBeenConnected, + localTimeDifference, + isSystemTimeCorrect, + isForceCheckingNodeTime, + localBlockHeight, + networkBlockHeight, + latestLocalBlockTimestamp, + latestNetworkBlockTimestamp, + onForceCheckLocalTimeDifference, + onClose, + nodeConnectionError, + isSystemTimeIgnored, + onOpenExternalLink, + isDev, + isTestnet, + isStaging, + isMainnet, } = this.props; const { data, isNodeRestarting } = this.state; const isNTPServiceReachable = !!localTimeDifference; @@ -132,36 +196,50 @@ export default class NetworkStatus extends Component { const { message, code } = connectionError; const localTimeDifferenceClasses = classNames([ - ( - !isNTPServiceReachable || - (localTimeDifference && (localTimeDifference > ALLOWED_TIME_DIFFERENCE)) - ) ? styles.red : styles.green, + !isNTPServiceReachable || + (localTimeDifference && localTimeDifference > ALLOWED_TIME_DIFFERENCE) + ? styles.red + : styles.green, ]); const remainingUnsyncedBlocks = networkBlockHeight - localBlockHeight; const remainingUnsyncedBlocksClasses = classNames([ - ( - remainingUnsyncedBlocks < 0 || - remainingUnsyncedBlocks > UNSYNCED_BLOCKS_ALLOWED - ) ? styles.red : styles.green, + remainingUnsyncedBlocks < 0 || + remainingUnsyncedBlocks > UNSYNCED_BLOCKS_ALLOWED + ? styles.red + : styles.green, ]); - const latestLocalBlockAge = moment(Date.now()).diff(moment(latestLocalBlockTimestamp)); - const isLocalBlockHeightStalling = latestLocalBlockAge > MAX_ALLOWED_STALL_DURATION; + const latestLocalBlockAge = moment(Date.now()).diff( + moment(latestLocalBlockTimestamp) + ); + const isLocalBlockHeightStalling = + latestLocalBlockAge > MAX_ALLOWED_STALL_DURATION; const latestLocalBlockAgeClasses = classNames([ - latestLocalBlockTimestamp > 0 && !isLocalBlockHeightStalling ? styles.green : styles.red, + latestLocalBlockTimestamp > 0 && !isLocalBlockHeightStalling + ? styles.green + : styles.red, ]); - const latestNetworkBlockAge = moment(Date.now()).diff(moment(latestNetworkBlockTimestamp)); - const isNetworkBlockHeightStalling = latestNetworkBlockAge > MAX_ALLOWED_STALL_DURATION; + const latestNetworkBlockAge = moment(Date.now()).diff( + moment(latestNetworkBlockTimestamp) + ); + const isNetworkBlockHeightStalling = + latestNetworkBlockAge > MAX_ALLOWED_STALL_DURATION; const latestNetworkBlockAgeClasses = classNames([ - latestNetworkBlockTimestamp > 0 && !isNetworkBlockHeightStalling ? styles.green : styles.red, + latestNetworkBlockTimestamp > 0 && !isNetworkBlockHeightStalling + ? styles.green + : styles.red, ]); // Cardano Node EKG server is not enabled for the Mainnet! - const cardanoNodeEkgLink = isMainnet ? false : getNetworkEkgUrl({ - isDev, isStaging, isTestnet - }); + const cardanoNodeEkgLink = isMainnet + ? false + : getNetworkEkgUrl({ + isDev, + isStaging, + isTestnet, + }); return (
@@ -182,9 +260,7 @@ export default class NetworkStatus extends Component { hasBeenConnected: - - {hasBeenConnected ? 'YES' : 'NO'} - + {hasBeenConnected ? 'YES' : 'NO'} isSynced: @@ -213,25 +289,28 @@ export default class NetworkStatus extends Component { latestLocalBlockAge: - {latestLocalBlockTimestamp > 0 ? `${latestLocalBlockAge} ms` : '-'} + {latestLocalBlockTimestamp > 0 + ? `${latestLocalBlockAge} ms` + : '-'} latestNetworkBlockAge: - {latestNetworkBlockTimestamp > 0 ? `${latestNetworkBlockAge} ms` : '-'} + {latestNetworkBlockTimestamp > 0 + ? `${latestNetworkBlockAge} ms` + : '-'} localTimeDifference: - {isNTPServiceReachable ? ( - `${localTimeDifference || 0} μs` - ) : ( - 'NTP service unreachable' - )} - |  + {isNTPServiceReachable + ? `${localTimeDifference || 0} μs` + : 'NTP service unreachable'} + {' '} + | 
); } - } diff --git a/source/renderer/app/components/wallet/WalletBackupDialog.js b/source/renderer/app/components/wallet/WalletBackupDialog.js index e68997dbe6..813f80ab65 100644 --- a/source/renderer/app/components/wallet/WalletBackupDialog.js +++ b/source/renderer/app/components/wallet/WalletBackupDialog.js @@ -4,7 +4,10 @@ import { observer } from 'mobx-react'; import WalletBackupPrivacyWarningDialog from './backup-recovery/WalletBackupPrivacyWarningDialog'; import WalletRecoveryPhraseDisplayDialog from './backup-recovery/WalletRecoveryPhraseDisplayDialog'; import WalletRecoveryPhraseEntryDialog from './backup-recovery/WalletRecoveryPhraseEntryDialog'; -import type { RecoveryPhraseWord, walletBackupStep } from '../../types/walletBackupTypes'; +import type { + RecoveryPhraseWord, + walletBackupStep, +} from '../../types/walletBackupTypes'; import { WALLET_BACKUP_STEPS } from '../../types/walletBackupTypes'; type Props = { @@ -34,19 +37,30 @@ type Props = { @observer export default class WalletBackupDialog extends Component { - render() { const { - currentStep, onCancelBackup, - canPhraseBeShown, isPrivacyNoticeAccepted, - countdownRemaining, onAcceptPrivacyNotice, - onContinue, recoveryPhrase, - onStartWalletBackup, isTermDeviceAccepted, - enteredPhrase, canFinishBackup, - isTermRecoveryAccepted, isValid, isSubmitting, - onAcceptTermDevice, onAcceptTermRecovery, - onAddWord, onClear, onFinishBackup, - onRestartBackup, recoveryPhraseShuffled, + currentStep, + onCancelBackup, + canPhraseBeShown, + isPrivacyNoticeAccepted, + countdownRemaining, + onAcceptPrivacyNotice, + onContinue, + recoveryPhrase, + onStartWalletBackup, + isTermDeviceAccepted, + enteredPhrase, + canFinishBackup, + isTermRecoveryAccepted, + isValid, + isSubmitting, + onAcceptTermDevice, + onAcceptTermRecovery, + onAddWord, + onClear, + onFinishBackup, + onRestartBackup, + recoveryPhraseShuffled, } = this.props; if (currentStep === WALLET_BACKUP_STEPS.PRIVACY_WARNING) { diff --git a/source/renderer/app/components/wallet/WalletCreateDialog.js b/source/renderer/app/components/wallet/WalletCreateDialog.js index e32b478a13..1934d07e79 100644 --- a/source/renderer/app/components/wallet/WalletCreateDialog.js +++ b/source/renderer/app/components/wallet/WalletCreateDialog.js @@ -11,7 +11,11 @@ import { defineMessages, intlShape } from 'react-intl'; import ReactToolboxMobxForm from '../../utils/ReactToolboxMobxForm'; import DialogCloseButton from '../widgets/DialogCloseButton'; import Dialog from '../widgets/Dialog'; -import { isValidWalletName, isValidSpendingPassword, isValidRepeatPassword } from '../../utils/validations'; +import { + isValidWalletName, + isValidSpendingPassword, + isValidRepeatPassword, +} from '../../utils/validations'; import globalMessages from '../../i18n/global-messages'; import styles from './WalletCreateDialog.scss'; import { FORM_VALIDATION_DEBOUNCE_WAIT } from '../../config/timingConfig'; @@ -21,47 +25,56 @@ const messages = defineMessages({ dialogTitle: { id: 'wallet.create.dialog.title', defaultMessage: '!!!Create a new wallet', - description: 'Title "Create a new wallet" in the wallet create form.' + description: 'Title "Create a new wallet" in the wallet create form.', }, walletName: { id: 'wallet.create.dialog.name.label', defaultMessage: '!!!Wallet Name', - description: 'Label for the "Wallet Name" text input in the wallet create form.' + description: + 'Label for the "Wallet Name" text input in the wallet create form.', }, walletNameHint: { id: 'wallet.create.dialog.walletNameHint', defaultMessage: '!!!e.g: Shopping Wallet', - description: 'Hint for the "Wallet Name" text input in the wallet create form.' + description: + 'Hint for the "Wallet Name" text input in the wallet create form.', }, createPersonalWallet: { id: 'wallet.create.dialog.create.personal.wallet.button.label', defaultMessage: '!!!Create personal wallet', - description: 'Label for the "Create personal wallet" button on create wallet dialog.' + description: + 'Label for the "Create personal wallet" button on create wallet dialog.', }, passwordSwitchPlaceholder: { id: 'wallet.create.dialog.passwordSwitchPlaceholder', - defaultMessage: '!!!Keep your private keys safely encrypted by setting the spending password', - description: 'Text for the "Activate to create password" switch in the create wallet dialog.', + defaultMessage: + '!!!Keep your private keys safely encrypted by setting the spending password', + description: + 'Text for the "Activate to create password" switch in the create wallet dialog.', }, passwordSwitchLabel: { id: 'wallet.create.dialog.passwordSwitchLabel', defaultMessage: '!!!Spending password', - description: 'Label for the "Activate to create password" switch in the create wallet dialog.', + description: + 'Label for the "Activate to create password" switch in the create wallet dialog.', }, spendingPasswordLabel: { id: 'wallet.create.dialog.spendingPasswordLabel', defaultMessage: '!!!Enter password', - description: 'Label for the "Wallet password" input in the create wallet dialog.', + description: + 'Label for the "Wallet password" input in the create wallet dialog.', }, repeatPasswordLabel: { id: 'wallet.create.dialog.repeatPasswordLabel', defaultMessage: '!!!Repeat password', - description: 'Label for the "Repeat password" input in the create wallet dialog.', + description: + 'Label for the "Repeat password" input in the create wallet dialog.', }, passwordFieldPlaceholder: { id: 'wallet.create.dialog.passwordFieldPlaceholder', defaultMessage: '!!!Password', - description: 'Placeholder for the "Password" inputs in the create wallet dialog.', + description: + 'Placeholder for the "Password" inputs in the create wallet dialog.', }, }); @@ -77,7 +90,6 @@ type State = { @observer export default class WalletCreateDialog extends Component { - static contextTypes = { intl: intlShape.isRequired, }; @@ -88,67 +100,86 @@ export default class WalletCreateDialog extends Component { }; componentDidMount() { - setTimeout(() => { this.walletNameInput.focus(); }); + setTimeout(() => { + this.walletNameInput.focus(); + }); } walletNameInput: Input; - form = new ReactToolboxMobxForm({ - fields: { - walletName: { - label: this.context.intl.formatMessage(messages.walletName), - placeholder: this.context.intl.formatMessage(messages.walletNameHint), - value: '', - validators: [({ field }) => ( - [ - isValidWalletName(field.value), - this.context.intl.formatMessage(globalMessages.invalidWalletName) - ] - )], - }, - spendingPassword: { - type: 'password', - label: this.context.intl.formatMessage(messages.spendingPasswordLabel), - placeholder: this.context.intl.formatMessage(messages.passwordFieldPlaceholder), - value: '', - validators: [({ field, form }) => { - if (!this.state.createPassword) return [true]; - const repeatPasswordField = form.$('repeatPassword'); - if (repeatPasswordField.value.length > 0) { - repeatPasswordField.validate({ showErrors: true }); - } - return [ - isValidSpendingPassword(field.value), - this.context.intl.formatMessage(globalMessages.invalidSpendingPassword) - ]; - }], + form = new ReactToolboxMobxForm( + { + fields: { + walletName: { + label: this.context.intl.formatMessage(messages.walletName), + placeholder: this.context.intl.formatMessage(messages.walletNameHint), + value: '', + validators: [ + ({ field }) => [ + isValidWalletName(field.value), + this.context.intl.formatMessage(globalMessages.invalidWalletName), + ], + ], + }, + spendingPassword: { + type: 'password', + label: this.context.intl.formatMessage( + messages.spendingPasswordLabel + ), + placeholder: this.context.intl.formatMessage( + messages.passwordFieldPlaceholder + ), + value: '', + validators: [ + ({ field, form }) => { + if (!this.state.createPassword) return [true]; + const repeatPasswordField = form.$('repeatPassword'); + if (repeatPasswordField.value.length > 0) { + repeatPasswordField.validate({ showErrors: true }); + } + return [ + isValidSpendingPassword(field.value), + this.context.intl.formatMessage( + globalMessages.invalidSpendingPassword + ), + ]; + }, + ], + }, + repeatPassword: { + type: 'password', + label: this.context.intl.formatMessage(messages.repeatPasswordLabel), + placeholder: this.context.intl.formatMessage( + messages.passwordFieldPlaceholder + ), + value: '', + validators: [ + ({ field, form }) => { + if (!this.state.createPassword) return [true]; + const spendingPassword = form.$('spendingPassword').value; + if (spendingPassword.length === 0) return [true]; + return [ + isValidRepeatPassword(spendingPassword, field.value), + this.context.intl.formatMessage( + globalMessages.invalidRepeatPassword + ), + ]; + }, + ], + }, }, - repeatPassword: { - type: 'password', - label: this.context.intl.formatMessage(messages.repeatPasswordLabel), - placeholder: this.context.intl.formatMessage(messages.passwordFieldPlaceholder), - value: '', - validators: [({ field, form }) => { - if (!this.state.createPassword) return [true]; - const spendingPassword = form.$('spendingPassword').value; - if (spendingPassword.length === 0) return [true]; - return [ - isValidRepeatPassword(spendingPassword, field.value), - this.context.intl.formatMessage(globalMessages.invalidRepeatPassword) - ]; - }], + }, + { + options: { + validateOnChange: true, + validationDebounceWait: FORM_VALIDATION_DEBOUNCE_WAIT, }, } - }, { - options: { - validateOnChange: true, - validationDebounceWait: FORM_VALIDATION_DEBOUNCE_WAIT, - }, - }); + ); submit = () => { this.form.submit({ - onSuccess: (form) => { + onSuccess: form => { this.setState({ isSubmitting: true }); const { createPassword } = this.state; const { walletName, spendingPassword } = form.values(); @@ -173,10 +204,7 @@ export default class WalletCreateDialog extends Component { const { intl } = this.context; const { onCancel } = this.props; const { createPassword, isSubmitting } = this.state; - const dialogClasses = classnames([ - styles.component, - 'WalletCreateDialog', - ]); + const dialogClasses = classnames([styles.component, 'WalletCreateDialog']); const spendingPasswordFieldsClasses = classnames([ styles.spendingPasswordFields, createPassword ? styles.show : null, @@ -204,11 +232,12 @@ export default class WalletCreateDialog extends Component { onClose={!isSubmitting ? onCancel : () => {}} closeButton={} > - { this.walletNameInput = input; }} + ref={input => { + this.walletNameInput = input; + }} {...walletNameField.bind()} error={walletNameField.error} skin={InputSkin} @@ -248,9 +277,7 @@ export default class WalletCreateDialog extends Component {

- ); } - } diff --git a/source/renderer/app/components/wallet/WalletCreateDialog.scss b/source/renderer/app/components/wallet/WalletCreateDialog.scss index e82743350b..2f32a93fac 100644 --- a/source/renderer/app/components/wallet/WalletCreateDialog.scss +++ b/source/renderer/app/components/wallet/WalletCreateDialog.scss @@ -56,5 +56,5 @@ .isSubmitting { box-shadow: none !important; - @include loading-spinner("../../assets/images/spinner-light.svg"); + @include loading-spinner('../../assets/images/spinner-light.svg'); } diff --git a/source/renderer/app/components/wallet/WalletRestoreDialog.js b/source/renderer/app/components/wallet/WalletRestoreDialog.js index b92c26c752..fd31b07b84 100644 --- a/source/renderer/app/components/wallet/WalletRestoreDialog.js +++ b/source/renderer/app/components/wallet/WalletRestoreDialog.js @@ -14,104 +14,129 @@ import { defineMessages, intlShape } from 'react-intl'; import ReactToolboxMobxForm from '../../utils/ReactToolboxMobxForm'; import DialogCloseButton from '../widgets/DialogCloseButton'; import Dialog from '../widgets/Dialog'; -import { isValidWalletName, isValidSpendingPassword, isValidRepeatPassword } from '../../utils/validations'; +import { + isValidWalletName, + isValidSpendingPassword, + isValidRepeatPassword, +} from '../../utils/validations'; import globalMessages from '../../i18n/global-messages'; import LocalizableError from '../../i18n/LocalizableError'; -import { PAPER_WALLET_RECOVERY_PHRASE_WORD_COUNT, WALLET_RECOVERY_PHRASE_WORD_COUNT } from '../../config/cryptoConfig'; +import { + PAPER_WALLET_RECOVERY_PHRASE_WORD_COUNT, + WALLET_RECOVERY_PHRASE_WORD_COUNT, +} from '../../config/cryptoConfig'; import { FORM_VALIDATION_DEBOUNCE_WAIT } from '../../config/timingConfig'; import styles from './WalletRestoreDialog.scss'; import { submitOnEnter } from '../../utils/form'; const RESTORE_TYPES = { REGULAR: 'regular', - CERTIFICATE: 'certificate' + CERTIFICATE: 'certificate', }; const messages = defineMessages({ title: { id: 'wallet.restore.dialog.title.label', defaultMessage: '!!!Restore a wallet', - description: 'Label "Restore wallet" on the wallet restore dialog.' + description: 'Label "Restore wallet" on the wallet restore dialog.', }, walletNameInputLabel: { id: 'wallet.restore.dialog.wallet.name.input.label', defaultMessage: '!!!Wallet name', - description: 'Label for the wallet name input on the wallet restore dialog.' + description: + 'Label for the wallet name input on the wallet restore dialog.', }, walletNameInputHint: { id: 'wallet.restore.dialog.wallet.name.input.hint', defaultMessage: '!!!Name the wallet you are restoring', - description: 'Hint "Name the wallet you are restoring" for the wallet name input on the wallet restore dialog.' + description: + 'Hint "Name the wallet you are restoring" for the wallet name input on the wallet restore dialog.', }, recoveryPhraseInputLabel: { id: 'wallet.restore.dialog.recovery.phrase.input.label', defaultMessage: '!!!Recovery phrase', - description: 'Label for the recovery phrase input on the wallet restore dialog.' + description: + 'Label for the recovery phrase input on the wallet restore dialog.', }, recoveryPhraseInputHint: { id: 'wallet.restore.dialog.recovery.phrase.input.hint', defaultMessage: '!!!Enter recovery phrase', - description: 'Hint "Enter recovery phrase" for the recovery phrase input on the wallet restore dialog.' + description: + 'Hint "Enter recovery phrase" for the recovery phrase input on the wallet restore dialog.', }, recoveryPhraseNoResults: { id: 'wallet.restore.dialog.recovery.phrase.input.noResults', defaultMessage: '!!!No results', - description: '"No results" message for the recovery phrase input search results.' + description: + '"No results" message for the recovery phrase input search results.', }, importButtonLabel: { id: 'wallet.restore.dialog.restore.wallet.button.label', defaultMessage: '!!!Restore wallet', - description: 'Label for the "Restore wallet" button on the wallet restore dialog.' + description: + 'Label for the "Restore wallet" button on the wallet restore dialog.', }, invalidRecoveryPhrase: { id: 'wallet.restore.dialog.form.errors.invalidRecoveryPhrase', defaultMessage: '!!!Invalid recovery phrase', - description: 'Error message shown when invalid recovery phrase was entered.' + description: + 'Error message shown when invalid recovery phrase was entered.', }, passwordSwitchPlaceholder: { id: 'wallet.restore.dialog.passwordSwitchPlaceholder', - defaultMessage: '!!!Keep your private keys safely encrypted by setting the spending password', - description: 'Text for the "Spending password" switch in the wallet restore dialog.', + defaultMessage: + '!!!Keep your private keys safely encrypted by setting the spending password', + description: + 'Text for the "Spending password" switch in the wallet restore dialog.', }, passwordSwitchLabel: { id: 'wallet.restore.dialog.passwordSwitchLabel', defaultMessage: '!!!Spending password', - description: 'Label for the "Spending password" switch in the wallet restore dialog.', + description: + 'Label for the "Spending password" switch in the wallet restore dialog.', }, spendingPasswordLabel: { id: 'wallet.restore.dialog.spendingPasswordLabel', defaultMessage: '!!!Enter password', - description: 'Label for the "Wallet password" input in the wallet restore dialog.', + description: + 'Label for the "Wallet password" input in the wallet restore dialog.', }, repeatPasswordLabel: { id: 'wallet.restore.dialog.repeatPasswordLabel', defaultMessage: '!!!Repeat password', - description: 'Label for the "Repeat password" input in the wallet restore dialog.', + description: + 'Label for the "Repeat password" input in the wallet restore dialog.', }, passwordFieldPlaceholder: { id: 'wallet.restore.dialog.passwordFieldPlaceholder', defaultMessage: '!!!Password', - description: 'Placeholder for the "Password" inputs in the wallet restore dialog.', + description: + 'Placeholder for the "Password" inputs in the wallet restore dialog.', }, recoveryPhraseTabTitle: { id: 'wallet.restore.dialog.tab.title.recoveryPhrase', defaultMessage: '!!!Backup recovery phrase', - description: 'Tab title "Backup recovery phrase" in the wallet restore dialog.', + description: + 'Tab title "Backup recovery phrase" in the wallet restore dialog.', }, certificateTabTitle: { id: 'wallet.restore.dialog.tab.title.certificate', defaultMessage: '!!!Paper wallet certificate', - description: 'Tab title "Paper wallet certificate" in the wallet restore dialog.', + description: + 'Tab title "Paper wallet certificate" in the wallet restore dialog.', }, shieldedRecoveryPhraseInputLabel: { id: 'wallet.restore.dialog.shielded.recovery.phrase.input.label', defaultMessage: '!!!Paper wallet recovery phrase', - description: 'Label for the shielded recovery phrase input on the wallet restore dialog.' + description: + 'Label for the shielded recovery phrase input on the wallet restore dialog.', }, shieldedRecoveryPhraseInputHint: { id: 'wallet.restore.dialog.shielded.recovery.phrase.input.hint', - defaultMessage: '!!!Enter the recovery phrase from your paper wallet certificate', - description: 'Hint "Enter shielded recovery phrase" for the recovery phrase input on the wallet restore dialog.' + defaultMessage: + '!!!Enter the recovery phrase from your paper wallet certificate', + description: + 'Hint "Enter shielded recovery phrase" for the recovery phrase input on the wallet restore dialog.', }, }); @@ -134,7 +159,6 @@ type State = { @observer export default class WalletRestoreDialog extends Component { - static contextTypes = { intl: intlShape.isRequired, }; @@ -150,83 +174,104 @@ export default class WalletRestoreDialog extends Component { recoveryPhraseAutocomplete: Autocomplete; - form = new ReactToolboxMobxForm({ - fields: { - walletName: { - label: this.context.intl.formatMessage(messages.walletNameInputLabel), - placeholder: this.context.intl.formatMessage(messages.walletNameInputHint), - value: '', - validators: [({ field }) => ( - [ - isValidWalletName(field.value), - this.context.intl.formatMessage(globalMessages.invalidWalletName) - ] - )], - }, - recoveryPhrase: { - value: [], - validators: ({ field }) => { - const { intl } = this.context; - const enteredWords = field.value; - const wordCount = enteredWords.length; - const expectedWordCount = (this.isRegular() ? - WALLET_RECOVERY_PHRASE_WORD_COUNT : PAPER_WALLET_RECOVERY_PHRASE_WORD_COUNT - ); - const value = join(enteredWords, ' '); - // Regular mnemonics have 12 and paper wallet recovery needs 27 words - const isPhraseComplete = wordCount === expectedWordCount; - if (!isPhraseComplete) { + form = new ReactToolboxMobxForm( + { + fields: { + walletName: { + label: this.context.intl.formatMessage(messages.walletNameInputLabel), + placeholder: this.context.intl.formatMessage( + messages.walletNameInputHint + ), + value: '', + validators: [ + ({ field }) => [ + isValidWalletName(field.value), + this.context.intl.formatMessage(globalMessages.invalidWalletName), + ], + ], + }, + recoveryPhrase: { + value: [], + validators: ({ field }) => { + const { intl } = this.context; + const enteredWords = field.value; + const wordCount = enteredWords.length; + const expectedWordCount = this.isRegular() + ? WALLET_RECOVERY_PHRASE_WORD_COUNT + : PAPER_WALLET_RECOVERY_PHRASE_WORD_COUNT; + const value = join(enteredWords, ' '); + // Regular mnemonics have 12 and paper wallet recovery needs 27 words + const isPhraseComplete = wordCount === expectedWordCount; + if (!isPhraseComplete) { + return [ + false, + intl.formatMessage(globalMessages.incompleteMnemonic, { + expected: expectedWordCount, + }), + ]; + } return [ - false, - intl.formatMessage(globalMessages.incompleteMnemonic, { expected: expectedWordCount }) + // TODO: we should also validate paper wallets mnemonics here! + this.isRegular() ? this.props.mnemonicValidator(value) : true, + this.context.intl.formatMessage(messages.invalidRecoveryPhrase), ]; - } - return [ - // TODO: we should also validate paper wallets mnemonics here! - this.isRegular() ? this.props.mnemonicValidator(value) : true, - this.context.intl.formatMessage(messages.invalidRecoveryPhrase) - ]; + }, + }, + spendingPassword: { + type: 'password', + label: this.context.intl.formatMessage( + messages.spendingPasswordLabel + ), + placeholder: this.context.intl.formatMessage( + messages.passwordFieldPlaceholder + ), + value: '', + validators: [ + ({ field, form }) => { + if (!this.state.createPassword) return [true]; + const repeatPasswordField = form.$('repeatPassword'); + if (repeatPasswordField.value.length > 0) { + repeatPasswordField.validate({ showErrors: true }); + } + return [ + isValidSpendingPassword(field.value), + this.context.intl.formatMessage( + globalMessages.invalidSpendingPassword + ), + ]; + }, + ], + }, + repeatPassword: { + type: 'password', + label: this.context.intl.formatMessage(messages.repeatPasswordLabel), + placeholder: this.context.intl.formatMessage( + messages.passwordFieldPlaceholder + ), + value: '', + validators: [ + ({ field, form }) => { + if (!this.state.createPassword) return [true]; + const spendingPassword = form.$('spendingPassword').value; + if (spendingPassword.length === 0) return [true]; + return [ + isValidRepeatPassword(spendingPassword, field.value), + this.context.intl.formatMessage( + globalMessages.invalidRepeatPassword + ), + ]; + }, + ], }, - }, - spendingPassword: { - type: 'password', - label: this.context.intl.formatMessage(messages.spendingPasswordLabel), - placeholder: this.context.intl.formatMessage(messages.passwordFieldPlaceholder), - value: '', - validators: [({ field, form }) => { - if (!this.state.createPassword) return [true]; - const repeatPasswordField = form.$('repeatPassword'); - if (repeatPasswordField.value.length > 0) { - repeatPasswordField.validate({ showErrors: true }); - } - return [ - isValidSpendingPassword(field.value), - this.context.intl.formatMessage(globalMessages.invalidSpendingPassword) - ]; - }], - }, - repeatPassword: { - type: 'password', - label: this.context.intl.formatMessage(messages.repeatPasswordLabel), - placeholder: this.context.intl.formatMessage(messages.passwordFieldPlaceholder), - value: '', - validators: [({ field, form }) => { - if (!this.state.createPassword) return [true]; - const spendingPassword = form.$('spendingPassword').value; - if (spendingPassword.length === 0) return [true]; - return [ - isValidRepeatPassword(spendingPassword, field.value), - this.context.intl.formatMessage(globalMessages.invalidRepeatPassword) - ]; - }], }, }, - }, { - options: { - validateOnChange: true, - validationDebounceWait: FORM_VALIDATION_DEBOUNCE_WAIT, - }, - }); + { + options: { + validateOnChange: true, + validationDebounceWait: FORM_VALIDATION_DEBOUNCE_WAIT, + }, + } + ); handlePasswordSwitchToggle = (value: boolean) => { this.setState({ createPassword: value }); @@ -234,14 +279,10 @@ export default class WalletRestoreDialog extends Component { submit = () => { this.form.submit({ - onSuccess: (form) => { + onSuccess: form => { const { createPassword } = this.state; const { onSubmit } = this.props; - const { - recoveryPhrase, - walletName, - spendingPassword, - } = form.values(); + const { recoveryPhrase, walletName, spendingPassword } = form.values(); const walletData: Object = { recoveryPhrase: join(recoveryPhrase, ' '), @@ -253,14 +294,16 @@ export default class WalletRestoreDialog extends Component { onSubmit(walletData); }, - onError: () => {} + onError: () => {}, }); }; resetForm = () => { const { form } = this; // Cancel all debounced field validations - form.each((field) => { field.debouncedValidation.cancel(); }); + form.each(field => { + field.debouncedValidation.cancel(); + }); form.reset(); form.showErrors(false); @@ -271,12 +314,7 @@ export default class WalletRestoreDialog extends Component { render() { const { intl } = this.context; const { form } = this; - const { - suggestedMnemonics, - isSubmitting, - error, - onCancel, - } = this.props; + const { suggestedMnemonics, isSubmitting, error, onCancel } = this.props; const { createPassword } = this.state; const dialogClasses = classnames([ @@ -354,22 +392,30 @@ export default class WalletRestoreDialog extends Component { { this.recoveryPhraseAutocomplete = autocomplete; }} - label={this.isRegular() - ? intl.formatMessage(messages.recoveryPhraseInputLabel) - : intl.formatMessage(messages.shieldedRecoveryPhraseInputLabel) + ref={autocomplete => { + this.recoveryPhraseAutocomplete = autocomplete; + }} + label={ + this.isRegular() + ? intl.formatMessage(messages.recoveryPhraseInputLabel) + : intl.formatMessage(messages.shieldedRecoveryPhraseInputLabel) } - placeholder={this.isRegular() - ? intl.formatMessage(messages.recoveryPhraseInputHint) - : intl.formatMessage(messages.shieldedRecoveryPhraseInputHint) + placeholder={ + this.isRegular() + ? intl.formatMessage(messages.recoveryPhraseInputHint) + : intl.formatMessage(messages.shieldedRecoveryPhraseInputHint) } options={suggestedMnemonics} - maxSelections={(this.isCertificate() ? - PAPER_WALLET_RECOVERY_PHRASE_WORD_COUNT : WALLET_RECOVERY_PHRASE_WORD_COUNT - )} + maxSelections={ + this.isCertificate() + ? PAPER_WALLET_RECOVERY_PHRASE_WORD_COUNT + : WALLET_RECOVERY_PHRASE_WORD_COUNT + } error={recoveryPhraseField.error} maxVisibleOptions={5} - noResultsMessage={intl.formatMessage(messages.recoveryPhraseNoResults)} + noResultsMessage={intl.formatMessage( + messages.recoveryPhraseNoResults + )} skin={AutocompleteSkin} /> @@ -409,7 +455,6 @@ export default class WalletRestoreDialog extends Component {
{error &&

{intl.formatMessage(error)}

} - ); } diff --git a/source/renderer/app/components/wallet/WalletRestoreDialog.scss b/source/renderer/app/components/wallet/WalletRestoreDialog.scss index 8c1c28f208..24971717bd 100644 --- a/source/renderer/app/components/wallet/WalletRestoreDialog.scss +++ b/source/renderer/app/components/wallet/WalletRestoreDialog.scss @@ -86,11 +86,11 @@ .activeButton { color: var(--theme-choice-tabs-text-color-active); - border-bottom: 2px solid var(--theme-choice-tabs-bottom-border-color-active); + border-bottom: 2px solid + var(--theme-choice-tabs-bottom-border-color-active); cursor: default; opacity: 1; } - } .error { @@ -101,6 +101,6 @@ .isSubmitting { box-shadow: none !important; - @include loading-spinner("../../assets/images/spinner-light.svg"); + @include loading-spinner('../../assets/images/spinner-light.svg'); } } diff --git a/source/renderer/app/components/wallet/WalletSendConfirmationDialog.js b/source/renderer/app/components/wallet/WalletSendConfirmationDialog.js index 186cffd44e..88988ca1e8 100644 --- a/source/renderer/app/components/wallet/WalletSendConfirmationDialog.js +++ b/source/renderer/app/components/wallet/WalletSendConfirmationDialog.js @@ -19,12 +19,13 @@ export const messages = defineMessages({ dialogTitle: { id: 'wallet.send.confirmationDialog.title', defaultMessage: '!!!Confirm transaction', - description: 'Title for the "Confirm transaction" dialog.' + description: 'Title for the "Confirm transaction" dialog.', }, spendingPasswordLabel: { id: 'wallet.send.confirmationDialog.spendingPasswordLabel', defaultMessage: '!!!Spending password', - description: 'Label for the "Spending password" input in the wallet send confirmation dialog.', + description: + 'Label for the "Spending password" input in the wallet send confirmation dialog.', }, addressToLabel: { id: 'wallet.send.confirmationDialog.addressToLabel', @@ -34,7 +35,8 @@ export const messages = defineMessages({ amountLabel: { id: 'wallet.send.confirmationDialog.amountLabel', defaultMessage: '!!!Amount', - description: 'Label for the "Amount" in the wallet send confirmation dialog.', + description: + 'Label for the "Amount" in the wallet send confirmation dialog.', }, feesLabel: { id: 'wallet.send.confirmationDialog.feesLabel', @@ -44,22 +46,26 @@ export const messages = defineMessages({ totalLabel: { id: 'wallet.send.confirmationDialog.totalLabel', defaultMessage: '!!!Total', - description: 'Label for the "Total" in the wallet send confirmation dialog.', + description: + 'Label for the "Total" in the wallet send confirmation dialog.', }, spendingPasswordFieldPlaceholder: { id: 'wallet.send.confirmationDialog.spendingPasswordFieldPlaceholder', defaultMessage: '!!!Type your spending password', - description: 'Placeholder for the "Spending password" inputs in the wallet send confirmation dialog.', + description: + 'Placeholder for the "Spending password" inputs in the wallet send confirmation dialog.', }, sendButtonLabel: { id: 'wallet.send.confirmationDialog.submit', defaultMessage: '!!!Send', - description: 'Label for the send button in the wallet send confirmation dialog.' + description: + 'Label for the send button in the wallet send confirmation dialog.', }, backButtonLabel: { id: 'wallet.send.confirmationDialog.back', defaultMessage: '!!!Back', - description: 'Label for the back button in the wallet send confirmation dialog.' + description: + 'Label for the back button in the wallet send confirmation dialog.', }, }); @@ -82,37 +88,53 @@ type Props = { @observer export default class WalletSendConfirmationDialog extends Component { - static contextTypes = { intl: intlShape.isRequired, }; - form = new ReactToolboxMobxForm({ - fields: { - spendingPassword: { - type: 'password', - label: this.context.intl.formatMessage(messages.spendingPasswordLabel), - placeholder: this.context.intl.formatMessage(messages.spendingPasswordFieldPlaceholder), - value: '', - validators: [({ field }) => { - if (this.props.isSpendingPasswordSet && field.value === '') { - return [false, this.context.intl.formatMessage(messages.fieldIsRequired)]; - } - return [true]; - }], + form = new ReactToolboxMobxForm( + { + fields: { + spendingPassword: { + type: 'password', + label: this.context.intl.formatMessage( + messages.spendingPasswordLabel + ), + placeholder: this.context.intl.formatMessage( + messages.spendingPasswordFieldPlaceholder + ), + value: '', + validators: [ + ({ field }) => { + if (this.props.isSpendingPasswordSet && field.value === '') { + return [ + false, + this.context.intl.formatMessage(messages.fieldIsRequired), + ]; + } + return [true]; + }, + ], + }, }, - } - }, { - options: { - validateOnChange: true, - validationDebounceWait: FORM_VALIDATION_DEBOUNCE_WAIT, }, - }); + { + options: { + validateOnChange: true, + validationDebounceWait: FORM_VALIDATION_DEBOUNCE_WAIT, + }, + } + ); submit = () => { this.form.submit({ - onSuccess: (form) => { - const { isSpendingPasswordSet, receiver, amount, amountToNaturalUnits } = this.props; + onSuccess: form => { + const { + isSpendingPasswordSet, + receiver, + amount, + amountToNaturalUnits, + } = this.props; const { spendingPassword } = form.values(); const transactionData = { receiver, @@ -121,11 +143,13 @@ export default class WalletSendConfirmationDialog extends Component { }; this.props.onSubmit(transactionData); }, - onError: () => {} + onError: () => {}, }); }; - submitOnEnter = (event: {}) => this.form.$('spendingPassword').isValid && submitOnEnter(this.submit, event); + submitOnEnter = (event: {}) => + this.form.$('spendingPassword').isValid && + submitOnEnter(this.submit, event); render() { const { form } = this; @@ -141,7 +165,7 @@ export default class WalletSendConfirmationDialog extends Component { isSubmitting, error, currencyUnit, - onExternalLinkClick + onExternalLinkClick, } = this.props; const confirmButtonClasses = classnames([ @@ -166,14 +190,14 @@ export default class WalletSendConfirmationDialog extends Component { let errorElement = null; if (error) { const errorHasLink = !!error.values.linkLabel; - errorElement = errorHasLink - ? ( - - ) - : this.context.intl.formatMessage(error); + errorElement = errorHasLink ? ( + + ) : ( + this.context.intl.formatMessage(error) + ); } return ( @@ -196,24 +220,39 @@ export default class WalletSendConfirmationDialog extends Component {
-
{intl.formatMessage(messages.amountLabel)}
-
{amount} -  {currencyUnit} +
+ {intl.formatMessage(messages.amountLabel)} +
+
+ {amount} + +  {currencyUnit} +
-
{intl.formatMessage(messages.feesLabel)}
-
+{transactionFee} -  {currencyUnit} +
+ {intl.formatMessage(messages.feesLabel)} +
+
+ +{transactionFee} + +  {currencyUnit} +
-
{intl.formatMessage(messages.totalLabel)}
-
{totalAmount} -  {currencyUnit} +
+ {intl.formatMessage(messages.totalLabel)} +
+
+ {totalAmount} + +  {currencyUnit} +
@@ -231,9 +270,7 @@ export default class WalletSendConfirmationDialog extends Component {
{errorElement ?

{errorElement}

: null} - ); } - } diff --git a/source/renderer/app/components/wallet/WalletSendConfirmationDialog.scss b/source/renderer/app/components/wallet/WalletSendConfirmationDialog.scss index c3895ba436..10e7d17b25 100644 --- a/source/renderer/app/components/wallet/WalletSendConfirmationDialog.scss +++ b/source/renderer/app/components/wallet/WalletSendConfirmationDialog.scss @@ -17,7 +17,7 @@ } .addressToLabelWrapper, - .amountFeesWrapper{ + .amountFeesWrapper { margin-bottom: 20px; } @@ -90,5 +90,5 @@ .submitButtonSpinning { box-shadow: none !important; - @include loading-spinner("../../assets/images/spinner-light.svg"); + @include loading-spinner('../../assets/images/spinner-light.svg'); } diff --git a/source/renderer/app/components/wallet/WalletSendForm.js b/source/renderer/app/components/wallet/WalletSendForm.js index a78abee669..eff6e13f04 100755 --- a/source/renderer/app/components/wallet/WalletSendForm.js +++ b/source/renderer/app/components/wallet/WalletSendForm.js @@ -19,7 +19,11 @@ import styles from './WalletSendForm.scss'; import globalMessages from '../../i18n/global-messages'; import WalletSendConfirmationDialog from './WalletSendConfirmationDialog'; import WalletSendConfirmationDialogContainer from '../../containers/wallet/dialogs/WalletSendConfirmationDialogContainer'; -import { formattedAmountToBigNumber, formattedAmountToNaturalUnits, formattedAmountToLovelace } from '../../utils/formatters'; +import { + formattedAmountToBigNumber, + formattedAmountToNaturalUnits, + formattedAmountToLovelace, +} from '../../utils/formatters'; import { FORM_VALIDATION_DEBOUNCE_WAIT } from '../../config/timingConfig'; import { FormattedHTMLMessageWithLink } from '../widgets/FormattedHTMLMessageWithLink'; @@ -27,47 +31,50 @@ export const messages = defineMessages({ titleLabel: { id: 'wallet.send.form.title.label', defaultMessage: '!!!Title', - description: 'Label for the "Title" text input in the wallet send form.' + description: 'Label for the "Title" text input in the wallet send form.', }, titleHint: { id: 'wallet.send.form.title.hint', defaultMessage: '!!!E.g: Money for Frank', - description: 'Hint inside the "Receiver" text input in the wallet send form.' + description: + 'Hint inside the "Receiver" text input in the wallet send form.', }, receiverLabel: { id: 'wallet.send.form.receiver.label', defaultMessage: '!!!Receiver', - description: 'Label for the "Receiver" text input in the wallet send form.' + description: 'Label for the "Receiver" text input in the wallet send form.', }, receiverHint: { id: 'wallet.send.form.receiver.hint', defaultMessage: '!!!Wallet Address', - description: 'Hint inside the "Receiver" text input in the wallet send form.' + description: + 'Hint inside the "Receiver" text input in the wallet send form.', }, amountLabel: { id: 'wallet.send.form.amount.label', defaultMessage: '!!!Amount', - description: 'Label for the "Amount" number input in the wallet send form.' + description: 'Label for the "Amount" number input in the wallet send form.', }, descriptionLabel: { id: 'wallet.send.form.description.label', defaultMessage: '!!!Description', - description: 'Label for the "description" text area in the wallet send form.' + description: + 'Label for the "description" text area in the wallet send form.', }, descriptionHint: { id: 'wallet.send.form.description.hint', defaultMessage: '!!!You can add a message if you want', - description: 'Hint in the "description" text area in the wallet send form.' + description: 'Hint in the "description" text area in the wallet send form.', }, nextButtonLabel: { id: 'wallet.send.form.next', defaultMessage: '!!!Next', - description: 'Label for the next button on the wallet send form.' + description: 'Label for the next button on the wallet send form.', }, invalidAddress: { id: 'wallet.send.form.errors.invalidAddress', defaultMessage: '!!!Please enter a valid address.', - description: 'Error message shown when invalid address was entered.' + description: 'Error message shown when invalid address was entered.', }, invalidAmount: { id: 'wallet.send.form.errors.invalidAmount', @@ -77,12 +84,15 @@ export const messages = defineMessages({ invalidTitle: { id: 'wallet.send.form.errors.invalidTitle', defaultMessage: '!!!Please enter a title with at least 3 characters.', - description: 'Error message shown when invalid transaction title was entered.', + description: + 'Error message shown when invalid transaction title was entered.', }, syncingTransactionsMessage: { id: 'wallet.send.form.syncingTransactionsMessage', - defaultMessage: '!!!This wallet is currently being synced with the blockchain. While synchronisation is in progress transacting is not possible and transaction history is not complete.', - description: 'Syncing transactions message shown during async wallet restore in the wallet send form.', + defaultMessage: + '!!!This wallet is currently being synced with the blockchain. While synchronisation is in progress transacting is not possible and transaction history is not complete.', + description: + 'Syncing transactions message shown during async wallet restore in the wallet send form.', }, }); @@ -93,7 +103,10 @@ type Props = { currencyMaxIntegerDigits?: number, currencyMaxFractionalDigits: number, validateAmount: (amountInNaturalUnits: string) => Promise, - calculateTransactionFee: (address: string, amount: number) => Promise, + calculateTransactionFee: ( + address: string, + amount: number + ) => Promise, addressValidator: Function, openDialogAction: Function, isDialogOpen: Function, @@ -109,7 +122,6 @@ type State = { @observer export default class WalletSendForm extends Component { - static contextTypes = { intl: intlShape.isRequired, }; @@ -149,74 +161,104 @@ export default class WalletSendForm extends Component { }); }; - isDisabled = () => this._isCalculatingFee || !this.state.isTransactionFeeCalculated; + isDisabled = () => + this._isCalculatingFee || !this.state.isTransactionFeeCalculated; // FORM VALIDATION - form = new ReactToolboxMobxForm({ - fields: { - receiver: { - label: this.context.intl.formatMessage(messages.receiverLabel), - placeholder: this.context.intl.formatMessage(messages.receiverHint), - value: '', - validators: [async ({ field, form }) => { - const value = field.value; - if (value === '') { - this._resetTransactionFee(); - return [false, this.context.intl.formatMessage(messages.fieldIsRequired)]; - } - const isValidAddress = await this.props.addressValidator(value); - const amountField = form.$('amount'); - const amountValue = amountField.value; - const isAmountValid = amountField.isValid; - if (isValidAddress && isAmountValid) { - await this._calculateTransactionFee(value, amountValue); - } else { - this._resetTransactionFee(); - } - return [isValidAddress, this.context.intl.formatMessage(messages.invalidAddress)]; - }], - }, - amount: { - label: this.context.intl.formatMessage(messages.amountLabel), - placeholder: `0.${'0'.repeat(this.props.currencyMaxFractionalDigits)}`, - value: '', - validators: [async ({ field, form }) => { - const amountValue = field.value; - if (amountValue === '') { - this._resetTransactionFee(); - return [false, this.context.intl.formatMessage(messages.fieldIsRequired)]; - } - const isValid = await this.props.validateAmount( - formattedAmountToNaturalUnits(amountValue) - ); - const receiverField = form.$('receiver'); - const receiverValue = receiverField.value; - const isReceiverValid = receiverField.isValid; - if (isValid && isReceiverValid) { - await this._calculateTransactionFee(receiverValue, amountValue); - } else { - this._resetTransactionFee(); - } - return [isValid, this.context.intl.formatMessage(messages.invalidAmount)]; - }], + form = new ReactToolboxMobxForm( + { + fields: { + receiver: { + label: this.context.intl.formatMessage(messages.receiverLabel), + placeholder: this.context.intl.formatMessage(messages.receiverHint), + value: '', + validators: [ + async ({ field, form }) => { + const value = field.value; + if (value === '') { + this._resetTransactionFee(); + return [ + false, + this.context.intl.formatMessage(messages.fieldIsRequired), + ]; + } + const isValidAddress = await this.props.addressValidator(value); + const amountField = form.$('amount'); + const amountValue = amountField.value; + const isAmountValid = amountField.isValid; + if (isValidAddress && isAmountValid) { + await this._calculateTransactionFee(value, amountValue); + } else { + this._resetTransactionFee(); + } + return [ + isValidAddress, + this.context.intl.formatMessage(messages.invalidAddress), + ]; + }, + ], + }, + amount: { + label: this.context.intl.formatMessage(messages.amountLabel), + placeholder: `0.${'0'.repeat( + this.props.currencyMaxFractionalDigits + )}`, + value: '', + validators: [ + async ({ field, form }) => { + const amountValue = field.value; + if (amountValue === '') { + this._resetTransactionFee(); + return [ + false, + this.context.intl.formatMessage(messages.fieldIsRequired), + ]; + } + const isValid = await this.props.validateAmount( + formattedAmountToNaturalUnits(amountValue) + ); + const receiverField = form.$('receiver'); + const receiverValue = receiverField.value; + const isReceiverValid = receiverField.isValid; + if (isValid && isReceiverValid) { + await this._calculateTransactionFee(receiverValue, amountValue); + } else { + this._resetTransactionFee(); + } + return [ + isValid, + this.context.intl.formatMessage(messages.invalidAmount), + ]; + }, + ], + }, }, }, - }, { - options: { - validateOnBlur: false, - validateOnChange: true, - validationDebounceWait: FORM_VALIDATION_DEBOUNCE_WAIT, - }, - }); + { + options: { + validateOnBlur: false, + validateOnChange: true, + validationDebounceWait: FORM_VALIDATION_DEBOUNCE_WAIT, + }, + } + ); render() { const { form } = this; const { intl } = this.context; const { - currencyUnit, currencyMaxIntegerDigits, currencyMaxFractionalDigits, - isDialogOpen, isRestoreActive, onExternalLinkClick + currencyUnit, + currencyMaxIntegerDigits, + currencyMaxFractionalDigits, + isDialogOpen, + isRestoreActive, + onExternalLinkClick, } = this.props; - const { isTransactionFeeCalculated, transactionFee, transactionFeeError } = this.state; + const { + isTransactionFeeCalculated, + transactionFee, + transactionFeeError, + } = this.state; const amountField = form.$('amount'); const receiverField = form.$('receiver'); const receiverFieldProps = receiverField.bind(); @@ -230,14 +272,10 @@ export default class WalletSendForm extends Component { total = amount.add(transactionFee).toFormat(currencyMaxFractionalDigits); } - const buttonClasses = classnames([ - 'primary', - styles.nextButton, - ]); + const buttonClasses = classnames(['primary', styles.nextButton]); return (
- {isRestoreActive ? (
@@ -254,7 +292,7 @@ export default class WalletSendForm extends Component { label={intl.formatMessage(messages.receiverLabel)} {...receiverField.bind()} error={receiverField.error} - onChange={(value) => { + onChange={value => { this._isCalculatingFee = true; receiverField.onChange(value || ''); }} @@ -271,7 +309,7 @@ export default class WalletSendForm extends Component { maxBeforeDot={currencyMaxIntegerDigits} maxAfterDot={currencyMaxFractionalDigits} error={transactionFeeError || amountField.error} - onChange={(value) => { + onChange={value => { this._isCalculatingFee = true; amountField.onChange(value || ''); }} @@ -306,7 +344,6 @@ export default class WalletSendForm extends Component { onExternalLinkClick={onExternalLinkClick} /> ) : null} -
); } @@ -335,14 +372,14 @@ export default class WalletSendForm extends Component { } } catch (error) { const errorHasLink = !!error.values.linkLabel; - const transactionFeeError = errorHasLink - ? ( - - ) - : this.context.intl.formatMessage(error); + const transactionFeeError = errorHasLink ? ( + + ) : ( + this.context.intl.formatMessage(error) + ); if (this._isMounted) { this._isCalculatingFee = false; this.setState({ diff --git a/source/renderer/app/components/wallet/WalletSendForm.scss b/source/renderer/app/components/wallet/WalletSendForm.scss index 4986416647..83f3831bce 100755 --- a/source/renderer/app/components/wallet/WalletSendForm.scss +++ b/source/renderer/app/components/wallet/WalletSendForm.scss @@ -13,7 +13,6 @@ } } - .syncingTransactionsText { color: var(--theme-transactions-list-group-date-color); font-family: var(--font-regular); diff --git a/source/renderer/app/components/wallet/WalletSettings.js b/source/renderer/app/components/wallet/WalletSettings.js index 8c284d44af..21945bc67e 100644 --- a/source/renderer/app/components/wallet/WalletSettings.js +++ b/source/renderer/app/components/wallet/WalletSettings.js @@ -26,7 +26,8 @@ export const messages = defineMessages({ assuranceLevelLabel: { id: 'wallet.settings.assurance', defaultMessage: '!!!Transaction assurance security level', - description: 'Label for the "Transaction assurance security level" dropdown.', + description: + 'Label for the "Transaction assurance security level" dropdown.', }, passwordLabel: { id: 'wallet.settings.password', @@ -40,8 +41,8 @@ export const messages = defineMessages({ }, passwordNotSet: { id: 'wallet.settings.passwordNotSet', - defaultMessage: '!!!You still don\'t have password', - description: 'You still don\'t have password set message.', + defaultMessage: "!!!You still don't have password", + description: "You still don't have password set message.", }, exportButtonLabel: { id: 'wallet.settings.exportWalletButtonLabel', @@ -76,13 +77,12 @@ type Props = { @observer export default class WalletSettings extends Component { - static contextTypes = { intl: intlShape.isRequired, }; static defaultProps = { - showExportLink: false + showExportLink: false, }; componentWillUnmount() { @@ -93,15 +93,24 @@ export default class WalletSettings extends Component { render() { const { intl } = this.context; const { - assuranceLevels, walletAssurance, - walletName, isSpendingPasswordSet, - spendingPasswordUpdateDate, error, - openDialogAction, isDialogOpen, - onFieldValueChange, onStartEditing, - onStopEditing, onCancelEditing, - nameValidator, activeField, - isSubmitting, isInvalid, - lastUpdatedField, showExportLink, + assuranceLevels, + walletAssurance, + walletName, + isSpendingPasswordSet, + spendingPasswordUpdateDate, + error, + openDialogAction, + isDialogOpen, + onFieldValueChange, + onStartEditing, + onStopEditing, + onCancelEditing, + nameValidator, + activeField, + isSubmitting, + isInvalid, + lastUpdatedField, + showExportLink, changeSpendingPasswordDialog, deleteWalletDialogContainer, exportWalletDialogContainer, @@ -112,17 +121,15 @@ export default class WalletSettings extends Component { label: intl.formatMessage(assurance.label), })); - const passwordMessage = isSpendingPasswordSet ? ( - intl.formatMessage(messages.passwordLastUpdated, { - lastUpdated: moment(spendingPasswordUpdateDate).fromNow(), - }) - ) : intl.formatMessage(messages.passwordNotSet); + const passwordMessage = isSpendingPasswordSet + ? intl.formatMessage(messages.passwordLastUpdated, { + lastUpdated: moment(spendingPasswordUpdateDate).fromNow(), + }) + : intl.formatMessage(messages.passwordNotSet); return (
- - { onStartEditing={() => onStartEditing('name')} onStopEditing={onStopEditing} onCancelEditing={onCancelEditing} - onSubmit={(value) => onFieldValueChange('name', value)} + onSubmit={value => onFieldValueChange('name', value)} isValid={nameValidator} - validationErrorMessage={intl.formatMessage(globalMessages.invalidWalletName)} - successfullyUpdated={!isSubmitting && lastUpdatedField === 'name' && !isInvalid} + validationErrorMessage={intl.formatMessage( + globalMessages.invalidWalletName + )} + successfullyUpdated={ + !isSubmitting && lastUpdatedField === 'name' && !isInvalid + } /> { isActive={activeField === 'assurance'} onStartEditing={() => onStartEditing('assurance')} onStopEditing={onStopEditing} - onSubmit={(value) => onFieldValueChange('assurance', value)} - successfullyUpdated={!isSubmitting && lastUpdatedField === 'assurance'} + onSubmit={value => onFieldValueChange('assurance', value)} + successfullyUpdated={ + !isSubmitting && lastUpdatedField === 'assurance' + } /> openDialogAction({ - dialog: ChangeSpendingPasswordDialog, - })} + onClick={() => + openDialogAction({ + dialog: ChangeSpendingPasswordDialog, + }) + } /> {error &&

{intl.formatMessage(error)}

} @@ -164,37 +179,40 @@ export default class WalletSettings extends Component { {showExportLink ? ( - ) : false} + ) : ( + false + )} openDialogAction({ - dialog: DeleteWalletConfirmationDialog, - })} + onClick={() => + openDialogAction({ + dialog: DeleteWalletConfirmationDialog, + }) + } />
- - {isDialogOpen(ChangeSpendingPasswordDialog) ? ( - changeSpendingPasswordDialog - ) : false} - - {isDialogOpen(DeleteWalletConfirmationDialog) ? ( - deleteWalletDialogContainer - ) : false} + {isDialogOpen(ChangeSpendingPasswordDialog) + ? changeSpendingPasswordDialog + : false} - {isDialogOpen(ExportWalletToFileDialog) ? ( - exportWalletDialogContainer - ) : false} + {isDialogOpen(DeleteWalletConfirmationDialog) + ? deleteWalletDialogContainer + : false} + {isDialogOpen(ExportWalletToFileDialog) + ? exportWalletDialogContainer + : false}
); } - } diff --git a/source/renderer/app/components/wallet/WalletSettings.scss b/source/renderer/app/components/wallet/WalletSettings.scss index c572ea7863..5f63977618 100644 --- a/source/renderer/app/components/wallet/WalletSettings.scss +++ b/source/renderer/app/components/wallet/WalletSettings.scss @@ -32,4 +32,3 @@ @include error-message; text-align: center; } - diff --git a/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionChoices.js b/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionChoices.js index d78a0441d1..6a0802fc79 100644 --- a/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionChoices.js +++ b/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionChoices.js @@ -10,27 +10,27 @@ const messages = defineMessages({ regularTabTitle: { id: 'wallet.redeem.choices.tab.title.regularVended', defaultMessage: '!!!Regular', - description: 'Tab title "Regular" on Ada redemption page.' + description: 'Tab title "Regular" on Ada redemption page.', }, forceVendedTabTitle: { id: 'wallet.redeem.choices.tab.title.forceVended', defaultMessage: '!!!Force vended', - description: 'Tab title "Force vended" on Ada redemption page.' + description: 'Tab title "Force vended" on Ada redemption page.', }, paperVendedTabTitle: { id: 'wallet.redeem.choices.tab.title.paperVended', defaultMessage: '!!!Paper vended', - description: 'Tab title "Paper vended" on Ada redemption page.' + description: 'Tab title "Paper vended" on Ada redemption page.', }, recoveryRegularTabTitle: { id: 'wallet.redeem.choices.tab.title.recoveryRegular', defaultMessage: '!!!Recovery - regular', - description: 'Tab title "Recovery - regular" on Ada redemption page.' + description: 'Tab title "Recovery - regular" on Ada redemption page.', }, recoveryForceVendedTabTitle: { id: 'wallet.redeem.choices.tab.title.recoveryForceVended', defaultMessage: '!!!Recovery - force vended', - description: 'Tab title "Recovery - force vended" on Ada redemption page.' + description: 'Tab title "Recovery - force vended" on Ada redemption page.', }, }); @@ -41,7 +41,6 @@ type Props = { @observer export default class AdaRedemptionChoices extends Component { - static contextTypes = { intl: intlShape.isRequired, }; @@ -52,37 +51,58 @@ export default class AdaRedemptionChoices extends Component { return (
); } - } diff --git a/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionDisclaimer.js b/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionDisclaimer.js index 35866840e8..50baeddb00 100644 --- a/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionDisclaimer.js +++ b/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionDisclaimer.js @@ -14,22 +14,26 @@ const messages = defineMessages({ disclaimerTitle: { id: 'wallet.redeem.disclaimerOverlay.title', defaultMessage: '!!!Daedalus Redemption Disclamer', - description: 'Title of "Redemption disclaimer" on Ada redemption page.' + description: 'Title of "Redemption disclaimer" on Ada redemption page.', }, disclaimerText: { id: 'wallet.redeem.disclaimerOverlay.disclaimerText', - defaultMessage: '!!!ATTENTION: Redeeming on the Cardano Test-net will validate that your certificate or redemption key is correct and will allow you to redeem TEST-ADA for testing purposes only. KEEP your certificate or redemption key safe and secure. You will need to redeem again when Cardano SL launches the mainnet. TEST-ADA holds no value and cannot be exchanged.', - description: 'Disclaimer text for "Redemption disclaimer" on Ada redemption page.' + defaultMessage: + '!!!ATTENTION: Redeeming on the Cardano Test-net will validate that your certificate or redemption key is correct and will allow you to redeem TEST-ADA for testing purposes only. KEEP your certificate or redemption key safe and secure. You will need to redeem again when Cardano SL launches the mainnet. TEST-ADA holds no value and cannot be exchanged.', + description: + 'Disclaimer text for "Redemption disclaimer" on Ada redemption page.', }, checkboxLabel: { id: 'wallet.redeem.disclaimerOverlay.checkboxLabel', defaultMessage: '!!!I’ve understood the information above', - description: 'Label for "I’ve understood the information above" checkbox on Ada redemption page "Redemption disclaimer".' + description: + 'Label for "I’ve understood the information above" checkbox on Ada redemption page "Redemption disclaimer".', }, submitLabel: { id: 'wallet.redeem.disclaimerOverlay.submitLabel', defaultMessage: '!!!Continue', - description: 'Label for "Continue" button on Ada redemption page "Redemption disclaimer".' + description: + 'Label for "Continue" button on Ada redemption page "Redemption disclaimer".', }, }); @@ -43,7 +47,6 @@ type State = { @observer export default class AdaRedemptionDisclaimer extends Component { - static contextTypes = { intl: intlShape.isRequired, }; @@ -63,7 +66,6 @@ export default class AdaRedemptionDisclaimer extends Component { return (
-

{intl.formatMessage(messages.disclaimerTitle)}

@@ -86,9 +88,7 @@ export default class AdaRedemptionDisclaimer extends Component { disabled={!isAccepted} skin={ButtonSkin} /> -
); } - } diff --git a/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionDisclaimer.scss b/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionDisclaimer.scss index 62b526e1a2..7807d28cc0 100644 --- a/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionDisclaimer.scss +++ b/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionDisclaimer.scss @@ -32,7 +32,9 @@ } } - h1, p, button { + h1, + p, + button { font-family: var(--font-regular); } @@ -55,13 +57,19 @@ padding-top: 20px; .SimpleCheckbox_check { - border-color: var(--theme-ada-redemption-disclaimer-checkbox-color-check); + border-color: var( + --theme-ada-redemption-disclaimer-checkbox-color-check + ); &.SimpleCheckbox_checked { - background-color: var(--theme-ada-redemption-disclaimer-checkbox-color-checked); + background-color: var( + --theme-ada-redemption-disclaimer-checkbox-color-checked + ); &:after { - border-color: var(--theme-ada-redemption-disclaimer-checkbox-color-after); + border-color: var( + --theme-ada-redemption-disclaimer-checkbox-color-after + ); } } } diff --git a/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js b/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js index 77f4d30aae..39cd2a3e9f 100644 --- a/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js +++ b/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js @@ -19,7 +19,11 @@ import AdaRedemptionChoices from './AdaRedemptionChoices'; import AdaRedemptionDisclaimer from './AdaRedemptionDisclaimer'; import BorderedBox from '../../widgets/BorderedBox'; import LocalizableError from '../../../i18n/LocalizableError'; -import { InvalidMnemonicError, InvalidEmailError, FieldRequiredError } from '../../../i18n/errors'; +import { + InvalidMnemonicError, + InvalidEmailError, + FieldRequiredError, +} from '../../../i18n/errors'; import globalMessages from '../../../i18n/global-messages'; import styles from './AdaRedemptionForm.scss'; import { FORM_VALIDATION_DEBOUNCE_WAIT } from '../../../config/timingConfig'; @@ -32,62 +36,75 @@ const messages = defineMessages({ headline: { id: 'wallet.redeem.dialog.headline', defaultMessage: '!!!Ada Redemption', - description: 'Headline "Ada redemption" dialog.' + description: 'Headline "Ada redemption" dialog.', }, instructionsRegular: { id: 'wallet.redeem.dialog.instructions.regular', - defaultMessage: '!!!

To redeem your ada, upload your certificate or copy and paste your redemption code from the certificate. Below is an example of a redemption key. Your key will look similar:

B_GQOAffMBeRIn6vh1hJmeOT3ViS_TmaT4XAHAfDVH0=

If you upload a PDF file with your certificate, a redemption code will be automatically extracted.

If you upload an encrypted certificate, you will need to provide a {adaRedemptionPassphraseLength} word mnemonic passphrase to decrypt your certificate and your redemption code will be automatically extracted.

', - description: 'Detailed instructions for redeeming ada from the regular vending', + defaultMessage: + '!!!

To redeem your ada, upload your certificate or copy and paste your redemption code from the certificate. Below is an example of a redemption key. Your key will look similar:

B_GQOAffMBeRIn6vh1hJmeOT3ViS_TmaT4XAHAfDVH0=

If you upload a PDF file with your certificate, a redemption code will be automatically extracted.

If you upload an encrypted certificate, you will need to provide a {adaRedemptionPassphraseLength} word mnemonic passphrase to decrypt your certificate and your redemption code will be automatically extracted.

', + description: + 'Detailed instructions for redeeming ada from the regular vending', }, instructionsForceVended: { id: 'wallet.redeem.dialog.instructions.forceVended', - defaultMessage: '!!!

To redeem your ada, upload your certificate or copy and paste your redemption code from the certificate. Below is an example of a redemption key. Your key will look similar:

B_GQOAffMBeRIn6vh1hJmeOT3ViS_TmaT4XAHAfDVH0=

If you upload a PDF file with your certificate, the redemption code will be automatically extracted.

If you upload an encrypted certificate, you will need to provide your email address, ada passcode and ada amount to decrypt your certificate and your redemption code will be automatically extracted.

', - description: 'Detailed instructions for redeeming ada from the force vending', + defaultMessage: + '!!!

To redeem your ada, upload your certificate or copy and paste your redemption code from the certificate. Below is an example of a redemption key. Your key will look similar:

B_GQOAffMBeRIn6vh1hJmeOT3ViS_TmaT4XAHAfDVH0=

If you upload a PDF file with your certificate, the redemption code will be automatically extracted.

If you upload an encrypted certificate, you will need to provide your email address, ada passcode and ada amount to decrypt your certificate and your redemption code will be automatically extracted.

', + description: + 'Detailed instructions for redeeming ada from the force vending', }, instructionsRecoveryRegular: { id: 'wallet.redeem.dialog.instructions.recoveryRegular', - defaultMessage: '!!!

To redeem your ada using the regularly vended certificate from the recovery service, please upload your encrypted certificate and enter a {adaRedemptionPassphraseLength}-word mnemonic passphrase.

After you upload your encrypted certificate and enter your {adaRedemptionPassphraseLength}-word mnemonic passphrase, your redemption key will be automatically extracted and you will be able to redeem your ada to the selected wallet.

', - description: 'Detailed instructions for redeeming ada from the regular vending via Recovery service', + defaultMessage: + '!!!

To redeem your ada using the regularly vended certificate from the recovery service, please upload your encrypted certificate and enter a {adaRedemptionPassphraseLength}-word mnemonic passphrase.

After you upload your encrypted certificate and enter your {adaRedemptionPassphraseLength}-word mnemonic passphrase, your redemption key will be automatically extracted and you will be able to redeem your ada to the selected wallet.

', + description: + 'Detailed instructions for redeeming ada from the regular vending via Recovery service', }, instructionsRecoveryForceVended: { id: 'wallet.redeem.dialog.instructions.recoveryForceVended', - defaultMessage: '!!!

To redeem your ada using the force vended certificate from the recovery service, please upload your encrypted certificate and enter the decryption key. Your decryption key should look like this:

qXQWDxI3JrlFRtC4SeQjeGzLbVXWBomYPbNO1Vfm1T4=

After you upload your encrypted certificate and enter your decryption key, your redemption key will be automatically extracted and you will be able to redeem your ada to the selected wallet.

', - description: 'Detailed instructions for redeeming ada from the force vending via Recovery service', + defaultMessage: + '!!!

To redeem your ada using the force vended certificate from the recovery service, please upload your encrypted certificate and enter the decryption key. Your decryption key should look like this:

qXQWDxI3JrlFRtC4SeQjeGzLbVXWBomYPbNO1Vfm1T4=

After you upload your encrypted certificate and enter your decryption key, your redemption key will be automatically extracted and you will be able to redeem your ada to the selected wallet.

', + description: + 'Detailed instructions for redeeming ada from the force vending via Recovery service', }, instructionsPaperVended: { id: 'wallet.redeem.dialog.instructions.paperVended', - defaultMessage: '!!!

To redeem your ada, enter your shielded vending key from the certificate, choose a wallet where ada should be redeemed and enter {adaRedemptionPassphraseLength} word mnemonic passphrase.

', - description: 'Detailed instructions for redeeming ada from the paper vending', + defaultMessage: + '!!!

To redeem your ada, enter your shielded vending key from the certificate, choose a wallet where ada should be redeemed and enter {adaRedemptionPassphraseLength} word mnemonic passphrase.

', + description: + 'Detailed instructions for redeeming ada from the paper vending', }, certificateLabel: { id: 'wallet.redeem.dialog.certificateLabel', defaultMessage: '!!!Certificate', - description: 'Label for the certificate file upload' + description: 'Label for the certificate file upload', }, certificateHint: { id: 'wallet.redeem.dialog.certificateHint', - defaultMessage: '!!!Drop the file with your certificate here or click to find on your computer', - description: 'Hint for the certificate file upload' + defaultMessage: + '!!!Drop the file with your certificate here or click to find on your computer', + description: 'Hint for the certificate file upload', }, walletSelectLabel: { id: 'wallet.redeem.dialog.walletSelectLabel', defaultMessage: '!!!Choose Wallet', - description: 'Label for the wallet select field on ada redemption form' + description: 'Label for the wallet select field on ada redemption form', }, passphraseLabel: { id: 'wallet.redeem.dialog.passphraseLabel', defaultMessage: '!!!Passphrase to Decrypt the ada Voucher Certificate', - description: 'Label for the passphrase to decrypt ada voucher certificate input' + description: + 'Label for the passphrase to decrypt ada voucher certificate input', }, passphraseHint: { id: 'wallet.redeem.dialog.passphraseHint', defaultMessage: '!!!Enter your {length} word mnemonic here', - description: 'Hint for the mnemonic passphrase input' + description: 'Hint for the mnemonic passphrase input', }, passphraseNoResults: { id: 'wallet.redeem.dialog.passphrase.input.noResults', defaultMessage: '!!!No results', - description: '"No results" message for the passphrase input search results.' + description: + '"No results" message for the passphrase input search results.', }, redemptionKeyLabel: { id: 'wallet.redeem.dialog.redemptionKeyLabel', @@ -112,7 +129,8 @@ const messages = defineMessages({ shieldedRedemptionKeyError: { id: 'wallet.redeem.dialog.shieldedRedemptionCodeError', defaultMessage: '!!!Invalid shielded vending key', - description: 'Error "Invalid shielded vending key" for ada redemption code input', + description: + 'Error "Invalid shielded vending key" for ada redemption code input', }, redemptionKeyHint: { id: 'wallet.redeem.dialog.redemptionCodeHint', @@ -137,37 +155,37 @@ const messages = defineMessages({ submitLabel: { id: 'wallet.redeem.dialog.submitLabel', defaultMessage: '!!!Redeem your money', - description: 'Label for the "Redeem your money" dialog submit button.' + description: 'Label for the "Redeem your money" dialog submit button.', }, emailLabel: { id: 'wallet.redeem.dialog.emailLabel', defaultMessage: '!!!Email', - description: 'Label for the email input field.' + description: 'Label for the email input field.', }, emailHint: { id: 'wallet.redeem.dialog.emailHint', defaultMessage: '!!!Enter your email address', - description: 'Hint for the email input field.' + description: 'Hint for the email input field.', }, adaPasscodeLabel: { id: 'wallet.redeem.dialog.adaPasscodeLabel', defaultMessage: '!!!Ada passcode', - description: 'Label for the ada passcode input field.' + description: 'Label for the ada passcode input field.', }, adaPasscodeHint: { id: 'wallet.redeem.dialog.adaPasscodeHint', defaultMessage: '!!!Enter your ada passcode', - description: 'Hint for the ada passcode input field.' + description: 'Hint for the ada passcode input field.', }, adaAmountLabel: { id: 'wallet.redeem.dialog.adaAmountLabel', defaultMessage: '!!!Ada amount', - description: 'Label for the ada amount input field.' + description: 'Label for the ada amount input field.', }, adaAmountHint: { id: 'wallet.redeem.dialog.adaAmountHint', defaultMessage: '!!!Enter your ada amount', - description: 'Hint for the ada amount input field.' + description: 'Hint for the ada amount input field.', }, spendingPasswordPlaceholder: { id: 'wallet.redeem.dialog.spendingPasswordPlaceholder', @@ -216,150 +234,204 @@ type Props = { @observer export default class AdaRedemptionForm extends Component { - static contextTypes = { intl: intlShape.isRequired, }; - form = new ReactToolboxMobxForm({ - fields: { - certificate: { - label: this.context.intl.formatMessage(messages.certificateLabel), - placeholder: this.context.intl.formatMessage(messages.certificateHint), - type: 'file', - }, - passPhrase: { - label: this.context.intl.formatMessage(messages.passphraseLabel), - placeholder: this.context.intl.formatMessage(messages.passphraseHint, { - length: ADA_REDEMPTION_PASSPHRASE_LENGTH - }), - value: [], - validators: [({ field }) => { - // Don't validate No pass phrase needed when certificate is not encrypted - if (!this.props.showPassPhraseWidget) return [true]; - // Otherwise check mnemonic - const passPhrase = join(field.value, ' '); - if (!isEmpty(passPhrase)) this.props.onPassPhraseChanged(passPhrase); - return [ - this.props.mnemonicValidator(passPhrase), - this.context.intl.formatMessage(new InvalidMnemonicError()) - ]; - }] - }, - redemptionKey: { - label: this.context.intl.formatMessage(messages.redemptionKeyLabel), - value: '', - validators: ({ field }) => { - if (this.props.redemptionType === ADA_REDEMPTION_TYPES.PAPER_VENDED) return [true]; - const value = this.props.redemptionCode || field.value; - if (value === '') return [false, this.context.intl.formatMessage(messages.fieldIsRequired)]; - return [ - this.props.redemptionCodeValidator(value), - this.context.intl.formatMessage(messages.redemptionKeyError) - ]; + form = new ReactToolboxMobxForm( + { + fields: { + certificate: { + label: this.context.intl.formatMessage(messages.certificateLabel), + placeholder: this.context.intl.formatMessage( + messages.certificateHint + ), + type: 'file', }, - }, - shieldedRedemptionKey: { - label: this.context.intl.formatMessage(messages.shieldedRedemptionKeyLabel), - placeholder: this.context.intl.formatMessage(messages.shieldedRedemptionKeyHint), - value: '', - validators: ({ field }) => { - if (this.props.redemptionType !== ADA_REDEMPTION_TYPES.PAPER_VENDED) return [true]; - const value = field.value; - if (value === '') return [false, this.context.intl.formatMessage(messages.fieldIsRequired)]; - return [ - this.props.postVendRedemptionCodeValidator(value), - this.context.intl.formatMessage(messages.shieldedRedemptionKeyError) - ]; + passPhrase: { + label: this.context.intl.formatMessage(messages.passphraseLabel), + placeholder: this.context.intl.formatMessage( + messages.passphraseHint, + { + length: ADA_REDEMPTION_PASSPHRASE_LENGTH, + } + ), + value: [], + validators: [ + ({ field }) => { + // Don't validate No pass phrase needed when certificate is not encrypted + if (!this.props.showPassPhraseWidget) return [true]; + // Otherwise check mnemonic + const passPhrase = join(field.value, ' '); + if (!isEmpty(passPhrase)) + this.props.onPassPhraseChanged(passPhrase); + return [ + this.props.mnemonicValidator(passPhrase), + this.context.intl.formatMessage(new InvalidMnemonicError()), + ]; + }, + ], }, - }, - walletId: { - label: this.context.intl.formatMessage(messages.walletSelectLabel), - value: this.props.wallets[0].value, - }, - email: { - label: this.context.intl.formatMessage(messages.emailLabel), - placeholder: this.context.intl.formatMessage(messages.emailHint), - value: '', - validators: [({ field }) => { - if (!this.props.showInputsForDecryptingForceVendedCertificate) return [true]; - const email = field.value; - if (isEmail(email)) this.props.onEmailChanged(email); - return [ - isEmail(email), - this.context.intl.formatMessage(new InvalidEmailError()) - ]; - }] - }, - adaPasscode: { - label: this.context.intl.formatMessage(messages.adaPasscodeLabel), - placeholder: this.context.intl.formatMessage(messages.adaPasscodeHint), - value: '', - validators: [({ field }) => { - if (!this.props.showInputsForDecryptingForceVendedCertificate) return [true]; - const adaPasscode = field.value; - if (!isEmpty(adaPasscode)) this.props.onAdaPasscodeChanged(adaPasscode); - return [ - !isEmpty(adaPasscode), - this.context.intl.formatMessage(new FieldRequiredError()) - ]; - }], - }, - adaAmount: { - label: this.context.intl.formatMessage(messages.adaAmountLabel), - placeholder: this.context.intl.formatMessage(messages.adaAmountHint), - value: '', - validators: [({ field }) => { - if (!this.props.showInputsForDecryptingForceVendedCertificate) return [true]; - const adaAmount = field.value; - if (!isEmpty(adaAmount)) this.props.onAdaAmountChanged(adaAmount); - return [ - !isEmpty(adaAmount), - this.context.intl.formatMessage(new FieldRequiredError()) - ]; - }], - }, - spendingPassword: { - type: 'password', - label: this.context.intl.formatMessage(messages.spendingPasswordLabel), - placeholder: this.context.intl.formatMessage(messages.spendingPasswordPlaceholder), - value: '', - validators: [({ field, form }) => { - const password = field.value; - const walletId = form.$('walletId').value; - const wallet = this.props.getSelectedWallet(walletId); - if (wallet && wallet.hasPassword && password === '') { - return [false, this.context.intl.formatMessage(messages.fieldIsRequired)]; - } - return [true]; - }], - }, - decryptionKey: { - label: this.context.intl.formatMessage(messages.decryptionKeyLabel), - placeholder: this.context.intl.formatMessage(messages.decryptionKeyHint), - value: '', - validators: ({ field }) => { - if (!this.props.showInputForDecryptionKey) return [true]; - const decryptionKey = field.value; - if (!isEmpty(decryptionKey)) this.props.onDecryptionKeyChanged(decryptionKey); - return [ - !isEmpty(decryptionKey), - this.context.intl.formatMessage(new FieldRequiredError()) - ]; + redemptionKey: { + label: this.context.intl.formatMessage(messages.redemptionKeyLabel), + value: '', + validators: ({ field }) => { + if (this.props.redemptionType === ADA_REDEMPTION_TYPES.PAPER_VENDED) + return [true]; + const value = this.props.redemptionCode || field.value; + if (value === '') + return [ + false, + this.context.intl.formatMessage(messages.fieldIsRequired), + ]; + return [ + this.props.redemptionCodeValidator(value), + this.context.intl.formatMessage(messages.redemptionKeyError), + ]; + }, + }, + shieldedRedemptionKey: { + label: this.context.intl.formatMessage( + messages.shieldedRedemptionKeyLabel + ), + placeholder: this.context.intl.formatMessage( + messages.shieldedRedemptionKeyHint + ), + value: '', + validators: ({ field }) => { + if (this.props.redemptionType !== ADA_REDEMPTION_TYPES.PAPER_VENDED) + return [true]; + const value = field.value; + if (value === '') + return [ + false, + this.context.intl.formatMessage(messages.fieldIsRequired), + ]; + return [ + this.props.postVendRedemptionCodeValidator(value), + this.context.intl.formatMessage( + messages.shieldedRedemptionKeyError + ), + ]; + }, + }, + walletId: { + label: this.context.intl.formatMessage(messages.walletSelectLabel), + value: this.props.wallets[0].value, + }, + email: { + label: this.context.intl.formatMessage(messages.emailLabel), + placeholder: this.context.intl.formatMessage(messages.emailHint), + value: '', + validators: [ + ({ field }) => { + if (!this.props.showInputsForDecryptingForceVendedCertificate) + return [true]; + const email = field.value; + if (isEmail(email)) this.props.onEmailChanged(email); + return [ + isEmail(email), + this.context.intl.formatMessage(new InvalidEmailError()), + ]; + }, + ], + }, + adaPasscode: { + label: this.context.intl.formatMessage(messages.adaPasscodeLabel), + placeholder: this.context.intl.formatMessage( + messages.adaPasscodeHint + ), + value: '', + validators: [ + ({ field }) => { + if (!this.props.showInputsForDecryptingForceVendedCertificate) + return [true]; + const adaPasscode = field.value; + if (!isEmpty(adaPasscode)) + this.props.onAdaPasscodeChanged(adaPasscode); + return [ + !isEmpty(adaPasscode), + this.context.intl.formatMessage(new FieldRequiredError()), + ]; + }, + ], + }, + adaAmount: { + label: this.context.intl.formatMessage(messages.adaAmountLabel), + placeholder: this.context.intl.formatMessage(messages.adaAmountHint), + value: '', + validators: [ + ({ field }) => { + if (!this.props.showInputsForDecryptingForceVendedCertificate) + return [true]; + const adaAmount = field.value; + if (!isEmpty(adaAmount)) this.props.onAdaAmountChanged(adaAmount); + return [ + !isEmpty(adaAmount), + this.context.intl.formatMessage(new FieldRequiredError()), + ]; + }, + ], + }, + spendingPassword: { + type: 'password', + label: this.context.intl.formatMessage( + messages.spendingPasswordLabel + ), + placeholder: this.context.intl.formatMessage( + messages.spendingPasswordPlaceholder + ), + value: '', + validators: [ + ({ field, form }) => { + const password = field.value; + const walletId = form.$('walletId').value; + const wallet = this.props.getSelectedWallet(walletId); + if (wallet && wallet.hasPassword && password === '') { + return [ + false, + this.context.intl.formatMessage(messages.fieldIsRequired), + ]; + } + return [true]; + }, + ], + }, + decryptionKey: { + label: this.context.intl.formatMessage(messages.decryptionKeyLabel), + placeholder: this.context.intl.formatMessage( + messages.decryptionKeyHint + ), + value: '', + validators: ({ field }) => { + if (!this.props.showInputForDecryptionKey) return [true]; + const decryptionKey = field.value; + if (!isEmpty(decryptionKey)) + this.props.onDecryptionKeyChanged(decryptionKey); + return [ + !isEmpty(decryptionKey), + this.context.intl.formatMessage(new FieldRequiredError()), + ]; + }, }, }, - } - }, { - options: { - validateOnChange: true, - validationDebounceWait: FORM_VALIDATION_DEBOUNCE_WAIT, }, - }); + { + options: { + validateOnChange: true, + validationDebounceWait: FORM_VALIDATION_DEBOUNCE_WAIT, + }, + } + ); submit = () => { this.form.submit({ - onSuccess: (form) => { - const { walletId, shieldedRedemptionKey, spendingPassword } = form.values(); + onSuccess: form => { + const { + walletId, + shieldedRedemptionKey, + spendingPassword, + } = form.values(); this.props.onSubmit({ walletId, shieldedRedemptionKey, @@ -374,7 +446,9 @@ export default class AdaRedemptionForm extends Component { const { form } = this; // Cancel all debounced field validations - form.each((field) => { field.debouncedValidation.cancel(); }); + form.each(field => { + field.debouncedValidation.cancel(); + }); // We can not user form.reset() call here as it would reset selected walletId // which is a bad UX since we are calling resetForm on certificate add/remove @@ -395,18 +469,31 @@ export default class AdaRedemptionForm extends Component { const { form } = this; form.$('walletId').value = walletId; form.$('spendingPassword').value = ''; - } + }; render() { const { intl } = this.context; const { form, resetForm, submit } = this; const { - wallets, isCertificateSelected, isCertificateEncrypted, - isSubmitting, onCertificateSelected, redemptionCode, - onRedemptionCodeChanged, onRemoveCertificate, onChooseRedemptionType, - isCertificateInvalid, redemptionType, showInputsForDecryptingForceVendedCertificate, - showPassPhraseWidget, isRedemptionDisclaimerAccepted, onAcceptRedemptionDisclaimer, error, - getSelectedWallet, suggestedMnemonics, showInputForDecryptionKey, + wallets, + isCertificateSelected, + isCertificateEncrypted, + isSubmitting, + onCertificateSelected, + redemptionCode, + onRedemptionCodeChanged, + onRemoveCertificate, + onChooseRedemptionType, + isCertificateInvalid, + redemptionType, + showInputsForDecryptingForceVendedCertificate, + showPassPhraseWidget, + isRedemptionDisclaimerAccepted, + onAcceptRedemptionDisclaimer, + error, + getSelectedWallet, + suggestedMnemonics, + showInputForDecryptionKey, } = this.props; const certificateField = form.$('certificate'); const passPhraseField = form.$('passPhrase'); @@ -420,57 +507,67 @@ export default class AdaRedemptionForm extends Component { const decryptionKeyField = form.$('decryptionKey'); const componentClasses = classnames([ styles.component, - isSubmitting ? styles.isSubmitting : null + isSubmitting ? styles.isSubmitting : null, ]); const selectedWallet = getSelectedWallet(walletId.value); const walletHasPassword = selectedWallet.hasPassword; - const showUploadWidget = redemptionType !== ADA_REDEMPTION_TYPES.PAPER_VENDED; - const isRecovery = ( + const showUploadWidget = + redemptionType !== ADA_REDEMPTION_TYPES.PAPER_VENDED; + const isRecovery = redemptionType === ADA_REDEMPTION_TYPES.RECOVERY_REGULAR || - redemptionType === ADA_REDEMPTION_TYPES.RECOVERY_FORCE_VENDED - ); + redemptionType === ADA_REDEMPTION_TYPES.RECOVERY_FORCE_VENDED; - const passwordSubmittable = !walletHasPassword || spendingPasswordField.value !== ''; + const passwordSubmittable = + !walletHasPassword || spendingPasswordField.value !== ''; let canSubmit = false; - if (( - redemptionType === ADA_REDEMPTION_TYPES.REGULAR || - redemptionType === ADA_REDEMPTION_TYPES.RECOVERY_REGULAR) && + if ( + (redemptionType === ADA_REDEMPTION_TYPES.REGULAR || + redemptionType === ADA_REDEMPTION_TYPES.RECOVERY_REGULAR) && redemptionCode !== '' && passwordSubmittable - ) canSubmit = true; - if (( - redemptionType === ADA_REDEMPTION_TYPES.FORCE_VENDED || - redemptionType === ADA_REDEMPTION_TYPES.RECOVERY_FORCE_VENDED) && + ) + canSubmit = true; + if ( + (redemptionType === ADA_REDEMPTION_TYPES.FORCE_VENDED || + redemptionType === ADA_REDEMPTION_TYPES.RECOVERY_FORCE_VENDED) && redemptionCode !== '' && passwordSubmittable - ) canSubmit = true; + ) + canSubmit = true; if ( redemptionType === ADA_REDEMPTION_TYPES.PAPER_VENDED && shieldedRedemptionKeyField.isDirty && passPhraseField.isDirty && passwordSubmittable - ) canSubmit = true; + ) + canSubmit = true; let instructionMessage = ''; let instructionValues = {}; switch (redemptionType) { case ADA_REDEMPTION_TYPES.REGULAR: instructionMessage = messages.instructionsRegular; - instructionValues = { adaRedemptionPassphraseLength: ADA_REDEMPTION_PASSPHRASE_LENGTH }; + instructionValues = { + adaRedemptionPassphraseLength: ADA_REDEMPTION_PASSPHRASE_LENGTH, + }; break; case ADA_REDEMPTION_TYPES.FORCE_VENDED: instructionMessage = messages.instructionsForceVended; break; case ADA_REDEMPTION_TYPES.PAPER_VENDED: instructionMessage = messages.instructionsPaperVended; - instructionValues = { adaRedemptionPassphraseLength: ADA_REDEMPTION_PASSPHRASE_LENGTH }; + instructionValues = { + adaRedemptionPassphraseLength: ADA_REDEMPTION_PASSPHRASE_LENGTH, + }; break; case ADA_REDEMPTION_TYPES.RECOVERY_REGULAR: instructionMessage = messages.instructionsRecoveryRegular; - instructionValues = { adaRedemptionPassphraseLength: ADA_REDEMPTION_PASSPHRASE_LENGTH }; + instructionValues = { + adaRedemptionPassphraseLength: ADA_REDEMPTION_PASSPHRASE_LENGTH, + }; break; case ADA_REDEMPTION_TYPES.RECOVERY_FORCE_VENDED: instructionMessage = messages.instructionsRecoveryForceVended; @@ -486,12 +583,11 @@ export default class AdaRedemptionForm extends Component { return (
-
- - -

{intl.formatMessage(messages.headline)}

+

+ {intl.formatMessage(messages.headline)} +

{ />
- +
@@ -513,13 +612,15 @@ export default class AdaRedemptionForm extends Component { onKeyPress={submitOnEnter.bind(this, submit)} className="redemption-key" {...redemptionKeyField.bind()} - placeholder={ - intl.formatMessage(messages[ - isRecovery ? 'recoveryRedemptionKeyHint' : 'redemptionKeyHint' - ]) - } + placeholder={intl.formatMessage( + messages[ + isRecovery + ? 'recoveryRedemptionKeyHint' + : 'redemptionKeyHint' + ] + )} value={redemptionCode} - onChange={(value) => { + onChange={value => { onRedemptionCodeChanged(value); redemptionKeyField.onChange(value); }} @@ -553,7 +654,7 @@ export default class AdaRedemptionForm extends Component { { + onFileSelected={file => { resetForm(); onCertificateSelected(file); certificateField.set(file); @@ -591,7 +692,9 @@ export default class AdaRedemptionForm extends Component { {...passPhraseField.bind()} error={passPhraseField.error} maxVisibleOptions={5} - noResultsMessage={intl.formatMessage(messages.passphraseNoResults)} + noResultsMessage={intl.formatMessage( + messages.passphraseNoResults + )} isOpeningUpward skin={AutocompleteSkin} /> @@ -646,7 +749,9 @@ export default class AdaRedemptionForm extends Component {
) : null} - {error ?

{intl.formatMessage(error)}

: null} + {error ? ( +

{intl.formatMessage(error)}

+ ) : null}
{!isRedemptionDisclaimerAccepted ? ( - + ) : null} -
); } - } diff --git a/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.scss b/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.scss index a42895812e..d70d305d3b 100644 --- a/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.scss +++ b/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.scss @@ -77,7 +77,7 @@ .submitButtonSpinning { box-shadow: none !important; - @include loading-spinner("../../../assets/images/spinner-light.svg"); + @include loading-spinner('../../../assets/images/spinner-light.svg'); } .error { diff --git a/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionNoWallets.js b/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionNoWallets.js index 3a75ea17d5..935188743f 100644 --- a/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionNoWallets.js +++ b/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionNoWallets.js @@ -11,27 +11,29 @@ import icon from '../../../assets/images/attention-big-thin.inline.svg'; const messages = defineMessages({ headLine: { id: 'wallet.redeem.noWallets.headLine', - defaultMessage: '!!!Ada redemption is not available because you don\'t have any wallets.', - description: '"No wallets" headLine on the Ada Redemption Page.' + defaultMessage: + "!!!Ada redemption is not available because you don't have any wallets.", + description: '"No wallets" headLine on the Ada Redemption Page.', }, instructions: { id: 'wallet.redeem.noWallets.instructions', - defaultMessage: '!!!Create a new wallet (or restore an existing one), come back here and choose it for Ada redemption.', - description: '"No wallets" instructions on the Ada Redemption Page.' + defaultMessage: + '!!!Create a new wallet (or restore an existing one), come back here and choose it for Ada redemption.', + description: '"No wallets" instructions on the Ada Redemption Page.', }, createWalletLink: { id: 'wallet.redeem.noWallets.createWalletLink', defaultMessage: '!!!Create your first wallet', - description: 'URL for the "FAQ on Daedalus website" link in the FAQ section on the support settings page', + description: + 'URL for the "FAQ on Daedalus website" link in the FAQ section on the support settings page', }, }); type Props = { - onGoToCreateWalletClick: Function + onGoToCreateWalletClick: Function, }; export default class AdaRedemptionNoWallets extends Component { - static contextTypes = { intl: intlShape.isRequired, }; @@ -55,5 +57,4 @@ export default class AdaRedemptionNoWallets extends Component {
); } - } diff --git a/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionSuccessOverlay.js b/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionSuccessOverlay.js index d231370b41..698ef44d05 100644 --- a/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionSuccessOverlay.js +++ b/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionSuccessOverlay.js @@ -14,12 +14,12 @@ const messages = defineMessages({ headline: { id: 'wallet.redeem.success.overlay.headline', defaultMessage: '!!!You have successfully redeemed', - description: 'Headline for the ada redemption success overlay.' + description: 'Headline for the ada redemption success overlay.', }, confirmButton: { id: 'wallet.redeem.success.overlay.confirmButton', defaultMessage: '!!!Great', - description: 'Confirm button text' + description: 'Confirm button text', }, }); @@ -30,9 +30,8 @@ type Props = { @observer export default class AdaRedemptionSuccessOverlay extends Component { - static contextTypes = { - intl: intlShape.isRequired + intl: intlShape.isRequired, }; render() { @@ -43,7 +42,9 @@ export default class AdaRedemptionSuccessOverlay extends Component {
-

{intl.formatMessage(messages.headline)}

+

+ {intl.formatMessage(messages.headline)} +

{amount} ADA
); } - } diff --git a/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionSuccessOverlay.scss b/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionSuccessOverlay.scss index 1a42acfdde..66dda8ce74 100644 --- a/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionSuccessOverlay.scss +++ b/source/renderer/app/components/wallet/ada-redemption/AdaRedemptionSuccessOverlay.scss @@ -3,7 +3,9 @@ top: 0; width: 100%; height: 100%; - background-color: var(--theme-ada-redemption-success-overlay-background-color); + background-color: var( + --theme-ada-redemption-success-overlay-background-color + ); color: var(--theme-ada-redemption-success-overlay-message-color); display: flex; justify-content: center; @@ -49,12 +51,18 @@ font-size: 14px; height: 50px; margin-top: 30px; - transition: box-shadow 0.2s cubic-bezier(0.4, 0, 1, 1), background-color 0.2s cubic-bezier(0.4, 0, 0.2, 1), color 0.2s cubic-bezier(0.4, 0, 0.2, 1); + transition: box-shadow 0.2s cubic-bezier(0.4, 0, 1, 1), + background-color 0.2s cubic-bezier(0.4, 0, 0.2, 1), + color 0.2s cubic-bezier(0.4, 0, 0.2, 1); width: 360px; &:hover { - background-color: var(--theme-ada-redemption-success-overlay-button-background-color-hover) !important; - color: var(--theme-ada-redemption-success-overlay-button-text-color-hover); + background-color: var( + --theme-ada-redemption-success-overlay-button-background-color-hover + ) !important; + color: var( + --theme-ada-redemption-success-overlay-button-text-color-hover + ); } } diff --git a/source/renderer/app/components/wallet/backup-recovery/MnemonicWord.js b/source/renderer/app/components/wallet/backup-recovery/MnemonicWord.js index b75620e4fe..c6c05a3d67 100644 --- a/source/renderer/app/components/wallet/backup-recovery/MnemonicWord.js +++ b/source/renderer/app/components/wallet/backup-recovery/MnemonicWord.js @@ -14,7 +14,6 @@ type Props = { @observer export default class MnemonicWord extends Component { - render() { const { word, index, isActive, onClick } = this.props; const handleClick = onClick.bind(null, { word, index }); @@ -30,5 +29,4 @@ export default class MnemonicWord extends Component { /> ); } - } diff --git a/source/renderer/app/components/wallet/backup-recovery/MnemonicWord.scss b/source/renderer/app/components/wallet/backup-recovery/MnemonicWord.scss index c13b1b8833..89dc516e9c 100644 --- a/source/renderer/app/components/wallet/backup-recovery/MnemonicWord.scss +++ b/source/renderer/app/components/wallet/backup-recovery/MnemonicWord.scss @@ -13,7 +13,9 @@ &:active { cursor: pointer; &:hover { - background-color: var(--theme-mnemonic-background-color-hover) !important; + background-color: var( + --theme-mnemonic-background-color-hover + ) !important; } } } diff --git a/source/renderer/app/components/wallet/backup-recovery/WalletBackupPrivacyWarningDialog.js b/source/renderer/app/components/wallet/backup-recovery/WalletBackupPrivacyWarningDialog.js index acdc337625..a52c003079 100644 --- a/source/renderer/app/components/wallet/backup-recovery/WalletBackupPrivacyWarningDialog.js +++ b/source/renderer/app/components/wallet/backup-recovery/WalletBackupPrivacyWarningDialog.js @@ -18,18 +18,21 @@ const messages = defineMessages({ defaultMessage: `!!!On the following screen, you will see a set of X random words. This is your wallet backup phrase. It can be entered in any version of Daedalus application in order to back up or restore your wallet’s funds and private key.`, - description: 'Instructions for backing up wallet recovery phrase on dialog that displays wallet recovery phrase.' + description: + 'Instructions for backing up wallet recovery phrase on dialog that displays wallet recovery phrase.', }, buttonLabelContinue: { id: 'wallet.backup.privacy.warning.dialog..button.labelContinue', // TODO: fix translation key path 'dialog..button' defaultMessage: '!!!Continue', - description: 'Label for button "Continue" on wallet backup dialog' + description: 'Label for button "Continue" on wallet backup dialog', }, termNobodyWatching: { id: 'wallet.backup.privacy.warning.dialog.checkbox.label.nobodyWatching', - defaultMessage: '!!!Make sure nobody looks into your screen unless you want them to have access to your funds.', - description: 'Label for the checkbox on wallet backup dialog describing that nobody should be watching when recovery phrase is shown' - } + defaultMessage: + '!!!Make sure nobody looks into your screen unless you want them to have access to your funds.', + description: + 'Label for the checkbox on wallet backup dialog describing that nobody should be watching when recovery phrase is shown', + }, }); type Props = { @@ -43,7 +46,6 @@ type Props = { @observer export default class WalletBackupPrivacyWarningDialog extends Component { - static contextTypes = { intl: intlShape.isRequired, }; @@ -56,9 +58,10 @@ export default class WalletBackupPrivacyWarningDialog extends Component { onAcceptPrivacyNotice, onCancelBackup, isPrivacyNoticeAccepted, - onContinue + onContinue, } = this.props; - const countdownDisplay = countdownRemaining > 0 ? ` (${countdownRemaining})` : ''; + const countdownDisplay = + countdownRemaining > 0 ? ` (${countdownRemaining})` : ''; const dialogClasses = classnames([ styles.component, 'WalletBackupPrivacyWarningDialog', @@ -66,11 +69,12 @@ export default class WalletBackupPrivacyWarningDialog extends Component { const actions = [ { - label: intl.formatMessage(messages.buttonLabelContinue) + countdownDisplay, + label: + intl.formatMessage(messages.buttonLabelContinue) + countdownDisplay, onClick: onContinue, disabled: !canPhraseBeShown, - primary: true - } + primary: true, + }, ]; return ( @@ -83,9 +87,12 @@ export default class WalletBackupPrivacyWarningDialog extends Component { closeButton={} >
{ ); } - } diff --git a/source/renderer/app/components/wallet/backup-recovery/WalletBackupPrivacyWarningDialog.scss b/source/renderer/app/components/wallet/backup-recovery/WalletBackupPrivacyWarningDialog.scss index 4f9471ef4b..df8b5b42fe 100644 --- a/source/renderer/app/components/wallet/backup-recovery/WalletBackupPrivacyWarningDialog.scss +++ b/source/renderer/app/components/wallet/backup-recovery/WalletBackupPrivacyWarningDialog.scss @@ -2,10 +2,10 @@ margin-top: 20px; } -.component{ +.component { :global { .WalletRecoveryInstructions_component { text-align: left; } } -} \ No newline at end of file +} diff --git a/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryInstructions.js b/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryInstructions.js index cfdf103504..1a5f34b64a 100644 --- a/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryInstructions.js +++ b/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryInstructions.js @@ -10,12 +10,8 @@ type Props = { @observer export default class WalletRecoveryInstructions extends Component { - render() { const { instructionsText } = this.props; - return ( -
{instructionsText}
- ); + return
{instructionsText}
; } - } diff --git a/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseDisplayDialog.js b/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseDisplayDialog.js index bd92468a28..8f5b7c8cb5 100644 --- a/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseDisplayDialog.js +++ b/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseDisplayDialog.js @@ -15,13 +15,16 @@ const messages = defineMessages({ id: 'wallet.backup.recovery.phrase.display.dialog.backup.instructions', defaultMessage: `!!!Please, make sure you have carefully written down your recovery phrase somewhere safe. You will need this phrase later for next use and recover. Phrase is case sensitive.`, - description: 'Instructions for backing up wallet recovery phrase on dialog that displays wallet recovery phrase.' + description: + 'Instructions for backing up wallet recovery phrase on dialog that displays wallet recovery phrase.', }, buttonLabelIHaveWrittenItDown: { - id: 'wallet.backup.recovery.phrase.display.dialog.button.label.iHaveWrittenItDown', + id: + 'wallet.backup.recovery.phrase.display.dialog.button.label.iHaveWrittenItDown', defaultMessage: '!!!Yes, I’ve written it down', - description: 'Label for button "Yes, I’ve written it down" on wallet backup dialog' - } + description: + 'Label for button "Yes, I’ve written it down" on wallet backup dialog', + }, }); type Props = { @@ -32,18 +35,13 @@ type Props = { @observer export default class WalletRecoveryPhraseDisplayDialog extends Component { - static contextTypes = { intl: intlShape.isRequired, }; render() { const { intl } = this.context; - const { - recoveryPhrase, - onStartWalletBackup, - onCancelBackup, - } = this.props; + const { recoveryPhrase, onStartWalletBackup, onCancelBackup } = this.props; const dialogClasses = classnames([ styles.component, 'WalletRecoveryPhraseDisplayDialog', @@ -53,8 +51,8 @@ export default class WalletRecoveryPhraseDisplayDialog extends Component { label: intl.formatMessage(messages.buttonLabelIHaveWrittenItDown), onClick: onStartWalletBackup, - primary: true - } + primary: true, + }, ]; return ( @@ -67,11 +65,12 @@ export default class WalletRecoveryPhraseDisplayDialog extends Component closeButton={} > } + instructionsText={ + + } /> ); } - } diff --git a/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseDisplayDialog.scss b/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseDisplayDialog.scss index 457b087417..1d97d9be9b 100644 --- a/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseDisplayDialog.scss +++ b/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseDisplayDialog.scss @@ -1,4 +1,4 @@ -.component{ +.component { :global { .WalletRecoveryInstructions_component { text-align: center !important; diff --git a/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseEntryDialog.js b/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseEntryDialog.js index b0179ddfa8..45ac8753cf 100644 --- a/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseEntryDialog.js +++ b/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseEntryDialog.js @@ -18,30 +18,36 @@ import type { RecoveryPhraseWord } from '../../../types/walletBackupTypes'; const messages = defineMessages({ verificationInstructions: { id: 'wallet.backup.recovery.phrase.entry.dialog.verification.instructions', - defaultMessage: '!!!Tap each word in the correct order to verify your recovery phrase', - description: 'Instructions for verifying wallet recovery phrase on dialog for entering wallet recovery phrase.' + defaultMessage: + '!!!Tap each word in the correct order to verify your recovery phrase', + description: + 'Instructions for verifying wallet recovery phrase on dialog for entering wallet recovery phrase.', }, buttonLabelConfirm: { id: 'wallet.recovery.phrase.show.entry.dialog.button.labelConfirm', defaultMessage: '!!!Confirm', - description: 'Label for button "Confirm" on wallet backup dialog' + description: 'Label for button "Confirm" on wallet backup dialog', }, buttonLabelClear: { id: 'wallet.recovery.phrase.show.entry.dialog.button.labelClear', defaultMessage: '!!!Clear', - description: 'Label for button "Clear" on wallet backup dialog' + description: 'Label for button "Clear" on wallet backup dialog', }, termDevice: { id: 'wallet.backup.recovery.phrase.entry.dialog.terms.and.condition.device', - defaultMessage: '!!!I understand that my money are held securely on this device only, not on the company servers', - description: 'Term and condition on wallet backup dialog describing that wallet is on a users device, not on company servers' + defaultMessage: + '!!!I understand that my money are held securely on this device only, not on the company servers', + description: + 'Term and condition on wallet backup dialog describing that wallet is on a users device, not on company servers', }, termRecovery: { - id: 'wallet.backup.recovery.phrase.entry.dialog.terms.and.condition.recovery', + id: + 'wallet.backup.recovery.phrase.entry.dialog.terms.and.condition.recovery', defaultMessage: `!!!I understand that if this application is moved to another device or deleted, my money can be only recovered with the backup phrase which were written down in a secure place`, - description: 'Term and condition on wallet backup dialog describing that wallet can only be recovered with a security phrase' - } + description: + 'Term and condition on wallet backup dialog describing that wallet can only be recovered with a security phrase', + }, }); type Props = { @@ -63,7 +69,6 @@ type Props = { @observer export default class WalletRecoveryPhraseEntryDialog extends Component { - static contextTypes = { intl: intlShape.isRequired, }; @@ -84,14 +89,17 @@ export default class WalletRecoveryPhraseEntryDialog extends Component { canFinishBackup, onRestartBackup, onCancelBackup, - onFinishBackup + onFinishBackup, } = this.props; const dialogClasses = classnames([ styles.component, 'WalletRecoveryPhraseEntryDialog', ]); - const enteredPhraseString = enteredPhrase.reduce((phrase, { word }) => `${phrase} ${word}`, ''); + const enteredPhraseString = enteredPhrase.reduce( + (phrase, { word }) => `${phrase} ${word}`, + '' + ); const actions = []; @@ -100,7 +108,7 @@ export default class WalletRecoveryPhraseEntryDialog extends Component { label: intl.formatMessage(messages.buttonLabelConfirm), onClick: onFinishBackup, disabled: !canFinishBackup, - primary: true + primary: true, }); // Only show "Clear" button when user is not yet done with entering mnemonic @@ -119,11 +127,15 @@ export default class WalletRecoveryPhraseEntryDialog extends Component { closeOnOverlayClick={false} onClose={onCancelBackup} closeButton={} - backButton={!isValid ? : null} + backButton={ + !isValid ? : null + } > {!isValid && ( )} @@ -170,5 +182,4 @@ export default class WalletRecoveryPhraseEntryDialog extends Component { ); } - } diff --git a/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseEntryDialog.scss b/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseEntryDialog.scss index 52cad0705c..a09d895e9b 100644 --- a/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseEntryDialog.scss +++ b/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseEntryDialog.scss @@ -16,7 +16,7 @@ } } -.component{ +.component { :global { .WalletRecoveryInstructions_component { text-align: center; @@ -26,5 +26,5 @@ .isSubmitting { box-shadow: none !important; - @include loading-spinner("../../../assets/images/spinner-light.svg"); + @include loading-spinner('../../../assets/images/spinner-light.svg'); } diff --git a/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseMnemonic.js b/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseMnemonic.js index 43e50ea331..d9447fee2c 100644 --- a/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseMnemonic.js +++ b/source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseMnemonic.js @@ -9,12 +9,8 @@ type Props = { @observer export default class WalletRecoveryPhraseMnemonic extends Component { - render() { const { phrase } = this.props; - return ( -
{phrase}
- ); + return
{phrase}
; } - } diff --git a/source/renderer/app/components/wallet/file-import/WalletFileImportDialog.js b/source/renderer/app/components/wallet/file-import/WalletFileImportDialog.js index c1d28b11c5..a509d860ff 100644 --- a/source/renderer/app/components/wallet/file-import/WalletFileImportDialog.js +++ b/source/renderer/app/components/wallet/file-import/WalletFileImportDialog.js @@ -12,7 +12,11 @@ import DialogCloseButton from '../../widgets/DialogCloseButton'; import Dialog from '../../widgets/Dialog'; import ReactToolboxMobxForm from '../../../utils/ReactToolboxMobxForm'; import FileUploadWidget from '../../widgets/forms/FileUploadWidget'; -import { isValidWalletName, isValidSpendingPassword, isValidRepeatPassword } from '../../../utils/validations'; +import { + isValidWalletName, + isValidSpendingPassword, + isValidRepeatPassword, +} from '../../../utils/validations'; import globalMessages from '../../../i18n/global-messages'; import LocalizableError from '../../../i18n/LocalizableError'; import styles from './WalletFileImportDialog.scss'; @@ -22,57 +26,66 @@ const messages = defineMessages({ headline: { id: 'wallet.file.import.dialog.headline', defaultMessage: '!!!Import Wallet', - description: 'headline for "Import wallet from file" dialog.' + description: 'headline for "Import wallet from file" dialog.', }, walletFileLabel: { id: 'wallet.file.import.dialog.walletFileLabel', defaultMessage: '!!!Import file', - description: 'Label "Import file" on the dialog for importing a wallet from a file.' + description: + 'Label "Import file" on the dialog for importing a wallet from a file.', }, walletFileHint: { id: 'wallet.file.import.dialog.walletFileHint', defaultMessage: '!!!Drop file here or click to choose', - description: 'Hint for the file upload field on the dialog for importing a wallet from a file.' + description: + 'Hint for the file upload field on the dialog for importing a wallet from a file.', }, walletNameInputLabel: { id: 'wallet.file.import.dialog.wallet.name.input.label', defaultMessage: '!!!Wallet name', - description: 'Label for the "wallet name" input in the wallet file import dialog.' + description: + 'Label for the "wallet name" input in the wallet file import dialog.', }, walletNameInputHint: { id: 'wallet.file.import.dialog.wallet.name.input.hint', defaultMessage: '!!!e.g: Shopping Wallet', - description: 'Hint for the "Wallet name" in the wallet file import dialog.' + description: 'Hint for the "Wallet name" in the wallet file import dialog.', }, submitLabel: { id: 'wallet.file.import.dialog.submitLabel', defaultMessage: '!!!Import wallet', - description: 'Label "Import wallet" submit button on the dialog for importing a wallet from a file.' + description: + 'Label "Import wallet" submit button on the dialog for importing a wallet from a file.', }, passwordSwitchPlaceholder: { id: 'wallet.file.import.dialog.passwordSwitchPlaceholder', defaultMessage: '!!!Activate to create password', - description: 'Text for the "Activate to create password" switch in the wallet file import dialog.', + description: + 'Text for the "Activate to create password" switch in the wallet file import dialog.', }, passwordSwitchLabel: { id: 'wallet.file.import.dialog.passwordSwitchLabel', defaultMessage: '!!!Password', - description: 'Label for the "Activate to create password" switch in the wallet file import dialog.', + description: + 'Label for the "Activate to create password" switch in the wallet file import dialog.', }, spendingPasswordLabel: { id: 'wallet.file.import.dialog.spendingPasswordLabel', defaultMessage: '!!!Wallet password', - description: 'Label for the "Wallet password" input in the wallet file import dialog.', + description: + 'Label for the "Wallet password" input in the wallet file import dialog.', }, repeatPasswordLabel: { id: 'wallet.file.import.dialog.repeatPasswordLabel', defaultMessage: '!!!Repeat password', - description: 'Label for the "Repeat password" input in the wallet file import dialog.', + description: + 'Label for the "Repeat password" input in the wallet file import dialog.', }, passwordFieldPlaceholder: { id: 'wallet.file.import.dialog.passwordFieldPlaceholder', defaultMessage: '!!!Password', - description: 'Placeholder for the "Password" inputs in the wallet file import dialog.', + description: + 'Placeholder for the "Password" inputs in the wallet file import dialog.', }, }); @@ -89,7 +102,6 @@ type State = { @observer export default class WalletFileImportDialog extends Component { - state = { createPassword: false, }; @@ -102,78 +114,101 @@ export default class WalletFileImportDialog extends Component { this.setState({ createPassword: value }); }; - form = new ReactToolboxMobxForm({ - fields: { - walletFile: { - label: this.context.intl.formatMessage(messages.walletFileLabel), - placeholder: this.context.intl.formatMessage(messages.walletFileHint), - type: 'file', - }, - walletName: { - label: this.context.intl.formatMessage(messages.walletNameInputLabel), - placeholder: this.context.intl.formatMessage(messages.walletNameInputHint), - value: '', - validators: [({ field }) => { - if (field.value.length === 0) return [true]; - return [ - isValidWalletName(field.value), - this.context.intl.formatMessage(globalMessages.invalidWalletName) - ]; - }], - }, - spendingPassword: { - type: 'password', - label: this.context.intl.formatMessage(messages.spendingPasswordLabel), - placeholder: this.context.intl.formatMessage(messages.passwordFieldPlaceholder), - value: '', - validators: [({ field, form }) => { - if (!this.state.createPassword) return [true]; - const repeatPasswordField = form.$('repeatPassword'); - if (repeatPasswordField.value.length > 0) { - repeatPasswordField.validate({ showErrors: true }); - } - return [ - isValidSpendingPassword(field.value), - this.context.intl.formatMessage(globalMessages.invalidSpendingPassword) - ]; - }], + form = new ReactToolboxMobxForm( + { + fields: { + walletFile: { + label: this.context.intl.formatMessage(messages.walletFileLabel), + placeholder: this.context.intl.formatMessage(messages.walletFileHint), + type: 'file', + }, + walletName: { + label: this.context.intl.formatMessage(messages.walletNameInputLabel), + placeholder: this.context.intl.formatMessage( + messages.walletNameInputHint + ), + value: '', + validators: [ + ({ field }) => { + if (field.value.length === 0) return [true]; + return [ + isValidWalletName(field.value), + this.context.intl.formatMessage( + globalMessages.invalidWalletName + ), + ]; + }, + ], + }, + spendingPassword: { + type: 'password', + label: this.context.intl.formatMessage( + messages.spendingPasswordLabel + ), + placeholder: this.context.intl.formatMessage( + messages.passwordFieldPlaceholder + ), + value: '', + validators: [ + ({ field, form }) => { + if (!this.state.createPassword) return [true]; + const repeatPasswordField = form.$('repeatPassword'); + if (repeatPasswordField.value.length > 0) { + repeatPasswordField.validate({ showErrors: true }); + } + return [ + isValidSpendingPassword(field.value), + this.context.intl.formatMessage( + globalMessages.invalidSpendingPassword + ), + ]; + }, + ], + }, + repeatPassword: { + type: 'password', + label: this.context.intl.formatMessage(messages.repeatPasswordLabel), + placeholder: this.context.intl.formatMessage( + messages.passwordFieldPlaceholder + ), + value: '', + validators: [ + ({ field, form }) => { + if (!this.state.createPassword) return [true]; + const spendingPassword = form.$('spendingPassword').value; + if (spendingPassword.length === 0) return [true]; + return [ + isValidRepeatPassword(spendingPassword, field.value), + this.context.intl.formatMessage( + globalMessages.invalidRepeatPassword + ), + ]; + }, + ], + }, }, - repeatPassword: { - type: 'password', - label: this.context.intl.formatMessage(messages.repeatPasswordLabel), - placeholder: this.context.intl.formatMessage(messages.passwordFieldPlaceholder), - value: '', - validators: [({ field, form }) => { - if (!this.state.createPassword) return [true]; - const spendingPassword = form.$('spendingPassword').value; - if (spendingPassword.length === 0) return [true]; - return [ - isValidRepeatPassword(spendingPassword, field.value), - this.context.intl.formatMessage(globalMessages.invalidRepeatPassword) - ]; - }], - }, - }, - }, { - options: { - validateOnChange: true, - validationDebounceWait: FORM_VALIDATION_DEBOUNCE_WAIT, }, - }); + { + options: { + validateOnChange: true, + validationDebounceWait: FORM_VALIDATION_DEBOUNCE_WAIT, + }, + } + ); submit = () => { this.form.submit({ - onSuccess: (form) => { + onSuccess: form => { const { createPassword } = this.state; const { walletFile, spendingPassword, walletName } = form.values(); const walletData = { filePath: walletFile.path, spendingPassword: createPassword ? spendingPassword : null, - walletName: (walletName.length > 0) ? walletName : null, + walletName: walletName.length > 0 ? walletName : null, }; this.props.onSubmit(walletData); }, - onError: () => {} + onError: () => {}, }); }; @@ -201,7 +236,7 @@ export default class WalletFileImportDialog extends Component { primary: true, disabled: isSubmitting || !(walletFile.value instanceof File), onClick: this.submit, - } + }, ]; // const walletNameField = form.$('walletName'); @@ -217,12 +252,11 @@ export default class WalletFileImportDialog extends Component { onClose={onClose} closeButton={} > -
{ + onFileSelected={file => { // "set(value)" is an unbound method and thus must be explicitly called walletFile.set(file); }} @@ -274,9 +308,7 @@ export default class WalletFileImportDialog extends Component { */} {error &&

{intl.formatMessage(error)}

} - ); } - } diff --git a/source/renderer/app/components/wallet/file-import/WalletFileImportDialog.scss b/source/renderer/app/components/wallet/file-import/WalletFileImportDialog.scss index 370c80c560..eece46b1fe 100644 --- a/source/renderer/app/components/wallet/file-import/WalletFileImportDialog.scss +++ b/source/renderer/app/components/wallet/file-import/WalletFileImportDialog.scss @@ -75,5 +75,5 @@ .isSubmitting { box-shadow: none !important; - @include loading-spinner("../../../assets/images/spinner-light.svg"); + @include loading-spinner('../../../assets/images/spinner-light.svg'); } diff --git a/source/renderer/app/components/wallet/layouts/WalletWithNavigation.js b/source/renderer/app/components/wallet/layouts/WalletWithNavigation.js index 196350305d..3de8022732 100644 --- a/source/renderer/app/components/wallet/layouts/WalletWithNavigation.js +++ b/source/renderer/app/components/wallet/layouts/WalletWithNavigation.js @@ -13,7 +13,6 @@ type Props = { @observer export default class WalletWithNavigation extends Component { - render() { const { children, isActiveScreen, onWalletNavItemClick } = this.props; return ( @@ -24,9 +23,7 @@ export default class WalletWithNavigation extends Component { onNavItemClick={onWalletNavItemClick} />
-
- {children} -
+
{children}
); } diff --git a/source/renderer/app/components/wallet/navigation/WalletNavButton.js b/source/renderer/app/components/wallet/navigation/WalletNavButton.js index c85962020e..d66a85afbe 100755 --- a/source/renderer/app/components/wallet/navigation/WalletNavButton.js +++ b/source/renderer/app/components/wallet/navigation/WalletNavButton.js @@ -15,17 +15,16 @@ type Props = { @observer export default class WalletNavButton extends Component { - render() { const { isActive, icon, onClick, className } = this.props; const componentClasses = classnames([ className, styles.component, - isActive ? styles.active : styles.normal + isActive ? styles.active : styles.normal, ]); const iconClasses = classnames([ styles.icon, - isActive ? styles.activeIcon : styles.normalIcon + isActive ? styles.activeIcon : styles.normalIcon, ]); return (
)} -
); } - } diff --git a/source/renderer/app/components/widgets/NotificationMessage.scss b/source/renderer/app/components/widgets/NotificationMessage.scss index 3aab46711a..bc599410f5 100644 --- a/source/renderer/app/components/widgets/NotificationMessage.scss +++ b/source/renderer/app/components/widgets/NotificationMessage.scss @@ -21,7 +21,7 @@ cursor: pointer; &:hover { .closeButton { - opacity: .8; + opacity: 0.8; } } } @@ -51,9 +51,9 @@ position: absolute; right: 20px; top: 25.5px; - opacity: .5; + opacity: 0.5; &:hover { - opacity: .8; + opacity: 0.8; } svg { diff --git a/source/renderer/app/components/widgets/ProgressBar.js b/source/renderer/app/components/widgets/ProgressBar.js index 4658854ff8..e274e09173 100644 --- a/source/renderer/app/components/widgets/ProgressBar.js +++ b/source/renderer/app/components/widgets/ProgressBar.js @@ -9,7 +9,6 @@ type Props = { @observer export default class ProgressBar extends Component { - static defaultProps = { progress: 0, }; @@ -22,5 +21,4 @@ export default class ProgressBar extends Component {
); } - } diff --git a/source/renderer/app/components/widgets/WalletTestEnvironmentLabel.js b/source/renderer/app/components/widgets/WalletTestEnvironmentLabel.js index 70bfab7463..7542b28168 100644 --- a/source/renderer/app/components/widgets/WalletTestEnvironmentLabel.js +++ b/source/renderer/app/components/widgets/WalletTestEnvironmentLabel.js @@ -8,18 +8,18 @@ const messages = defineMessages({ staging: { id: 'test.environment.stagingLabel', defaultMessage: '!!!Staging vx', - description: 'Label for staging network with version.' + description: 'Label for staging network with version.', }, testnet: { id: 'test.environment.testnetLabel', defaultMessage: '!!!Testnet vx', - description: 'Label for testnet with version.' + description: 'Label for testnet with version.', }, development: { id: 'test.environment.developmentLabel', defaultMessage: '!!!Development vx', - description: 'Label for development with version.' - } + description: 'Label for development with version.', + }, }); type Props = { @@ -27,7 +27,6 @@ type Props = { }; export default class WalletTestEnvironmentLabel extends Component { - static contextTypes = { intl: intlShape.isRequired, }; @@ -36,11 +35,6 @@ export default class WalletTestEnvironmentLabel extends Component { const { network } = this.props; const { intl } = this.context; const label = messages[network]; - return ( -
- {intl.formatMessage(label)} -
- ); + return
{intl.formatMessage(label)}
; } - } diff --git a/source/renderer/app/components/widgets/WalletTestEnvironmentLabel.scss b/source/renderer/app/components/widgets/WalletTestEnvironmentLabel.scss index 2bc04c1d9e..633f826042 100644 --- a/source/renderer/app/components/widgets/WalletTestEnvironmentLabel.scss +++ b/source/renderer/app/components/widgets/WalletTestEnvironmentLabel.scss @@ -10,9 +10,9 @@ position: absolute; right: 0; &::before { - background: url("../../assets/images/top-bar/sticker.svg") 0 0 no-repeat; + background: url('../../assets/images/top-bar/sticker.svg') 0 0 no-repeat; background-size: auto 100%; - content: ""; + content: ''; height: 42px; position: absolute; right: 100%; diff --git a/source/renderer/app/components/widgets/forms/AdaCertificateUploadWidget.js b/source/renderer/app/components/widgets/forms/AdaCertificateUploadWidget.js index 1e699335c0..964d769c02 100644 --- a/source/renderer/app/components/widgets/forms/AdaCertificateUploadWidget.js +++ b/source/renderer/app/components/widgets/forms/AdaCertificateUploadWidget.js @@ -23,7 +23,6 @@ type Props = { @observer export default class AdaCertificateUploadWidget extends Component { - static contextTypes = { intl: intlShape.isRequired, }; @@ -34,15 +33,22 @@ export default class AdaCertificateUploadWidget extends Component { render() { const { intl } = this.context; - const { label, acceptedFileTypes, isCertificateEncrypted, - isCertificateSelected, onRemoveCertificate, isCertificateInvalid + const { + label, + acceptedFileTypes, + isCertificateEncrypted, + isCertificateSelected, + onRemoveCertificate, + isCertificateInvalid, } = this.props; let certificateIcon; if (isCertificateEncrypted) { certificateIcon = certificateLockedIcon; } else { - certificateIcon = isCertificateInvalid ? certificateInvalidIcon : certificateNormalIcon; + certificateIcon = isCertificateInvalid + ? certificateInvalidIcon + : certificateNormalIcon; } return (
@@ -50,10 +56,19 @@ export default class AdaCertificateUploadWidget extends Component {
{isCertificateSelected ? (
- - +
) : ( {
); } - } diff --git a/source/renderer/app/components/widgets/forms/FileUploadWidget.js b/source/renderer/app/components/widgets/forms/FileUploadWidget.js index 6f1aeb2d19..8ad0a3961b 100644 --- a/source/renderer/app/components/widgets/forms/FileUploadWidget.js +++ b/source/renderer/app/components/widgets/forms/FileUploadWidget.js @@ -16,7 +16,6 @@ type Props = { @observer export default class FileUploadWidget extends Component { - onDrop = (files: [File]) => { this.props.onFileSelected(files[0]); }; @@ -42,5 +41,4 @@ export default class FileUploadWidget extends Component {
); } - } diff --git a/source/renderer/app/components/widgets/forms/ImageUploadWidget.js b/source/renderer/app/components/widgets/forms/ImageUploadWidget.js index ddc9ab7147..6f80b99d18 100644 --- a/source/renderer/app/components/widgets/forms/ImageUploadWidget.js +++ b/source/renderer/app/components/widgets/forms/ImageUploadWidget.js @@ -8,22 +8,21 @@ export const messages = defineMessages({ dropFileHere: { id: 'ImageUploadWidget.dropFileHint', defaultMessage: '!!!Drop file here', - description: 'Label "Drop file here" on the file upload widget.' + description: 'Label "Drop file here" on the file upload widget.', }, orClickToUpload: { id: 'ImageUploadWidget.clickToUploadLabel', defaultMessage: '!!!or click to upload', - description: 'Label "or click to upload" on the file upload widget.' + description: 'Label "or click to upload" on the file upload widget.', }, }); type Props = { - label: string + label: string, }; @observer export default class ImageUploadWidget extends Component { - static contextTypes = { intl: intlShape.isRequired, }; @@ -36,12 +35,15 @@ export default class ImageUploadWidget extends Component {
{label}
-
{intl.formatMessage(messages.dropFileHere)}
-
{intl.formatMessage(messages.orClickToUpload)}
+
+ {intl.formatMessage(messages.dropFileHere)} +
+
+ {intl.formatMessage(messages.orClickToUpload)} +
); } - } diff --git a/source/renderer/app/components/widgets/forms/InlineEditingDropdown.js b/source/renderer/app/components/widgets/forms/InlineEditingDropdown.js index 5da7079ddd..46ca28ff9a 100644 --- a/source/renderer/app/components/widgets/forms/InlineEditingDropdown.js +++ b/source/renderer/app/components/widgets/forms/InlineEditingDropdown.js @@ -11,7 +11,8 @@ const messages = defineMessages({ changesSaved: { id: 'inline.editing.dropdown.changesSaved', defaultMessage: '!!!Your changes have been saved', - description: 'Message "Your changes have been saved" for inline editing (eg. on Wallet Settings page).', + description: + 'Message "Your changes have been saved" for inline editing (eg. on Wallet Settings page).', }, }); @@ -19,7 +20,7 @@ type Props = { className?: string, isActive: boolean, label: string, - options: Array<{ value: (number | string), label: string }>, + options: Array<{ value: number | string, label: string }>, value: number | string, onSubmit: Function, onStartEditing: Function, @@ -29,7 +30,6 @@ type Props = { @observer export default class InlineEditingDropdown extends Component { - static contextTypes = { intl: intlShape.isRequired, }; @@ -43,19 +43,19 @@ export default class InlineEditingDropdown extends Component { render() { const { intl } = this.context; const { - className, isActive, label, options, - value, successfullyUpdated, - } = this.props; - const componentClasses = classnames([ className, - styles.component, - ]); + isActive, + label, + options, + value, + successfullyUpdated, + } = this.props; + const componentClasses = classnames([className, styles.component]); const dropdownStyles = classnames([ successfullyUpdated ? 'dropdown_animateSuccess' : null, ]); return (
- { skin={InputSkin} /> - -
); } - } diff --git a/source/renderer/app/components/widgets/forms/TinySwitch.js b/source/renderer/app/components/widgets/forms/TinySwitch.js index b7259744fc..bf6f261ec9 100644 --- a/source/renderer/app/components/widgets/forms/TinySwitch.js +++ b/source/renderer/app/components/widgets/forms/TinySwitch.js @@ -12,9 +12,7 @@ type Props = { }; export default class TinySwitch extends Component { - render() { - return ( { /> ); } - } diff --git a/source/renderer/app/config/urlsConfig.js b/source/renderer/app/config/urlsConfig.js index d4285c0bf5..2b209eafce 100644 --- a/source/renderer/app/config/urlsConfig.js +++ b/source/renderer/app/config/urlsConfig.js @@ -1,7 +1,9 @@ // @flow export const MAINNET_EXPLORER_URL = 'https://cardanoexplorer.com'; -export const STAGING_EXPLORER_URL = 'http://cardano-explorer.awstest.iohkdev.io'; -export const TESTNET_EXPLORER_URL = 'http://cardano-explorer.cardano-testnet.iohkdev.io'; +export const STAGING_EXPLORER_URL = + 'http://cardano-explorer.awstest.iohkdev.io'; +export const TESTNET_EXPLORER_URL = + 'http://cardano-explorer.cardano-testnet.iohkdev.io'; export const DEVELOPMENT_EKG_URL = 'http://localhost:8083'; export const STAGING_EKG_URL = 'http://localhost:8082'; diff --git a/source/renderer/app/containers/LoadingPage.js b/source/renderer/app/containers/LoadingPage.js index ff6f31844f..6b030e211e 100644 --- a/source/renderer/app/containers/LoadingPage.js +++ b/source/renderer/app/containers/LoadingPage.js @@ -17,12 +17,12 @@ export const messages = defineMessages({ loadingWalletData: { id: 'loading.screen.loadingWalletData', defaultMessage: '!!!Loading wallet data', - description: 'Message "Loading wallet data" on the loading screen.' + description: 'Message "Loading wallet data" on the loading screen.', }, reportIssueButtonUrl: { id: 'loading.screen.reportIssue.reportIssueButtonUrl', defaultMessage: '!!!https://iohk.zendesk.com/hc/en-us/requests/new/', - description: 'Link to Open Support page' + description: 'Link to Open Support page', }, downloadLogsSuccess: { id: 'loading.screen.reportIssue.downloadLogsSuccessMessage', @@ -31,9 +31,9 @@ export const messages = defineMessages({ }, }); -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class LoadingPage extends Component { - static contextTypes = { intl: intlShape.isRequired, }; @@ -53,12 +53,28 @@ export default class LoadingPage extends Component { render() { const { stores } = this.props; const { - cardanoNodeState, isConnected, isSynced, syncPercentage, hasBeenConnected, - localTimeDifference, isSystemTimeCorrect, forceCheckTimeDifferenceRequest, - forceCheckLocalTimeDifference, ignoreSystemTimeChecks, isNodeStopping, isNodeStopped, - isNotEnoughDiskSpace, diskSpaceRequired, diskSpaceMissing, diskSpaceRecommended, + cardanoNodeState, + isConnected, + isSynced, + syncPercentage, + hasBeenConnected, + localTimeDifference, + isSystemTimeCorrect, + forceCheckTimeDifferenceRequest, + forceCheckLocalTimeDifference, + ignoreSystemTimeChecks, + isNodeStopping, + isNodeStopped, + isNotEnoughDiskSpace, + diskSpaceRequired, + diskSpaceMissing, + diskSpaceRecommended, } = stores.networkStatus; - const { hasLoadedCurrentLocale, hasLoadedCurrentTheme, currentLocale } = stores.profile; + const { + hasLoadedCurrentLocale, + hasLoadedCurrentTheme, + currentLocale, + } = stores.profile; const { id, message } = this.notification; return ( @@ -119,7 +135,9 @@ export default class LoadingPage extends Component { handleReportIssueClick = async (event: SyntheticEvent) => { event.persist(); const { intl } = this.context; - const reportIssueButtonUrl = intl.formatMessage(messages.reportIssueButtonUrl); + const reportIssueButtonUrl = intl.formatMessage( + messages.reportIssueButtonUrl + ); const locale = this.props.stores.profile.currentLocale; const supportUrl = await getSupportUrl(reportIssueButtonUrl, locale); this.props.stores.app.openExternalLink(supportUrl); diff --git a/source/renderer/app/containers/MainLayout.js b/source/renderer/app/containers/MainLayout.js index 0957e6cc09..990bb7d342 100644 --- a/source/renderer/app/containers/MainLayout.js +++ b/source/renderer/app/containers/MainLayout.js @@ -9,14 +9,14 @@ import PaperWalletCreateCertificatePage from './wallet/PaperWalletCreateCertific import type { InjectedContainerProps } from '../types/injectedPropsType'; import { ROUTES } from '../routes-config'; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class MainLayout extends Component { - static defaultProps = { actions: null, stores: null, children: null, - onClose: () => {} + onClose: () => {}, }; render() { @@ -26,17 +26,20 @@ export default class MainLayout extends Component { const activeWallet = wallets.active; const activeWalletId = activeWallet ? activeWallet.id : null; - const sidebarMenus = sidebar.wallets.length > 0 ? { - wallets: { - items: sidebar.wallets, - activeWalletId, - actions: { - onWalletItemClick: (walletId: string) => { - actions.sidebar.walletSelected.trigger({ walletId }); - }, - } - } - } : null; + const sidebarMenus = + sidebar.wallets.length > 0 + ? { + wallets: { + items: sidebar.wallets, + activeWalletId, + actions: { + onWalletItemClick: (walletId: string) => { + actions.sidebar.walletSelected.trigger({ walletId }); + }, + }, + }, + } + : null; const sidebarComponent = ( { }} isSynced openDialogAction={actions.dialogs.open.trigger} - onAddWallet={() => actions.router.goToRoute.trigger({ route: ROUTES.WALLETS.ADD })} - onSubmitSupportRequest={ - () => actions.router.goToRoute.trigger({ route: ROUTES.SETTINGS.SUPPORT }) + onAddWallet={() => + actions.router.goToRoute.trigger({ route: ROUTES.WALLETS.ADD }) + } + onSubmitSupportRequest={() => + actions.router.goToRoute.trigger({ route: ROUTES.SETTINGS.SUPPORT }) } pathname={this.props.stores.router.location.pathname} /> ); - const addNodeUpdateNotification = ( - isUpdateAvailable && !isUpdatePostponed ? : null - ); + const addNodeUpdateNotification = + isUpdateAvailable && !isUpdatePostponed ? : null; return ( { ); } - } diff --git a/source/renderer/app/containers/Root.js b/source/renderer/app/containers/Root.js index 638a8fbeae..01af4052a3 100644 --- a/source/renderer/app/containers/Root.js +++ b/source/renderer/app/containers/Root.js @@ -7,9 +7,9 @@ import type { InjectedContainerProps } from '../types/injectedPropsType'; type Props = InjectedContainerProps; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class Root extends Component { - render() { const { stores, actions, children } = this.props; const { networkStatus, profile, adaRedemption, app, wallets } = stores; @@ -18,8 +18,11 @@ export default class Root extends Component { const { isAdaRedemptionPage } = adaRedemption; const { hasLoadedWallets } = wallets; const { - isSynced, isNodeStopping, isNodeStopped, - isSystemTimeCorrect, isNotEnoughDiskSpace, + isSynced, + isNodeStopping, + isNodeStopped, + isSystemTimeCorrect, + isNotEnoughDiskSpace, } = networkStatus; const isPageThatDoesntNeedWallets = ( diff --git a/source/renderer/app/containers/TopBarContainer.js b/source/renderer/app/containers/TopBarContainer.js index d4aaa722a8..e8f014417f 100644 --- a/source/renderer/app/containers/TopBarContainer.js +++ b/source/renderer/app/containers/TopBarContainer.js @@ -12,26 +12,34 @@ import { ROUTES } from '../routes-config'; type Props = InjectedProps; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class TopBarContainer extends Component { - static defaultProps = { actions: null, stores: null }; render() { const { actions, stores } = this.props; const { sidebar, app, networkStatus, wallets } = stores; const { active, isWalletRoute, hasAnyWallets } = wallets; - const { currentRoute, environment: { isMainnet, network } } = app; - - const walletRoutesMatch = matchRoute(`${ROUTES.WALLETS.ROOT}/:id(*page)`, currentRoute); + const { + currentRoute, + environment: { isMainnet, network }, + } = app; + + const walletRoutesMatch = matchRoute( + `${ROUTES.WALLETS.ROOT}/:id(*page)`, + currentRoute + ); const showSubMenuToggle = isWalletRoute && hasAnyWallets; const activeWallet = walletRoutesMatch && active != null ? active : null; - const leftIconSVG = sidebar.isShowingSubMenus ? menuIconOpened : menuIconClosed; + const leftIconSVG = sidebar.isShowingSubMenus + ? menuIconOpened + : menuIconClosed; const leftIcon = showSubMenuToggle ? leftIconSVG : null; - const testnetLabel = ( - !isMainnet ? : null - ); + const testnetLabel = !isMainnet ? ( + + ) : null; return ( { ); } - } diff --git a/source/renderer/app/containers/notifications/NodeUpdatePage.js b/source/renderer/app/containers/notifications/NodeUpdatePage.js index 49574d615e..0516924981 100755 --- a/source/renderer/app/containers/notifications/NodeUpdatePage.js +++ b/source/renderer/app/containers/notifications/NodeUpdatePage.js @@ -4,9 +4,9 @@ import { observer, inject } from 'mobx-react'; import NodeUpdateNotification from '../../components/notifications/NodeUpdateNotification'; import type { InjectedProps } from '../../types/injectedPropsType'; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class NodeUpdatePage extends Component { - static defaultProps = { actions: null, stores: null }; render() { diff --git a/source/renderer/app/containers/profile/DataLayerMigrationPage.js b/source/renderer/app/containers/profile/DataLayerMigrationPage.js index 2d3356b7a3..143dcca80a 100644 --- a/source/renderer/app/containers/profile/DataLayerMigrationPage.js +++ b/source/renderer/app/containers/profile/DataLayerMigrationPage.js @@ -5,9 +5,9 @@ import CenteredLayout from '../../components/layout/CenteredLayout'; import DataLayerMigrationForm from '../../components/profile/data-layer-migration/DataLayerMigrationForm'; import type { InjectedProps } from '../../types/injectedPropsType'; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class DataLayerMigrationPage extends Component { - static defaultProps = { actions: null, stores: null }; onSubmit = () => { @@ -15,7 +15,9 @@ export default class DataLayerMigrationPage extends Component { }; render() { - const { setDataLayerMigrationAcceptanceRequest } = this.props.stores.profile; + const { + setDataLayerMigrationAcceptanceRequest, + } = this.props.stores.profile; return ( { - static defaultProps = { actions: null, stores: null }; onSubmit = async (values: { locale: string }) => { @@ -19,13 +19,16 @@ export default class LanguageSelectionPage extends Component { render() { const { currentRoute } = this.props.stores.app; - const { setProfileLocaleRequest, LANGUAGE_OPTIONS } = this.props.stores.profile; + const { + setProfileLocaleRequest, + LANGUAGE_OPTIONS, + } = this.props.stores.profile; const isSubmitting = setProfileLocaleRequest.isExecuting; - const topbar = ; + const topbar = ( + + ); return ( - + { - static defaultProps = { actions: null, stores: null }; onSubmit = () => { @@ -16,14 +16,17 @@ export default class TermsOfUsePage extends Component { }; render() { - const { setTermsOfUseAcceptanceRequest, termsOfUse } = this.props.stores.profile; + const { + setTermsOfUseAcceptanceRequest, + termsOfUse, + } = this.props.stores.profile; const { currentRoute } = this.props.stores.app; const isSubmitting = setTermsOfUseAcceptanceRequest.isExecuting; - const topbar = ; + const topbar = ( + + ); return ( - + { - static defaultProps = { actions: null, stores: null }; isActivePage = (route: string) => { @@ -24,15 +24,13 @@ export default class Settings extends Component { const { actions, children } = this.props; const menu = ( actions.router.goToRoute.trigger({ route })} + onItemClick={route => actions.router.goToRoute.trigger({ route })} isActiveItem={this.isActivePage} /> ); return ( - - {children} - + {children} ); } diff --git a/source/renderer/app/containers/settings/categories/DisplaySettingsPage.js b/source/renderer/app/containers/settings/categories/DisplaySettingsPage.js index d6e1ef302d..35be94a300 100644 --- a/source/renderer/app/containers/settings/categories/DisplaySettingsPage.js +++ b/source/renderer/app/containers/settings/categories/DisplaySettingsPage.js @@ -4,9 +4,9 @@ import { inject, observer } from 'mobx-react'; import DisplaySettings from '../../../components/settings/categories/DisplaySettings'; import type { InjectedProps } from '../../../types/injectedPropsType'; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class DisplaySettingsPage extends Component { - static defaultProps = { actions: null, stores: null }; selectTheme = (values: { theme: string }) => { @@ -17,11 +17,7 @@ export default class DisplaySettingsPage extends Component { const { currentTheme } = this.props.stores.profile; return ( - + ); } - } diff --git a/source/renderer/app/containers/settings/categories/GeneralSettingsPage.js b/source/renderer/app/containers/settings/categories/GeneralSettingsPage.js index 2812312041..de7d08a9be 100644 --- a/source/renderer/app/containers/settings/categories/GeneralSettingsPage.js +++ b/source/renderer/app/containers/settings/categories/GeneralSettingsPage.js @@ -5,9 +5,9 @@ import GeneralSettings from '../../../components/settings/categories/GeneralSett import { rebuildApplicationMenu } from '../../../ipc/rebuild-application-menu.js'; import type { InjectedProps } from '../../../types/injectedPropsType'; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class GeneralSettingsPage extends Component { - static defaultProps = { actions: null, stores: null }; onSelectLanguage = async (values: { locale: string }) => { @@ -16,7 +16,11 @@ export default class GeneralSettingsPage extends Component { }; render() { - const { setProfileLocaleRequest, LANGUAGE_OPTIONS, currentLocale } = this.props.stores.profile; + const { + setProfileLocaleRequest, + LANGUAGE_OPTIONS, + currentLocale, + } = this.props.stores.profile; const isSubmitting = setProfileLocaleRequest.isExecuting; return ( { /> ); } - } diff --git a/source/renderer/app/containers/settings/categories/SupportSettingsPage.js b/source/renderer/app/containers/settings/categories/SupportSettingsPage.js index 7eaf2688d5..8c281f5d74 100644 --- a/source/renderer/app/containers/settings/categories/SupportSettingsPage.js +++ b/source/renderer/app/containers/settings/categories/SupportSettingsPage.js @@ -14,7 +14,8 @@ const messages = defineMessages({ supportRequestLinkUrl: { id: 'settings.support.reportProblem.linkUrl', defaultMessage: '!!!https://iohk.zendesk.com/hc/en-us/requests/new/', - description: '"submit a support request" link URL in the "Report a problem" section on the support settings page.', + description: + '"submit a support request" link URL in the "Report a problem" section on the support settings page.', }, downloadLogsSuccess: { id: 'settings.support.reportProblem.downloadLogsSuccessMessage', @@ -23,9 +24,9 @@ const messages = defineMessages({ }, }); -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class SupportSettingsPage extends Component { - static contextTypes = { intl: intlShape.isRequired, }; @@ -44,10 +45,14 @@ export default class SupportSettingsPage extends Component { this.closeNotification(); } - handleSupportRequestClick = async (event: SyntheticEvent) => { + handleSupportRequestClick = async ( + event: SyntheticEvent + ) => { event.persist(); const { intl } = this.context; - const supportRequestLinkUrl = intl.formatMessage(messages.supportRequestLinkUrl); + const supportRequestLinkUrl = intl.formatMessage( + messages.supportRequestLinkUrl + ); const locale = this.props.stores.profile.currentLocale; const supportUrl = await getSupportUrl(supportRequestLinkUrl, locale); this.props.stores.app.openExternalLink(supportUrl); @@ -88,7 +93,7 @@ export default class SupportSettingsPage extends Component { closeNotification = () => { const { id } = this.notification; this.props.actions.notifications.closeActiveNotification.trigger({ id }); - } + }; render() { const { stores } = this.props; @@ -112,5 +117,4 @@ export default class SupportSettingsPage extends Component { ); } - } diff --git a/source/renderer/app/containers/settings/categories/TermsOfUseSettingsPage.js b/source/renderer/app/containers/settings/categories/TermsOfUseSettingsPage.js index 43da10cc2a..49351dbab5 100644 --- a/source/renderer/app/containers/settings/categories/TermsOfUseSettingsPage.js +++ b/source/renderer/app/containers/settings/categories/TermsOfUseSettingsPage.js @@ -4,16 +4,13 @@ import { observer, inject } from 'mobx-react'; import TermsOfUseSettings from '../../../components/settings/categories/TermsOfUseSettings'; import type { InjectedProps } from '../../../types/injectedPropsType'; -@inject('stores') @observer +@inject('stores') +@observer export default class TermsOfUseSettingsPage extends Component { - static defaultProps = { actions: null, stores: null }; render() { const { termsOfUse } = this.props.stores.profile; - return ( - - ); + return ; } - } diff --git a/source/renderer/app/containers/staking/StakingPage.js b/source/renderer/app/containers/staking/StakingPage.js index 396ecec0fe..6705c155ff 100644 --- a/source/renderer/app/containers/staking/StakingPage.js +++ b/source/renderer/app/containers/staking/StakingPage.js @@ -6,7 +6,6 @@ import Layout from '../MainLayout'; @observer export default class StakingPage extends Component { - render() { return ( @@ -16,5 +15,4 @@ export default class StakingPage extends Component { ); } - } diff --git a/source/renderer/app/containers/static/AboutDialog.js b/source/renderer/app/containers/static/AboutDialog.js index 1099632d91..93a5c56084 100644 --- a/source/renderer/app/containers/static/AboutDialog.js +++ b/source/renderer/app/containers/static/AboutDialog.js @@ -8,9 +8,9 @@ import type { InjectedProps } from '../../types/injectedPropsType'; type Props = InjectedProps; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class AboutDialog extends Component { - static defaultProps = { actions: null, stores: null }; render() { diff --git a/source/renderer/app/containers/status/BlockConsolidationStatusPage.js b/source/renderer/app/containers/status/BlockConsolidationStatusPage.js index 08940f5f69..325549b93e 100644 --- a/source/renderer/app/containers/status/BlockConsolidationStatusPage.js +++ b/source/renderer/app/containers/status/BlockConsolidationStatusPage.js @@ -5,9 +5,9 @@ import type { InjectedProps } from '../../types/injectedPropsType'; import BlockConsolidationStatus from '../../components/status/BlockConsolidationStatus'; import { EPOCH_DATA_UPDATE_INTERVAL } from '../../config/timingConfig'; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class BlockConsolidationStatusPage extends Component { - pollingInterval: ?IntervalID = null; componentWillMount() { @@ -45,5 +45,4 @@ export default class BlockConsolidationStatusPage extends Component ); } - } diff --git a/source/renderer/app/containers/status/NetworkStatusDialog.js b/source/renderer/app/containers/status/NetworkStatusDialog.js index 9f85c988ab..0fcaa6b4ee 100644 --- a/source/renderer/app/containers/status/NetworkStatusDialog.js +++ b/source/renderer/app/containers/status/NetworkStatusDialog.js @@ -8,9 +8,9 @@ import type { InjectedProps } from '../../types/injectedPropsType'; type Props = InjectedProps; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class NetworkStatusDialog extends Component { - static defaultProps = { actions: null, stores: null }; render() { @@ -20,14 +20,29 @@ export default class NetworkStatusDialog extends Component { const { openExternalLink } = app; const { // Node state - cardanoNodeState, isNodeResponding, isNodeSubscribed, - isNodeSyncing, isNodeInSync, isNodeTimeCorrect, + cardanoNodeState, + isNodeResponding, + isNodeSubscribed, + isNodeSyncing, + isNodeInSync, + isNodeTimeCorrect, // Application state - isConnected, isSynced, syncPercentage, hasBeenConnected, - localTimeDifference, isSystemTimeCorrect, forceCheckTimeDifferenceRequest, - forceCheckLocalTimeDifference, getNetworkStatusRequest, - localBlockHeight, networkBlockHeight, latestLocalBlockTimestamp, latestNetworkBlockTimestamp, - restartNode, isSystemTimeIgnored, environment, + isConnected, + isSynced, + syncPercentage, + hasBeenConnected, + localTimeDifference, + isSystemTimeCorrect, + forceCheckTimeDifferenceRequest, + forceCheckLocalTimeDifference, + getNetworkStatusRequest, + localBlockHeight, + networkBlockHeight, + latestLocalBlockTimestamp, + latestNetworkBlockTimestamp, + restartNode, + isSystemTimeIgnored, + environment, } = networkStatus; return ( @@ -61,7 +76,8 @@ export default class NetworkStatusDialog extends Component { latestLocalBlockTimestamp={latestLocalBlockTimestamp} latestNetworkBlockTimestamp={latestNetworkBlockTimestamp} nodeConnectionError={ - getNetworkStatusRequest.error || forceCheckTimeDifferenceRequest.error + getNetworkStatusRequest.error || + forceCheckTimeDifferenceRequest.error } localBlockHeight={localBlockHeight} networkBlockHeight={networkBlockHeight} @@ -73,5 +89,4 @@ export default class NetworkStatusDialog extends Component { ); } - } diff --git a/source/renderer/app/containers/wallet/AdaRedemptionPage.js b/source/renderer/app/containers/wallet/AdaRedemptionPage.js index 092f2918c5..c9218ec09c 100644 --- a/source/renderer/app/containers/wallet/AdaRedemptionPage.js +++ b/source/renderer/app/containers/wallet/AdaRedemptionPage.js @@ -13,9 +13,9 @@ import { ROUTES } from '../../routes-config'; type Props = InjectedProps; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class AdaRedemptionPage extends Component { - static defaultProps = { actions: null, stores: null }; constructor(props: Props) { @@ -40,19 +40,38 @@ export default class AdaRedemptionPage extends Component { }; render() { - const { wallets, adaRedemption, app: { environment } } = this.props.stores; + const { + wallets, + adaRedemption, + app: { environment }, + } = this.props.stores; const { isMainnet } = environment; const { - redeemAdaRequest, redeemPaperVendedAdaRequest, isCertificateEncrypted, isValidRedemptionKey, - redemptionType, isValidRedemptionMnemonic, isValidPaperVendRedemptionKey, - isRedemptionDisclaimerAccepted, error + redeemAdaRequest, + redeemPaperVendedAdaRequest, + isCertificateEncrypted, + isValidRedemptionKey, + redemptionType, + isValidRedemptionMnemonic, + isValidPaperVendRedemptionKey, + isRedemptionDisclaimerAccepted, + error, } = adaRedemption; const { - chooseRedemptionType, setCertificate, setPassPhrase, setRedemptionCode, removeCertificate, - setEmail, setAdaPasscode, setAdaAmount, setDecryptionKey, acceptRedemptionDisclaimer + chooseRedemptionType, + setCertificate, + setPassPhrase, + setRedemptionCode, + removeCertificate, + setEmail, + setAdaPasscode, + setAdaAmount, + setDecryptionKey, + acceptRedemptionDisclaimer, } = this.props.actions.adaRedemption; - const selectableWallets = wallets.all.map((w) => ({ - value: w.id, label: w.name + const selectableWallets = wallets.all.map(w => ({ + value: w.id, + label: w.name, })); if (!wallets.all.length) { @@ -65,41 +84,55 @@ export default class AdaRedemptionPage extends Component { ); } - if (selectableWallets.length === 0) return ; + if (selectableWallets.length === 0) + return ( + + + + ); - const request = (redemptionType === ADA_REDEMPTION_TYPES.PAPER_VENDED ? - redeemPaperVendedAdaRequest : redeemAdaRequest - ); + const request = + redemptionType === ADA_REDEMPTION_TYPES.PAPER_VENDED + ? redeemPaperVendedAdaRequest + : redeemAdaRequest; const isCertificateSelected = adaRedemption.certificate !== null; - const showInputsForDecryptingForceVendedCertificate = ( - isCertificateSelected && isCertificateEncrypted && - redemptionType === ADA_REDEMPTION_TYPES.FORCE_VENDED - ); - const showInputForDecryptionKey = ( - isCertificateSelected && isCertificateEncrypted && - redemptionType === ADA_REDEMPTION_TYPES.RECOVERY_FORCE_VENDED - ); - const showPassPhraseWidget = redemptionType === ADA_REDEMPTION_TYPES.PAPER_VENDED || ( - isCertificateSelected && isCertificateEncrypted && ( - redemptionType === ADA_REDEMPTION_TYPES.REGULAR || - redemptionType === ADA_REDEMPTION_TYPES.RECOVERY_REGULAR - ) - ); + const showInputsForDecryptingForceVendedCertificate = + isCertificateSelected && + isCertificateEncrypted && + redemptionType === ADA_REDEMPTION_TYPES.FORCE_VENDED; + const showInputForDecryptionKey = + isCertificateSelected && + isCertificateEncrypted && + redemptionType === ADA_REDEMPTION_TYPES.RECOVERY_FORCE_VENDED; + const showPassPhraseWidget = + redemptionType === ADA_REDEMPTION_TYPES.PAPER_VENDED || + (isCertificateSelected && + isCertificateEncrypted && + (redemptionType === ADA_REDEMPTION_TYPES.REGULAR || + redemptionType === ADA_REDEMPTION_TYPES.RECOVERY_REGULAR)); return ( setCertificate.trigger({ certificate })} - onPassPhraseChanged={(passPhrase) => setPassPhrase.trigger({ passPhrase })} - onRedemptionCodeChanged={(redemptionCode) => { + onCertificateSelected={certificate => + setCertificate.trigger({ certificate }) + } + onPassPhraseChanged={passPhrase => + setPassPhrase.trigger({ passPhrase }) + } + onRedemptionCodeChanged={redemptionCode => { setRedemptionCode.trigger({ redemptionCode }); }} - onEmailChanged={(email) => setEmail.trigger({ email })} - onAdaAmountChanged={(adaAmount) => setAdaAmount.trigger({ adaAmount })} - onAdaPasscodeChanged={(adaPasscode) => setAdaPasscode.trigger({ adaPasscode })} - onDecryptionKeyChanged={(decryptionKey) => setDecryptionKey.trigger({ decryptionKey })} - onChooseRedemptionType={(choice) => { + onEmailChanged={email => setEmail.trigger({ email })} + onAdaAmountChanged={adaAmount => setAdaAmount.trigger({ adaAmount })} + onAdaPasscodeChanged={adaPasscode => + setAdaPasscode.trigger({ adaPasscode }) + } + onDecryptionKeyChanged={decryptionKey => + setDecryptionKey.trigger({ decryptionKey }) + } + onChooseRedemptionType={choice => { chooseRedemptionType.trigger({ redemptionType: choice }); }} redemptionCode={adaRedemption.redemptionCode} @@ -107,13 +140,17 @@ export default class AdaRedemptionPage extends Component { suggestedMnemonics={validWords} isCertificateSelected={isCertificateSelected} isCertificateEncrypted={isCertificateEncrypted} - isCertificateInvalid={error instanceof AdaRedemptionCertificateParseError} + isCertificateInvalid={ + error instanceof AdaRedemptionCertificateParseError + } isSubmitting={request.isExecuting} error={adaRedemption.error} onRemoveCertificate={removeCertificate.trigger} - onSubmit={(redemptionType === ADA_REDEMPTION_TYPES.PAPER_VENDED ? - this.onSubmitPaperVended : this.onSubmit - )} + onSubmit={ + redemptionType === ADA_REDEMPTION_TYPES.PAPER_VENDED + ? this.onSubmitPaperVended + : this.onSubmit + } mnemonicValidator={isValidRedemptionMnemonic} redemptionCodeValidator={isValidRedemptionKey} postVendRedemptionCodeValidator={isValidPaperVendRedemptionKey} @@ -123,8 +160,12 @@ export default class AdaRedemptionPage extends Component { } showInputForDecryptionKey={showInputForDecryptionKey} showPassPhraseWidget={showPassPhraseWidget} - isRedemptionDisclaimerAccepted={isMainnet || isRedemptionDisclaimerAccepted} - onAcceptRedemptionDisclaimer={() => acceptRedemptionDisclaimer.trigger()} + isRedemptionDisclaimerAccepted={ + isMainnet || isRedemptionDisclaimerAccepted + } + onAcceptRedemptionDisclaimer={() => + acceptRedemptionDisclaimer.trigger() + } getSelectedWallet={walletId => wallets.getWalletById(walletId)} /> diff --git a/source/renderer/app/containers/wallet/PaperWalletCreateCertificatePage.js b/source/renderer/app/containers/wallet/PaperWalletCreateCertificatePage.js index 721035ddcc..1d79bcc940 100644 --- a/source/renderer/app/containers/wallet/PaperWalletCreateCertificatePage.js +++ b/source/renderer/app/containers/wallet/PaperWalletCreateCertificatePage.js @@ -21,13 +21,17 @@ type State = { showConfirmationDialog: boolean, }; -@inject('actions', 'stores') @observer -export default class PaperWalletCreateCertificatePage extends Component { - +@inject('actions', 'stores') +@observer +export default class PaperWalletCreateCertificatePage extends Component< + Props, + State +> { static defaultProps = { actions: null, stores: null }; componentWillReceiveProps(nextProps: Props) { - const stepChanged = nextProps.stores.wallets.certificateStep !== this.state.currentStep; + const stepChanged = + nextProps.stores.wallets.certificateStep !== this.state.currentStep; if (nextProps.stores.wallets.certificateStep && stepChanged) { this.onContinue(nextProps.stores.wallets.certificateStep); } @@ -89,11 +93,7 @@ export default class PaperWalletCreateCertificatePage extends Component - ); + activeDialog = ; } return ( diff --git a/source/renderer/app/containers/wallet/Wallet.js b/source/renderer/app/containers/wallet/Wallet.js index 43cda06da7..5eb20e1675 100644 --- a/source/renderer/app/containers/wallet/Wallet.js +++ b/source/renderer/app/containers/wallet/Wallet.js @@ -14,15 +14,18 @@ import { WalletSyncStateTags } from '../../domains/Wallet'; type Props = InjectedContainerProps; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class Wallet extends Component { - static defaultProps = { actions: null, stores: null }; isActiveScreen = (page: string) => { const { app, wallets } = this.props.stores; if (!wallets.active) return false; - const screenRoute = buildRoute(ROUTES.WALLETS.PAGE, { id: wallets.active.id, page }); + const screenRoute = buildRoute(ROUTES.WALLETS.PAGE, { + id: wallets.active.id, + page, + }); return app.currentRoute === screenRoute; }; @@ -41,11 +44,25 @@ export default class Wallet extends Component { const { showAdaRedemptionSuccessMessage, amountRedeemed } = adaRedemption; const { currentLocale } = profile; - if (!wallets.active) return ; + if (!wallets.active) + return ( + + + + ); - const isRestoreActive = get(wallets.active, 'syncState.tag') === WalletSyncStateTags.RESTORING; - const restoreProgress = get(wallets.active, 'syncState.data.percentage.quantity', 0); - const restoreETA = get(wallets.active, 'syncState.data.estimatedCompletionTime.quantity', 0); + const isRestoreActive = + get(wallets.active, 'syncState.tag') === WalletSyncStateTags.RESTORING; + const restoreProgress = get( + wallets.active, + 'syncState.data.percentage.quantity', + 0 + ); + const restoreETA = get( + wallets.active, + 'syncState.data.estimatedCompletionTime.quantity', + 0 + ); return ( @@ -67,7 +84,9 @@ export default class Wallet extends Component { {showAdaRedemptionSuccessMessage ? ( ) : null} diff --git a/source/renderer/app/containers/wallet/WalletAddPage.js b/source/renderer/app/containers/wallet/WalletAddPage.js index b8b4ea46a6..a21ca32a3c 100644 --- a/source/renderer/app/containers/wallet/WalletAddPage.js +++ b/source/renderer/app/containers/wallet/WalletAddPage.js @@ -15,9 +15,9 @@ import type { InjectedProps } from '../../types/injectedPropsType'; type Props = InjectedProps; -@inject('actions', 'stores') @observer +@inject('actions', 'stores') +@observer export default class WalletAddPage extends Component { - static defaultProps = { actions: null, stores: null }; onClose = () => { @@ -28,7 +28,9 @@ export default class WalletAddPage extends Component { const { actions, stores } = this.props; const { wallets, uiDialogs, app } = stores; const { isRestoreActive } = wallets; - const { environment: { isMainnet, isTestnet } } = app; + const { + environment: { isMainnet, isTestnet }, + } = app; let content = null; @@ -45,9 +47,15 @@ export default class WalletAddPage extends Component { actions.dialogs.open.trigger({ dialog: WalletCreateDialog })} - onRestore={() => actions.dialogs.open.trigger({ dialog: WalletRestoreDialog })} - onImportFile={() => actions.dialogs.open.trigger({ dialog: WalletFileImportDialog })} + onCreate={() => + actions.dialogs.open.trigger({ dialog: WalletCreateDialog }) + } + onRestore={() => + actions.dialogs.open.trigger({ dialog: WalletRestoreDialog }) + } + onImportFile={() => + actions.dialogs.open.trigger({ dialog: WalletFileImportDialog }) + } isRestoreActive={isRestoreActive} isMaxNumberOfWalletsReached={wallets.hasMaxWallets} /> @@ -55,5 +63,4 @@ export default class WalletAddPage extends Component { } return {content}; } - } diff --git a/source/renderer/app/containers/wallet/WalletReceivePage.js b/source/renderer/app/containers/wallet/WalletReceivePage.js index 7158882629..ffa7febd52 100755 --- a/source/renderer/app/containers/wallet/WalletReceivePage.js +++ b/source/renderer/app/containers/wallet/WalletReceivePage.js @@ -25,9 +25,9 @@ type State = { copiedAddress: string, }; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class WalletReceivePage extends Component { - static defaultProps = { actions: null, stores: null }; state = { @@ -60,7 +60,9 @@ export default class WalletReceivePage extends Component { const wallet = wallets.active; if (wallet) { const notificationId = `${wallet.id}-copyNotification`; - this.props.actions.notifications.closeActiveNotification.trigger({ id: notificationId }); + this.props.actions.notifications.closeActiveNotification.trigger({ + id: notificationId, + }); } }; @@ -71,10 +73,13 @@ export default class WalletReceivePage extends Component { const wallet = wallets.active; // Guard against potential null values - if (!wallet) throw new Error('Active wallet required for WalletReceivePage.'); + if (!wallet) + throw new Error('Active wallet required for WalletReceivePage.'); const walletAddress = addresses.active ? addresses.active.id : ''; - const isWalletAddressUsed = addresses.active ? addresses.active.used : false; + const isWalletAddressUsed = addresses.active + ? addresses.active.used + : false; const walletAddresses = addresses.all.slice().reverse(); const notification = { @@ -88,7 +93,7 @@ export default class WalletReceivePage extends Component { copiedAddress, ADDRESS_COPY_NOTIFICATION_ELLIPSIS, ADDRESS_COPY_NOTIFICATION_ELLIPSIS - ) + ), }} /> ), @@ -102,7 +107,7 @@ export default class WalletReceivePage extends Component { isWalletAddressUsed={isWalletAddressUsed} walletAddresses={walletAddresses} onGenerateAddress={this.handleGenerateAddress} - onCopyAddress={(address) => { + onCopyAddress={address => { this.setState({ copiedAddress: address }); actions.notifications.open.trigger({ id: notification.id, @@ -121,7 +126,7 @@ export default class WalletReceivePage extends Component { show={uiNotifications.isOpen(notification.id)} onClose={() => { actions.notifications.closeActiveNotification.trigger({ - id: notification.id + id: notification.id, }); }} clickToClose diff --git a/source/renderer/app/containers/wallet/WalletSendPage.js b/source/renderer/app/containers/wallet/WalletSendPage.js index 8731b0c176..5c73bdb73b 100755 --- a/source/renderer/app/containers/wallet/WalletSendPage.js +++ b/source/renderer/app/containers/wallet/WalletSendPage.js @@ -6,14 +6,17 @@ import { get } from 'lodash'; import WalletSendForm from '../../components/wallet/WalletSendForm'; import type { InjectedProps } from '../../types/injectedPropsType'; import globalMessages from '../../i18n/global-messages'; -import { DECIMAL_PLACES_IN_ADA, MAX_INTEGER_PLACES_IN_ADA } from '../../config/numbersConfig'; +import { + DECIMAL_PLACES_IN_ADA, + MAX_INTEGER_PLACES_IN_ADA, +} from '../../config/numbersConfig'; import { WalletSyncStateTags } from '../../domains/Wallet'; type Props = InjectedProps; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class WalletSendPage extends Component { - static defaultProps = { actions: null, stores: null }; static contextTypes = { @@ -29,9 +32,11 @@ export default class WalletSendPage extends Component { const activeWallet = wallets.active; // Guard against potential null values - if (!activeWallet) throw new Error('Active wallet required for WalletSendPage.'); + if (!activeWallet) + throw new Error('Active wallet required for WalletSendPage.'); - const isRestoreActive = get(activeWallet, 'syncState.tag') === WalletSyncStateTags.RESTORING; + const isRestoreActive = + get(activeWallet, 'syncState.tag') === WalletSyncStateTags.RESTORING; return ( { currencyMaxIntegerDigits={MAX_INTEGER_PLACES_IN_ADA} currencyMaxFractionalDigits={DECIMAL_PLACES_IN_ADA} validateAmount={validateAmount} - calculateTransactionFee={(address: string, amount: number) => ( - calculateTransactionFee({ walletId: activeWallet.id, address, amount }) - )} + calculateTransactionFee={(address: string, amount: number) => + calculateTransactionFee({ + walletId: activeWallet.id, + address, + amount, + }) + } addressValidator={isValidAddress} isDialogOpen={uiDialogs.isOpen} openDialogAction={actions.dialogs.open.trigger} @@ -50,5 +59,4 @@ export default class WalletSendPage extends Component { /> ); } - } diff --git a/source/renderer/app/containers/wallet/WalletSettingsPage.js b/source/renderer/app/containers/wallet/WalletSettingsPage.js index 74fa81d629..89f2e449dd 100644 --- a/source/renderer/app/containers/wallet/WalletSettingsPage.js +++ b/source/renderer/app/containers/wallet/WalletSettingsPage.js @@ -8,17 +8,19 @@ import ChangeSpendingPasswordDialogContainer from './dialogs/settings/ChangeSpen import DeleteWalletDialogContainer from './dialogs/settings/DeleteWalletDialogContainer'; import ExportWalletToFileDialogContainer from './dialogs/settings/ExportWalletToFileDialogContainer'; -type Props = InjectedProps +type Props = InjectedProps; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class WalletSettingsPage extends Component { - static defaultProps = { actions: null, stores: null }; render() { const { uiDialogs, wallets, walletSettings, app } = this.props.stores; const { actions } = this.props; - const { environment: { isProduction } } = app; + const { + environment: { isProduction }, + } = app; const activeWallet = wallets.active; const { WALLET_ASSURANCE_LEVEL_OPTIONS, @@ -34,7 +36,8 @@ export default class WalletSettingsPage extends Component { } = actions.walletSettings; // Guard against potential null values - if (!activeWallet) throw new Error('Active wallet required for WalletSettingsPage.'); + if (!activeWallet) + throw new Error('Active wallet required for WalletSettingsPage.'); return ( { isDialogOpen={uiDialogs.isOpen} walletName={activeWallet.name} isSubmitting={updateWalletRequest.isExecuting} - isInvalid={updateWalletRequest.wasExecuted && updateWalletRequest.result === false} + isInvalid={ + updateWalletRequest.wasExecuted && + updateWalletRequest.result === false + } showExportLink={!isProduction} lastUpdatedField={lastUpdatedWalletField} - onFieldValueChange={(field, value) => updateWalletField.trigger({ field, value })} + onFieldValueChange={(field, value) => + updateWalletField.trigger({ field, value }) + } onStartEditing={field => startEditingWalletField.trigger({ field })} onStopEditing={stopEditingWalletField.trigger} onCancelEditing={cancelEditingWalletField.trigger} @@ -62,5 +70,4 @@ export default class WalletSettingsPage extends Component { /> ); } - } diff --git a/source/renderer/app/containers/wallet/WalletSummaryPage.js b/source/renderer/app/containers/wallet/WalletSummaryPage.js index 7cbcdad00b..3779d73386 100755 --- a/source/renderer/app/containers/wallet/WalletSummaryPage.js +++ b/source/renderer/app/containers/wallet/WalletSummaryPage.js @@ -17,15 +17,16 @@ export const messages = defineMessages({ noTransactions: { id: 'wallet.summary.no.transactions', defaultMessage: '!!!No recent transactions', - description: 'Message shown when wallet has no transactions on wallet summary page.' + description: + 'Message shown when wallet has no transactions on wallet summary page.', }, }); type Props = InjectedProps; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class WalletSummaryPage extends Component { - static defaultProps = { actions: null, stores: null }; static contextTypes = { @@ -42,7 +43,10 @@ export default class WalletSummaryPage extends Component { render() { const { intl } = this.context; const { app, wallets, transactions } = this.props.stores; - const { openExternalLink, environment: { network } } = app; + const { + openExternalLink, + environment: { network }, + } = app; const { hasAny, totalAvailable, @@ -52,14 +56,20 @@ export default class WalletSummaryPage extends Component { } = transactions; const wallet = wallets.active; // Guard against potential null values - if (!wallet) throw new Error('Active wallet required for WalletSummaryPage.'); + if (!wallet) + throw new Error('Active wallet required for WalletSummaryPage.'); let walletTransactions = null; const noTransactionsLabel = intl.formatMessage(messages.noTransactions); - const isRestoreActive = get(wallet, 'syncState.tag') === WalletSyncStateTags.RESTORING; + const isRestoreActive = + get(wallet, 'syncState.tag') === WalletSyncStateTags.RESTORING; - if (recentTransactionsRequest.isExecutingFirstTime || hasAny || isRestoreActive) { + if ( + recentTransactionsRequest.isExecutingFirstTime || + hasAny || + isRestoreActive + ) { walletTransactions = ( { walletId={wallet.id} isRestoreActive={isRestoreActive} formattedWalletAmount={formattedWalletAmount} - showMoreTransactionsButton={recent.length > MAX_TRANSACTIONS_ON_SUMMARY_PAGE} + showMoreTransactionsButton={ + recent.length > MAX_TRANSACTIONS_ON_SUMMARY_PAGE + } network={network} onOpenExternalLink={openExternalLink} onShowMoreTransactions={this.handleShowMoreTransaction} diff --git a/source/renderer/app/containers/wallet/WalletTransactionsPage.js b/source/renderer/app/containers/wallet/WalletTransactionsPage.js index 00f51f14e0..2906e4e229 100755 --- a/source/renderer/app/containers/wallet/WalletTransactionsPage.js +++ b/source/renderer/app/containers/wallet/WalletTransactionsPage.js @@ -15,20 +15,21 @@ export const messages = defineMessages({ noTransactions: { id: 'wallet.transactions.no.transactions', defaultMessage: '!!!No transactions', - description: 'Message shown when wallet has no transactions yet.' + description: 'Message shown when wallet has no transactions yet.', }, noTransactionsFound: { id: 'wallet.transactions.no.transactions.found', defaultMessage: '!!!No transactions found', - description: 'Message shown when wallet transaction search returns zero results.' - } + description: + 'Message shown when wallet transaction search returns zero results.', + }, }); type Props = InjectedProps; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class WalletTransactionsPage extends Component { - static defaultProps = { actions: null, stores: null }; static contextTypes = { @@ -43,7 +44,10 @@ export default class WalletTransactionsPage extends Component { const { intl } = this.context; const { actions, stores } = this.props; const { app, wallets } = stores; - const { openExternalLink, environment: { network } } = app; + const { + openExternalLink, + environment: { network }, + } = app; const activeWallet = wallets.active; const { searchOptions, @@ -62,10 +66,14 @@ export default class WalletTransactionsPage extends Component { let walletTransactions = null; // let transactionSearch = null; const noTransactionsLabel = intl.formatMessage(messages.noTransactions); - const noTransactionsFoundLabel = intl.formatMessage(messages.noTransactionsFound); - const hasMoreToLoad = () => searchLimit !== null && totalAvailable > searchLimit; + const noTransactionsFoundLabel = intl.formatMessage( + messages.noTransactionsFound + ); + const hasMoreToLoad = () => + searchLimit !== null && totalAvailable > searchLimit; - const isRestoreActive = get(activeWallet, 'syncState.tag') === WalletSyncStateTags.RESTORING; + const isRestoreActive = + get(activeWallet, 'syncState.tag') === WalletSyncStateTags.RESTORING; // if (wasSearched || hasAny) { // transactionSearch = ( @@ -79,7 +87,7 @@ export default class WalletTransactionsPage extends Component { // } // Straight away show recent transactions if filtered ones are not loaded yet - const transactions = (recent.length && !filtered.length) ? recent : filtered; + const transactions = recent.length && !filtered.length ? recent : filtered; if (searchRequest.isExecutingFirstTime || hasAny || isRestoreActive) { walletTransactions = ( @@ -98,7 +106,9 @@ export default class WalletTransactionsPage extends Component { /> ); } else if (wasSearched && !hasAny) { - walletTransactions = ; + walletTransactions = ( + + ); } else if (!hasAny) { walletTransactions = ; } @@ -110,5 +120,4 @@ export default class WalletTransactionsPage extends Component { ); } - } diff --git a/source/renderer/app/containers/wallet/dialogs/WalletBackupDialogContainer.js b/source/renderer/app/containers/wallet/dialogs/WalletBackupDialogContainer.js index eae8660b54..7826b2030a 100644 --- a/source/renderer/app/containers/wallet/dialogs/WalletBackupDialogContainer.js +++ b/source/renderer/app/containers/wallet/dialogs/WalletBackupDialogContainer.js @@ -6,10 +6,15 @@ import type { InjectedDialogContainerProps } from '../../../types/injectedPropsT type Props = InjectedDialogContainerProps; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class WalletBackupDialogContainer extends Component { - - static defaultProps = { actions: null, stores: null, children: null, onClose: () => {} }; + static defaultProps = { + actions: null, + stores: null, + children: null, + onClose: () => {}, + }; onCancelBackup = () => { this.props.onClose(); @@ -27,7 +32,7 @@ export default class WalletBackupDialogContainer extends Component { isTermDeviceAccepted, isTermRecoveryAccepted, isPrivacyNoticeAccepted, - currentStep + currentStep, } = stores.walletBackup; const { startWalletBackup, @@ -38,7 +43,7 @@ export default class WalletBackupDialogContainer extends Component { restartWalletBackup, finishWalletBackup, acceptPrivacyNoticeForWalletBackup, - continueToRecoveryPhraseForWalletBackup + continueToRecoveryPhraseForWalletBackup, } = actions.walletBackup; const { createWalletRequest } = stores.wallets; return ( @@ -53,12 +58,19 @@ export default class WalletBackupDialogContainer extends Component { onAcceptPrivacyNotice={acceptPrivacyNoticeForWalletBackup.trigger} onContinue={continueToRecoveryPhraseForWalletBackup.trigger} // Props for WalletRecoveryPhraseDisplayDialog - recoveryPhrase={recoveryPhraseWords.reduce((phrase, { word }) => `${phrase} ${word}`, '')} + recoveryPhrase={recoveryPhraseWords.reduce( + (phrase, { word }) => `${phrase} ${word}`, + '' + )} onStartWalletBackup={startWalletBackup.trigger} // Props for WalletRecoveryPhraseEntryDialog isTermDeviceAccepted={isTermDeviceAccepted} enteredPhrase={enteredPhrase} - canFinishBackup={isRecoveryPhraseValid && isTermDeviceAccepted && isTermRecoveryAccepted} + canFinishBackup={ + isRecoveryPhraseValid && + isTermDeviceAccepted && + isTermRecoveryAccepted + } isTermRecoveryAccepted={isTermRecoveryAccepted} isValid={isRecoveryPhraseValid} isSubmitting={createWalletRequest.isExecuting} diff --git a/source/renderer/app/containers/wallet/dialogs/WalletCreateDialogContainer.js b/source/renderer/app/containers/wallet/dialogs/WalletCreateDialogContainer.js index 0ad750369d..4bec1b2a44 100644 --- a/source/renderer/app/containers/wallet/dialogs/WalletCreateDialogContainer.js +++ b/source/renderer/app/containers/wallet/dialogs/WalletCreateDialogContainer.js @@ -6,10 +6,15 @@ import type { InjectedDialogContainerProps } from '../../../types/injectedPropsT type Props = InjectedDialogContainerProps; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class WalletCreateDialogContainer extends Component { - - static defaultProps = { actions: null, stores: null, children: null, onClose: () => {} }; + static defaultProps = { + actions: null, + stores: null, + children: null, + onClose: () => {}, + }; onSubmit = (values: { name: string, spendingPassword: ?string }) => { this.props.actions.wallets.createWallet.trigger(values); diff --git a/source/renderer/app/containers/wallet/dialogs/WalletFileImportDialogContainer.js b/source/renderer/app/containers/wallet/dialogs/WalletFileImportDialogContainer.js index ea916e6b73..7ba60b8348 100644 --- a/source/renderer/app/containers/wallet/dialogs/WalletFileImportDialogContainer.js +++ b/source/renderer/app/containers/wallet/dialogs/WalletFileImportDialogContainer.js @@ -6,12 +6,21 @@ import type { InjectedDialogContainerProps } from '../../../types/injectedPropsT type Props = InjectedDialogContainerProps; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class WalletFileImportDialogContainer extends Component { + static defaultProps = { + actions: null, + stores: null, + children: null, + onClose: () => {}, + }; - static defaultProps = { actions: null, stores: null, children: null, onClose: () => {} }; - - onSubmit = (values: { filePath: string, spendingPassword: ?string, walletName: ?string }) => { + onSubmit = (values: { + filePath: string, + spendingPassword: ?string, + walletName: ?string, + }) => { this.props.actions.wallets.importWalletFromFile.trigger(values); }; diff --git a/source/renderer/app/containers/wallet/dialogs/WalletRestoreDialogContainer.js b/source/renderer/app/containers/wallet/dialogs/WalletRestoreDialogContainer.js index 2b789814e8..13b1d2e1bd 100644 --- a/source/renderer/app/containers/wallet/dialogs/WalletRestoreDialogContainer.js +++ b/source/renderer/app/containers/wallet/dialogs/WalletRestoreDialogContainer.js @@ -7,10 +7,15 @@ import validWords from '../../../../../common/crypto/valid-words.en'; type Props = InjectedDialogContainerProps; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class WalletRestoreDialogContainer extends Component { - - static defaultProps = { actions: null, stores: null, children: null, onClose: () => {} }; + static defaultProps = { + actions: null, + stores: null, + children: null, + onClose: () => {}, + }; onSubmit = (values: { recoveryPhrase: string, @@ -39,13 +44,14 @@ export default class WalletRestoreDialogContainer extends Component { render() { const { wallets } = this.props.stores; const { - restoreRequest, isValidMnemonic, + restoreRequest, + isValidMnemonic, getWalletRecoveryPhraseFromCertificateRequest, } = wallets; - const error = ( - restoreRequest.error || getWalletRecoveryPhraseFromCertificateRequest.error - ); + const error = + restoreRequest.error || + getWalletRecoveryPhraseFromCertificateRequest.error; return ( { /> ); } - } diff --git a/source/renderer/app/containers/wallet/dialogs/WalletSendConfirmationDialogContainer.js b/source/renderer/app/containers/wallet/dialogs/WalletSendConfirmationDialogContainer.js index 2f21bf7a58..831ad4782d 100644 --- a/source/renderer/app/containers/wallet/dialogs/WalletSendConfirmationDialogContainer.js +++ b/source/renderer/app/containers/wallet/dialogs/WalletSendConfirmationDialogContainer.js @@ -17,9 +17,9 @@ type Props = { onExternalLinkClick: Function, }; -@inject('actions', 'stores') @observer +@inject('actions', 'stores') +@observer export default class WalletSendConfirmationDialogContainer extends Component { - static defaultProps = { actions: null, stores: null }; handleWalletSendFormSubmit = (values: Object) => { @@ -28,13 +28,20 @@ export default class WalletSendConfirmationDialogContainer extends Component ); } - } diff --git a/source/renderer/app/containers/wallet/dialogs/paper-wallet-certificate/CompletionDialogContainer.js b/source/renderer/app/containers/wallet/dialogs/paper-wallet-certificate/CompletionDialogContainer.js index 34f4cf7398..d978a6422c 100644 --- a/source/renderer/app/containers/wallet/dialogs/paper-wallet-certificate/CompletionDialogContainer.js +++ b/source/renderer/app/containers/wallet/dialogs/paper-wallet-certificate/CompletionDialogContainer.js @@ -7,22 +7,26 @@ import { ADDRESS_COPY_NOTIFICATION_SMALL_DURATION } from '../../../../config/tim type Props = InjectedDialogContainerProps; -@inject('stores') @observer +@inject('stores') +@observer export default class CompletionDialogContainer extends Component { - static defaultProps = { actions: null, stores: null, children: null, - onClose: () => {} + onClose: () => {}, }; render() { const { app, wallets } = this.props.stores; - const { environment: { network } } = app; + const { + environment: { network }, + } = app; const { walletCertificateAddress } = wallets; if (!walletCertificateAddress) { - throw new Error('Prop "walletCertificateAddress" is required but was null.'); + throw new Error( + 'Prop "walletCertificateAddress" is required but was null.' + ); } return ( @@ -30,7 +34,9 @@ export default class CompletionDialogContainer extends Component { walletCertificateAddress={walletCertificateAddress} onClose={this.props.onClose} onOpenExternalLink={this.props.stores.app.openExternalLink} - copyAddressNotificationDuration={ADDRESS_COPY_NOTIFICATION_SMALL_DURATION} + copyAddressNotificationDuration={ + ADDRESS_COPY_NOTIFICATION_SMALL_DURATION + } network={network} /> ); diff --git a/source/renderer/app/containers/wallet/dialogs/paper-wallet-certificate/InstructionsDialogContainer.js b/source/renderer/app/containers/wallet/dialogs/paper-wallet-certificate/InstructionsDialogContainer.js index 0dfca40627..8653fe8afe 100644 --- a/source/renderer/app/containers/wallet/dialogs/paper-wallet-certificate/InstructionsDialogContainer.js +++ b/source/renderer/app/containers/wallet/dialogs/paper-wallet-certificate/InstructionsDialogContainer.js @@ -6,18 +6,26 @@ import type { InjectedDialogContainerProps } from '../../../../types/injectedPro type Props = InjectedDialogContainerProps; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class InstructionsDialogContainer extends Component { - static defaultProps = { actions: null, stores: null, children: null, onClose: () => {} }; + static defaultProps = { + actions: null, + stores: null, + children: null, + onClose: () => {}, + }; onPrint = () => { // TODO: refactor this direct access to the dialog api const filePath = global.dialog.showSaveDialog({ defaultPath: 'paper-wallet-certificate.pdf', - filters: [{ - name: 'paper-wallet-certificate', - extensions: ['pdf'], - }], + filters: [ + { + name: 'paper-wallet-certificate', + extensions: ['pdf'], + }, + ], }); // if cancel button is clicked or path is empty @@ -28,7 +36,10 @@ export default class InstructionsDialogContainer extends Component { render() { const { wallets, app } = this.props.stores; - const { openExternalLink, environment: { network } } = app; + const { + openExternalLink, + environment: { network }, + } = app; return ( { - static defaultProps = { actions: null, stores: null, children: null, onClose: () => {} }; + static defaultProps = { + actions: null, + stores: null, + children: null, + onClose: () => {}, + }; onContinue = () => { this.props.actions.wallets.updateCertificateStep.trigger(); @@ -16,10 +22,7 @@ export default class PrintDialogContainer extends Component { render() { return ( - + ); } } diff --git a/source/renderer/app/containers/wallet/dialogs/paper-wallet-certificate/SecuringPasswordDialogContainer.js b/source/renderer/app/containers/wallet/dialogs/paper-wallet-certificate/SecuringPasswordDialogContainer.js index 506dd84e82..b6496e45cc 100644 --- a/source/renderer/app/containers/wallet/dialogs/paper-wallet-certificate/SecuringPasswordDialogContainer.js +++ b/source/renderer/app/containers/wallet/dialogs/paper-wallet-certificate/SecuringPasswordDialogContainer.js @@ -6,14 +6,14 @@ import type { InjectedDialogContainerProps } from '../../../../types/injectedPro type Props = InjectedDialogContainerProps; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class SecuringPasswordDialogContainer extends Component { - static defaultProps = { actions: null, stores: null, children: null, - onClose: () => {} + onClose: () => {}, }; onContinue = () => { diff --git a/source/renderer/app/containers/wallet/dialogs/paper-wallet-certificate/VerificationDialogContainer.js b/source/renderer/app/containers/wallet/dialogs/paper-wallet-certificate/VerificationDialogContainer.js index 92de607846..4c7260ca60 100644 --- a/source/renderer/app/containers/wallet/dialogs/paper-wallet-certificate/VerificationDialogContainer.js +++ b/source/renderer/app/containers/wallet/dialogs/paper-wallet-certificate/VerificationDialogContainer.js @@ -7,14 +7,14 @@ import type { InjectedDialogContainerProps } from '../../../../types/injectedPro type Props = InjectedDialogContainerProps; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class VerificationDialogContainer extends Component { - static defaultProps = { actions: null, stores: null, children: null, - onClose: () => {} + onClose: () => {}, }; onContinue = () => { diff --git a/source/renderer/app/containers/wallet/dialogs/settings/ChangeSpendingPasswordDialogContainer.js b/source/renderer/app/containers/wallet/dialogs/settings/ChangeSpendingPasswordDialogContainer.js index a6335587df..b8bfa41fd9 100644 --- a/source/renderer/app/containers/wallet/dialogs/settings/ChangeSpendingPasswordDialogContainer.js +++ b/source/renderer/app/containers/wallet/dialogs/settings/ChangeSpendingPasswordDialogContainer.js @@ -4,9 +4,9 @@ import { inject, observer } from 'mobx-react'; import ChangeSpendingPasswordDialog from '../../../../components/wallet/settings/ChangeSpendingPasswordDialog'; import type { InjectedProps } from '../../../../types/injectedPropsType'; -@inject('actions', 'stores') @observer +@inject('actions', 'stores') +@observer export default class ChangeSpendingPasswordDialogContainer extends Component { - static defaultProps = { actions: null, stores: null }; render() { @@ -17,7 +17,10 @@ export default class ChangeSpendingPasswordDialogContainer extends Component { @@ -47,5 +52,4 @@ export default class ChangeSpendingPasswordDialogContainer extends Component ); } - } diff --git a/source/renderer/app/containers/wallet/dialogs/settings/DeleteWalletDialogContainer.js b/source/renderer/app/containers/wallet/dialogs/settings/DeleteWalletDialogContainer.js index e2b1d8a7f4..0f1eeada0e 100644 --- a/source/renderer/app/containers/wallet/dialogs/settings/DeleteWalletDialogContainer.js +++ b/source/renderer/app/containers/wallet/dialogs/settings/DeleteWalletDialogContainer.js @@ -6,9 +6,9 @@ import type { InjectedProps } from '../../../../types/injectedPropsType'; type Props = InjectedProps; -@inject('actions', 'stores') @observer +@inject('actions', 'stores') +@observer export default class DeleteWalletDialogContainer extends Component { - static defaultProps = { actions: null, stores: null }; render() { @@ -18,10 +18,15 @@ export default class DeleteWalletDialogContainer extends Component { const { updateDataForActiveDialog } = actions.dialogs; const activeWallet = wallets.active; const { deleteWalletRequest } = wallets; - const { environment: { isTest } } = app; + const { + environment: { isTest }, + } = app; // Guard against potential null values - if (!activeWallet) throw new Error('Active wallet required for DeleteWalletDialogContainer.'); + if (!activeWallet) + throw new Error( + 'Active wallet required for DeleteWalletDialogContainer.' + ); return ( { hasWalletFunds={activeWallet.hasFunds} countdownFn={uiDialogs.countdownSinceDialogOpened} isBackupNoticeAccepted={dialogData.isBackupNoticeAccepted} - onAcceptBackupNotice={() => updateDataForActiveDialog.trigger({ - data: { isBackupNoticeAccepted: true } - })} + onAcceptBackupNotice={() => + updateDataForActiveDialog.trigger({ + data: { isBackupNoticeAccepted: true }, + }) + } onContinue={() => { actions.wallets.deleteWallet.trigger({ walletId: activeWallet.id }); }} @@ -41,12 +48,13 @@ export default class DeleteWalletDialogContainer extends Component { deleteWalletRequest.reset(); }} confirmationValue={dialogData.confirmationValue} - onConfirmationValueChange={confirmationValue => updateDataForActiveDialog.trigger({ - data: { confirmationValue } - })} + onConfirmationValueChange={confirmationValue => + updateDataForActiveDialog.trigger({ + data: { confirmationValue }, + }) + } isSubmitting={deleteWalletRequest.isExecuting} /> ); } - } diff --git a/source/renderer/app/containers/wallet/dialogs/settings/ExportWalletToFileDialogContainer.js b/source/renderer/app/containers/wallet/dialogs/settings/ExportWalletToFileDialogContainer.js index a0ec0508b4..6f6c84afc1 100644 --- a/source/renderer/app/containers/wallet/dialogs/settings/ExportWalletToFileDialogContainer.js +++ b/source/renderer/app/containers/wallet/dialogs/settings/ExportWalletToFileDialogContainer.js @@ -8,19 +8,26 @@ import type { InjectedDialogContainerProps } from '../../../../types/injectedPro type Props = InjectedDialogContainerProps; -@inject('stores', 'actions') @observer +@inject('stores', 'actions') +@observer export default class ExportWalletToFileDialogContainer extends Component { - - static defaultProps = { actions: null, stores: null, children: null, onClose: () => {} }; + static defaultProps = { + actions: null, + stores: null, + children: null, + onClose: () => {}, + }; onSubmit = (params: OnSubmitParams) => { // TODO: refactor this direct access to the dialog api const filePath = global.dialog.showSaveDialog({ defaultPath: 'wallet-export.json', - filters: [{ - name: 'wallet-export', - extensions: ['json'], - }], + filters: [ + { + name: 'wallet-export', + extensions: ['json'], + }, + ], }); const { stores, actions } = this.props; const activeWallet = stores.wallets.active; @@ -28,7 +35,7 @@ export default class ExportWalletToFileDialogContainer extends Component actions.walletSettings.exportToFile.trigger({ walletId: activeWallet.id, filePath, - ...params + ...params, }); }; @@ -58,5 +65,4 @@ export default class ExportWalletToFileDialogContainer extends Component /> ); } - } diff --git a/source/renderer/app/domains/Profile.js b/source/renderer/app/domains/Profile.js index 47af4bbafa..fe7798271d 100644 --- a/source/renderer/app/domains/Profile.js +++ b/source/renderer/app/domains/Profile.js @@ -2,7 +2,6 @@ import { observable } from 'mobx'; export default class Profile { - @observable name: string; @observable email: string; @observable phoneNumber: string; @@ -16,9 +15,8 @@ export default class Profile { phoneNumber: string, passwordHash: string, passwordUpdateDate: Date, - languageLocale: string + languageLocale: string, }) { Object.assign(this, data); } - } diff --git a/source/renderer/app/domains/User.js b/source/renderer/app/domains/User.js index 6a42026475..9cd733ecf0 100644 --- a/source/renderer/app/domains/User.js +++ b/source/renderer/app/domains/User.js @@ -3,7 +3,6 @@ import { observable } from 'mobx'; import Profile from './Profile'; export default class User { - @observable id: string; @observable profile: Profile; @@ -11,5 +10,4 @@ export default class User { this.id = id; this.profile = profile; } - } diff --git a/source/renderer/app/domains/Wallet.js b/source/renderer/app/domains/Wallet.js index b2a329cee4..8c61c1d31a 100644 --- a/source/renderer/app/domains/Wallet.js +++ b/source/renderer/app/domains/Wallet.js @@ -6,22 +6,29 @@ import type { WalletAssuranceLevel, WalletAssuranceMode, WalletSyncState, - SyncStateTag + SyncStateTag, } from '../api/wallets/types'; export const WalletAssuranceModeOptions: { - NORMAL: WalletAssuranceLevel, STRICT: WalletAssuranceLevel, + NORMAL: WalletAssuranceLevel, + STRICT: WalletAssuranceLevel, } = { - NORMAL: 'normal', STRICT: 'strict', + NORMAL: 'normal', + STRICT: 'strict', }; export const WalletSyncStateTags: { - RESTORING: SyncStateTag, SYNCED: SyncStateTag, + RESTORING: SyncStateTag, + SYNCED: SyncStateTag, } = { - RESTORING: 'restoring', SYNCED: 'synced', + RESTORING: 'restoring', + SYNCED: 'synced', }; -const WalletAssuranceModes: { NORMAL: WalletAssuranceMode, STRICT: WalletAssuranceMode } = { +const WalletAssuranceModes: { + NORMAL: WalletAssuranceMode, + STRICT: WalletAssuranceMode, +} = { NORMAL: { low: 3, medium: 9, @@ -29,7 +36,7 @@ const WalletAssuranceModes: { NORMAL: WalletAssuranceMode, STRICT: WalletAssuran STRICT: { low: 5, medium: 15, - } + }, }; export type WalletProps = { @@ -43,7 +50,6 @@ export type WalletProps = { }; export default class Wallet { - id: string = ''; @observable name: string = ''; @observable amount: BigNumber; @@ -57,9 +63,18 @@ export default class Wallet { } @action update(other: Wallet) { - Object.assign(this, pick(other, [ - 'id', 'name', 'amount', 'assurance', 'hasPassword', 'passwordUpdateDate', 'syncState' - ])); + Object.assign( + this, + pick(other, [ + 'id', + 'name', + 'amount', + 'assurance', + 'hasPassword', + 'passwordUpdateDate', + 'syncState', + ]) + ); } @computed get hasFunds(): boolean { @@ -68,10 +83,12 @@ export default class Wallet { @computed get assuranceMode(): WalletAssuranceMode { switch (this.assurance) { - case WalletAssuranceModeOptions.NORMAL: return WalletAssuranceModes.NORMAL; - case WalletAssuranceModeOptions.STRICT: return WalletAssuranceModes.STRICT; - default: return WalletAssuranceModes.NORMAL; + case WalletAssuranceModeOptions.NORMAL: + return WalletAssuranceModes.NORMAL; + case WalletAssuranceModeOptions.STRICT: + return WalletAssuranceModes.STRICT; + default: + return WalletAssuranceModes.NORMAL; } } - } diff --git a/source/renderer/app/domains/WalletAddress.js b/source/renderer/app/domains/WalletAddress.js index a0b58fff4e..cc5923e64c 100644 --- a/source/renderer/app/domains/WalletAddress.js +++ b/source/renderer/app/domains/WalletAddress.js @@ -8,7 +8,6 @@ type Params = { }; export default class WalletAddress { - @observable id: string = ''; @observable used: boolean = false; @observable changeAddress: boolean = false; @@ -16,5 +15,4 @@ export default class WalletAddress { constructor(data: Params) { Object.assign(this, data); } - } diff --git a/source/renderer/app/domains/WalletTransaction.js b/source/renderer/app/domains/WalletTransaction.js index 0e81ea193b..966c726ade 100644 --- a/source/renderer/app/domains/WalletTransaction.js +++ b/source/renderer/app/domains/WalletTransaction.js @@ -6,19 +6,27 @@ import type { TxnAssuranceLevel, TransactionState, TrasactionAddresses, - TransactionType + TransactionType, } from '../api/transactions/types'; export const transactionStates: { - PENDING: TransactionState, FAILED: TransactionState, OK: TransactionState, + PENDING: TransactionState, + FAILED: TransactionState, + OK: TransactionState, } = { - PENDING: 'pending', FAILED: 'failed', OK: 'ok', + PENDING: 'pending', + FAILED: 'failed', + OK: 'ok', }; export const TxnAssuranceLevelOptions: { - LOW: TxnAssuranceLevel, MEDIUM: TxnAssuranceLevel, HIGH: TxnAssuranceLevel, + LOW: TxnAssuranceLevel, + MEDIUM: TxnAssuranceLevel, + HIGH: TxnAssuranceLevel, } = { - LOW: 'low', MEDIUM: 'medium', HIGH: 'high', + LOW: 'low', + MEDIUM: 'medium', + HIGH: 'high', }; export const transactionTypes: { @@ -34,7 +42,6 @@ export const transactionTypes: { }; export class WalletTransaction { - @observable id: string = ''; @observable type: TransactionType; @observable title: string = ''; @@ -68,5 +75,4 @@ export class WalletTransaction { } return TxnAssuranceLevelOptions.HIGH; } - } diff --git a/source/renderer/app/i18n/errors.js b/source/renderer/app/i18n/errors.js index 6f7b2867d4..9998752069 100644 --- a/source/renderer/app/i18n/errors.js +++ b/source/renderer/app/i18n/errors.js @@ -13,7 +13,8 @@ export class AdaRedemptionCertificateParseError extends LocalizableError { constructor() { super({ id: 'global.errors.AdaRedemptionCertificateParseError', - defaultMessage: '!!!The ada redemption code could not be parsed from the given document.', + defaultMessage: + '!!!The ada redemption code could not be parsed from the given document.', }); } } @@ -22,7 +23,8 @@ export class AdaRedemptionEncryptedCertificateParseError extends LocalizableErro constructor() { super({ id: 'global.errors.AdaRedemptionEncryptedCertificateParseError', - defaultMessage: '!!!The ada redemption code could not be parsed, please check your passphrase.', + defaultMessage: + '!!!The ada redemption code could not be parsed, please check your passphrase.', }); } } diff --git a/source/renderer/app/i18n/global-messages.js b/source/renderer/app/i18n/global-messages.js index 5cd0977228..94f8cdc059 100644 --- a/source/renderer/app/i18n/global-messages.js +++ b/source/renderer/app/i18n/global-messages.js @@ -4,72 +4,86 @@ export default defineMessages({ fieldIsRequired: { id: 'global.errors.fieldIsRequired', defaultMessage: '!!!This field is required.', - description: 'Error message when required fields are left empty.' + description: 'Error message when required fields are left empty.', }, incompleteMnemonic: { id: 'global.errors.incompleteMnemonic', defaultMessage: '!!!Please enter all {expected} words.', - description: 'Error message shown when incomplete bip39 mnemonic was entered.' + description: + 'Error message shown when incomplete bip39 mnemonic was entered.', }, invalidMnemonic: { id: 'global.errors.invalidMnemonic', defaultMessage: '!!!Invalid phrase entered, please check.', - description: 'Error message shown when invalid bip39 mnemonic was entered.' + description: 'Error message shown when invalid bip39 mnemonic was entered.', }, invalidEmail: { id: 'global.errors.invalidEmail', defaultMessage: '!!!Invalid email entered, please check.', - description: 'Error message shown when invalid email was entered.' + description: 'Error message shown when invalid email was entered.', }, invalidAdaRedemptionCertificate: { id: 'global.errors.AdaRedemptionCertificateParseError', - defaultMessage: '!!!The ada redemption code could not be parsed from the given document.', - description: 'Error message shown when invalid Ada redemption certificate was uploaded.', + defaultMessage: + '!!!The ada redemption code could not be parsed from the given document.', + description: + 'Error message shown when invalid Ada redemption certificate was uploaded.', }, invalidAdaRedemptionEncryptedCertificate: { id: 'global.errors.AdaRedemptionEncryptedCertificateParseError', - defaultMessage: '!!!The ada redemption code could not be parsed, please check your passphrase.', - description: 'Error message shown when invalid Ada redemption encrypted certificate was uploaded.', + defaultMessage: + '!!!The ada redemption code could not be parsed, please check your passphrase.', + description: + 'Error message shown when invalid Ada redemption encrypted certificate was uploaded.', }, invalidWalletName: { id: 'global.errors.invalidWalletName', - defaultMessage: '!!!Wallet name requires at least 3 and at most 40 letters.', - description: 'Error message shown when invalid wallet name was entered in create wallet dialog.' + defaultMessage: + '!!!Wallet name requires at least 3 and at most 40 letters.', + description: + 'Error message shown when invalid wallet name was entered in create wallet dialog.', }, invalidSpendingPassword: { id: 'global.errors.invalidSpendingPassword', defaultMessage: '!!!Invalid password', - description: 'Error message shown when invalid wallet password was entered in create wallet dialog.' + description: + 'Error message shown when invalid wallet password was entered in create wallet dialog.', }, invalidRepeatPassword: { id: 'global.errors.invalidRepeatPassword', - defaultMessage: '!!!Doesn\'t match.', - description: 'Error message shown when wallet password and repeat passwords don\'t match in create wallet dialog.' + defaultMessage: "!!!Doesn't match.", + description: + "Error message shown when wallet password and repeat passwords don't match in create wallet dialog.", }, passwordInstructions: { id: 'global.passwordInstructions', - defaultMessage: '!!!Note that password needs to be at least 7 characters long, and have at least 1 uppercase, 1 lowercase letter and 1 number.', + defaultMessage: + '!!!Note that password needs to be at least 7 characters long, and have at least 1 uppercase, 1 lowercase letter and 1 number.', description: 'Password instructions note.', }, cancel: { id: 'global.labels.cancel', defaultMessage: '!!!Cancel', - description: 'The word "cancel" reused at several places (like cancel buttons)', + description: + 'The word "cancel" reused at several places (like cancel buttons)', }, change: { id: 'global.labels.change', defaultMessage: '!!!Change', - description: 'The word "change" reused at several places (like change buttons)', + description: + 'The word "change" reused at several places (like change buttons)', }, create: { id: 'global.labels.create', defaultMessage: '!!!Create', - description: 'The word "create" reused at several places (like create buttons)', + description: + 'The word "create" reused at several places (like create buttons)', }, remove: { id: 'global.labels.remove', defaultMessage: '!!!Remove', - description: 'The word "remove" reused at several places (like remove buttons)', + description: + 'The word "remove" reused at several places (like remove buttons)', }, save: { id: 'global.labels.save', @@ -79,81 +93,85 @@ export default defineMessages({ languageEnglish: { id: 'global.language.english', defaultMessage: '!!!English', - description: 'Language name for "English" language.' + description: 'Language name for "English" language.', }, languageJapanese: { id: 'global.language.japanese', defaultMessage: '!!!Japanese', - description: 'Language name for "Japanese" language.' + description: 'Language name for "Japanese" language.', }, languageChinese: { id: 'global.language.chinese', defaultMessage: '!!!Chinese', - description: 'Language name for "Chinese" language.' + description: 'Language name for "Chinese" language.', }, languageKorean: { id: 'global.language.korean', defaultMessage: '!!!Korean', - description: 'Language name for "Korean" language.' + description: 'Language name for "Korean" language.', }, languageGerman: { id: 'global.language.german', defaultMessage: '!!!German', - description: 'Language name for "German" language.' + description: 'Language name for "German" language.', }, languageCroatian: { id: 'global.language.croatian', defaultMessage: '!!!Croatian', - description: 'Language name for "Croatian" language.' + description: 'Language name for "Croatian" language.', }, assuranceLevelNormal: { id: 'global.assuranceLevel.normal', defaultMessage: '!!!Normal', - description: 'Name for "Normal" transaction assurance security level.' + description: 'Name for "Normal" transaction assurance security level.', }, assuranceLevelStrict: { id: 'global.assuranceLevel.strict', defaultMessage: '!!!Strict', - description: 'Name for "Strict" transaction assurance security level.' + description: 'Name for "Strict" transaction assurance security level.', }, unitAda: { id: 'global.unit.ada', defaultMessage: '!!!ADA', - description: 'Name for "ADA" unit.' + description: 'Name for "ADA" unit.', }, recoveryPhraseDialogTitle: { id: 'wallet.backup.recovery.phrase.dialog.title', defaultMessage: '!!!Recovery phrase', - description: 'Title for the "Recovery Phrase" dialog.' + description: 'Title for the "Recovery Phrase" dialog.', }, spendingPasswordLabel: { id: 'global.spendingPasswordLabel', defaultMessage: '!!!Spending Password', - description: 'Label for the "Wallet password" input in the create wallet dialog.', + description: + 'Label for the "Wallet password" input in the create wallet dialog.', }, spendingPasswordPlaceholder: { id: 'global.spendingPasswordPlaceholder', defaultMessage: '!!!Password', - description: 'Placeholder for the "Password" inputs in the create wallet dialog.', + description: + 'Placeholder for the "Password" inputs in the create wallet dialog.', }, dialogButtonContinueLabel: { id: 'global.dialog.button.continue', defaultMessage: '!!!Continue', - description: 'Label "Continue" in dialogs.' + description: 'Label "Continue" in dialogs.', }, faqLinkUrl: { id: 'settings.support.faq.faqLinkURL', - defaultMessage: '!!!https://iohk.zendesk.com/hc/en-us/articles/360011451693', - description: 'URL for the "Known Issues" link in the "Help and support" section on the support settings page', + defaultMessage: + '!!!https://iohk.zendesk.com/hc/en-us/articles/360011451693', + description: + 'URL for the "Known Issues" link in the "Help and support" section on the support settings page', }, currency: { id: 'environment.currency.ada', defaultMessage: '!!!ADA', - description: 'Name for "Ada" unit.' + description: 'Name for "Ada" unit.', }, apiName: { id: 'environment.apiName.cardano', defaultMessage: '!!!Cardano', - description: 'Name for "Cardano" client.' + description: 'Name for "Cardano" client.', }, }); diff --git a/source/renderer/app/i18n/locales/defaultMessages.json b/source/renderer/app/i18n/locales/defaultMessages.json index 27812616ad..d5d0212308 100644 --- a/source/renderer/app/i18n/locales/defaultMessages.json +++ b/source/renderer/app/i18n/locales/defaultMessages.json @@ -34,7 +34,7 @@ "description": "\"There was a problem sending the support request.\" error message", "end": { "column": 3, - "line": 21 + "line": 22 }, "file": "source/renderer/app/api/common/errors.js", "id": "api.errors.ReportRequestError", @@ -48,13 +48,13 @@ "description": "\"This API method is not yet implemented.\" error message.", "end": { "column": 3, - "line": 26 + "line": 27 }, "file": "source/renderer/app/api/common/errors.js", "id": "api.errors.ApiMethodNotYetImplementedError", "start": { "column": 35, - "line": 22 + "line": 23 } }, { @@ -62,13 +62,13 @@ "description": "\"Forbidden Mnemonic: an example Mnemonic has been submitted.\" error message", "end": { "column": 3, - "line": 31 + "line": 34 }, "file": "source/renderer/app/api/common/errors.js", "id": "api.errors.ForbiddenMnemonicError", "start": { "column": 26, - "line": 27 + "line": 28 } } ], @@ -81,7 +81,7 @@ "description": "\"It's not allowed to send money to the same address you are sending from.\" error message.", "end": { "column": 3, - "line": 9 + "line": 11 }, "file": "source/renderer/app/api/transactions/errors.js", "id": "api.errors.NotAllowedToSendMoneyToSameAddressError", @@ -95,13 +95,13 @@ "description": "\"It is not allowed to send money to ada redemption address.\" error message.", "end": { "column": 3, - "line": 14 + "line": 18 }, "file": "source/renderer/app/api/transactions/errors.js", "id": "api.errors.NotAllowedToSendMoneyToRedeemAddressError", "start": { "column": 45, - "line": 10 + "line": 12 } }, { @@ -109,13 +109,13 @@ "description": "\"Not enough money to make this transaction.\" error message.", "end": { "column": 3, - "line": 19 + "line": 23 }, "file": "source/renderer/app/api/transactions/errors.js", "id": "api.errors.NotEnoughMoneyToSendError", "start": { "column": 29, - "line": 15 + "line": 19 } }, { @@ -123,13 +123,13 @@ "description": "\"Your ADA could not be redeemed correctly.\" error message.", "end": { "column": 3, - "line": 24 + "line": 28 }, "file": "source/renderer/app/api/transactions/errors.js", "id": "api.errors.RedeemAdaError", "start": { "column": 18, - "line": 20 + "line": 24 } }, { @@ -137,13 +137,13 @@ "description": "\"All your funds are already at the address you are trying send money to.\" error message.", "end": { "column": 3, - "line": 29 + "line": 35 }, "file": "source/renderer/app/api/transactions/errors.js", "id": "api.errors.AllFundsAlreadyAtReceiverAddressError", "start": { "column": 41, - "line": 25 + "line": 29 } }, { @@ -151,13 +151,13 @@ "description": "\"Not enough ada for fees. Try sending a smaller amount.\" error message", "end": { "column": 3, - "line": 34 + "line": 41 }, "file": "source/renderer/app/api/transactions/errors.js", "id": "api.errors.NotEnoughFundsForTransactionFeesError", "start": { "column": 41, - "line": 30 + "line": 36 } }, { @@ -165,13 +165,13 @@ "description": "\"Not enough ada . Try sending a smaller amount.\" error message", "end": { "column": 3, - "line": 39 + "line": 47 }, "file": "source/renderer/app/api/transactions/errors.js", "id": "api.errors.NotEnoughFundsForTransactionError", "start": { "column": 37, - "line": 35 + "line": 42 } }, { @@ -179,13 +179,13 @@ "description": "\"Cannot calculate fees while there are pending transactions.\" error message", "end": { "column": 3, - "line": 44 + "line": 54 }, "file": "source/renderer/app/api/transactions/errors.js", "id": "api.errors.CanNotCalculateTransactionFeesError", "start": { "column": 39, - "line": 40 + "line": 48 } }, { @@ -193,13 +193,13 @@ "description": "\"Transaction too big due to too many inputs.\" error message.", "end": { "column": 3, - "line": 49 + "line": 59 }, "file": "source/renderer/app/api/transactions/errors.js", "id": "api.errors.TooBigTransactionError", "start": { "column": 26, - "line": 45 + "line": 55 } }, { @@ -207,13 +207,13 @@ "description": "\"Transaction too big due to too many inputs.\" error link label.", "end": { "column": 3, - "line": 54 + "line": 65 }, "file": "source/renderer/app/api/transactions/errors.js", "id": "api.errors.TooBigTransactionErrorLinkLabel", "start": { "column": 35, - "line": 50 + "line": 60 } }, { @@ -221,13 +221,13 @@ "description": "\"Transaction too big due to too many inputs.\" error link URL.", "end": { "column": 3, - "line": 59 + "line": 72 }, "file": "source/renderer/app/api/transactions/errors.js", "id": "api.errors.TooBigTransactionErrorLinkURL", "start": { "column": 33, - "line": 55 + "line": 66 } } ], @@ -240,7 +240,7 @@ "description": "\"Wallet you are trying to restore already exists.\" error message.", "end": { "column": 3, - "line": 9 + "line": 10 }, "file": "source/renderer/app/api/wallets/errors.js", "id": "api.errors.WalletAlreadyRestoredError", @@ -254,13 +254,13 @@ "description": "\"Wallet you are trying to import already exists.\" error message.", "end": { "column": 3, - "line": 14 + "line": 16 }, "file": "source/renderer/app/api/wallets/errors.js", "id": "api.errors.WalletAlreadyImportedError", "start": { "column": 30, - "line": 10 + "line": 11 } }, { @@ -268,13 +268,13 @@ "description": "\"Wallet could not be imported, please make sure you are providing a correct file.\" error message.", "end": { "column": 3, - "line": 19 + "line": 23 }, "file": "source/renderer/app/api/wallets/errors.js", "id": "api.errors.WalletFileImportError", "start": { "column": 25, - "line": 15 + "line": 17 } } ], @@ -371,7 +371,7 @@ "description": "Message \"Unable to start Cardano node. Please submit a support request.\" on the loading screen.", "end": { "column": 3, - "line": 58 + "line": 60 }, "file": "source/renderer/app/components/loading/Loading.js", "id": "loading.screen.unrecoverableCardanoMessage", @@ -385,13 +385,13 @@ "description": "Message \"Connecting to network\" on the loading screen.", "end": { "column": 3, - "line": 63 + "line": 65 }, "file": "source/renderer/app/components/loading/Loading.js", "id": "loading.screen.connectingToNetworkMessage", "start": { "column": 14, - "line": 59 + "line": 61 } }, { @@ -399,13 +399,13 @@ "description": "Message \"Network connection lost - reconnecting\" on the loading screen.", "end": { "column": 3, - "line": 68 + "line": 71 }, "file": "source/renderer/app/components/loading/Loading.js", "id": "loading.screen.reconnectingToNetworkMessage", "start": { "column": 16, - "line": 64 + "line": 66 } }, { @@ -413,13 +413,13 @@ "description": "Message \"Syncing blocks\" on the loading screen.", "end": { "column": 3, - "line": 73 + "line": 76 }, "file": "source/renderer/app/components/loading/Loading.js", "id": "loading.screen.syncingBlocksMessage", "start": { "column": 11, - "line": 69 + "line": 72 } }, { @@ -427,13 +427,13 @@ "description": "Report connecting issue text on the loading screen.", "end": { "column": 3, - "line": 78 + "line": 81 }, "file": "source/renderer/app/components/loading/Loading.js", "id": "loading.screen.reportIssue.connecting.text", "start": { "column": 29, - "line": 74 + "line": 77 } }, { @@ -441,13 +441,13 @@ "description": "Report syncing issue text on the loading screen.", "end": { "column": 3, - "line": 83 + "line": 86 }, "file": "source/renderer/app/components/loading/Loading.js", "id": "loading.screen.reportIssue.syncing.text", "start": { "column": 26, - "line": 79 + "line": 82 } }, { @@ -455,13 +455,13 @@ "description": "Open support ticket button label on the loading.", "end": { "column": 3, - "line": 88 + "line": 91 }, "file": "source/renderer/app/components/loading/Loading.js", "id": "loading.screen.reportIssue.buttonLabel", "start": { "column": 26, - "line": 84 + "line": 87 } }, { @@ -469,13 +469,13 @@ "description": "Download logs button label on the loading.", "end": { "column": 3, - "line": 93 + "line": 96 }, "file": "source/renderer/app/components/loading/Loading.js", "id": "loading.screen.reportIssue.downloadLogsLinkLabel", "start": { "column": 36, - "line": 89 + "line": 92 } } ], @@ -488,7 +488,7 @@ "description": "Content of No disk space overlay", "end": { "column": 3, - "line": 14 + "line": 15 }, "file": "source/renderer/app/components/loading/NoDiskSpaceOverlay.js", "id": "noDiskSpace.error.overlayContent", @@ -502,13 +502,13 @@ "description": "Title of No disk space overlay", "end": { "column": 3, - "line": 19 + "line": 20 }, "file": "source/renderer/app/components/loading/NoDiskSpaceOverlay.js", "id": "noDiskSpace.error.overlayTitle", "start": { "column": 16, - "line": 15 + "line": 16 } } ], @@ -535,7 +535,7 @@ "description": "First paragraph of Sync error overlay", "end": { "column": 3, - "line": 21 + "line": 22 }, "file": "source/renderer/app/components/loading/SystemTimeErrorOverlay.js", "id": "systemTime.error.overlayTextP1", @@ -549,13 +549,13 @@ "description": "Second paragraph of Sync error overlay", "end": { "column": 3, - "line": 26 + "line": 28 }, "file": "source/renderer/app/components/loading/SystemTimeErrorOverlay.js", "id": "systemTime.error.overlayTextP2", "start": { "column": 17, - "line": 22 + "line": 23 } }, { @@ -563,13 +563,13 @@ "description": "Text of Sync error overlay when NTP service is unreachable", "end": { "column": 3, - "line": 31 + "line": 34 }, "file": "source/renderer/app/components/loading/SystemTimeErrorOverlay.js", "id": "systemTime.error.ntpUnreachableTextP1", "start": { "column": 24, - "line": 27 + "line": 29 } }, { @@ -577,13 +577,13 @@ "description": "Text of Sync error overlay when NTP service is unreachable", "end": { "column": 3, - "line": 36 + "line": 40 }, "file": "source/renderer/app/components/loading/SystemTimeErrorOverlay.js", "id": "systemTime.error.ntpUnreachableTextP2", "start": { "column": 24, - "line": 32 + "line": 35 } }, { @@ -591,13 +591,13 @@ "description": "\"Support Portal\" link text", "end": { "column": 3, - "line": 41 + "line": 45 }, "file": "source/renderer/app/components/loading/SystemTimeErrorOverlay.js", "id": "systemTime.error.supportPortalLink", "start": { "column": 21, - "line": 37 + "line": 41 } }, { @@ -605,13 +605,13 @@ "description": "Link to \"Machine clock out of sync with Cardano network\" support page", "end": { "column": 3, - "line": 46 + "line": 52 }, "file": "source/renderer/app/components/loading/SystemTimeErrorOverlay.js", "id": "systemTime.error.supportPortalLinkUrl", "start": { "column": 24, - "line": 42 + "line": 46 } }, { @@ -619,13 +619,13 @@ "description": "Text of Check the time again button", "end": { "column": 3, - "line": 51 + "line": 57 }, "file": "source/renderer/app/components/loading/SystemTimeErrorOverlay.js", "id": "systemTime.error.onCheckTheTimeAgainLink", "start": { "column": 27, - "line": 47 + "line": 53 } }, { @@ -633,13 +633,13 @@ "description": "Text of \"Continue without clock synchronization checks\" button", "end": { "column": 3, - "line": 56 + "line": 63 }, "file": "source/renderer/app/components/loading/SystemTimeErrorOverlay.js", "id": "systemTime.error.onContinueWithoutClockSyncCheckLink", "start": { "column": 39, - "line": 52 + "line": 58 } } ], @@ -652,7 +652,7 @@ "description": "Label \"Update and restart\" on the Cardano node update notification.", "end": { "column": 3, - "line": 17 + "line": 18 }, "file": "source/renderer/app/components/notifications/NodeUpdateNotification.js", "id": "cardano.node.update.notification.accept.button.label", @@ -666,13 +666,13 @@ "description": "Label \"Postpone until restart\" on the Cardano node update notification.", "end": { "column": 3, - "line": 22 + "line": 24 }, "file": "source/renderer/app/components/notifications/NodeUpdateNotification.js", "id": "cardano.node.update.notification.postpone.button.label", "start": { "column": 13, - "line": 18 + "line": 19 } }, { @@ -680,13 +680,13 @@ "description": "Cardano-Core update notification with version.", "end": { "column": 3, - "line": 27 + "line": 29 }, "file": "source/renderer/app/components/notifications/NodeUpdateNotification.js", "id": "cardano.node.update.notification.titleWithVersion", "start": { "column": 20, - "line": 23 + "line": 25 } }, { @@ -694,13 +694,13 @@ "description": "Cardano-Core update notification without version.", "end": { "column": 3, - "line": 32 + "line": 34 }, "file": "source/renderer/app/components/notifications/NodeUpdateNotification.js", "id": "cardano.node.update.notification.titleWithoutVersion", "start": { "column": 23, - "line": 28 + "line": 30 } }, { @@ -708,13 +708,13 @@ "description": "Message shown when there is a Daedalus and Cardano node update available.", "end": { "column": 3, - "line": 37 + "line": 41 }, "file": "source/renderer/app/components/notifications/NodeUpdateNotification.js", "id": "cardano.node.update.notification.message", "start": { "column": 17, - "line": 33 + "line": 35 } } ], @@ -727,7 +727,7 @@ "description": "Status message \"Wallet restore in progress\" shown while wallet is being restored.", "end": { "column": 3, - "line": 16 + "line": 17 }, "file": "source/renderer/app/components/notifications/RestoreNotification.js", "id": "wallet.statusMessages.activeRestore", @@ -760,7 +760,7 @@ "description": "Content for the Data Layer Migration screen.", "end": { "column": 3, - "line": 20 + "line": 21 }, "file": "source/renderer/app/components/profile/data-layer-migration/DataLayerMigrationForm.js", "id": "profile.dataLayerMigration.content1", @@ -774,13 +774,13 @@ "description": "Content for the Data Layer Migration screen.", "end": { "column": 3, - "line": 25 + "line": 27 }, "file": "source/renderer/app/components/profile/data-layer-migration/DataLayerMigrationForm.js", "id": "profile.dataLayerMigration.content2", "start": { "column": 12, - "line": 21 + "line": 22 } }, { @@ -788,13 +788,13 @@ "description": "Content for the Data Layer Migration screen.", "end": { "column": 3, - "line": 30 + "line": 33 }, "file": "source/renderer/app/components/profile/data-layer-migration/DataLayerMigrationForm.js", "id": "profile.dataLayerMigration.content3", "start": { "column": 12, - "line": 26 + "line": 28 } }, { @@ -802,13 +802,13 @@ "description": "Submit label for the Data Layer Migration screen.", "end": { "column": 3, - "line": 35 + "line": 38 }, "file": "source/renderer/app/components/profile/data-layer-migration/DataLayerMigrationForm.js", "id": "profile.dataLayerMigration.submitLabel", "start": { "column": 15, - "line": 31 + "line": 34 } } ], @@ -868,7 +868,7 @@ "description": "Label for the \"I agree with terms of use\" checkbox when terms of use are not translated.", "end": { "column": 3, - "line": 24 + "line": 26 }, "file": "source/renderer/app/components/profile/terms-of-use/TermsOfUseForm.js", "id": "profile.termsOfUse.checkboxLabelWithDisclaimer", @@ -882,13 +882,13 @@ "description": "Label for the \"Terms of use\" form submit button.", "end": { "column": 3, - "line": 29 + "line": 31 }, "file": "source/renderer/app/components/profile/terms-of-use/TermsOfUseForm.js", "id": "profile.termsOfUse.submitLabel", "start": { "column": 15, - "line": 25 + "line": 27 } } ], @@ -901,7 +901,7 @@ "description": "Label for the \"Theme\" selection on the display settings page.", "end": { "column": 3, - "line": 17 + "line": 18 }, "file": "source/renderer/app/components/settings/categories/DisplaySettings.js", "id": "settings.display.themeLabel", @@ -915,13 +915,13 @@ "description": "Name of the \"Light blue\" theme on the display settings page.", "end": { "column": 3, - "line": 22 + "line": 23 }, "file": "source/renderer/app/components/settings/categories/DisplaySettings.js", "id": "settings.display.themeNames.lightBlue", "start": { "column": 18, - "line": 18 + "line": 19 } }, { @@ -929,13 +929,13 @@ "description": "Name of the \"Cardano\" theme on the display settings page.", "end": { "column": 3, - "line": 27 + "line": 28 }, "file": "source/renderer/app/components/settings/categories/DisplaySettings.js", "id": "settings.display.themeNames.cardano", "start": { "column": 16, - "line": 23 + "line": 24 } }, { @@ -943,13 +943,13 @@ "description": "Name of the \"Dark blue\" theme on the display settings page.", "end": { "column": 3, - "line": 32 + "line": 33 }, "file": "source/renderer/app/components/settings/categories/DisplaySettings.js", "id": "settings.display.themeNames.darkBlue", "start": { "column": 17, - "line": 28 + "line": 29 } } ], @@ -995,7 +995,7 @@ "description": "Content for the \"Help and support\" section on the support settings page.", "end": { "column": 3, - "line": 18 + "line": 20 }, "file": "source/renderer/app/components/settings/categories/SupportSettings.js", "id": "settings.support.faq.content", @@ -1009,13 +1009,13 @@ "description": "\"Known Issues\" link in the \"Help and support\" section on the support settings page", "end": { "column": 3, - "line": 23 + "line": 26 }, "file": "source/renderer/app/components/settings/categories/SupportSettings.js", "id": "settings.support.faq.faqLink", "start": { "column": 11, - "line": 19 + "line": 21 } }, { @@ -1023,13 +1023,13 @@ "description": "Title \"Reporting a problem\" on the support settings page.", "end": { "column": 3, - "line": 28 + "line": 31 }, "file": "source/renderer/app/components/settings/categories/SupportSettings.js", "id": "settings.support.reportProblem.title", "start": { "column": 22, - "line": 24 + "line": 27 } }, { @@ -1037,13 +1037,13 @@ "description": "Content for the \"Reporting a problem\" section on the support settings page.", "end": { "column": 3, - "line": 33 + "line": 38 }, "file": "source/renderer/app/components/settings/categories/SupportSettings.js", "id": "settings.support.reportProblem.content", "start": { "column": 24, - "line": 29 + "line": 32 } }, { @@ -1051,13 +1051,13 @@ "description": "\"submit a support request\" link in the \"Report a problem\" section on the support settings page.", "end": { "column": 3, - "line": 38 + "line": 44 }, "file": "source/renderer/app/components/settings/categories/SupportSettings.js", "id": "settings.support.reportProblem.link", "start": { "column": 22, - "line": 34 + "line": 39 } }, { @@ -1065,13 +1065,13 @@ "description": "Title \"Logs\" on the support settings page.", "end": { "column": 3, - "line": 43 + "line": 49 }, "file": "source/renderer/app/components/settings/categories/SupportSettings.js", "id": "settings.support.logs.title", "start": { "column": 13, - "line": 39 + "line": 45 } }, { @@ -1079,13 +1079,13 @@ "description": "Content for the \"Logs\" section on the support settings page.", "end": { "column": 3, - "line": 48 + "line": 55 }, "file": "source/renderer/app/components/settings/categories/SupportSettings.js", "id": "settings.support.logs.content", "start": { "column": 15, - "line": 44 + "line": 50 } }, { @@ -1093,13 +1093,13 @@ "description": "\"download your logs here\" link in the Logs section on the support settings page", "end": { "column": 3, - "line": 53 + "line": 61 }, "file": "source/renderer/app/components/settings/categories/SupportSettings.js", "id": "settings.support.logs.downloadLogsLink", "start": { "column": 20, - "line": 49 + "line": 56 } } ], @@ -1234,7 +1234,7 @@ "description": "About page daedalus team members", "end": { "column": 3, - "line": 30 + "line": 31 }, "file": "source/renderer/app/components/static/About.js", "id": "static.about.content.daedalus.members", @@ -1248,13 +1248,13 @@ "description": "About page cardano team members", "end": { "column": 3, - "line": 35 + "line": 37 }, "file": "source/renderer/app/components/static/About.js", "id": "static.about.content.cardano.members", "start": { "column": 30, - "line": 31 + "line": 32 } }, { @@ -1262,13 +1262,13 @@ "description": "About \"copyright\"", "end": { "column": 3, - "line": 40 + "line": 42 }, "file": "source/renderer/app/components/static/About.js", "id": "static.about.copyright", "start": { "column": 18, - "line": 36 + "line": 38 } }, { @@ -1276,13 +1276,13 @@ "description": "About page license name", "end": { "column": 3, - "line": 45 + "line": 47 }, "file": "source/renderer/app/components/static/About.js", "id": "static.about.license", "start": { "column": 15, - "line": 41 + "line": 43 } }, { @@ -1290,13 +1290,13 @@ "description": "About page build information", "end": { "column": 3, - "line": 50 + "line": 52 }, "file": "source/renderer/app/components/static/About.js", "id": "static.about.buildInfo", "start": { "column": 18, - "line": 46 + "line": 48 } } ], @@ -1337,7 +1337,7 @@ "description": "Description 2 of \"Block consolidation status\" page.", "end": { "column": 3, - "line": 27 + "line": 28 }, "file": "source/renderer/app/components/status/BlockConsolidationStatus.js", "id": "blockConsolidationStatus.description2", @@ -1351,13 +1351,13 @@ "description": "Description 3 of \"Block consolidation status\" page.", "end": { "column": 3, - "line": 32 + "line": 34 }, "file": "source/renderer/app/components/status/BlockConsolidationStatus.js", "id": "blockConsolidationStatus.description3", "start": { "column": 16, - "line": 28 + "line": 29 } }, { @@ -1365,13 +1365,13 @@ "description": "Epochs Consolidated Of Total on \"Block consolidation status\" page.", "end": { "column": 3, - "line": 37 + "line": 41 }, "file": "source/renderer/app/components/status/BlockConsolidationStatus.js", "id": "blockConsolidationStatus.epochsConsolidatedOfTotal", "start": { "column": 29, - "line": 33 + "line": 35 } }, { @@ -1379,13 +1379,13 @@ "description": "Singular Epoch on \"Block consolidation status\" page.", "end": { "column": 3, - "line": 42 + "line": 46 }, "file": "source/renderer/app/components/status/BlockConsolidationStatus.js", "id": "blockConsolidationStatus.epoch", "start": { "column": 9, - "line": 38 + "line": 42 } }, { @@ -1393,13 +1393,13 @@ "description": "Plural Epochs on \"Block consolidation status\" page.", "end": { "column": 3, - "line": 47 + "line": 51 }, "file": "source/renderer/app/components/status/BlockConsolidationStatus.js", "id": "blockConsolidationStatus.epochs", "start": { "column": 10, - "line": 43 + "line": 47 } }, { @@ -1407,13 +1407,13 @@ "description": "Epochs consolidated on \"Block consolidation status\" page.", "end": { "column": 3, - "line": 52 + "line": 56 }, "file": "source/renderer/app/components/status/BlockConsolidationStatus.js", "id": "blockConsolidationStatus.epochsConsolidated", "start": { "column": 22, - "line": 48 + "line": 52 } }, { @@ -1421,13 +1421,13 @@ "description": "synced on \"Block consolidation status\" page.", "end": { "column": 3, - "line": 57 + "line": 61 }, "file": "source/renderer/app/components/status/BlockConsolidationStatus.js", "id": "blockConsolidationStatus.synced", "start": { "column": 10, - "line": 53 + "line": 57 } }, { @@ -1435,13 +1435,13 @@ "description": "Support Button on \"Block consolidation status\" page.", "end": { "column": 3, - "line": 62 + "line": 66 }, "file": "source/renderer/app/components/status/BlockConsolidationStatus.js", "id": "blockConsolidationStatus.supportButton", "start": { "column": 17, - "line": 58 + "line": 62 } }, { @@ -1449,13 +1449,13 @@ "description": "URL of Support Button on \"Block consolidation status\" page.", "end": { "column": 3, - "line": 67 + "line": 72 }, "file": "source/renderer/app/components/status/BlockConsolidationStatus.js", "id": "blockConsolidationStatus.supportButtonURL", "start": { "column": 20, - "line": 63 + "line": 67 } } ], @@ -1557,7 +1557,7 @@ "description": "Disclaimer text for \"Redemption disclaimer\" on Ada redemption page.", "end": { "column": 3, - "line": 23 + "line": 25 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionDisclaimer.js", "id": "wallet.redeem.disclaimerOverlay.disclaimerText", @@ -1571,13 +1571,13 @@ "description": "Label for \"I’ve understood the information above\" checkbox on Ada redemption page \"Redemption disclaimer\".", "end": { "column": 3, - "line": 28 + "line": 31 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionDisclaimer.js", "id": "wallet.redeem.disclaimerOverlay.checkboxLabel", "start": { "column": 17, - "line": 24 + "line": 26 } }, { @@ -1585,13 +1585,13 @@ "description": "Label for \"Continue\" button on Ada redemption page \"Redemption disclaimer\".", "end": { "column": 3, - "line": 33 + "line": 37 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionDisclaimer.js", "id": "wallet.redeem.disclaimerOverlay.submitLabel", "start": { "column": 15, - "line": 29 + "line": 32 } } ], @@ -1604,13 +1604,13 @@ "description": "Headline \"Ada redemption\" dialog.", "end": { "column": 3, - "line": 36 + "line": 40 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.headline", "start": { "column": 12, - "line": 32 + "line": 36 } }, { @@ -1618,13 +1618,13 @@ "description": "Detailed instructions for redeeming ada from the regular vending", "end": { "column": 3, - "line": 41 + "line": 47 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.instructions.regular", "start": { "column": 23, - "line": 37 + "line": 41 } }, { @@ -1632,13 +1632,13 @@ "description": "Detailed instructions for redeeming ada from the force vending", "end": { "column": 3, - "line": 46 + "line": 54 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.instructions.forceVended", "start": { "column": 27, - "line": 42 + "line": 48 } }, { @@ -1646,13 +1646,13 @@ "description": "Detailed instructions for redeeming ada from the regular vending via Recovery service", "end": { "column": 3, - "line": 51 + "line": 61 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.instructions.recoveryRegular", "start": { "column": 31, - "line": 47 + "line": 55 } }, { @@ -1660,13 +1660,13 @@ "description": "Detailed instructions for redeeming ada from the force vending via Recovery service", "end": { "column": 3, - "line": 56 + "line": 68 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.instructions.recoveryForceVended", "start": { "column": 35, - "line": 52 + "line": 62 } }, { @@ -1674,13 +1674,13 @@ "description": "Detailed instructions for redeeming ada from the paper vending", "end": { "column": 3, - "line": 61 + "line": 75 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.instructions.paperVended", "start": { "column": 27, - "line": 57 + "line": 69 } }, { @@ -1688,13 +1688,13 @@ "description": "Label for the certificate file upload", "end": { "column": 3, - "line": 66 + "line": 80 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.certificateLabel", "start": { "column": 20, - "line": 62 + "line": 76 } }, { @@ -1702,13 +1702,13 @@ "description": "Hint for the certificate file upload", "end": { "column": 3, - "line": 71 + "line": 86 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.certificateHint", "start": { "column": 19, - "line": 67 + "line": 81 } }, { @@ -1716,13 +1716,13 @@ "description": "Label for the wallet select field on ada redemption form", "end": { "column": 3, - "line": 76 + "line": 91 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.walletSelectLabel", "start": { "column": 21, - "line": 72 + "line": 87 } }, { @@ -1730,13 +1730,13 @@ "description": "Label for the passphrase to decrypt ada voucher certificate input", "end": { "column": 3, - "line": 81 + "line": 97 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.passphraseLabel", "start": { "column": 19, - "line": 77 + "line": 92 } }, { @@ -1744,13 +1744,13 @@ "description": "Hint for the mnemonic passphrase input", "end": { "column": 3, - "line": 86 + "line": 102 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.passphraseHint", "start": { "column": 18, - "line": 82 + "line": 98 } }, { @@ -1758,13 +1758,13 @@ "description": "\"No results\" message for the passphrase input search results.", "end": { "column": 3, - "line": 91 + "line": 108 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.passphrase.input.noResults", "start": { "column": 23, - "line": 87 + "line": 103 } }, { @@ -1772,13 +1772,13 @@ "description": "Label for ada redemption key input", "end": { "column": 3, - "line": 96 + "line": 113 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.redemptionKeyLabel", "start": { "column": 22, - "line": 92 + "line": 109 } }, { @@ -1786,13 +1786,13 @@ "description": "Label for shielded redemption key input", "end": { "column": 3, - "line": 101 + "line": 118 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.shieldedRedemptionKeyLabel", "start": { "column": 30, - "line": 97 + "line": 114 } }, { @@ -1800,13 +1800,13 @@ "description": "Label for decryption key input", "end": { "column": 3, - "line": 106 + "line": 123 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.decryptionKeyLabel", "start": { "column": 22, - "line": 102 + "line": 119 } }, { @@ -1814,13 +1814,13 @@ "description": "Error \"Invalid redemption key\" for ada redemption code input", "end": { "column": 3, - "line": 111 + "line": 128 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.redemptionCodeError", "start": { "column": 22, - "line": 107 + "line": 124 } }, { @@ -1828,13 +1828,13 @@ "description": "Error \"Invalid shielded vending key\" for ada redemption code input", "end": { "column": 3, - "line": 116 + "line": 134 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.shieldedRedemptionCodeError", "start": { "column": 30, - "line": 112 + "line": 129 } }, { @@ -1842,13 +1842,13 @@ "description": "Hint for ada redemption key input", "end": { "column": 3, - "line": 121 + "line": 139 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.redemptionCodeHint", "start": { "column": 21, - "line": 117 + "line": 135 } }, { @@ -1856,13 +1856,13 @@ "description": "Hint for ada redemption key input shown on Recovery tabs", "end": { "column": 3, - "line": 126 + "line": 144 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.recoveryRedemptionKeyHint", "start": { "column": 29, - "line": 122 + "line": 140 } }, { @@ -1870,13 +1870,13 @@ "description": "Hint for shielded vending key input", "end": { "column": 3, - "line": 131 + "line": 149 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.shieldedRedemptionKeyHint", "start": { "column": 29, - "line": 127 + "line": 145 } }, { @@ -1884,13 +1884,13 @@ "description": "Hint for decryption key input", "end": { "column": 3, - "line": 136 + "line": 154 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.decryptionKeyHint", "start": { "column": 21, - "line": 132 + "line": 150 } }, { @@ -1898,13 +1898,13 @@ "description": "Label for the \"Redeem your money\" dialog submit button.", "end": { "column": 3, - "line": 141 + "line": 159 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.submitLabel", "start": { "column": 15, - "line": 137 + "line": 155 } }, { @@ -1912,13 +1912,13 @@ "description": "Label for the email input field.", "end": { "column": 3, - "line": 146 + "line": 164 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.emailLabel", "start": { "column": 14, - "line": 142 + "line": 160 } }, { @@ -1926,13 +1926,13 @@ "description": "Hint for the email input field.", "end": { "column": 3, - "line": 151 + "line": 169 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.emailHint", "start": { "column": 13, - "line": 147 + "line": 165 } }, { @@ -1940,13 +1940,13 @@ "description": "Label for the ada passcode input field.", "end": { "column": 3, - "line": 156 + "line": 174 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.adaPasscodeLabel", "start": { "column": 20, - "line": 152 + "line": 170 } }, { @@ -1954,13 +1954,13 @@ "description": "Hint for the ada passcode input field.", "end": { "column": 3, - "line": 161 + "line": 179 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.adaPasscodeHint", "start": { "column": 19, - "line": 157 + "line": 175 } }, { @@ -1968,13 +1968,13 @@ "description": "Label for the ada amount input field.", "end": { "column": 3, - "line": 166 + "line": 184 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.adaAmountLabel", "start": { "column": 18, - "line": 162 + "line": 180 } }, { @@ -1982,13 +1982,13 @@ "description": "Hint for the ada amount input field.", "end": { "column": 3, - "line": 171 + "line": 189 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.adaAmountHint", "start": { "column": 17, - "line": 167 + "line": 185 } }, { @@ -1996,13 +1996,13 @@ "description": "Placeholder for \"spending password\"", "end": { "column": 3, - "line": 176 + "line": 194 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.spendingPasswordPlaceholder", "start": { "column": 31, - "line": 172 + "line": 190 } }, { @@ -2010,13 +2010,13 @@ "description": "Label for \"spending password\"", "end": { "column": 3, - "line": 181 + "line": 199 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionForm.js", "id": "wallet.redeem.dialog.spendingPasswordLabel", "start": { "column": 25, - "line": 177 + "line": 195 } } ], @@ -2029,7 +2029,7 @@ "description": "\"No wallets\" headLine on the Ada Redemption Page.", "end": { "column": 3, - "line": 16 + "line": 17 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionNoWallets.js", "id": "wallet.redeem.noWallets.headLine", @@ -2043,13 +2043,13 @@ "description": "\"No wallets\" instructions on the Ada Redemption Page.", "end": { "column": 3, - "line": 21 + "line": 23 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionNoWallets.js", "id": "wallet.redeem.noWallets.instructions", "start": { "column": 16, - "line": 17 + "line": 18 } }, { @@ -2057,13 +2057,13 @@ "description": "URL for the \"FAQ on Daedalus website\" link in the FAQ section on the support settings page", "end": { "column": 3, - "line": 26 + "line": 29 }, "file": "source/renderer/app/components/wallet/ada-redemption/AdaRedemptionNoWallets.js", "id": "wallet.redeem.noWallets.createWalletLink", "start": { "column": 20, - "line": 22 + "line": 24 } } ], @@ -2109,7 +2109,7 @@ "description": "Instructions for backing up wallet recovery phrase on dialog that displays wallet recovery phrase.", "end": { "column": 3, - "line": 22 + "line": 23 }, "file": "source/renderer/app/components/wallet/backup-recovery/WalletBackupPrivacyWarningDialog.js", "id": "wallet.backup.privacy.warning.dialog.recoveryPhraseInstructions", @@ -2123,13 +2123,13 @@ "description": "Label for button \"Continue\" on wallet backup dialog", "end": { "column": 3, - "line": 27 + "line": 28 }, "file": "source/renderer/app/components/wallet/backup-recovery/WalletBackupPrivacyWarningDialog.js", "id": "wallet.backup.privacy.warning.dialog..button.labelContinue", "start": { "column": 23, - "line": 23 + "line": 24 } }, { @@ -2137,13 +2137,13 @@ "description": "Label for the checkbox on wallet backup dialog describing that nobody should be watching when recovery phrase is shown", "end": { "column": 3, - "line": 32 + "line": 35 }, "file": "source/renderer/app/components/wallet/backup-recovery/WalletBackupPrivacyWarningDialog.js", "id": "wallet.backup.privacy.warning.dialog.checkbox.label.nobodyWatching", "start": { "column": 22, - "line": 28 + "line": 29 } } ], @@ -2156,7 +2156,7 @@ "description": "Instructions for backing up wallet recovery phrase on dialog that displays wallet recovery phrase.", "end": { "column": 3, - "line": 19 + "line": 20 }, "file": "source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseDisplayDialog.js", "id": "wallet.backup.recovery.phrase.display.dialog.backup.instructions", @@ -2170,13 +2170,13 @@ "description": "Label for button \"Yes, I’ve written it down\" on wallet backup dialog", "end": { "column": 3, - "line": 24 + "line": 27 }, "file": "source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseDisplayDialog.js", "id": "wallet.backup.recovery.phrase.display.dialog.button.label.iHaveWrittenItDown", "start": { "column": 33, - "line": 20 + "line": 21 } } ], @@ -2189,7 +2189,7 @@ "description": "Instructions for verifying wallet recovery phrase on dialog for entering wallet recovery phrase.", "end": { "column": 3, - "line": 23 + "line": 25 }, "file": "source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseEntryDialog.js", "id": "wallet.backup.recovery.phrase.entry.dialog.verification.instructions", @@ -2203,13 +2203,13 @@ "description": "Label for button \"Confirm\" on wallet backup dialog", "end": { "column": 3, - "line": 28 + "line": 30 }, "file": "source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseEntryDialog.js", "id": "wallet.recovery.phrase.show.entry.dialog.button.labelConfirm", "start": { "column": 22, - "line": 24 + "line": 26 } }, { @@ -2217,13 +2217,13 @@ "description": "Label for button \"Clear\" on wallet backup dialog", "end": { "column": 3, - "line": 33 + "line": 35 }, "file": "source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseEntryDialog.js", "id": "wallet.recovery.phrase.show.entry.dialog.button.labelClear", "start": { "column": 20, - "line": 29 + "line": 31 } }, { @@ -2231,13 +2231,13 @@ "description": "Term and condition on wallet backup dialog describing that wallet is on a users device, not on company servers", "end": { "column": 3, - "line": 38 + "line": 42 }, "file": "source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseEntryDialog.js", "id": "wallet.backup.recovery.phrase.entry.dialog.terms.and.condition.device", "start": { "column": 14, - "line": 34 + "line": 36 } }, { @@ -2245,13 +2245,13 @@ "description": "Term and condition on wallet backup dialog describing that wallet can only be recovered with a security phrase", "end": { "column": 3, - "line": 44 + "line": 50 }, "file": "source/renderer/app/components/wallet/backup-recovery/WalletRecoveryPhraseEntryDialog.js", "id": "wallet.backup.recovery.phrase.entry.dialog.terms.and.condition.recovery", "start": { "column": 16, - "line": 39 + "line": 43 } } ], @@ -2264,13 +2264,13 @@ "description": "headline for \"Import wallet from file\" dialog.", "end": { "column": 3, - "line": 26 + "line": 30 }, "file": "source/renderer/app/components/wallet/file-import/WalletFileImportDialog.js", "id": "wallet.file.import.dialog.headline", "start": { "column": 12, - "line": 22 + "line": 26 } }, { @@ -2278,13 +2278,13 @@ "description": "Label \"Import file\" on the dialog for importing a wallet from a file.", "end": { "column": 3, - "line": 31 + "line": 36 }, "file": "source/renderer/app/components/wallet/file-import/WalletFileImportDialog.js", "id": "wallet.file.import.dialog.walletFileLabel", "start": { "column": 19, - "line": 27 + "line": 31 } }, { @@ -2292,13 +2292,13 @@ "description": "Hint for the file upload field on the dialog for importing a wallet from a file.", "end": { "column": 3, - "line": 36 + "line": 42 }, "file": "source/renderer/app/components/wallet/file-import/WalletFileImportDialog.js", "id": "wallet.file.import.dialog.walletFileHint", "start": { "column": 18, - "line": 32 + "line": 37 } }, { @@ -2306,13 +2306,13 @@ "description": "Label for the \"wallet name\" input in the wallet file import dialog.", "end": { "column": 3, - "line": 41 + "line": 48 }, "file": "source/renderer/app/components/wallet/file-import/WalletFileImportDialog.js", "id": "wallet.file.import.dialog.wallet.name.input.label", "start": { "column": 24, - "line": 37 + "line": 43 } }, { @@ -2320,13 +2320,13 @@ "description": "Hint for the \"Wallet name\" in the wallet file import dialog.", "end": { "column": 3, - "line": 46 + "line": 53 }, "file": "source/renderer/app/components/wallet/file-import/WalletFileImportDialog.js", "id": "wallet.file.import.dialog.wallet.name.input.hint", "start": { "column": 23, - "line": 42 + "line": 49 } }, { @@ -2334,13 +2334,13 @@ "description": "Label \"Import wallet\" submit button on the dialog for importing a wallet from a file.", "end": { "column": 3, - "line": 51 + "line": 59 }, "file": "source/renderer/app/components/wallet/file-import/WalletFileImportDialog.js", "id": "wallet.file.import.dialog.submitLabel", "start": { "column": 15, - "line": 47 + "line": 54 } }, { @@ -2348,13 +2348,13 @@ "description": "Text for the \"Activate to create password\" switch in the wallet file import dialog.", "end": { "column": 3, - "line": 56 + "line": 65 }, "file": "source/renderer/app/components/wallet/file-import/WalletFileImportDialog.js", "id": "wallet.file.import.dialog.passwordSwitchPlaceholder", "start": { "column": 29, - "line": 52 + "line": 60 } }, { @@ -2362,13 +2362,13 @@ "description": "Label for the \"Activate to create password\" switch in the wallet file import dialog.", "end": { "column": 3, - "line": 61 + "line": 71 }, "file": "source/renderer/app/components/wallet/file-import/WalletFileImportDialog.js", "id": "wallet.file.import.dialog.passwordSwitchLabel", "start": { "column": 23, - "line": 57 + "line": 66 } }, { @@ -2376,13 +2376,13 @@ "description": "Label for the \"Wallet password\" input in the wallet file import dialog.", "end": { "column": 3, - "line": 66 + "line": 77 }, "file": "source/renderer/app/components/wallet/file-import/WalletFileImportDialog.js", "id": "wallet.file.import.dialog.spendingPasswordLabel", "start": { "column": 25, - "line": 62 + "line": 72 } }, { @@ -2390,13 +2390,13 @@ "description": "Label for the \"Repeat password\" input in the wallet file import dialog.", "end": { "column": 3, - "line": 71 + "line": 83 }, "file": "source/renderer/app/components/wallet/file-import/WalletFileImportDialog.js", "id": "wallet.file.import.dialog.repeatPasswordLabel", "start": { "column": 23, - "line": 67 + "line": 78 } }, { @@ -2404,13 +2404,13 @@ "description": "Placeholder for the \"Password\" inputs in the wallet file import dialog.", "end": { "column": 3, - "line": 76 + "line": 89 }, "file": "source/renderer/app/components/wallet/file-import/WalletFileImportDialog.js", "id": "wallet.file.import.dialog.passwordFieldPlaceholder", "start": { "column": 28, - "line": 72 + "line": 84 } } ], @@ -2465,7 +2465,7 @@ "description": "Label for the \"Transactions\" nav button in the wallet navigation.", "end": { "column": 3, - "line": 33 + "line": 34 }, "file": "source/renderer/app/components/wallet/navigation/WalletNavigation.js", "id": "wallet.navigation.transactions", @@ -2479,13 +2479,13 @@ "description": "Label for the \"Settings\" nav button in the wallet navigation.", "end": { "column": 3, - "line": 38 + "line": 40 }, "file": "source/renderer/app/components/wallet/navigation/WalletNavigation.js", "id": "wallet.navigation.settings", "start": { "column": 12, - "line": 34 + "line": 35 } } ], @@ -2498,7 +2498,7 @@ "description": "Headline for the \"Paper wallet create certificate completion dialog\" headline.", "end": { "column": 3, - "line": 21 + "line": 22 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/CompletionDialog.js", "id": "paper.wallet.create.certificate.completion.dialog.headline", @@ -2512,13 +2512,13 @@ "description": "Headline for the \"Paper wallet create certificate completion dialog\" subtitle.", "end": { "column": 3, - "line": 26 + "line": 29 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/CompletionDialog.js", "id": "paper.wallet.create.certificate.completion.dialog.subtitle", "start": { "column": 12, - "line": 22 + "line": 23 } }, { @@ -2526,13 +2526,13 @@ "description": "Headline for the \"Paper wallet create certificate completion dialog\" link instructions.", "end": { "column": 3, - "line": 32 + "line": 36 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/CompletionDialog.js", "id": "paper.wallet.create.certificate.completion.dialog.linkInstructions", "start": { "column": 20, - "line": 27 + "line": 30 } }, { @@ -2540,13 +2540,13 @@ "description": "Headline for the \"Paper wallet create certificate completion dialog\" address instructions.", "end": { "column": 3, - "line": 37 + "line": 43 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/CompletionDialog.js", "id": "paper.wallet.create.certificate.completion.dialog.addressInstructions", "start": { "column": 23, - "line": 33 + "line": 37 } }, { @@ -2554,13 +2554,13 @@ "description": "\"Paper wallet create certificate completion dialog\" cardano link label.", "end": { "column": 3, - "line": 42 + "line": 49 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/CompletionDialog.js", "id": "paper.wallet.create.certificate.completion.dialog.cardanoLinkLabel", "start": { "column": 20, - "line": 38 + "line": 44 } }, { @@ -2568,13 +2568,13 @@ "description": "\"Paper wallet create certificate completion dialog\" address copied.", "end": { "column": 3, - "line": 47 + "line": 55 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/CompletionDialog.js", "id": "paper.wallet.create.certificate.completion.dialog.addressCopiedLabel", "start": { "column": 22, - "line": 43 + "line": 50 } }, { @@ -2582,13 +2582,13 @@ "description": "\"Paper wallet create certificate completion dialog\" wallet address label.", "end": { "column": 3, - "line": 52 + "line": 61 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/CompletionDialog.js", "id": "paper.wallet.create.certificate.completion.dialog.addressLabel", "start": { "column": 16, - "line": 48 + "line": 56 } }, { @@ -2596,13 +2596,13 @@ "description": "\"Paper wallet create certificate completion dialog\" finish button label.", "end": { "column": 3, - "line": 57 + "line": 67 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/CompletionDialog.js", "id": "paper.wallet.create.certificate.completion.dialog.finishButtonLabel", "start": { "column": 21, - "line": 53 + "line": 62 } } ], @@ -2615,7 +2615,7 @@ "description": "Headline for the paper wallet certificate cancellation confirmation dialog.", "end": { "column": 3, - "line": 14 + "line": 15 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/ConfirmationDialog.js", "id": "paper.wallet.create.certificate.confirmation.dialog.headline", @@ -2629,13 +2629,13 @@ "description": "Content for the paper wallet certificate cancellation confirmation dialog.", "end": { "column": 3, - "line": 19 + "line": 22 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/ConfirmationDialog.js", "id": "paper.wallet.create.certificate.confirmation.dialog.contentPart1", "start": { "column": 12, - "line": 15 + "line": 16 } }, { @@ -2643,13 +2643,13 @@ "description": "Content for the paper wallet certificate cancellation confirmation dialog.", "end": { "column": 3, - "line": 24 + "line": 29 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/ConfirmationDialog.js", "id": "paper.wallet.create.certificate.confirmation.dialog.contentPart2", "start": { "column": 12, - "line": 20 + "line": 23 } }, { @@ -2657,13 +2657,13 @@ "description": "\"Cancel\" button label for the paper wallet certificate cancellation confirmation dialog.", "end": { "column": 3, - "line": 29 + "line": 35 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/ConfirmationDialog.js", "id": "paper.wallet.create.certificate.confirmation.dialog.button.backLabel", "start": { "column": 21, - "line": 25 + "line": 30 } }, { @@ -2671,13 +2671,13 @@ "description": "\"Abort\" button label for the paper wallet certificate cancellation confirmation dialog.", "end": { "column": 3, - "line": 34 + "line": 41 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/ConfirmationDialog.js", "id": "paper.wallet.create.certificate.confirmation.dialog.button.abortLabel", "start": { "column": 22, - "line": 30 + "line": 36 } } ], @@ -2690,7 +2690,7 @@ "description": "Headline for the \"Paper wallet create certificate instructions dialog\".", "end": { "column": 3, - "line": 22 + "line": 23 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/InstructionsDialog.js", "id": "paper.wallet.create.certificate.instructions.dialog.headline", @@ -2704,13 +2704,13 @@ "description": "Subtitle for the \"Paper wallet create certificate instructions dialog\".", "end": { "column": 3, - "line": 27 + "line": 30 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/InstructionsDialog.js", "id": "paper.wallet.create.certificate.instructions.dialog.subtitle", "start": { "column": 12, - "line": 23 + "line": 24 } }, { @@ -2718,13 +2718,13 @@ "description": "subtitle2 for the \"Paper wallet create certificate instructions dialog\".", "end": { "column": 3, - "line": 32 + "line": 37 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/InstructionsDialog.js", "id": "paper.wallet.create.certificate.instructions.dialog.subtitle2", "start": { "column": 13, - "line": 28 + "line": 31 } }, { @@ -2732,13 +2732,13 @@ "description": "Instructions list label for the \"Paper wallet create certificate instructions dialog\".", "end": { "column": 3, - "line": 37 + "line": 44 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/InstructionsDialog.js", "id": "paper.wallet.create.certificate.instructions.dialog.instructionsList.label", "start": { "column": 25, - "line": 33 + "line": 38 } }, { @@ -2746,13 +2746,13 @@ "description": "Wallet certificate create instructions dialog definition 1.", "end": { "column": 3, - "line": 45 + "line": 53 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/InstructionsDialog.js", "id": "paper.wallet.create.certificate.instructions.dialog.instructionsList.definition1", "start": { "column": 31, - "line": 38 + "line": 45 } }, { @@ -2760,13 +2760,13 @@ "description": "Wallet certificate create instructions dialog definition 2.", "end": { "column": 3, - "line": 52 + "line": 61 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/InstructionsDialog.js", "id": "paper.wallet.create.certificate.instructions.dialog.instructionsList.definition2", "start": { "column": 31, - "line": 46 + "line": 54 } }, { @@ -2774,13 +2774,13 @@ "description": "Wallet certificate create instructions dialog definition 3.", "end": { "column": 3, - "line": 57 + "line": 68 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/InstructionsDialog.js", "id": "paper.wallet.create.certificate.instructions.dialog.instructionsList.definition3", "start": { "column": 31, - "line": 53 + "line": 62 } }, { @@ -2788,13 +2788,13 @@ "description": "Wallet certificate create instructions dialog definition 4.", "end": { "column": 3, - "line": 63 + "line": 75 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/InstructionsDialog.js", "id": "paper.wallet.create.certificate.instructions.dialog.instructionsList.definition4", "start": { "column": 31, - "line": 58 + "line": 69 } }, { @@ -2802,13 +2802,13 @@ "description": "Wallet certificate create instructions dialog definition 5.", "end": { "column": 3, - "line": 68 + "line": 82 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/InstructionsDialog.js", "id": "paper.wallet.create.certificate.instructions.dialog.instructionsList.definition5", "start": { "column": 31, - "line": 64 + "line": 76 } }, { @@ -2816,13 +2816,13 @@ "description": "Wallet certificate create instructions dialog - printing instructions.", "end": { "column": 3, - "line": 75 + "line": 91 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/InstructionsDialog.js", "id": "paper.wallet.create.certificate.instructions.dialog.printingInstructions", "start": { "column": 24, - "line": 69 + "line": 83 } }, { @@ -2830,13 +2830,13 @@ "description": "Wallet certificate create instructions dialog \"Cardano Explorer\" label", "end": { "column": 3, - "line": 80 + "line": 97 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/InstructionsDialog.js", "id": "paper.wallet.create.certificate.instructions.dialog.cardanoExplorer", "start": { "column": 19, - "line": 76 + "line": 92 } }, { @@ -2844,13 +2844,13 @@ "description": "\"Wallet certificate create instructions dialog\" print button label.", "end": { "column": 3, - "line": 85 + "line": 103 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/InstructionsDialog.js", "id": "paper.wallet.create.certificate.instructions.dialog.button.printLabel", "start": { "column": 20, - "line": 81 + "line": 98 } } ], @@ -2863,7 +2863,7 @@ "description": "Headline for the \"Paper wallet create certificate print dialog\".", "end": { "column": 3, - "line": 22 + "line": 23 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/PrintDialog.js", "id": "paper.wallet.create.certificate.print.dialog.headline", @@ -2877,13 +2877,13 @@ "description": "\"Paper wallet create certificate print dialog\" subtitle.", "end": { "column": 3, - "line": 29 + "line": 30 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/PrintDialog.js", "id": "paper.wallet.create.certificate.print.dialog.subtitle", "start": { "column": 12, - "line": 23 + "line": 24 } }, { @@ -2891,13 +2891,13 @@ "description": "\"Paper wallet create certificate print dialog\" info.", "end": { "column": 3, - "line": 36 + "line": 37 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/PrintDialog.js", "id": "paper.wallet.create.certificate.print.dialog.info", "start": { "column": 8, - "line": 30 + "line": 31 } }, { @@ -2905,13 +2905,13 @@ "description": "\"Paper wallet create certificate print dialog\" certificate printed confirmation.", "end": { "column": 3, - "line": 41 + "line": 45 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/PrintDialog.js", "id": "paper.wallet.create.certificate.print.dialog.certificatePrintedConfirmation", "start": { "column": 39, - "line": 37 + "line": 38 } }, { @@ -2919,13 +2919,13 @@ "description": "\"Paper wallet create certificate print dialog\" certificate readable confirmation.", "end": { "column": 3, - "line": 46 + "line": 53 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/PrintDialog.js", "id": "paper.wallet.create.certificate.print.dialog.certificateReadableConfirmation", "start": { "column": 40, - "line": 42 + "line": 46 } }, { @@ -2933,13 +2933,13 @@ "description": "\"Paper wallet create certificate print dialog\" QR scannable confirmation.", "end": { "column": 3, - "line": 51 + "line": 59 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/PrintDialog.js", "id": "paper.wallet.create.certificate.print.dialog.qrScannableConfirmation", "start": { "column": 32, - "line": 47 + "line": 54 } } ], @@ -2952,7 +2952,7 @@ "description": "Headline for the \"Paper wallet create certificate securing password dialog\".", "end": { "column": 3, - "line": 20 + "line": 21 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/SecuringPasswordDialog.js", "id": "paper.wallet.create.certificate.securingPassword.dialog.headline", @@ -2966,13 +2966,13 @@ "description": "\"Paper wallet create certificate securing password dialog\" first info label.", "end": { "column": 3, - "line": 27 + "line": 29 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/SecuringPasswordDialog.js", "id": "paper.wallet.create.certificate.securingPassword.dialog.infoLabel1", "start": { "column": 14, - "line": 21 + "line": 22 } }, { @@ -2980,13 +2980,13 @@ "description": "You may write the remaining words here:", "end": { "column": 3, - "line": 32 + "line": 35 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/SecuringPasswordDialog.js", "id": "paper.wallet.create.certificate.securingPassword.dialog.infoLabel2", "start": { "column": 14, - "line": 28 + "line": 30 } }, { @@ -2994,13 +2994,13 @@ "description": "\"Paper wallet create certificate securing password dialog\" secure password confirmation.", "end": { "column": 3, - "line": 37 + "line": 43 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/SecuringPasswordDialog.js", "id": "paper.wallet.create.certificate.securingPassword.dialog.securingPasswordConfirmation", "start": { "column": 32, - "line": 33 + "line": 36 } } ], @@ -3013,7 +3013,7 @@ "description": "Headline for the \"Paper wallet create certificate verification dialog\".", "end": { "column": 3, - "line": 29 + "line": 30 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/VerificationDialog.js", "id": "paper.wallet.create.certificate.verification.dialog.headline", @@ -3027,13 +3027,13 @@ "description": "\"Paper wallet create certificate verification dialog\" subtitle.", "end": { "column": 3, - "line": 34 + "line": 37 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/VerificationDialog.js", "id": "paper.wallet.create.certificate.verification.dialog.subtitle", "start": { "column": 12, - "line": 30 + "line": 31 } }, { @@ -3041,13 +3041,13 @@ "description": "\"Paper wallet create certificate verification dialog\" subtitle.", "end": { "column": 3, - "line": 40 + "line": 44 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/VerificationDialog.js", "id": "paper.wallet.create.certificate.verification.dialog.instructions", "start": { "column": 16, - "line": 35 + "line": 38 } }, { @@ -3055,13 +3055,13 @@ "description": "\"Paper wallet create certificate verification dialog\" recovery phrase label.", "end": { "column": 3, - "line": 45 + "line": 51 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/VerificationDialog.js", "id": "paper.wallet.create.certificate.verification.dialog.recoveryPhrase.label", "start": { "column": 23, - "line": 41 + "line": 45 } }, { @@ -3069,13 +3069,13 @@ "description": "\"Paper wallet create certificate verification dialog\" recovery phrase hint.", "end": { "column": 3, - "line": 50 + "line": 58 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/VerificationDialog.js", "id": "paper.wallet.create.certificate.verification.dialog.recoveryPhrase.hint", "start": { "column": 22, - "line": 46 + "line": 52 } }, { @@ -3083,13 +3083,13 @@ "description": "\"Paper wallet create certificate verification dialog\" recovery phrase no results label.", "end": { "column": 3, - "line": 55 + "line": 65 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/VerificationDialog.js", "id": "paper.wallet.create.certificate.verification.dialog.recoveryPhrase.noResults", "start": { "column": 27, - "line": 51 + "line": 59 } }, { @@ -3097,13 +3097,13 @@ "description": "\"Paper wallet create certificate verification dialog\" button clear label.", "end": { "column": 3, - "line": 60 + "line": 71 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/VerificationDialog.js", "id": "paper.wallet.create.certificate.verification.dialog.button.clearLabel", "start": { "column": 20, - "line": 56 + "line": 66 } }, { @@ -3111,13 +3111,13 @@ "description": "\"Paper wallet create certificate verification dialog\" storing understandance confirmation.", "end": { "column": 3, - "line": 65 + "line": 79 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/VerificationDialog.js", "id": "paper.wallet.create.certificate.verification.dialog.storingUnderstandanceConfirmationLabel", "start": { "column": 30, - "line": 61 + "line": 72 } }, { @@ -3125,13 +3125,13 @@ "description": "\"Paper wallet create certificate verification dialog\" recovering understandance confirmation.", "end": { "column": 3, - "line": 70 + "line": 87 }, "file": "source/renderer/app/components/wallet/paper-wallet-certificate/VerificationDialog.js", "id": "paper.wallet.create.certificate.verification.dialog.recoveringUnderstandanceConfirmationLabel", "start": { "column": 33, - "line": 66 + "line": 80 } } ], @@ -3144,13 +3144,13 @@ "description": "Label for wallet address on the wallet \"Receive page\"", "end": { "column": 3, - "line": 30 + "line": 33 }, "file": "source/renderer/app/components/wallet/receive/WalletReceive.js", "id": "wallet.receive.page.walletAddressLabel", "start": { "column": 22, - "line": 26 + "line": 29 } }, { @@ -3158,13 +3158,13 @@ "description": "Wallet receive payments instructions on the wallet \"Receive page\"", "end": { "column": 3, - "line": 35 + "line": 40 }, "file": "source/renderer/app/components/wallet/receive/WalletReceive.js", "id": "wallet.receive.page.walletReceiveInstructions", "start": { "column": 29, - "line": 31 + "line": 34 } }, { @@ -3172,13 +3172,13 @@ "description": "Label for \"Generate new address\" button on the wallet \"Receive page\"", "end": { "column": 3, - "line": 40 + "line": 46 }, "file": "source/renderer/app/components/wallet/receive/WalletReceive.js", "id": "wallet.receive.page.generateNewAddressButtonLabel", "start": { "column": 33, - "line": 36 + "line": 41 } }, { @@ -3186,13 +3186,13 @@ "description": "\"Generated addresses\" section title on the wallet \"Receive page\"", "end": { "column": 3, - "line": 45 + "line": 52 }, "file": "source/renderer/app/components/wallet/receive/WalletReceive.js", "id": "wallet.receive.page.generatedAddressesSectionTitle", "start": { "column": 34, - "line": 41 + "line": 47 } }, { @@ -3200,13 +3200,13 @@ "description": "Label for \"show used\" wallet addresses link on the wallet \"Receive page\"", "end": { "column": 3, - "line": 50 + "line": 58 }, "file": "source/renderer/app/components/wallet/receive/WalletReceive.js", "id": "wallet.receive.page.showUsedLabel", "start": { "column": 17, - "line": 46 + "line": 53 } }, { @@ -3214,13 +3214,13 @@ "description": "Placeholder for \"spending password\" on the wallet \"Receive page\"", "end": { "column": 3, - "line": 55 + "line": 64 }, "file": "source/renderer/app/components/wallet/receive/WalletReceive.js", "id": "wallet.receive.page.spendingPasswordPlaceholder", "start": { "column": 31, - "line": 51 + "line": 59 } }, { @@ -3228,13 +3228,13 @@ "description": "Label for \"Copy address\" link on the wallet \"Receive page\"", "end": { "column": 3, - "line": 60 + "line": 69 }, "file": "source/renderer/app/components/wallet/receive/WalletReceive.js", "id": "wallet.receive.page.copyAddressLabel", "start": { "column": 20, - "line": 56 + "line": 65 } } ], @@ -3247,13 +3247,13 @@ "description": "Title for the \"Change wallet password\" dialog when there is no password set.", "end": { "column": 3, - "line": 26 + "line": 30 }, "file": "source/renderer/app/components/wallet/settings/ChangeSpendingPasswordDialog.js", "id": "wallet.settings.changePassword.dialog.title.setPassword", "start": { "column": 26, - "line": 22 + "line": 25 } }, { @@ -3261,13 +3261,13 @@ "description": "Title for the \"Change wallet password\" dialog when there is already password set.", "end": { "column": 3, - "line": 31 + "line": 36 }, "file": "source/renderer/app/components/wallet/settings/ChangeSpendingPasswordDialog.js", "id": "wallet.settings.changePassword.dialog.title.changePassword", "start": { "column": 29, - "line": 27 + "line": 31 } }, { @@ -3275,13 +3275,13 @@ "description": "Label for the \"Spending password\" input in the change wallet password dialog.", "end": { "column": 3, - "line": 36 + "line": 42 }, "file": "source/renderer/app/components/wallet/settings/ChangeSpendingPasswordDialog.js", "id": "wallet.settings.changePassword.dialog.spendingPasswordLabel", "start": { "column": 25, - "line": 32 + "line": 37 } }, { @@ -3289,13 +3289,13 @@ "description": "Label for the \"Current password\" input in the change wallet password dialog.", "end": { "column": 3, - "line": 41 + "line": 48 }, "file": "source/renderer/app/components/wallet/settings/ChangeSpendingPasswordDialog.js", "id": "wallet.settings.changePassword.dialog.currentPasswordLabel", "start": { "column": 24, - "line": 37 + "line": 43 } }, { @@ -3303,13 +3303,13 @@ "description": "Label for the \"New password\" input in the change wallet password dialog.", "end": { "column": 3, - "line": 46 + "line": 54 }, "file": "source/renderer/app/components/wallet/settings/ChangeSpendingPasswordDialog.js", "id": "wallet.settings.changePassword.dialog.newPasswordLabel", "start": { "column": 20, - "line": 42 + "line": 49 } }, { @@ -3317,13 +3317,13 @@ "description": "Label for the \"Repeat password\" input in the change wallet password dialog.", "end": { "column": 3, - "line": 51 + "line": 60 }, "file": "source/renderer/app/components/wallet/settings/ChangeSpendingPasswordDialog.js", "id": "wallet.settings.changePassword.dialog.repeatPasswordLabel", "start": { "column": 23, - "line": 47 + "line": 55 } }, { @@ -3331,13 +3331,13 @@ "description": "Placeholder for the \"Current password\" inputs in the change wallet password dialog.", "end": { "column": 3, - "line": 56 + "line": 66 }, "file": "source/renderer/app/components/wallet/settings/ChangeSpendingPasswordDialog.js", "id": "wallet.settings.changePassword.dialog.currentPasswordFieldPlaceholder", "start": { "column": 35, - "line": 52 + "line": 61 } }, { @@ -3345,13 +3345,13 @@ "description": "Placeholder for the \"New password\" inputs in the change wallet password dialog.", "end": { "column": 3, - "line": 61 + "line": 72 }, "file": "source/renderer/app/components/wallet/settings/ChangeSpendingPasswordDialog.js", "id": "wallet.settings.changePassword.dialog.newPasswordFieldPlaceholder", "start": { "column": 31, - "line": 57 + "line": 67 } }, { @@ -3359,13 +3359,13 @@ "description": "Placeholder for the \"Repeat password\" inputs in the change wallet password dialog.", "end": { "column": 3, - "line": 66 + "line": 78 }, "file": "source/renderer/app/components/wallet/settings/ChangeSpendingPasswordDialog.js", "id": "wallet.settings.changePassword.dialog.repeatPasswordFieldPlaceholder", "start": { "column": 34, - "line": 62 + "line": 73 } }, { @@ -3373,13 +3373,13 @@ "description": "Label for the \"Check to deactivate password\" switch in the change wallet password dialog.", "end": { "column": 3, - "line": 71 + "line": 84 }, "file": "source/renderer/app/components/wallet/settings/ChangeSpendingPasswordDialog.js", "id": "wallet.settings.changePassword.dialog.passwordSwitchLabel", "start": { "column": 23, - "line": 67 + "line": 79 } }, { @@ -3387,13 +3387,13 @@ "description": "Text for the \"Check to deactivate password\" switch in the change wallet password dialog.", "end": { "column": 3, - "line": 76 + "line": 90 }, "file": "source/renderer/app/components/wallet/settings/ChangeSpendingPasswordDialog.js", "id": "wallet.settings.changePassword.dialog.passwordSwitchPlaceholder", "start": { "column": 29, - "line": 72 + "line": 85 } } ], @@ -3439,7 +3439,7 @@ "description": "Label for the \"Delete (x)\" button in the delete wallet dialog.", "end": { "column": 3, - "line": 27 + "line": 28 }, "file": "source/renderer/app/components/wallet/settings/DeleteWalletConfirmationDialog.js", "id": "wallet.settings.delete.dialog.confirmButtonLabel", @@ -3453,13 +3453,13 @@ "description": "Question if the user really wants to delete the wallet.", "end": { "column": 3, - "line": 32 + "line": 34 }, "file": "source/renderer/app/components/wallet/settings/DeleteWalletConfirmationDialog.js", "id": "wallet.settings.delete.dialog.wantToDeleteWalletQuestion", "start": { "column": 30, - "line": 28 + "line": 29 } }, { @@ -3467,13 +3467,13 @@ "description": "Notice to confirm if the user has made a backup of his wallet", "end": { "column": 3, - "line": 37 + "line": 41 }, "file": "source/renderer/app/components/wallet/settings/DeleteWalletConfirmationDialog.js", "id": "wallet.settings.delete.dialog.confirmBackupNotice", "start": { "column": 23, - "line": 33 + "line": 35 } }, { @@ -3481,13 +3481,13 @@ "description": "Instruction for recovery word on delete wallet dialog", "end": { "column": 3, - "line": 42 + "line": 46 }, "file": "source/renderer/app/components/wallet/settings/DeleteWalletConfirmationDialog.js", "id": "wallet.settings.delete.dialog.enterRecoveryWordLabel", "start": { "column": 26, - "line": 38 + "line": 42 } } ], @@ -3514,7 +3514,7 @@ "description": "headline for \"export wallet to file\" dialog.", "end": { "column": 3, - "line": 28 + "line": 29 }, "file": "source/renderer/app/components/wallet/settings/ExportWalletToFileDialog.js", "id": "wallet.settings.exportToFile.dialog.introduction", @@ -3528,13 +3528,13 @@ "description": "Label for export wallet to file submit button.", "end": { "column": 3, - "line": 33 + "line": 34 }, "file": "source/renderer/app/components/wallet/settings/ExportWalletToFileDialog.js", "id": "wallet.settings.exportToFile.dialog.submit.label", "start": { "column": 21, - "line": 29 + "line": 30 } } ], @@ -3547,7 +3547,7 @@ "description": "Label for the \"+ 12.042481 of fees\" message above amount input field.", "end": { "column": 3, - "line": 13 + "line": 14 }, "file": "source/renderer/app/components/wallet/skins/AmountInputSkin.js", "id": "wallet.amountInput.feesLabel", @@ -3641,7 +3641,7 @@ "description": "Transaction type shown for money exchanges between currencies.", "end": { "column": 3, - "line": 37 + "line": 38 }, "file": "source/renderer/app/components/wallet/transactions/Transaction.js", "id": "wallet.transaction.type.exchange", @@ -3655,13 +3655,13 @@ "description": "Transaction assurance level.", "end": { "column": 3, - "line": 42 + "line": 43 }, "file": "source/renderer/app/components/wallet/transactions/Transaction.js", "id": "wallet.transaction.assuranceLevel", "start": { "column": 18, - "line": 38 + "line": 39 } }, { @@ -3669,13 +3669,13 @@ "description": "Transaction confirmations.", "end": { "column": 3, - "line": 47 + "line": 48 }, "file": "source/renderer/app/components/wallet/transactions/Transaction.js", "id": "wallet.transaction.confirmations", "start": { "column": 17, - "line": 43 + "line": 44 } }, { @@ -3683,13 +3683,13 @@ "description": "Transaction ID.", "end": { "column": 3, - "line": 52 + "line": 53 }, "file": "source/renderer/app/components/wallet/transactions/Transaction.js", "id": "wallet.transaction.transactionId", "start": { "column": 17, - "line": 48 + "line": 49 } }, { @@ -3697,13 +3697,13 @@ "description": "Conversion rate.", "end": { "column": 3, - "line": 57 + "line": 58 }, "file": "source/renderer/app/components/wallet/transactions/Transaction.js", "id": "wallet.transaction.conversion.rate", "start": { "column": 18, - "line": 53 + "line": 54 } }, { @@ -3711,13 +3711,13 @@ "description": "Label \"{currency} sent\" for the transaction.", "end": { "column": 3, - "line": 62 + "line": 63 }, "file": "source/renderer/app/components/wallet/transactions/Transaction.js", "id": "wallet.transaction.sent", "start": { "column": 8, - "line": 58 + "line": 59 } }, { @@ -3725,13 +3725,13 @@ "description": "Label \"{currency} received\" for the transaction.", "end": { "column": 3, - "line": 67 + "line": 68 }, "file": "source/renderer/app/components/wallet/transactions/Transaction.js", "id": "wallet.transaction.received", "start": { "column": 12, - "line": 63 + "line": 64 } }, { @@ -3739,13 +3739,13 @@ "description": "From address", "end": { "column": 3, - "line": 72 + "line": 73 }, "file": "source/renderer/app/components/wallet/transactions/Transaction.js", "id": "wallet.transaction.address.from", "start": { "column": 15, - "line": 68 + "line": 69 } }, { @@ -3753,13 +3753,13 @@ "description": "From addresses", "end": { "column": 3, - "line": 77 + "line": 78 }, "file": "source/renderer/app/components/wallet/transactions/Transaction.js", "id": "wallet.transaction.addresses.from", "start": { "column": 17, - "line": 73 + "line": 74 } }, { @@ -3767,13 +3767,13 @@ "description": "To address", "end": { "column": 3, - "line": 82 + "line": 83 }, "file": "source/renderer/app/components/wallet/transactions/Transaction.js", "id": "wallet.transaction.address.to", "start": { "column": 13, - "line": 78 + "line": 79 } }, { @@ -3781,13 +3781,13 @@ "description": "To addresses", "end": { "column": 3, - "line": 87 + "line": 88 }, "file": "source/renderer/app/components/wallet/transactions/Transaction.js", "id": "wallet.transaction.addresses.to", "start": { "column": 15, - "line": 83 + "line": 84 } }, { @@ -3795,13 +3795,13 @@ "description": "Transaction amount.", "end": { "column": 3, - "line": 92 + "line": 93 }, "file": "source/renderer/app/components/wallet/transactions/Transaction.js", "id": "wallet.transaction.transactionAmount", "start": { "column": 21, - "line": 88 + "line": 89 } }, { @@ -3809,13 +3809,13 @@ "description": "Transaction assurance level \"low\".", "end": { "column": 3, - "line": 100 + "line": 101 }, "file": "source/renderer/app/components/wallet/transactions/Transaction.js", "id": "wallet.transaction.assuranceLevel.low", "start": { "column": 34, - "line": 96 + "line": 97 } }, { @@ -3823,13 +3823,13 @@ "description": "Transaction assurance level \"medium\".", "end": { "column": 3, - "line": 105 + "line": 106 }, "file": "source/renderer/app/components/wallet/transactions/Transaction.js", "id": "wallet.transaction.assuranceLevel.medium", "start": { "column": 37, - "line": 101 + "line": 102 } }, { @@ -3837,13 +3837,13 @@ "description": "Transaction assurance level \"high\".", "end": { "column": 3, - "line": 110 + "line": 111 }, "file": "source/renderer/app/components/wallet/transactions/Transaction.js", "id": "wallet.transaction.assuranceLevel.high", "start": { "column": 35, - "line": 106 + "line": 107 } }, { @@ -3851,13 +3851,13 @@ "description": "Transaction state \"pending\"", "end": { "column": 3, - "line": 118 + "line": 119 }, "file": "source/renderer/app/components/wallet/transactions/Transaction.js", "id": "wallet.transaction.state.pending", "start": { "column": 31, - "line": 114 + "line": 115 } }, { @@ -3865,13 +3865,13 @@ "description": "Transaction state \"pending\"", "end": { "column": 3, - "line": 123 + "line": 124 }, "file": "source/renderer/app/components/wallet/transactions/Transaction.js", "id": "wallet.transaction.state.failed", "start": { "column": 30, - "line": 119 + "line": 120 } } ], @@ -3912,7 +3912,7 @@ "description": "Label for the \"Show more transactions\" button on the wallet summary page.", "end": { "column": 3, - "line": 37 + "line": 38 }, "file": "source/renderer/app/components/wallet/transactions/WalletTransactionsList.js", "id": "wallet.summary.page.showMoreTransactionsButtonLabel", @@ -3926,13 +3926,13 @@ "description": "Syncing transactions message on async wallet restore.", "end": { "column": 3, - "line": 42 + "line": 44 }, "file": "source/renderer/app/components/wallet/transactions/WalletTransactionsList.js", "id": "wallet.summary.page.syncingTransactionsMessage", "start": { "column": 30, - "line": 38 + "line": 39 } } ], @@ -3973,7 +3973,7 @@ "description": "Description for the \"Create\" button on the wallet add dialog.", "end": { "column": 3, - "line": 29 + "line": 30 }, "file": "source/renderer/app/components/wallet/WalletAdd.js", "id": "wallet.add.dialog.create.description", @@ -3987,13 +3987,13 @@ "description": "Label for the \"Join\" button on the wallet add dialog.", "end": { "column": 3, - "line": 34 + "line": 35 }, "file": "source/renderer/app/components/wallet/WalletAdd.js", "id": "wallet.add.dialog.join.label", "start": { "column": 13, - "line": 30 + "line": 31 } }, { @@ -4001,13 +4001,13 @@ "description": "Description for the \"Join\" button on the wallet add dialog.", "end": { "column": 3, - "line": 39 + "line": 40 }, "file": "source/renderer/app/components/wallet/WalletAdd.js", "id": "wallet.add.dialog.join.description", "start": { "column": 19, - "line": 35 + "line": 36 } }, { @@ -4015,13 +4015,13 @@ "description": "Label for the \"Restore\" button on the wallet add dialog.", "end": { "column": 3, - "line": 44 + "line": 45 }, "file": "source/renderer/app/components/wallet/WalletAdd.js", "id": "wallet.add.dialog.restore.label", "start": { "column": 16, - "line": 40 + "line": 41 } }, { @@ -4029,13 +4029,13 @@ "description": "Description for the \"Restore\" button with paper wallet certificate on the wallet add dialog.", "end": { "column": 3, - "line": 49 + "line": 52 }, "file": "source/renderer/app/components/wallet/WalletAdd.js", "id": "wallet.add.dialog.restore.withCertificate.description", "start": { "column": 37, - "line": 45 + "line": 46 } }, { @@ -4043,13 +4043,13 @@ "description": "Description for the \"Restore\" button without paper wallet certificate on the wallet add dialog.", "end": { "column": 3, - "line": 54 + "line": 58 }, "file": "source/renderer/app/components/wallet/WalletAdd.js", "id": "wallet.add.dialog.restore.withoutCertificate.description", "start": { "column": 40, - "line": 50 + "line": 53 } }, { @@ -4057,13 +4057,13 @@ "description": "Label for the \"Import\" button on the wallet add dialog.", "end": { "column": 3, - "line": 59 + "line": 63 }, "file": "source/renderer/app/components/wallet/WalletAdd.js", "id": "wallet.add.dialog.import.label", "start": { "column": 15, - "line": 55 + "line": 59 } }, { @@ -4071,13 +4071,13 @@ "description": "Description for the \"Import\" button on the wallet add dialog.", "end": { "column": 3, - "line": 64 + "line": 69 }, "file": "source/renderer/app/components/wallet/WalletAdd.js", "id": "wallet.add.dialog.import.description", "start": { "column": 21, - "line": 60 + "line": 64 } }, { @@ -4085,13 +4085,13 @@ "description": "Restore notification message shown during async wallet restore on the wallet add screen.", "end": { "column": 3, - "line": 69 + "line": 76 }, "file": "source/renderer/app/components/wallet/WalletAdd.js", "id": "wallet.add.dialog.restoreNotificationMessage", "start": { "column": 30, - "line": 65 + "line": 70 } }, { @@ -4099,13 +4099,13 @@ "description": "\"Maximum number of wallets reached\" notification message shown on the wallet add screen if user has 50 wallets.", "end": { "column": 3, - "line": 74 + "line": 83 }, "file": "source/renderer/app/components/wallet/WalletAdd.js", "id": "wallet.add.dialog.maxNumberOfWalletsNotificationMessage", "start": { "column": 41, - "line": 70 + "line": 77 } } ], @@ -4118,13 +4118,13 @@ "description": "Title \"Create a new wallet\" in the wallet create form.", "end": { "column": 3, - "line": 25 + "line": 29 }, "file": "source/renderer/app/components/wallet/WalletCreateDialog.js", "id": "wallet.create.dialog.title", "start": { "column": 15, - "line": 21 + "line": 25 } }, { @@ -4132,13 +4132,13 @@ "description": "Label for the \"Wallet Name\" text input in the wallet create form.", "end": { "column": 3, - "line": 30 + "line": 35 }, "file": "source/renderer/app/components/wallet/WalletCreateDialog.js", "id": "wallet.create.dialog.name.label", "start": { "column": 14, - "line": 26 + "line": 30 } }, { @@ -4146,13 +4146,13 @@ "description": "Hint for the \"Wallet Name\" text input in the wallet create form.", "end": { "column": 3, - "line": 35 + "line": 41 }, "file": "source/renderer/app/components/wallet/WalletCreateDialog.js", "id": "wallet.create.dialog.walletNameHint", "start": { "column": 18, - "line": 31 + "line": 36 } }, { @@ -4160,13 +4160,13 @@ "description": "Label for the \"Create personal wallet\" button on create wallet dialog.", "end": { "column": 3, - "line": 40 + "line": 47 }, "file": "source/renderer/app/components/wallet/WalletCreateDialog.js", "id": "wallet.create.dialog.create.personal.wallet.button.label", "start": { "column": 24, - "line": 36 + "line": 42 } }, { @@ -4174,13 +4174,13 @@ "description": "Text for the \"Activate to create password\" switch in the create wallet dialog.", "end": { "column": 3, - "line": 45 + "line": 54 }, "file": "source/renderer/app/components/wallet/WalletCreateDialog.js", "id": "wallet.create.dialog.passwordSwitchPlaceholder", "start": { "column": 29, - "line": 41 + "line": 48 } }, { @@ -4188,13 +4188,13 @@ "description": "Label for the \"Activate to create password\" switch in the create wallet dialog.", "end": { "column": 3, - "line": 50 + "line": 60 }, "file": "source/renderer/app/components/wallet/WalletCreateDialog.js", "id": "wallet.create.dialog.passwordSwitchLabel", "start": { "column": 23, - "line": 46 + "line": 55 } }, { @@ -4202,13 +4202,13 @@ "description": "Label for the \"Wallet password\" input in the create wallet dialog.", "end": { "column": 3, - "line": 55 + "line": 66 }, "file": "source/renderer/app/components/wallet/WalletCreateDialog.js", "id": "wallet.create.dialog.spendingPasswordLabel", "start": { "column": 25, - "line": 51 + "line": 61 } }, { @@ -4216,13 +4216,13 @@ "description": "Label for the \"Repeat password\" input in the create wallet dialog.", "end": { "column": 3, - "line": 60 + "line": 72 }, "file": "source/renderer/app/components/wallet/WalletCreateDialog.js", "id": "wallet.create.dialog.repeatPasswordLabel", "start": { "column": 23, - "line": 56 + "line": 67 } }, { @@ -4230,13 +4230,13 @@ "description": "Placeholder for the \"Password\" inputs in the create wallet dialog.", "end": { "column": 3, - "line": 65 + "line": 78 }, "file": "source/renderer/app/components/wallet/WalletCreateDialog.js", "id": "wallet.create.dialog.passwordFieldPlaceholder", "start": { "column": 28, - "line": 61 + "line": 73 } } ], @@ -4249,13 +4249,13 @@ "description": "Label \"Restore wallet\" on the wallet restore dialog.", "end": { "column": 3, - "line": 35 + "line": 42 }, "file": "source/renderer/app/components/wallet/WalletRestoreDialog.js", "id": "wallet.restore.dialog.title.label", "start": { "column": 9, - "line": 31 + "line": 38 } }, { @@ -4263,13 +4263,13 @@ "description": "Label for the wallet name input on the wallet restore dialog.", "end": { "column": 3, - "line": 40 + "line": 48 }, "file": "source/renderer/app/components/wallet/WalletRestoreDialog.js", "id": "wallet.restore.dialog.wallet.name.input.label", "start": { "column": 24, - "line": 36 + "line": 43 } }, { @@ -4277,13 +4277,13 @@ "description": "Hint \"Name the wallet you are restoring\" for the wallet name input on the wallet restore dialog.", "end": { "column": 3, - "line": 45 + "line": 54 }, "file": "source/renderer/app/components/wallet/WalletRestoreDialog.js", "id": "wallet.restore.dialog.wallet.name.input.hint", "start": { "column": 23, - "line": 41 + "line": 49 } }, { @@ -4291,13 +4291,13 @@ "description": "Label for the recovery phrase input on the wallet restore dialog.", "end": { "column": 3, - "line": 50 + "line": 60 }, "file": "source/renderer/app/components/wallet/WalletRestoreDialog.js", "id": "wallet.restore.dialog.recovery.phrase.input.label", "start": { "column": 28, - "line": 46 + "line": 55 } }, { @@ -4305,13 +4305,13 @@ "description": "Hint \"Enter recovery phrase\" for the recovery phrase input on the wallet restore dialog.", "end": { "column": 3, - "line": 55 + "line": 66 }, "file": "source/renderer/app/components/wallet/WalletRestoreDialog.js", "id": "wallet.restore.dialog.recovery.phrase.input.hint", "start": { "column": 27, - "line": 51 + "line": 61 } }, { @@ -4319,13 +4319,13 @@ "description": "\"No results\" message for the recovery phrase input search results.", "end": { "column": 3, - "line": 60 + "line": 72 }, "file": "source/renderer/app/components/wallet/WalletRestoreDialog.js", "id": "wallet.restore.dialog.recovery.phrase.input.noResults", "start": { "column": 27, - "line": 56 + "line": 67 } }, { @@ -4333,13 +4333,13 @@ "description": "Label for the \"Restore wallet\" button on the wallet restore dialog.", "end": { "column": 3, - "line": 65 + "line": 78 }, "file": "source/renderer/app/components/wallet/WalletRestoreDialog.js", "id": "wallet.restore.dialog.restore.wallet.button.label", "start": { "column": 21, - "line": 61 + "line": 73 } }, { @@ -4347,13 +4347,13 @@ "description": "Error message shown when invalid recovery phrase was entered.", "end": { "column": 3, - "line": 70 + "line": 84 }, "file": "source/renderer/app/components/wallet/WalletRestoreDialog.js", "id": "wallet.restore.dialog.form.errors.invalidRecoveryPhrase", "start": { "column": 25, - "line": 66 + "line": 79 } }, { @@ -4361,13 +4361,13 @@ "description": "Text for the \"Spending password\" switch in the wallet restore dialog.", "end": { "column": 3, - "line": 75 + "line": 91 }, "file": "source/renderer/app/components/wallet/WalletRestoreDialog.js", "id": "wallet.restore.dialog.passwordSwitchPlaceholder", "start": { "column": 29, - "line": 71 + "line": 85 } }, { @@ -4375,13 +4375,13 @@ "description": "Label for the \"Spending password\" switch in the wallet restore dialog.", "end": { "column": 3, - "line": 80 + "line": 97 }, "file": "source/renderer/app/components/wallet/WalletRestoreDialog.js", "id": "wallet.restore.dialog.passwordSwitchLabel", "start": { "column": 23, - "line": 76 + "line": 92 } }, { @@ -4389,13 +4389,13 @@ "description": "Label for the \"Wallet password\" input in the wallet restore dialog.", "end": { "column": 3, - "line": 85 + "line": 103 }, "file": "source/renderer/app/components/wallet/WalletRestoreDialog.js", "id": "wallet.restore.dialog.spendingPasswordLabel", "start": { "column": 25, - "line": 81 + "line": 98 } }, { @@ -4403,13 +4403,13 @@ "description": "Label for the \"Repeat password\" input in the wallet restore dialog.", "end": { "column": 3, - "line": 90 + "line": 109 }, "file": "source/renderer/app/components/wallet/WalletRestoreDialog.js", "id": "wallet.restore.dialog.repeatPasswordLabel", "start": { "column": 23, - "line": 86 + "line": 104 } }, { @@ -4417,13 +4417,13 @@ "description": "Placeholder for the \"Password\" inputs in the wallet restore dialog.", "end": { "column": 3, - "line": 95 + "line": 115 }, "file": "source/renderer/app/components/wallet/WalletRestoreDialog.js", "id": "wallet.restore.dialog.passwordFieldPlaceholder", "start": { "column": 28, - "line": 91 + "line": 110 } }, { @@ -4431,13 +4431,13 @@ "description": "Tab title \"Backup recovery phrase\" in the wallet restore dialog.", "end": { "column": 3, - "line": 100 + "line": 121 }, "file": "source/renderer/app/components/wallet/WalletRestoreDialog.js", "id": "wallet.restore.dialog.tab.title.recoveryPhrase", "start": { "column": 26, - "line": 96 + "line": 116 } }, { @@ -4445,13 +4445,13 @@ "description": "Tab title \"Paper wallet certificate\" in the wallet restore dialog.", "end": { "column": 3, - "line": 105 + "line": 127 }, "file": "source/renderer/app/components/wallet/WalletRestoreDialog.js", "id": "wallet.restore.dialog.tab.title.certificate", "start": { "column": 23, - "line": 101 + "line": 122 } }, { @@ -4459,13 +4459,13 @@ "description": "Label for the shielded recovery phrase input on the wallet restore dialog.", "end": { "column": 3, - "line": 110 + "line": 133 }, "file": "source/renderer/app/components/wallet/WalletRestoreDialog.js", "id": "wallet.restore.dialog.shielded.recovery.phrase.input.label", "start": { "column": 36, - "line": 106 + "line": 128 } }, { @@ -4473,13 +4473,13 @@ "description": "Hint \"Enter shielded recovery phrase\" for the recovery phrase input on the wallet restore dialog.", "end": { "column": 3, - "line": 115 + "line": 140 }, "file": "source/renderer/app/components/wallet/WalletRestoreDialog.js", "id": "wallet.restore.dialog.shielded.recovery.phrase.input.hint", "start": { "column": 35, - "line": 111 + "line": 134 } } ], @@ -4506,7 +4506,7 @@ "description": "Label for the \"Spending password\" input in the wallet send confirmation dialog.", "end": { "column": 3, - "line": 28 + "line": 29 }, "file": "source/renderer/app/components/wallet/WalletSendConfirmationDialog.js", "id": "wallet.send.confirmationDialog.spendingPasswordLabel", @@ -4520,13 +4520,13 @@ "description": "Label for the \"To\" in the wallet send confirmation dialog.", "end": { "column": 3, - "line": 33 + "line": 34 }, "file": "source/renderer/app/components/wallet/WalletSendConfirmationDialog.js", "id": "wallet.send.confirmationDialog.addressToLabel", "start": { "column": 18, - "line": 29 + "line": 30 } }, { @@ -4534,13 +4534,13 @@ "description": "Label for the \"Amount\" in the wallet send confirmation dialog.", "end": { "column": 3, - "line": 38 + "line": 40 }, "file": "source/renderer/app/components/wallet/WalletSendConfirmationDialog.js", "id": "wallet.send.confirmationDialog.amountLabel", "start": { "column": 15, - "line": 34 + "line": 35 } }, { @@ -4548,13 +4548,13 @@ "description": "Label for the \"Fees\" in the wallet send confirmation dialog.", "end": { "column": 3, - "line": 43 + "line": 45 }, "file": "source/renderer/app/components/wallet/WalletSendConfirmationDialog.js", "id": "wallet.send.confirmationDialog.feesLabel", "start": { "column": 13, - "line": 39 + "line": 41 } }, { @@ -4562,13 +4562,13 @@ "description": "Label for the \"Total\" in the wallet send confirmation dialog.", "end": { "column": 3, - "line": 48 + "line": 51 }, "file": "source/renderer/app/components/wallet/WalletSendConfirmationDialog.js", "id": "wallet.send.confirmationDialog.totalLabel", "start": { "column": 14, - "line": 44 + "line": 46 } }, { @@ -4576,13 +4576,13 @@ "description": "Placeholder for the \"Spending password\" inputs in the wallet send confirmation dialog.", "end": { "column": 3, - "line": 53 + "line": 57 }, "file": "source/renderer/app/components/wallet/WalletSendConfirmationDialog.js", "id": "wallet.send.confirmationDialog.spendingPasswordFieldPlaceholder", "start": { "column": 36, - "line": 49 + "line": 52 } }, { @@ -4590,13 +4590,13 @@ "description": "Label for the send button in the wallet send confirmation dialog.", "end": { "column": 3, - "line": 58 + "line": 63 }, "file": "source/renderer/app/components/wallet/WalletSendConfirmationDialog.js", "id": "wallet.send.confirmationDialog.submit", "start": { "column": 19, - "line": 54 + "line": 58 } }, { @@ -4604,13 +4604,13 @@ "description": "Label for the back button in the wallet send confirmation dialog.", "end": { "column": 3, - "line": 63 + "line": 69 }, "file": "source/renderer/app/components/wallet/WalletSendConfirmationDialog.js", "id": "wallet.send.confirmationDialog.back", "start": { "column": 19, - "line": 59 + "line": 64 } } ], @@ -4623,13 +4623,13 @@ "description": "Label for the \"Title\" text input in the wallet send form.", "end": { "column": 3, - "line": 31 + "line": 35 }, "file": "source/renderer/app/components/wallet/WalletSendForm.js", "id": "wallet.send.form.title.label", "start": { "column": 14, - "line": 27 + "line": 31 } }, { @@ -4637,13 +4637,13 @@ "description": "Hint inside the \"Receiver\" text input in the wallet send form.", "end": { "column": 3, - "line": 36 + "line": 41 }, "file": "source/renderer/app/components/wallet/WalletSendForm.js", "id": "wallet.send.form.title.hint", "start": { "column": 13, - "line": 32 + "line": 36 } }, { @@ -4651,13 +4651,13 @@ "description": "Label for the \"Receiver\" text input in the wallet send form.", "end": { "column": 3, - "line": 41 + "line": 46 }, "file": "source/renderer/app/components/wallet/WalletSendForm.js", "id": "wallet.send.form.receiver.label", "start": { "column": 17, - "line": 37 + "line": 42 } }, { @@ -4665,13 +4665,13 @@ "description": "Hint inside the \"Receiver\" text input in the wallet send form.", "end": { "column": 3, - "line": 46 + "line": 52 }, "file": "source/renderer/app/components/wallet/WalletSendForm.js", "id": "wallet.send.form.receiver.hint", "start": { "column": 16, - "line": 42 + "line": 47 } }, { @@ -4679,13 +4679,13 @@ "description": "Label for the \"Amount\" number input in the wallet send form.", "end": { "column": 3, - "line": 51 + "line": 57 }, "file": "source/renderer/app/components/wallet/WalletSendForm.js", "id": "wallet.send.form.amount.label", "start": { "column": 15, - "line": 47 + "line": 53 } }, { @@ -4693,13 +4693,13 @@ "description": "Label for the \"description\" text area in the wallet send form.", "end": { "column": 3, - "line": 56 + "line": 63 }, "file": "source/renderer/app/components/wallet/WalletSendForm.js", "id": "wallet.send.form.description.label", "start": { "column": 20, - "line": 52 + "line": 58 } }, { @@ -4707,13 +4707,13 @@ "description": "Hint in the \"description\" text area in the wallet send form.", "end": { "column": 3, - "line": 61 + "line": 68 }, "file": "source/renderer/app/components/wallet/WalletSendForm.js", "id": "wallet.send.form.description.hint", "start": { "column": 19, - "line": 57 + "line": 64 } }, { @@ -4721,13 +4721,13 @@ "description": "Label for the next button on the wallet send form.", "end": { "column": 3, - "line": 66 + "line": 73 }, "file": "source/renderer/app/components/wallet/WalletSendForm.js", "id": "wallet.send.form.next", "start": { "column": 19, - "line": 62 + "line": 69 } }, { @@ -4735,13 +4735,13 @@ "description": "Error message shown when invalid address was entered.", "end": { "column": 3, - "line": 71 + "line": 78 }, "file": "source/renderer/app/components/wallet/WalletSendForm.js", "id": "wallet.send.form.errors.invalidAddress", "start": { "column": 18, - "line": 67 + "line": 74 } }, { @@ -4749,13 +4749,13 @@ "description": "Error message shown when invalid amount was entered.", "end": { "column": 3, - "line": 76 + "line": 83 }, "file": "source/renderer/app/components/wallet/WalletSendForm.js", "id": "wallet.send.form.errors.invalidAmount", "start": { "column": 17, - "line": 72 + "line": 79 } }, { @@ -4763,13 +4763,13 @@ "description": "Error message shown when invalid transaction title was entered.", "end": { "column": 3, - "line": 81 + "line": 89 }, "file": "source/renderer/app/components/wallet/WalletSendForm.js", "id": "wallet.send.form.errors.invalidTitle", "start": { "column": 16, - "line": 77 + "line": 84 } }, { @@ -4777,13 +4777,13 @@ "description": "Syncing transactions message shown during async wallet restore in the wallet send form.", "end": { "column": 3, - "line": 86 + "line": 96 }, "file": "source/renderer/app/components/wallet/WalletSendForm.js", "id": "wallet.send.form.syncingTransactionsMessage", "start": { "column": 30, - "line": 82 + "line": 90 } } ], @@ -4810,7 +4810,7 @@ "description": "Label for the \"Transaction assurance security level\" dropdown.", "end": { "column": 3, - "line": 30 + "line": 31 }, "file": "source/renderer/app/components/wallet/WalletSettings.js", "id": "wallet.settings.assurance", @@ -4824,13 +4824,13 @@ "description": "Label for the \"Password\" field.", "end": { "column": 3, - "line": 35 + "line": 36 }, "file": "source/renderer/app/components/wallet/WalletSettings.js", "id": "wallet.settings.password", "start": { "column": 17, - "line": 31 + "line": 32 } }, { @@ -4838,13 +4838,13 @@ "description": "Last updated X time ago message.", "end": { "column": 3, - "line": 40 + "line": 41 }, "file": "source/renderer/app/components/wallet/WalletSettings.js", "id": "wallet.settings.passwordLastUpdated", "start": { "column": 23, - "line": 36 + "line": 37 } }, { @@ -4852,13 +4852,13 @@ "description": "You still don't have password set message.", "end": { "column": 3, - "line": 45 + "line": 46 }, "file": "source/renderer/app/components/wallet/WalletSettings.js", "id": "wallet.settings.passwordNotSet", "start": { "column": 18, - "line": 41 + "line": 42 } }, { @@ -4866,13 +4866,13 @@ "description": "Label for the export button on wallet settings.", "end": { "column": 3, - "line": 50 + "line": 51 }, "file": "source/renderer/app/components/wallet/WalletSettings.js", "id": "wallet.settings.exportWalletButtonLabel", "start": { "column": 21, - "line": 46 + "line": 47 } } ], @@ -4918,7 +4918,7 @@ "description": "Message \"Your changes have been saved\" for inline editing (eg. on Wallet Settings page).", "end": { "column": 3, - "line": 15 + "line": 16 }, "file": "source/renderer/app/components/widgets/forms/InlineEditingDropdown.js", "id": "inline.editing.dropdown.changesSaved", @@ -4965,7 +4965,7 @@ "description": "Message \"Your changes have been saved\" for inline editing (eg. on Profile Settings page).", "end": { "column": 3, - "line": 27 + "line": 28 }, "file": "source/renderer/app/components/widgets/forms/InlineEditingInput.js", "id": "inline.editing.input.changesSaved", @@ -4984,7 +4984,7 @@ "description": "Label for the blocks synced info overlay on node sync status icon.", "end": { "column": 3, - "line": 14 + "line": 15 }, "file": "source/renderer/app/components/widgets/NodeSyncStatusIcon.js", "id": "cardano.node.sync.status.blocksSynced", @@ -5097,7 +5097,7 @@ "description": "\"submit a support request\" link URL in the \"Report a problem\" section on the support settings page.", "end": { "column": 3, - "line": 18 + "line": 19 }, "file": "source/renderer/app/containers/settings/categories/SupportSettingsPage.js", "id": "settings.support.reportProblem.linkUrl", @@ -5111,13 +5111,13 @@ "description": "Success message for download logs.", "end": { "column": 3, - "line": 23 + "line": 24 }, "file": "source/renderer/app/containers/settings/categories/SupportSettingsPage.js", "id": "settings.support.reportProblem.downloadLogsSuccessMessage", "start": { "column": 23, - "line": 19 + "line": 20 } } ], @@ -5149,7 +5149,7 @@ "description": "Message shown when wallet has no transactions on wallet summary page.", "end": { "column": 3, - "line": 21 + "line": 22 }, "file": "source/renderer/app/containers/wallet/WalletSummaryPage.js", "id": "wallet.summary.no.transactions", @@ -5182,7 +5182,7 @@ "description": "Message shown when wallet transaction search returns zero results.", "end": { "column": 3, - "line": 24 + "line": 25 }, "file": "source/renderer/app/containers/wallet/WalletTransactionsPage.js", "id": "wallet.transactions.no.transactions.found", @@ -5215,7 +5215,7 @@ "description": "Error message shown when incomplete bip39 mnemonic was entered.", "end": { "column": 3, - "line": 13 + "line": 14 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.errors.incompleteMnemonic", @@ -5229,13 +5229,13 @@ "description": "Error message shown when invalid bip39 mnemonic was entered.", "end": { "column": 3, - "line": 18 + "line": 19 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.errors.invalidMnemonic", "start": { "column": 19, - "line": 14 + "line": 15 } }, { @@ -5243,13 +5243,13 @@ "description": "Error message shown when invalid email was entered.", "end": { "column": 3, - "line": 23 + "line": 24 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.errors.invalidEmail", "start": { "column": 16, - "line": 19 + "line": 20 } }, { @@ -5257,13 +5257,13 @@ "description": "Error message shown when invalid Ada redemption certificate was uploaded.", "end": { "column": 3, - "line": 28 + "line": 31 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.errors.AdaRedemptionCertificateParseError", "start": { "column": 35, - "line": 24 + "line": 25 } }, { @@ -5271,13 +5271,13 @@ "description": "Error message shown when invalid Ada redemption encrypted certificate was uploaded.", "end": { "column": 3, - "line": 33 + "line": 38 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.errors.AdaRedemptionEncryptedCertificateParseError", "start": { "column": 44, - "line": 29 + "line": 32 } }, { @@ -5285,13 +5285,13 @@ "description": "Error message shown when invalid wallet name was entered in create wallet dialog.", "end": { "column": 3, - "line": 38 + "line": 45 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.errors.invalidWalletName", "start": { "column": 21, - "line": 34 + "line": 39 } }, { @@ -5299,13 +5299,13 @@ "description": "Error message shown when invalid wallet password was entered in create wallet dialog.", "end": { "column": 3, - "line": 43 + "line": 51 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.errors.invalidSpendingPassword", "start": { "column": 27, - "line": 39 + "line": 46 } }, { @@ -5313,13 +5313,13 @@ "description": "Error message shown when wallet password and repeat passwords don't match in create wallet dialog.", "end": { "column": 3, - "line": 48 + "line": 57 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.errors.invalidRepeatPassword", "start": { "column": 25, - "line": 44 + "line": 52 } }, { @@ -5327,13 +5327,13 @@ "description": "Password instructions note.", "end": { "column": 3, - "line": 53 + "line": 63 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.passwordInstructions", "start": { "column": 24, - "line": 49 + "line": 58 } }, { @@ -5341,13 +5341,13 @@ "description": "The word \"cancel\" reused at several places (like cancel buttons)", "end": { "column": 3, - "line": 58 + "line": 69 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.labels.cancel", "start": { "column": 10, - "line": 54 + "line": 64 } }, { @@ -5355,13 +5355,13 @@ "description": "The word \"change\" reused at several places (like change buttons)", "end": { "column": 3, - "line": 63 + "line": 75 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.labels.change", "start": { "column": 10, - "line": 59 + "line": 70 } }, { @@ -5369,13 +5369,13 @@ "description": "The word \"create\" reused at several places (like create buttons)", "end": { "column": 3, - "line": 68 + "line": 81 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.labels.create", "start": { "column": 10, - "line": 64 + "line": 76 } }, { @@ -5383,13 +5383,13 @@ "description": "The word \"remove\" reused at several places (like remove buttons)", "end": { "column": 3, - "line": 73 + "line": 87 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.labels.remove", "start": { "column": 10, - "line": 69 + "line": 82 } }, { @@ -5397,13 +5397,13 @@ "description": "The word \"save\" reused at several places (like save buttons)", "end": { "column": 3, - "line": 78 + "line": 92 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.labels.save", "start": { "column": 8, - "line": 74 + "line": 88 } }, { @@ -5411,13 +5411,13 @@ "description": "Language name for \"English\" language.", "end": { "column": 3, - "line": 83 + "line": 97 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.language.english", "start": { "column": 19, - "line": 79 + "line": 93 } }, { @@ -5425,13 +5425,13 @@ "description": "Language name for \"Japanese\" language.", "end": { "column": 3, - "line": 88 + "line": 102 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.language.japanese", "start": { "column": 20, - "line": 84 + "line": 98 } }, { @@ -5439,13 +5439,13 @@ "description": "Language name for \"Chinese\" language.", "end": { "column": 3, - "line": 93 + "line": 107 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.language.chinese", "start": { "column": 19, - "line": 89 + "line": 103 } }, { @@ -5453,13 +5453,13 @@ "description": "Language name for \"Korean\" language.", "end": { "column": 3, - "line": 98 + "line": 112 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.language.korean", "start": { "column": 18, - "line": 94 + "line": 108 } }, { @@ -5467,13 +5467,13 @@ "description": "Language name for \"German\" language.", "end": { "column": 3, - "line": 103 + "line": 117 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.language.german", "start": { "column": 18, - "line": 99 + "line": 113 } }, { @@ -5481,13 +5481,13 @@ "description": "Language name for \"Croatian\" language.", "end": { "column": 3, - "line": 108 + "line": 122 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.language.croatian", "start": { "column": 20, - "line": 104 + "line": 118 } }, { @@ -5495,13 +5495,13 @@ "description": "Name for \"Normal\" transaction assurance security level.", "end": { "column": 3, - "line": 113 + "line": 127 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.assuranceLevel.normal", "start": { "column": 24, - "line": 109 + "line": 123 } }, { @@ -5509,13 +5509,13 @@ "description": "Name for \"Strict\" transaction assurance security level.", "end": { "column": 3, - "line": 118 + "line": 132 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.assuranceLevel.strict", "start": { "column": 24, - "line": 114 + "line": 128 } }, { @@ -5523,13 +5523,13 @@ "description": "Name for \"ADA\" unit.", "end": { "column": 3, - "line": 123 + "line": 137 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.unit.ada", "start": { "column": 11, - "line": 119 + "line": 133 } }, { @@ -5537,13 +5537,13 @@ "description": "Title for the \"Recovery Phrase\" dialog.", "end": { "column": 3, - "line": 128 + "line": 142 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "wallet.backup.recovery.phrase.dialog.title", "start": { "column": 29, - "line": 124 + "line": 138 } }, { @@ -5551,13 +5551,13 @@ "description": "Label for the \"Wallet password\" input in the create wallet dialog.", "end": { "column": 3, - "line": 133 + "line": 148 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.spendingPasswordLabel", "start": { "column": 25, - "line": 129 + "line": 143 } }, { @@ -5565,13 +5565,13 @@ "description": "Placeholder for the \"Password\" inputs in the create wallet dialog.", "end": { "column": 3, - "line": 138 + "line": 154 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.spendingPasswordPlaceholder", "start": { "column": 31, - "line": 134 + "line": 149 } }, { @@ -5579,13 +5579,13 @@ "description": "Label \"Continue\" in dialogs.", "end": { "column": 3, - "line": 143 + "line": 159 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "global.dialog.button.continue", "start": { "column": 29, - "line": 139 + "line": 155 } }, { @@ -5593,13 +5593,13 @@ "description": "URL for the \"Known Issues\" link in the \"Help and support\" section on the support settings page", "end": { "column": 3, - "line": 148 + "line": 166 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "settings.support.faq.faqLinkURL", "start": { "column": 14, - "line": 144 + "line": 160 } }, { @@ -5607,13 +5607,13 @@ "description": "Name for \"Ada\" unit.", "end": { "column": 3, - "line": 153 + "line": 171 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "environment.currency.ada", "start": { "column": 12, - "line": 149 + "line": 167 } }, { @@ -5621,13 +5621,13 @@ "description": "Name for \"Cardano\" client.", "end": { "column": 3, - "line": 158 + "line": 176 }, "file": "source/renderer/app/i18n/global-messages.js", "id": "environment.apiName.cardano", "start": { "column": 11, - "line": 154 + "line": 172 } } ], diff --git a/source/renderer/app/i18n/translations.js b/source/renderer/app/i18n/translations.js index 16d26385f5..5a637bca42 100644 --- a/source/renderer/app/i18n/translations.js +++ b/source/renderer/app/i18n/translations.js @@ -2,7 +2,7 @@ const req = require.context('./locales', true, /\.json.*$/); const translations = {}; -req.keys().forEach((file) => { +req.keys().forEach(file => { const locale = file.replace('./', '').replace('.json', ''); translations[locale] = req(file); }); diff --git a/source/renderer/app/i18n/types.js b/source/renderer/app/i18n/types.js index d9af821c30..e522777177 100644 --- a/source/renderer/app/i18n/types.js +++ b/source/renderer/app/i18n/types.js @@ -3,5 +3,5 @@ export type ReactIntlMessageShape = { id: string, defaultMessage: string, - values?: Object + values?: Object, }; diff --git a/source/renderer/app/index.js b/source/renderer/app/index.js index 84b75ed291..58d08d1831 100755 --- a/source/renderer/app/index.js +++ b/source/renderer/app/index.js @@ -50,9 +50,12 @@ const initializeDaedalus = () => { const rootElement = document.getElementById('root'); if (!rootElement) throw new Error('No #root element found.'); - render(, rootElement); + render( + , + rootElement + ); }; window.addEventListener('load', initializeDaedalus); -window.addEventListener('dragover', (event) => event.preventDefault()); -window.addEventListener('drop', (event) => event.preventDefault()); +window.addEventListener('dragover', event => event.preventDefault()); +window.addEventListener('drop', event => event.preventDefault()); diff --git a/source/renderer/app/ipc/bugReportRequestChannel.js b/source/renderer/app/ipc/bugReportRequestChannel.js index 402254f26c..02a76d8434 100644 --- a/source/renderer/app/ipc/bugReportRequestChannel.js +++ b/source/renderer/app/ipc/bugReportRequestChannel.js @@ -2,13 +2,12 @@ import { SUBMIT_BUG_REPORT_REQUEST_CHANNEL } from '../../../common/ipc/api'; import type { SubmitBugReportRequestResponse, - SubmitBugReportRequest + SubmitBugReportRequest, } from '../../../common/ipc/api'; import { RendererIpcChannel } from './lib/RendererIpcChannel'; -export const bugReportRequestChannel: ( - // IpcChannel - RendererIpcChannel -) = ( - new RendererIpcChannel(SUBMIT_BUG_REPORT_REQUEST_CHANNEL) -); +export const bugReportRequestChannel: // IpcChannel +RendererIpcChannel< + SubmitBugReportRequestResponse, + SubmitBugReportRequest +> = new RendererIpcChannel(SUBMIT_BUG_REPORT_REQUEST_CHANNEL); diff --git a/source/renderer/app/ipc/cardano.ipc.js b/source/renderer/app/ipc/cardano.ipc.js index 49c688a9e4..5ab2e94b60 100644 --- a/source/renderer/app/ipc/cardano.ipc.js +++ b/source/renderer/app/ipc/cardano.ipc.js @@ -1,6 +1,7 @@ // @flow import type { - CardanoNodeState, CardanoStatus, + CardanoNodeState, + CardanoStatus, FaultInjectionIpcRequest, } from '../../../common/types/cardano-node.types'; import { RendererIpcChannel } from './lib/RendererIpcChannel'; @@ -11,38 +12,46 @@ import { GET_CACHED_CARDANO_STATUS_CHANNEL, CARDANO_TLS_CONFIG_CHANNEL, CARDANO_AWAIT_UPDATE_CHANNEL, - SET_CACHED_CARDANO_STATUS_CHANNEL + SET_CACHED_CARDANO_STATUS_CHANNEL, } from '../../../common/ipc/api'; import type { - CardanoTlsConfigResponse, CardanoTlsConfigRequest + CardanoTlsConfigResponse, + CardanoTlsConfigRequest, } from '../../../common/ipc/api'; // IpcChannel -export const cardanoTlsConfigChannel: ( - RendererIpcChannel -) = new RendererIpcChannel(CARDANO_TLS_CONFIG_CHANNEL); - -export const restartCardanoNodeChannel: ( - RendererIpcChannel -) = new RendererIpcChannel(CARDANO_RESTART_CHANNEL); - -export const cardanoStateChangeChannel: RendererIpcChannel = ( - new RendererIpcChannel(CARDANO_STATE_CHANNEL) -); - -export const awaitUpdateChannel: RendererIpcChannel = ( - new RendererIpcChannel(CARDANO_AWAIT_UPDATE_CHANNEL) -); - -export const cardanoFaultInjectionChannel: RendererIpcChannel = ( - new RendererIpcChannel(CARDANO_FAULT_INJECTION_CHANNEL) -); - -export const getCachedCardanoStatusChannel: RendererIpcChannel = ( - new RendererIpcChannel(GET_CACHED_CARDANO_STATUS_CHANNEL) -); - -export const setCachedCardanoStatusChannel: RendererIpcChannel = ( - new RendererIpcChannel(SET_CACHED_CARDANO_STATUS_CHANNEL) -); +export const cardanoTlsConfigChannel: RendererIpcChannel< + CardanoTlsConfigResponse, + CardanoTlsConfigRequest +> = new RendererIpcChannel(CARDANO_TLS_CONFIG_CHANNEL); + +export const restartCardanoNodeChannel: RendererIpcChannel< + void, + void +> = new RendererIpcChannel(CARDANO_RESTART_CHANNEL); + +export const cardanoStateChangeChannel: RendererIpcChannel< + CardanoNodeState, + void +> = new RendererIpcChannel(CARDANO_STATE_CHANNEL); + +export const awaitUpdateChannel: RendererIpcChannel< + void, + void +> = new RendererIpcChannel(CARDANO_AWAIT_UPDATE_CHANNEL); + +export const cardanoFaultInjectionChannel: RendererIpcChannel< + void, + FaultInjectionIpcRequest +> = new RendererIpcChannel(CARDANO_FAULT_INJECTION_CHANNEL); + +export const getCachedCardanoStatusChannel: RendererIpcChannel< + ?CardanoStatus, + ?CardanoStatus +> = new RendererIpcChannel(GET_CACHED_CARDANO_STATUS_CHANNEL); + +export const setCachedCardanoStatusChannel: RendererIpcChannel< + ?CardanoStatus, + ?CardanoStatus +> = new RendererIpcChannel(SET_CACHED_CARDANO_STATUS_CHANNEL); diff --git a/source/renderer/app/ipc/control-ui-parts.js b/source/renderer/app/ipc/control-ui-parts.js index 471989434f..b56f77b994 100644 --- a/source/renderer/app/ipc/control-ui-parts.js +++ b/source/renderer/app/ipc/control-ui-parts.js @@ -1,14 +1,22 @@ // @flow import { RendererIpcChannel } from './lib/RendererIpcChannel'; -import type { ShowUiPartRequest, ToggleUiPartRequest } from '../../../common/ipc/api'; -import { SHOW_UI_PART_CHANNEL, TOGGLE_UI_PART_CHANNEL } from '../../../common/ipc/api'; +import type { + ShowUiPartRequest, + ToggleUiPartRequest, +} from '../../../common/ipc/api'; +import { + SHOW_UI_PART_CHANNEL, + TOGGLE_UI_PART_CHANNEL, +} from '../../../common/ipc/api'; // IpcChannel -export const toggleUiPartChannel: ( - RendererIpcChannel -) = new RendererIpcChannel(TOGGLE_UI_PART_CHANNEL); +export const toggleUiPartChannel: RendererIpcChannel< + ToggleUiPartRequest, + void +> = new RendererIpcChannel(TOGGLE_UI_PART_CHANNEL); -export const showUiPartChannel: ( - RendererIpcChannel -) = new RendererIpcChannel(SHOW_UI_PART_CHANNEL); +export const showUiPartChannel: RendererIpcChannel< + ShowUiPartRequest, + void +> = new RendererIpcChannel(SHOW_UI_PART_CHANNEL); diff --git a/source/renderer/app/ipc/generatePaperWalletChannel.js b/source/renderer/app/ipc/generatePaperWalletChannel.js index a2bf557ee3..8e0207ab58 100644 --- a/source/renderer/app/ipc/generatePaperWalletChannel.js +++ b/source/renderer/app/ipc/generatePaperWalletChannel.js @@ -6,9 +6,8 @@ import type { } from '../../../common/ipc/api'; import { RendererIpcChannel } from './lib/RendererIpcChannel'; -export const generatePaperWalletChannel: ( - // IpcChannel - RendererIpcChannel -) = ( - new RendererIpcChannel(GENERATE_PAPER_WALLET_CHANNEL) -); +export const generatePaperWalletChannel: // IpcChannel +RendererIpcChannel< + GeneratePaperWalletResponse, + GeneratePaperWalletRequest +> = new RendererIpcChannel(GENERATE_PAPER_WALLET_CHANNEL); diff --git a/source/renderer/app/ipc/get-gpu-status.ipc.js b/source/renderer/app/ipc/get-gpu-status.ipc.js index 10e3917d5c..eaf2fca3ff 100644 --- a/source/renderer/app/ipc/get-gpu-status.ipc.js +++ b/source/renderer/app/ipc/get-gpu-status.ipc.js @@ -1,8 +1,12 @@ // @flow import { RendererIpcChannel } from './lib/RendererIpcChannel'; import { GET_GPU_STATUS_CHANNEL } from '../../../common/ipc/api'; -import type { GetGPUStatusRequest, GetGPUStatusResponse } from '../../../common/ipc/api'; +import type { + GetGPUStatusRequest, + GetGPUStatusResponse, +} from '../../../common/ipc/api'; -export const getGPUStatusChannel: ( - RendererIpcChannel -) = new RendererIpcChannel(GET_GPU_STATUS_CHANNEL); +export const getGPUStatusChannel: RendererIpcChannel< + GetGPUStatusResponse, + GetGPUStatusRequest +> = new RendererIpcChannel(GET_GPU_STATUS_CHANNEL); diff --git a/source/renderer/app/ipc/getDiskSpaceChannel.js b/source/renderer/app/ipc/getDiskSpaceChannel.js index 2dc19414ef..374dca58c1 100644 --- a/source/renderer/app/ipc/getDiskSpaceChannel.js +++ b/source/renderer/app/ipc/getDiskSpaceChannel.js @@ -2,13 +2,12 @@ import { GET_DISK_SPACE_STATUS_CHANNEL } from '../../../common/ipc/api'; import type { GetDiskSpaceStatusRendererRequest, - GetDiskSpaceStatusMainResponse + GetDiskSpaceStatusMainResponse, } from '../../../common/ipc/api'; import { RendererIpcChannel } from './lib/RendererIpcChannel'; -export const getDiskSpaceStatusChannel: ( - // IpcChannel - RendererIpcChannel -) = ( - new RendererIpcChannel(GET_DISK_SPACE_STATUS_CHANNEL) -); +export const getDiskSpaceStatusChannel: // IpcChannel +RendererIpcChannel< + GetDiskSpaceStatusMainResponse, + GetDiskSpaceStatusRendererRequest +> = new RendererIpcChannel(GET_DISK_SPACE_STATUS_CHANNEL); diff --git a/source/renderer/app/ipc/getNumberOfEpochsConsolidatedChannel.js b/source/renderer/app/ipc/getNumberOfEpochsConsolidatedChannel.js index d92e79984e..7ed3c20783 100644 --- a/source/renderer/app/ipc/getNumberOfEpochsConsolidatedChannel.js +++ b/source/renderer/app/ipc/getNumberOfEpochsConsolidatedChannel.js @@ -3,9 +3,8 @@ import { GET_CONSOLIDATED_EPOCHS_COUNT_CHANNEL } from '../../../common/ipc/api'; import type { GetConsolidatedEpochsCountResponse } from '../../../common/ipc/api'; import { RendererIpcChannel } from './lib/RendererIpcChannel'; -export const getNumberOfEpochsConsolidatedChannel: ( - // IpcChannel - RendererIpcChannel -) = ( - new RendererIpcChannel(GET_CONSOLIDATED_EPOCHS_COUNT_CHANNEL) -); +export const getNumberOfEpochsConsolidatedChannel: // IpcChannel +RendererIpcChannel< + GetConsolidatedEpochsCountResponse, + void +> = new RendererIpcChannel(GET_CONSOLIDATED_EPOCHS_COUNT_CHANNEL); diff --git a/source/renderer/app/ipc/getSystemStartTime.ipc.js b/source/renderer/app/ipc/getSystemStartTime.ipc.js index 79471d3e83..be16a4a425 100644 --- a/source/renderer/app/ipc/getSystemStartTime.ipc.js +++ b/source/renderer/app/ipc/getSystemStartTime.ipc.js @@ -3,9 +3,7 @@ import { GET_SYSTEM_START_TIME_CHANNEL } from '../../../common/ipc/api'; import type { GetSystemStartTimeResponse } from '../../../common/ipc/api'; import { RendererIpcChannel } from './lib/RendererIpcChannel'; -export const getSystemStartTimeChannel: ( - // IpcChannel - RendererIpcChannel -) = ( - new RendererIpcChannel(GET_SYSTEM_START_TIME_CHANNEL) +export const getSystemStartTimeChannel: // IpcChannel +RendererIpcChannel = new RendererIpcChannel( + GET_SYSTEM_START_TIME_CHANNEL ); diff --git a/source/renderer/app/ipc/lib/RendererIpcChannel.js b/source/renderer/app/ipc/lib/RendererIpcChannel.js index 3e7ef72093..523d2fef8f 100644 --- a/source/renderer/app/ipc/lib/RendererIpcChannel.js +++ b/source/renderer/app/ipc/lib/RendererIpcChannel.js @@ -1,12 +1,17 @@ // @flow import { IpcChannel } from '../../../../common/ipc/lib/IpcChannel'; -import type { IpcReceiver, IpcSender } from '../../../../common/ipc/lib/IpcChannel'; +import type { + IpcReceiver, + IpcSender, +} from '../../../../common/ipc/lib/IpcChannel'; /** * Subclass of IpcChannel that uses ipcRenderer to send and receive messages. */ -export class RendererIpcChannel extends IpcChannel { - +export class RendererIpcChannel extends IpcChannel< + Incoming, + Outgoing +> { async send( message: Outgoing, sender: IpcSender = global.ipcRenderer, @@ -31,10 +36,9 @@ export class RendererIpcChannel extends IpcChannel Promise, + handler: Incoming => Promise, receiver: IpcReceiver = global.ipcRenderer ): void { super.onRequest(handler, receiver); } - } diff --git a/source/renderer/app/ipc/loadAsset.js b/source/renderer/app/ipc/loadAsset.js index 248b04fce4..9b17f8508e 100644 --- a/source/renderer/app/ipc/loadAsset.js +++ b/source/renderer/app/ipc/loadAsset.js @@ -3,10 +3,11 @@ import { RendererIpcChannel } from './lib/RendererIpcChannel'; import { LOAD_ASSET_CHANNEL } from '../../../common/ipc/api'; import type { LoadAssetRendererRequest, - LoadAssetMainResponse + LoadAssetMainResponse, } from '../../../common/ipc/api'; // IpcChannel -export const loadAssetChannel: ( - RendererIpcChannel -) = new RendererIpcChannel(LOAD_ASSET_CHANNEL); +export const loadAssetChannel: RendererIpcChannel< + LoadAssetMainResponse, + LoadAssetRendererRequest +> = new RendererIpcChannel(LOAD_ASSET_CHANNEL); diff --git a/source/renderer/app/ipc/logs.ipc.js b/source/renderer/app/ipc/logs.ipc.js index 79962f3818..51e65e97ac 100644 --- a/source/renderer/app/ipc/logs.ipc.js +++ b/source/renderer/app/ipc/logs.ipc.js @@ -6,24 +6,27 @@ import type { DownloadLogsRequest, DownloadLogsResponse, GetLogsRequest, - GetLogsResponse + GetLogsResponse, } from '../../../common/ipc/api'; import { COMPRESS_LOGS_CHANNEL, DOWNLOAD_LOGS_CHANNEL, - GET_LOGS_CHANNEL + GET_LOGS_CHANNEL, } from '../../../common/ipc/api'; // IpcChannel -export const getLogsChannel: ( - RendererIpcChannel -) = new RendererIpcChannel(GET_LOGS_CHANNEL); +export const getLogsChannel: RendererIpcChannel< + GetLogsResponse, + GetLogsRequest +> = new RendererIpcChannel(GET_LOGS_CHANNEL); -export const compressLogsChannel: ( - RendererIpcChannel -) = new RendererIpcChannel(COMPRESS_LOGS_CHANNEL); +export const compressLogsChannel: RendererIpcChannel< + CompressLogsResponse, + CompressLogsRequest +> = new RendererIpcChannel(COMPRESS_LOGS_CHANNEL); -export const downloadLogsChannel: ( - RendererIpcChannel -) = new RendererIpcChannel(DOWNLOAD_LOGS_CHANNEL); +export const downloadLogsChannel: RendererIpcChannel< + DownloadLogsResponse, + DownloadLogsRequest +> = new RendererIpcChannel(DOWNLOAD_LOGS_CHANNEL); diff --git a/source/renderer/app/ipc/open-external-url.js b/source/renderer/app/ipc/open-external-url.js index fc9537248f..9f8f3d6f6c 100644 --- a/source/renderer/app/ipc/open-external-url.js +++ b/source/renderer/app/ipc/open-external-url.js @@ -6,10 +6,8 @@ import type { OpenExternalUrlRequest, } from '../../../common/ipc/api'; - -export const openExternalUrlChannel: ( - // IpcChannel - RendererIpcChannel -) = ( - new RendererIpcChannel(OPEN_EXTERNAL_URL_CHANNEL) -); +export const openExternalUrlChannel: // IpcChannel +RendererIpcChannel< + OpenExternalUrlResponse, + OpenExternalUrlRequest +> = new RendererIpcChannel(OPEN_EXTERNAL_URL_CHANNEL); diff --git a/source/renderer/app/ipc/parse-redemption-code.js b/source/renderer/app/ipc/parse-redemption-code.js index a32aa3746e..60d0de7edd 100644 --- a/source/renderer/app/ipc/parse-redemption-code.js +++ b/source/renderer/app/ipc/parse-redemption-code.js @@ -3,9 +3,10 @@ import { RendererIpcChannel } from './lib/RendererIpcChannel'; import { PARSE_REDEMPTION_CODE_CHANNEL } from '../../../common/ipc/api'; import type { ParseRedemptionCodeRequest, - ParseRedemptionCodeResponse + ParseRedemptionCodeResponse, } from '../../../common/ipc/api'; -export const parseRedemptionCodeChannel: ( - RendererIpcChannel -) = new RendererIpcChannel(PARSE_REDEMPTION_CODE_CHANNEL); +export const parseRedemptionCodeChannel: RendererIpcChannel< + ParseRedemptionCodeResponse, + ParseRedemptionCodeRequest +> = new RendererIpcChannel(PARSE_REDEMPTION_CODE_CHANNEL); diff --git a/source/renderer/app/ipc/rebuild-application-menu.js b/source/renderer/app/ipc/rebuild-application-menu.js index e497009ce1..e4a54f8421 100644 --- a/source/renderer/app/ipc/rebuild-application-menu.js +++ b/source/renderer/app/ipc/rebuild-application-menu.js @@ -2,9 +2,7 @@ import { RendererIpcChannel } from './lib/RendererIpcChannel'; import { REBUILD_APP_MENU_CHANNEL } from '../../../common/ipc/api'; -export const rebuildApplicationMenu: ( - // IpcChannel - RendererIpcChannel -) = ( - new RendererIpcChannel(REBUILD_APP_MENU_CHANNEL) +export const rebuildApplicationMenu: // IpcChannel +RendererIpcChannel = new RendererIpcChannel( + REBUILD_APP_MENU_CHANNEL ); diff --git a/source/renderer/app/stores/AdaRedemptionStore.js b/source/renderer/app/stores/AdaRedemptionStore.js index 9485405d61..ca1ce5dbd5 100644 --- a/source/renderer/app/stores/AdaRedemptionStore.js +++ b/source/renderer/app/stores/AdaRedemptionStore.js @@ -10,7 +10,7 @@ import { parseRedemptionCodeChannel } from '../ipc/parse-redemption-code'; import { InvalidMnemonicError, AdaRedemptionCertificateParseError, - AdaRedemptionEncryptedCertificateParseError + AdaRedemptionEncryptedCertificateParseError, } from '../i18n/errors'; import { DECIMAL_PLACES_IN_ADA } from '../config/numbersConfig'; import LocalizableError from '../i18n/LocalizableError'; @@ -22,8 +22,8 @@ import type { RedeemPaperVendedAdaParams } from '../api/transactions/requests/re import type { AdaRedemptionDecryptionKey } from '../../../common/types/ada-redemption.types'; export default class AdaRedemptionStore extends Store { - - @observable redemptionType: RedemptionTypeChoices = ADA_REDEMPTION_TYPES.REGULAR; + @observable redemptionType: RedemptionTypeChoices = + ADA_REDEMPTION_TYPES.REGULAR; @observable certificate: ?File = null; @observable isCertificateEncrypted = false; @observable passPhrase: ?string = null; @@ -37,9 +37,14 @@ export default class AdaRedemptionStore extends Store { @observable error: ?LocalizableError = null; @observable amountRedeemed: number = 0; @observable showAdaRedemptionSuccessMessage: boolean = false; - @observable redeemAdaRequest: Request = new Request(this.api.ada.redeemAda); + @observable redeemAdaRequest: Request = new Request( + this.api.ada.redeemAda + ); // eslint-disable-next-line - @observable redeemPaperVendedAdaRequest: Request = new Request(this.api.ada.redeemPaperVendedAda); + @observable + redeemPaperVendedAdaRequest: Request = new Request( + this.api.ada.redeemPaperVendedAda + ); @observable isRedemptionDisclaimerAccepted = false; setup() { @@ -55,26 +60,27 @@ export default class AdaRedemptionStore extends Store { actions.redeemAda.listen(this._redeemAda); actions.redeemPaperVendedAda.listen(this._redeemPaperVendedAda); actions.adaSuccessfullyRedeemed.listen(this._onAdaSuccessfullyRedeemed); - actions.closeAdaRedemptionSuccessOverlay.listen(this._onCloseAdaRedemptionSuccessOverlay); + actions.closeAdaRedemptionSuccessOverlay.listen( + this._onCloseAdaRedemptionSuccessOverlay + ); actions.removeCertificate.listen(this._onRemoveCertificate); - actions.acceptRedemptionDisclaimer.listen(this._onAcceptRedemptionDisclaimer); + actions.acceptRedemptionDisclaimer.listen( + this._onAcceptRedemptionDisclaimer + ); this.registerReactions([ this._resetRedemptionFormValuesOnAdaRedemptionPageLoad, ]); } - isValidRedemptionKey = (redemptionKey: string) => ( - this.api.ada.isValidRedemptionKey(redemptionKey) - ); + isValidRedemptionKey = (redemptionKey: string) => + this.api.ada.isValidRedemptionKey(redemptionKey); - isValidRedemptionMnemonic = (mnemonic: string) => ( - this.api.ada.isValidRedemptionMnemonic(mnemonic) - ); + isValidRedemptionMnemonic = (mnemonic: string) => + this.api.ada.isValidRedemptionMnemonic(mnemonic); - isValidPaperVendRedemptionKey = (mnemonic: string) => ( - this.api.ada.isValidPaperVendRedemptionKey(mnemonic) - ); + isValidPaperVendRedemptionKey = (mnemonic: string) => + this.api.ada.isValidPaperVendRedemptionKey(mnemonic); @computed get isAdaRedemptionPage(): boolean { return matchRoute(ROUTES.ADA_REDEMPTION, this.stores.app.currentRoute); @@ -96,7 +102,10 @@ export default class AdaRedemptionStore extends Store { _setCertificate = action(({ certificate }) => { this.certificate = certificate; this.isCertificateEncrypted = certificate.type !== 'application/pdf'; - if (this.isCertificateEncrypted && (!this.passPhrase || !this.decryptionKey)) { + if ( + this.isCertificateEncrypted && + (!this.passPhrase || !this.decryptionKey) + ) { this.redemptionCode = ''; this.passPhrase = null; this.decryptionKey = null; @@ -107,12 +116,15 @@ export default class AdaRedemptionStore extends Store { _setPassPhrase = action(({ passPhrase }: { passPhrase: string }) => { this.passPhrase = passPhrase; - if (this.isValidRedemptionMnemonic(passPhrase)) this._parseCodeFromCertificate(); + if (this.isValidRedemptionMnemonic(passPhrase)) + this._parseCodeFromCertificate(); }); - _setRedemptionCode = action(({ redemptionCode }: { redemptionCode: string }) => { - this.redemptionCode = redemptionCode; - }); + _setRedemptionCode = action( + ({ redemptionCode }: { redemptionCode: string }) => { + this.redemptionCode = redemptionCode; + } + ); _setEmail = action(({ email }: { email: string }) => { this.email = email; @@ -150,7 +162,10 @@ export default class AdaRedemptionStore extends Store { if (!this.passPhrase && this.isCertificateEncrypted) return; } if (this.redemptionType === ADA_REDEMPTION_TYPES.FORCE_VENDED) { - if ((!this.email || !this.adaAmount || !this.adaPasscode) && this.isCertificateEncrypted) { + if ( + (!this.email || !this.adaAmount || !this.adaPasscode) && + this.isCertificateEncrypted + ) { return; } } @@ -158,15 +173,19 @@ export default class AdaRedemptionStore extends Store { if (!this.decryptionKey && this.isCertificateEncrypted) return; } if (this.redemptionType === ADA_REDEMPTION_TYPES.PAPER_VENDED) return; - if (this.certificate == null) throw new Error('Certificate File is required for parsing.'); + if (this.certificate == null) + throw new Error('Certificate File is required for parsing.'); // PREPARATION const path = this.certificate.path; // eslint-disable-line - Logger.debug('AdaRedemptionStore: Parsing ADA Redemption code from certificate', { path }); + Logger.debug( + 'AdaRedemptionStore: Parsing ADA Redemption code from certificate', + { path } + ); let decryptionKey = null; - if (( - this.redemptionType === ADA_REDEMPTION_TYPES.REGULAR || - this.redemptionType === ADA_REDEMPTION_TYPES.RECOVERY_REGULAR) && + if ( + (this.redemptionType === ADA_REDEMPTION_TYPES.REGULAR || + this.redemptionType === ADA_REDEMPTION_TYPES.RECOVERY_REGULAR) && this.isCertificateEncrypted ) { decryptionKey = this.passPhrase; @@ -205,72 +224,90 @@ export default class AdaRedemptionStore extends Store { } } - _redeemAda = async ({ walletId, spendingPassword }: { + _redeemAda = async ({ + walletId, + spendingPassword, + }: { walletId: string, spendingPassword: ?string, }) => { - runInAction(() => this.walletId = walletId); + runInAction(() => (this.walletId = walletId)); - const accountIndex = await this.stores.addresses.getAccountIndexByWalletId(walletId); - if (!accountIndex) throw new Error('Active account required before redeeming Ada.'); + const accountIndex = await this.stores.addresses.getAccountIndexByWalletId( + walletId + ); + if (!accountIndex) + throw new Error('Active account required before redeeming Ada.'); try { - const transaction: WalletTransaction = await this.redeemAdaRequest.execute({ - walletId, - accountIndex, - spendingPassword, - redemptionCode: this.redemptionCode - }); + const transaction: WalletTransaction = await this.redeemAdaRequest.execute( + { + walletId, + accountIndex, + spendingPassword, + redemptionCode: this.redemptionCode, + } + ); this._reset(); this.actions.adaRedemption.adaSuccessfullyRedeemed.trigger({ walletId, amount: transaction.amount.toFormat(DECIMAL_PLACES_IN_ADA), }); } catch (error) { - runInAction(() => this.error = error); + runInAction(() => (this.error = error)); } }; - _redeemPaperVendedAda = async ({ walletId, shieldedRedemptionKey, spendingPassword }: { + _redeemPaperVendedAda = async ({ + walletId, + shieldedRedemptionKey, + spendingPassword, + }: { walletId: string, shieldedRedemptionKey: string, spendingPassword: ?string, }) => { - runInAction(() => this.walletId = walletId); + runInAction(() => (this.walletId = walletId)); - const accountIndex = await this.stores.addresses.getAccountIndexByWalletId(walletId); - if (!accountIndex) throw new Error('Active account required before redeeming Ada.'); + const accountIndex = await this.stores.addresses.getAccountIndexByWalletId( + walletId + ); + if (!accountIndex) + throw new Error('Active account required before redeeming Ada.'); try { - const transaction: WalletTransaction = await this.redeemPaperVendedAdaRequest.execute({ - walletId, - accountIndex, - spendingPassword, - redemptionCode: shieldedRedemptionKey, - mnemonic: this.passPhrase && this.passPhrase.split(' ') - }); + const transaction: WalletTransaction = await this.redeemPaperVendedAdaRequest.execute( + { + walletId, + accountIndex, + spendingPassword, + redemptionCode: shieldedRedemptionKey, + mnemonic: this.passPhrase && this.passPhrase.split(' '), + } + ); this._reset(); this.actions.adaRedemption.adaSuccessfullyRedeemed.trigger({ walletId, - amount: transaction.amount.toFormat(DECIMAL_PLACES_IN_ADA) + amount: transaction.amount.toFormat(DECIMAL_PLACES_IN_ADA), }); } catch (error) { - runInAction(() => this.error = error); + runInAction(() => (this.error = error)); } }; - _onAdaSuccessfullyRedeemed = action(({ walletId, amount }: { - walletId: string, - amount: number, - }) => { - Logger.debug('AdaRedemptionStore: ADA successfully redeemed for wallet', { walletId }); - this.stores.wallets.goToWalletRoute(walletId); - this.amountRedeemed = amount; - this.showAdaRedemptionSuccessMessage = true; - this.redemptionCode = ''; - this.passPhrase = null; - this.decryptionKey = null; - }); + _onAdaSuccessfullyRedeemed = action( + ({ walletId, amount }: { walletId: string, amount: number }) => { + Logger.debug('AdaRedemptionStore: ADA successfully redeemed for wallet', { + walletId, + }); + this.stores.wallets.goToWalletRoute(walletId); + this.amountRedeemed = amount; + this.showAdaRedemptionSuccessMessage = true; + this.redemptionCode = ''; + this.passPhrase = null; + this.decryptionKey = null; + } + ); _onCloseAdaRedemptionSuccessOverlay = action(() => { this.showAdaRedemptionSuccessMessage = false; @@ -305,5 +342,4 @@ export default class AdaRedemptionStore extends Store { this.adaAmount = null; this.decryptionKey = null; }; - } diff --git a/source/renderer/app/stores/AddressesStore.js b/source/renderer/app/stores/AddressesStore.js index f131125c93..f72597e163 100644 --- a/source/renderer/app/stores/AddressesStore.js +++ b/source/renderer/app/stores/AddressesStore.js @@ -5,20 +5,25 @@ import Store from './lib/Store'; import CachedRequest from './lib/LocalizedCachedRequest'; import Request from './lib/LocalizedRequest'; import LocalizableError from '../i18n/LocalizableError'; -import type { Address, Addresses, GetAddressesResponse } from '../api/addresses/types'; +import type { + Address, + Addresses, + GetAddressesResponse, +} from '../api/addresses/types'; export default class AddressesStore extends Store { - @observable lastGeneratedAddress: ?Address = null; @observable addressesRequests: Array<{ walletId: string, - allRequest: CachedRequest + allRequest: CachedRequest, }> = []; @observable error: ?LocalizableError = null; // REQUESTS /* eslint-disable max-len */ - @observable createAddressRequest: Request
= new Request(this.api.ada.createAddress); + @observable createAddressRequest: Request
= new Request( + this.api.ada.createAddress + ); /* eslint-disable max-len */ setup() { @@ -27,13 +32,18 @@ export default class AddressesStore extends Store { actions.resetErrors.listen(this._resetErrors); } - _createAddress = async (params: { walletId: string, spendingPassword: ?string }) => { + _createAddress = async (params: { + walletId: string, + spendingPassword: ?string, + }) => { try { const { walletId, spendingPassword } = params; const accountIndex = await this.getAccountIndexByWalletId(walletId); const address: ?Address = await this.createAddressRequest.execute({ - accountIndex, spendingPassword, walletId + accountIndex, + spendingPassword, + walletId, }).promise; if (address != null) { @@ -44,7 +54,9 @@ export default class AddressesStore extends Store { }); } } catch (error) { - runInAction('set error', () => { this.error = error; }); + runInAction('set error', () => { + this.error = error; + }); } }; @@ -102,10 +114,11 @@ export default class AddressesStore extends Store { return result ? result.addresses : []; }; - _getAddressesAllRequest = (walletId: string): CachedRequest => { + _getAddressesAllRequest = ( + walletId: string + ): CachedRequest => { const foundRequest = find(this.addressesRequests, { walletId }); if (foundRequest && foundRequest.allRequest) return foundRequest.allRequest; return new CachedRequest(this.api.ada.getAddresses); }; - } diff --git a/source/renderer/app/stores/AppStore.js b/source/renderer/app/stores/AppStore.js index 0a7438bf8d..44002b465e 100644 --- a/source/renderer/app/stores/AppStore.js +++ b/source/renderer/app/stores/AppStore.js @@ -7,13 +7,15 @@ import { buildRoute } from '../utils/routing'; import { ROUTES } from '../routes-config'; import { DIALOGS, SCREENS } from '../../../common/ipc/constants'; import { openExternalUrlChannel } from '../ipc/open-external-url'; -import { toggleUiPartChannel, showUiPartChannel } from '../ipc/control-ui-parts'; +import { + toggleUiPartChannel, + showUiPartChannel, +} from '../ipc/control-ui-parts'; import { getGPUStatusChannel } from '../ipc/get-gpu-status.ipc'; import type { GpuStatus } from '../types/gpuStatus'; export default class AppStore extends Store { - @observable error: ?LocalizableError = null; @observable isAboutDialogOpen = false; @observable isNetworkStatusDialogOpen = false; @@ -25,8 +27,12 @@ export default class AppStore extends Store { this.actions.router.goToRoute.listen(this._updateRouteLocation); this.actions.app.openAboutDialog.listen(this._openAboutDialog); this.actions.app.closeAboutDialog.listen(this._closeAboutDialog); - this.actions.app.openNetworkStatusDialog.listen(this._openNetworkStatusDialog); - this.actions.app.closeNetworkStatusDialog.listen(this._closeNetworkStatusDialog); + this.actions.app.openNetworkStatusDialog.listen( + this._openNetworkStatusDialog + ); + this.actions.app.closeNetworkStatusDialog.listen( + this._closeNetworkStatusDialog + ); this.actions.app.getGpuStatus.listen(this._getGpuStatus); this.actions.app.toggleBlockConsolidationStatusScreen.listen( this._toggleBlockConsolidationStatusScreen @@ -50,9 +56,15 @@ export default class AppStore extends Store { */ toggleUiPart = (uiPart: string) => { switch (uiPart) { - case DIALOGS.ABOUT: this._toggleAboutDialog(); break; - case DIALOGS.NETWORK_STATUS: this._toggleNetworkStatusDialog(); break; - case SCREENS.BLOCK_CONSOLIDATION: this._toggleBlockConsolidationStatusScreen(); break; + case DIALOGS.ABOUT: + this._toggleAboutDialog(); + break; + case DIALOGS.NETWORK_STATUS: + this._toggleNetworkStatusDialog(); + break; + case SCREENS.BLOCK_CONSOLIDATION: + this._toggleBlockConsolidationStatusScreen(); + break; default: } return Promise.resolve(); @@ -63,7 +75,9 @@ export default class AppStore extends Store { */ showUiPart = (uiPart: string) => { switch (uiPart) { - case SCREENS.ADA_REDEMPTION: this._showAdaRedemptionScreen(); break; + case SCREENS.ADA_REDEMPTION: + this._showAdaRedemptionScreen(); + break; default: } return Promise.resolve(); diff --git a/source/renderer/app/stores/NetworkStatusStore.js b/source/renderer/app/stores/NetworkStatusStore.js index 37fe6380e1..61f7595ad0 100644 --- a/source/renderer/app/stores/NetworkStatusStore.js +++ b/source/renderer/app/stores/NetworkStatusStore.js @@ -29,7 +29,7 @@ import type { GetNetworkStatusResponse } from '../api/nodes/types'; import type { CardanoNodeState, CardanoStatus, - TlsConfig + TlsConfig, } from '../../../common/types/cardano-node.types'; import type { NodeQueryParams } from '../api/nodes/requests/getNodeInfo'; import type { GetConsolidatedEpochsCountResponse } from '../../../common/ipc/api'; @@ -60,7 +60,6 @@ const NODE_STOPPED_STATES = [ // END CONSTANTS ---------------------------- export default class NetworkStatusStore extends Store { - // Initialize store properties _startTime = Date.now(); _tlsConfig: ?TlsConfig = null; @@ -78,7 +77,7 @@ export default class NetworkStatusStore extends Store { @observable systemStartTime: number = 0; @observable isNodeInSync = false; // 'true' if syncing & local/network blocks diff within limit @observable isNodeStopping = false; // 'true' if node is in `NODE_STOPPING_STATES` states - @observable isNodeStopped = false // 'true' if node is in `NODE_STOPPED_STATES` states + @observable isNodeStopped = false; // 'true' if node is in `NODE_STOPPED_STATES` states @observable hasBeenConnected = false; @observable syncProgress = null; @@ -91,10 +90,12 @@ export default class NetworkStatusStore extends Store { @observable latestNetworkBlockTimestamp = 0; // milliseconds @observable localTimeDifference: ?number = 0; // microseconds @observable isSystemTimeIgnored = false; // Tracks if NTP time checks are ignored - @observable getNetworkStatusRequest: Request = new Request( + @observable + getNetworkStatusRequest: Request = new Request( this.api.ada.getNetworkStatus ); - @observable forceCheckTimeDifferenceRequest: Request = new Request( + @observable + forceCheckTimeDifferenceRequest: Request = new Request( this.api.ada.getNetworkStatus ); @@ -151,7 +152,8 @@ export default class NetworkStatusStore extends Store { // Setup network status polling interval _setNetworkStatusPollingInterval = () => { this._networkStatusPollingInterval = setInterval( - this._updateNetworkStatus, NETWORK_STATUS_POLL_INTERVAL + this._updateNetworkStatus, + NETWORK_STATUS_POLL_INTERVAL ); }; @@ -160,7 +162,9 @@ export default class NetworkStatusStore extends Store { Logger.info('NetwortStatusStore: Requesting a restart of cardano-node'); await restartCardanoNodeChannel.send(); } catch (error) { - Logger.error('NetwortStatusStore: Restart of cardano-node failed', { error }); + Logger.error('NetwortStatusStore: Restart of cardano-node failed', { + error, + }); } } @@ -192,7 +196,9 @@ export default class NetworkStatusStore extends Store { Logger.info('NetworkStatusStore: Updating node status'); await setCachedCardanoStatusChannel.send(this._extractNodeStatus(this)); } catch (error) { - Logger.error('NetworkStatusStore: Error while updating node status', { error }); + Logger.error('NetworkStatusStore: Error while updating node status', { + error, + }); } }; @@ -209,7 +215,9 @@ export default class NetworkStatusStore extends Store { _requestCardanoState = async () => { Logger.info('NetworkStatusStore: requesting node state'); const state = await cardanoStateChangeChannel.request(); - Logger.info(`NetworkStatusStore: handling node state <${state}>`, { state }); + Logger.info(`NetworkStatusStore: handling node state <${state}>`, { + state, + }); await this._handleCardanoNodeStateChange(state); }; @@ -217,25 +225,35 @@ export default class NetworkStatusStore extends Store { try { Logger.info('NetworkStatusStore: requesting node status'); const status = await getCachedCardanoStatusChannel.request(); - Logger.info('NetworkStatusStore: received cached node status', { status }); - if (status) runInAction('assigning node status', () => Object.assign(this, status)); + Logger.info('NetworkStatusStore: received cached node status', { + status, + }); + if (status) + runInAction('assigning node status', () => Object.assign(this, status)); } catch (error) { - Logger.error('NetworkStatusStore: error while requesting node state', { error }); + Logger.error('NetworkStatusStore: error while requesting node state', { + error, + }); } }; _requestTlsConfig = async () => { try { const tlsConfig = await cardanoTlsConfigChannel.request(); - Logger.info('NetworkStatusStore: requesting tls config from main process'); + Logger.info( + 'NetworkStatusStore: requesting tls config from main process' + ); await this._updateTlsConfig(tlsConfig); } catch (error) { - Logger.error('NetworkStatusStore: error while requesting tls config', { error }); + Logger.error('NetworkStatusStore: error while requesting tls config', { + error, + }); } }; _updateTlsConfig = (config: ?TlsConfig): Promise => { - if (config == null || isEqual(config, this._tlsConfig)) return Promise.resolve(); + if (config == null || isEqual(config, this._tlsConfig)) + return Promise.resolve(); Logger.info('NetworkStatusStore: received tls config from main process'); this.api.ada.setRequestConfig(config); this._tlsConfig = config; @@ -244,18 +262,24 @@ export default class NetworkStatusStore extends Store { _handleCardanoNodeStateChange = async (state: CardanoNodeState) => { if (state === this.cardanoNodeState) return Promise.resolve(); - Logger.info(`NetworkStatusStore: handling cardano-node state <${state}>`, { state }); + Logger.info(`NetworkStatusStore: handling cardano-node state <${state}>`, { + state, + }); const wasConnected = this.isConnected; switch (state) { - case CardanoNodeStates.STARTING: break; - case CardanoNodeStates.RUNNING: await this._requestTlsConfig(); break; + case CardanoNodeStates.STARTING: + break; + case CardanoNodeStates.RUNNING: + await this._requestTlsConfig(); + break; case CardanoNodeStates.STOPPING: case CardanoNodeStates.EXITING: case CardanoNodeStates.UPDATING: - runInAction('reset _tlsConfig', () => this._tlsConfig = null); + runInAction('reset _tlsConfig', () => (this._tlsConfig = null)); this._setDisconnected(wasConnected); break; - default: this._setDisconnected(wasConnected); + default: + this._setDisconnected(wasConnected); } runInAction('setting cardanoNodeState', () => { this.cardanoNodeState = state; @@ -284,9 +308,7 @@ export default class NetworkStatusStore extends Store { }; _getSystemStartTime = async () => { - this._onReceiveSystemStartTime( - await getSystemStartTimeChannel.request() - ); + this._onReceiveSystemStartTime(await getSystemStartTimeChannel.request()); }; _getEpochsData = async () => { @@ -341,16 +363,17 @@ export default class NetworkStatusStore extends Store { const wasConnected = this.isConnected; try { - const networkStatus: GetNetworkStatusResponse = isForcedTimeDifferenceCheck ? ( - await this.forceCheckTimeDifferenceRequest.execute(queryParams).promise - ) : ( - await this.getNetworkStatusRequest.execute().promise - ); + const networkStatus: GetNetworkStatusResponse = isForcedTimeDifferenceCheck + ? await this.forceCheckTimeDifferenceRequest.execute(queryParams) + .promise + : await this.getNetworkStatusRequest.execute().promise; // In case we no longer have TLS config we ignore all API call responses // as this means we are in the Cardano shutdown (stopping|exiting|updating) sequence if (!this._tlsConfig) { - Logger.debug('NetworkStatusStore: Ignoring NetworkStatusRequest result during Cardano shutdown sequence...'); + Logger.debug( + 'NetworkStatusStore: Ignoring NetworkStatusRequest result during Cardano shutdown sequence...' + ); return; } @@ -378,14 +401,16 @@ export default class NetworkStatusStore extends Store { // Update localTimeDifference only in case NTP check status is not still pending if (localTimeInformation.status !== 'pending') { this.localTimeDifference = localTimeInformation.difference; - this.isNodeTimeCorrect = ( + this.isNodeTimeCorrect = this.localTimeDifference != null && // If we receive 'null' it means NTP check failed - this.localTimeDifference <= ALLOWED_TIME_DIFFERENCE - ); + this.localTimeDifference <= ALLOWED_TIME_DIFFERENCE; } }); - if (this._networkStatus === NETWORK_STATUS.CONNECTING && this.isNodeSubscribed) { + if ( + this._networkStatus === NETWORK_STATUS.CONNECTING && + this.isNodeSubscribed + ) { // We are connected for the first time, move on to syncing stage this._networkStatus = NETWORK_STATUS.SYNCING; Logger.info( @@ -403,85 +428,93 @@ export default class NetworkStatusStore extends Store { // If initial local block height isn't set, mark the first // result as the 'starting' height for the sync progress this.initialLocalHeight = localBlockchainHeight; - Logger.debug('NetworkStatusStore: Initial local block height', { localBlockchainHeight }); + Logger.debug('NetworkStatusStore: Initial local block height', { + localBlockchainHeight, + }); } // Update the local block height on each request const lastLocalBlockHeight = this.localBlockHeight; this.localBlockHeight = localBlockchainHeight; - Logger.debug('NetworkStatusStore: Local blockchain height', { localBlockchainHeight }); + Logger.debug('NetworkStatusStore: Local blockchain height', { + localBlockchainHeight, + }); // Update the network block height on each request const hasStartedReceivingBlocks = blockchainHeight > 0; const lastNetworkBlockHeight = this.networkBlockHeight; this.networkBlockHeight = blockchainHeight; if (hasStartedReceivingBlocks) { - Logger.debug('NetworkStatusStore: Network blockchain height', { blockchainHeight }); + Logger.debug('NetworkStatusStore: Network blockchain height', { + blockchainHeight, + }); } // Check if the local block height has ceased to change - const isLocalBlockHeightIncreasing = this.localBlockHeight > lastLocalBlockHeight; + const isLocalBlockHeightIncreasing = + this.localBlockHeight > lastLocalBlockHeight; if ( isLocalBlockHeightIncreasing || // New local block detected - this.latestLocalBlockTimestamp > Date.now() || // Guard against future timestamps - ( // Guard against incorrect system time - !this.isNodeTimeCorrect && !this.isSystemTimeIgnored - ) + this.latestLocalBlockTimestamp > Date.now() || // Guard against future timestamps // Guard against incorrect system time + (!this.isNodeTimeCorrect && !this.isSystemTimeIgnored) ) { this.latestLocalBlockTimestamp = Date.now(); // Record latest local block timestamp } - const latestLocalBlockAge = moment( - Date.now()).diff(moment(this.latestLocalBlockTimestamp) - ); - const isLocalBlockHeightStalling = latestLocalBlockAge > MAX_ALLOWED_STALL_DURATION; - const isLocalBlockHeightSyncing = ( - isLocalBlockHeightIncreasing || !isLocalBlockHeightStalling + const latestLocalBlockAge = moment(Date.now()).diff( + moment(this.latestLocalBlockTimestamp) ); + const isLocalBlockHeightStalling = + latestLocalBlockAge > MAX_ALLOWED_STALL_DURATION; + const isLocalBlockHeightSyncing = + isLocalBlockHeightIncreasing || !isLocalBlockHeightStalling; // Check if the network's block height has ceased to change - const isNetworkBlockHeightIncreasing = ( + const isNetworkBlockHeightIncreasing = hasStartedReceivingBlocks && - this.networkBlockHeight > lastNetworkBlockHeight - ); + this.networkBlockHeight > lastNetworkBlockHeight; if ( isNetworkBlockHeightIncreasing || // New network block detected - this.latestNetworkBlockTimestamp > Date.now() || // Guard against future timestamps - ( // Guard against incorrect system time - !this.isNodeTimeCorrect && !this.isSystemTimeIgnored - ) + this.latestNetworkBlockTimestamp > Date.now() || // Guard against future timestamps // Guard against incorrect system time + (!this.isNodeTimeCorrect && !this.isSystemTimeIgnored) ) { this.latestNetworkBlockTimestamp = Date.now(); // Record latest network block timestamp } - const latestNetworkBlockAge = moment( - Date.now()).diff(moment(this.latestNetworkBlockTimestamp) - ); - const isNetworkBlockHeightStalling = latestNetworkBlockAge > MAX_ALLOWED_STALL_DURATION; - const isNetworkBlockHeightSyncing = ( - isNetworkBlockHeightIncreasing || !isNetworkBlockHeightStalling + const latestNetworkBlockAge = moment(Date.now()).diff( + moment(this.latestNetworkBlockTimestamp) ); + const isNetworkBlockHeightStalling = + latestNetworkBlockAge > MAX_ALLOWED_STALL_DURATION; + const isNetworkBlockHeightSyncing = + isNetworkBlockHeightIncreasing || !isNetworkBlockHeightStalling; // Node is syncing in case we are receiving blocks and they are not stalling runInAction('update isNodeSyncing', () => { - this.isNodeSyncing = ( + this.isNodeSyncing = hasStartedReceivingBlocks && - (isLocalBlockHeightSyncing || isNetworkBlockHeightSyncing) - ); + (isLocalBlockHeightSyncing || isNetworkBlockHeightSyncing); }); runInAction('update isNodeInSync', () => { - const remainingUnsyncedBlocks = this.networkBlockHeight - this.localBlockHeight; - this.isNodeInSync = ( + const remainingUnsyncedBlocks = + this.networkBlockHeight - this.localBlockHeight; + this.isNodeInSync = this.isNodeSyncing && - remainingUnsyncedBlocks <= UNSYNCED_BLOCKS_ALLOWED - ); + remainingUnsyncedBlocks <= UNSYNCED_BLOCKS_ALLOWED; }); if (hasStartedReceivingBlocks) { const initialLocalHeight = this.initialLocalHeight || 0; - const blocksSyncedSinceStart = this.localBlockHeight - initialLocalHeight; - const totalUnsyncedBlocksAtStart = this.networkBlockHeight - initialLocalHeight; - Logger.debug('NetworkStatusStore: Total unsynced blocks at node start', { totalUnsyncedBlocksAtStart }); - Logger.debug('NetworkStatusStore: Blocks synced since node start', { blocksSyncedSinceStart }); + const blocksSyncedSinceStart = + this.localBlockHeight - initialLocalHeight; + const totalUnsyncedBlocksAtStart = + this.networkBlockHeight - initialLocalHeight; + Logger.debug( + 'NetworkStatusStore: Total unsynced blocks at node start', + { totalUnsyncedBlocksAtStart } + ); + Logger.debug('NetworkStatusStore: Blocks synced since node start', { + blocksSyncedSinceStart, + }); } }); @@ -489,13 +522,18 @@ export default class NetworkStatusStore extends Store { // We are synced for the first time, move on to running stage this._networkStatus = NETWORK_STATUS.RUNNING; this.actions.networkStatus.isSyncedAndReady.trigger(); - Logger.info(`========== Synced after ${this._getStartupTimeDelta()} milliseconds ==========`); + Logger.info( + `========== Synced after ${this._getStartupTimeDelta()} milliseconds ==========` + ); } if (wasConnected !== this.isConnected) { if (!this.isConnected) { if (!this.hasBeenConnected) { - runInAction('update hasBeenConnected', () => this.hasBeenConnected = true); + runInAction( + 'update hasBeenConnected', + () => (this.hasBeenConnected = true) + ); } Logger.debug('NetworkStatusStore: Connection Lost. Reconnecting...'); } else if (this.hasBeenConnected) { @@ -517,7 +555,10 @@ export default class NetworkStatusStore extends Store { this.isNodeInSync = false; if (wasConnected) { if (!this.hasBeenConnected) { - runInAction('update hasBeenConnected', () => this.hasBeenConnected = true); + runInAction( + 'update hasBeenConnected', + () => (this.hasBeenConnected = true) + ); } Logger.debug('NetworkStatusStore: Connection Lost. Reconnecting...'); } @@ -531,14 +572,12 @@ export default class NetworkStatusStore extends Store { if (this.isConnected) this._updateNetworkStatus({ force_ntp_check: true }); }; - @action _onCheckDiskSpace = ( - { - isNotEnoughDiskSpace, - diskSpaceRequired, - diskSpaceMissing, - diskSpaceRecommended, - }: CheckDiskSpaceResponse - ): Promise => { + @action _onCheckDiskSpace = ({ + isNotEnoughDiskSpace, + diskSpaceRequired, + diskSpaceMissing, + diskSpaceRecommended, + }: CheckDiskSpaceResponse): Promise => { this.isNotEnoughDiskSpace = isNotEnoughDiskSpace; this.diskSpaceRequired = diskSpaceRequired; this.diskSpaceMissing = diskSpaceMissing; @@ -573,10 +612,11 @@ export default class NetworkStatusStore extends Store { @computed get syncPercentage(): number { const { networkBlockHeight, localBlockHeight } = this; if (networkBlockHeight >= 1) { - if (localBlockHeight >= networkBlockHeight) { return 100; } - return localBlockHeight / networkBlockHeight * 100; + if (localBlockHeight >= networkBlockHeight) { + return 100; + } + return (localBlockHeight / networkBlockHeight) * 100; } return 0; } - } diff --git a/source/renderer/app/stores/NodeUpdateStore.js b/source/renderer/app/stores/NodeUpdateStore.js index 7bb3e57a54..8ccd3f1af5 100644 --- a/source/renderer/app/stores/NodeUpdateStore.js +++ b/source/renderer/app/stores/NodeUpdateStore.js @@ -6,7 +6,6 @@ import type { NodeSoftware } from '../api/nodes/types'; import { NODE_UPDATE_POLL_INTERVAL } from '../config/timingConfig'; export default class NodeUpdateStore extends Store { - @observable isUpdateAvailable = false; @observable isUpdatePostponed = false; @observable isNotificationExpanded = false; @@ -15,16 +14,24 @@ export default class NodeUpdateStore extends Store { // REQUESTS /* eslint-disable max-len */ - @observable nextUpdateRequest: Request = new Request(this.api.ada.nextUpdate); - @observable postponeUpdateRequest: Request> = new Request(this.api.ada.postponeUpdate); - @observable applyUpdateRequest: Request> = new Request(this.api.ada.applyUpdate); + @observable nextUpdateRequest: Request = new Request( + this.api.ada.nextUpdate + ); + @observable postponeUpdateRequest: Request> = new Request( + this.api.ada.postponeUpdate + ); + @observable applyUpdateRequest: Request> = new Request( + this.api.ada.applyUpdate + ); /* eslint-disable max-len */ setup() { const actions = this.actions.nodeUpdate; actions.acceptNodeUpdate.listen(this._acceptNodeUpdate); actions.postponeNodeUpdate.listen(this._postponeNodeUpdate); - actions.toggleNodeUpdateNotificationExpanded.listen(this._toggleNotificationExpanded); + actions.toggleNodeUpdateNotificationExpanded.listen( + this._toggleNotificationExpanded + ); setInterval(this.refreshNextUpdate, NODE_UPDATE_POLL_INTERVAL); } @@ -32,7 +39,12 @@ export default class NodeUpdateStore extends Store { if (this.stores.networkStatus.isSynced) { await this.nextUpdateRequest.execute(); const { result } = this.nextUpdateRequest; - if (result && !this.isUpdateAvailable && !this.isUpdatePostponed && !this.isUpdateInstalled) { + if ( + result && + !this.isUpdateAvailable && + !this.isUpdatePostponed && + !this.isUpdateInstalled + ) { runInAction('refreshNextUpdate', () => { this.isUpdateAvailable = true; this.isNotificationExpanded = true; @@ -56,5 +68,4 @@ export default class NodeUpdateStore extends Store { @action _toggleNotificationExpanded = () => { this.isNotificationExpanded = !this.isNotificationExpanded; }; - } diff --git a/source/renderer/app/stores/ProfileStore.js b/source/renderer/app/stores/ProfileStore.js index 996c1fa368..dfe318baa2 100644 --- a/source/renderer/app/stores/ProfileStore.js +++ b/source/renderer/app/stores/ProfileStore.js @@ -12,13 +12,16 @@ import globalMessages from '../i18n/global-messages'; import { WalletSupportRequestLogsCompressError } from '../i18n/errors'; import type { LogFiles, CompressedLogStatus } from '../types/LogTypes'; import { generateFileNameWithTimestamp } from '../../../common/utils/files'; -import { compressLogsChannel, downloadLogsChannel, getLogsChannel } from '../ipc/logs.ipc'; +import { + compressLogsChannel, + downloadLogsChannel, + getLogsChannel, +} from '../ipc/logs.ipc'; // TODO: refactor all parts that rely on this to ipc channels! const { ipcRenderer } = global; export default class SettingsStore extends Store { - LANGUAGE_OPTIONS = [ { value: 'en-US', label: globalMessages.languageEnglish }, { value: 'ja-JP', label: globalMessages.languageJapanese }, @@ -34,18 +37,36 @@ export default class SettingsStore extends Store { groupSize: 3, secondaryGroupSize: 0, fractionGroupSeparator: ' ', - fractionGroupSize: 0 + fractionGroupSize: 0, }; /* eslint-disable max-len */ - @observable getProfileLocaleRequest: Request = new Request(this.api.localStorage.getUserLocale); - @observable setProfileLocaleRequest: Request = new Request(this.api.localStorage.setUserLocale); - @observable getTermsOfUseAcceptanceRequest: Request = new Request(this.api.localStorage.getTermsOfUseAcceptance); - @observable setTermsOfUseAcceptanceRequest: Request = new Request(this.api.localStorage.setTermsOfUseAcceptance); - @observable getDataLayerMigrationAcceptanceRequest: Request = new Request(this.api.localStorage.getDataLayerMigrationAcceptance); - @observable setDataLayerMigrationAcceptanceRequest: Request = new Request(this.api.localStorage.setDataLayerMigrationAcceptance); - @observable getThemeRequest: Request = new Request(this.api.localStorage.getUserTheme); - @observable setThemeRequest: Request = new Request(this.api.localStorage.setUserTheme); + @observable getProfileLocaleRequest: Request = new Request( + this.api.localStorage.getUserLocale + ); + @observable setProfileLocaleRequest: Request = new Request( + this.api.localStorage.setUserLocale + ); + @observable getTermsOfUseAcceptanceRequest: Request = new Request( + this.api.localStorage.getTermsOfUseAcceptance + ); + @observable setTermsOfUseAcceptanceRequest: Request = new Request( + this.api.localStorage.setTermsOfUseAcceptance + ); + @observable + getDataLayerMigrationAcceptanceRequest: Request = new Request( + this.api.localStorage.getDataLayerMigrationAcceptance + ); + @observable + setDataLayerMigrationAcceptanceRequest: Request = new Request( + this.api.localStorage.setDataLayerMigrationAcceptance + ); + @observable getThemeRequest: Request = new Request( + this.api.localStorage.getUserTheme + ); + @observable setThemeRequest: Request = new Request( + this.api.localStorage.setUserTheme + ); @observable error: ?LocalizableError = null; @observable logFiles: LogFiles = {}; @observable compressedLogsFilePath: ?string = null; @@ -56,7 +77,9 @@ export default class SettingsStore extends Store { setup() { this.actions.profile.updateLocale.listen(this._updateLocale); this.actions.profile.acceptTermsOfUse.listen(this._acceptTermsOfUse); - this.actions.profile.acceptDataLayerMigration.listen(this._acceptDataLayerMigration); + this.actions.profile.acceptDataLayerMigration.listen( + this._acceptDataLayerMigration + ); this.actions.profile.updateTheme.listen(this._updateTheme); this.actions.profile.getLogs.listen(this._getLogs); this.actions.profile.getLogsAndCompress.listen(this._getLogsAndCompress); @@ -109,21 +132,21 @@ export default class SettingsStore extends Store { @computed get isCurrentThemeSet(): boolean { return ( - this.getThemeRequest.result !== null && - this.getThemeRequest.result !== '' + this.getThemeRequest.result !== null && this.getThemeRequest.result !== '' ); } @computed get hasLoadedCurrentTheme(): boolean { return ( - this.getThemeRequest.wasExecuted && - this.getThemeRequest.result !== null + this.getThemeRequest.wasExecuted && this.getThemeRequest.result !== null ); } @computed get termsOfUse(): string { const network = this.environment.isMainnet ? 'mainnet' : 'other'; - return require(`../i18n/locales/terms-of-use/${network}/${this.currentLocale}.md`); + return require(`../i18n/locales/terms-of-use/${network}/${ + this.currentLocale + }.md`); } @computed get hasLoadedTermsOfUseAcceptance(): boolean { @@ -190,23 +213,30 @@ export default class SettingsStore extends Store { _redirectToLanguageSelectionIfNoLocaleSet = () => { if (this.hasLoadedCurrentLocale && !this.isCurrentLocaleSet) { - this.actions.router.goToRoute.trigger({ route: ROUTES.PROFILE.LANGUAGE_SELECTION }); + this.actions.router.goToRoute.trigger({ + route: ROUTES.PROFILE.LANGUAGE_SELECTION, + }); } }; _redirectToTermsOfUseScreenIfTermsNotAccepted = () => { - const termsOfUseNotAccepted = this.hasLoadedTermsOfUseAcceptance && !this.areTermsOfUseAccepted; + const termsOfUseNotAccepted = + this.hasLoadedTermsOfUseAcceptance && !this.areTermsOfUseAccepted; if (this.isCurrentLocaleSet && termsOfUseNotAccepted) { - this.actions.router.goToRoute.trigger({ route: ROUTES.PROFILE.TERMS_OF_USE }); + this.actions.router.goToRoute.trigger({ + route: ROUTES.PROFILE.TERMS_OF_USE, + }); } }; - _isOnTermsOfUsePage = () => this.stores.app.currentRoute === ROUTES.PROFILE.TERMS_OF_USE; + _isOnTermsOfUsePage = () => + this.stores.app.currentRoute === ROUTES.PROFILE.TERMS_OF_USE; _redirectToDataLayerMigrationScreenIfMigrationHasNotAccepted = () => { const { isConnected } = this.stores.networkStatus; const dataLayerMigrationNotAccepted = - this.hasLoadedDataLayerMigrationAcceptance && !this.isDataLayerMigrationAccepted; + this.hasLoadedDataLayerMigrationAcceptance && + !this.isDataLayerMigrationAccepted; if ( isConnected && this.isCurrentLocaleSet && @@ -220,7 +250,9 @@ export default class SettingsStore extends Store { // in order to prevent future data migration checks this._acceptDataLayerMigration(); } else { - this.actions.router.goToRoute.trigger({ route: ROUTES.PROFILE.DATA_LAYER_MIGRATION }); + this.actions.router.goToRoute.trigger({ + route: ROUTES.PROFILE.DATA_LAYER_MIGRATION, + }); } } }; @@ -232,14 +264,16 @@ export default class SettingsStore extends Store { }; _redirectToMainUiAfterDataLayerMigrationIsAccepted = () => { - if (this.isDataLayerMigrationAccepted && this._isOnDataLayerMigrationPage()) { + if ( + this.isDataLayerMigrationAccepted && + this._isOnDataLayerMigrationPage() + ) { this._redirectToRoot(); } }; - _isOnDataLayerMigrationPage = () => ( - this.stores.app.currentRoute === ROUTES.PROFILE.DATA_LAYER_MIGRATION - ); + _isOnDataLayerMigrationPage = () => + this.stores.app.currentRoute === ROUTES.PROFILE.DATA_LAYER_MIGRATION; _redirectToRoot = () => { this.actions.router.goToRoute.trigger({ route: ROUTES.ROOT }); @@ -266,7 +300,9 @@ export default class SettingsStore extends Store { }; _compressLogs = action(async ({ logs }) => { - const { fileName = generateFileNameWithTimestamp() } = this.compressedLogsStatus; + const { + fileName = generateFileNameWithTimestamp(), + } = this.compressedLogsStatus; try { const outputPath = await compressLogsChannel.request({ logs: toJS(logs), @@ -324,5 +360,4 @@ export default class SettingsStore extends Store { this.compressedLogsStatus = {}; this.isSubmittingBugReport = false; }; - } diff --git a/source/renderer/app/stores/SidebarStore.js b/source/renderer/app/stores/SidebarStore.js index 238a52a6aa..555e7bb077 100644 --- a/source/renderer/app/stores/SidebarStore.js +++ b/source/renderer/app/stores/SidebarStore.js @@ -8,7 +8,6 @@ import { formattedWalletAmount } from '../utils/formatters'; import type { SidebarWalletType } from '../types/sidebarTypes'; export default class SidebarStore extends Store { - CATEGORIES = sidebarConfig.CATEGORIES; @observable activeSidebarCategory: string = this.CATEGORIES[0].route; @@ -21,9 +20,7 @@ export default class SidebarStore extends Store { actions.activateSidebarCategory.listen(this._onActivateSidebarCategory); actions.walletSelected.listen(this._onWalletSelected); - this.registerReactions([ - this._syncSidebarRouteWithRouter, - ]); + this.registerReactions([this._syncSidebarRouteWithRouter]); } @computed get wallets(): Array { @@ -33,12 +30,16 @@ export default class SidebarStore extends Store { title: w.name, info: formattedWalletAmount(w.amount), isConnected: networkStatus.isConnected, - isRestoreActive: get(w, 'syncState.tag') === WalletSyncStateTags.RESTORING, + isRestoreActive: + get(w, 'syncState.tag') === WalletSyncStateTags.RESTORING, restoreProgress: get(w, 'syncState.data.percentage.quantity', 0), })); } - @action _onActivateSidebarCategory = (params: { category: string, showSubMenu?: boolean }) => { + @action _onActivateSidebarCategory = (params: { + category: string, + showSubMenu?: boolean, + }) => { const { category, showSubMenu } = params; if (category !== this.activeSidebarCategory) { this.activeSidebarCategory = category; @@ -78,10 +79,10 @@ export default class SidebarStore extends Store { _syncSidebarRouteWithRouter = () => { const route = this.stores.app.currentRoute; - this.CATEGORIES.forEach((category) => { + this.CATEGORIES.forEach(category => { // If the current route starts with the root of the category - if (route.indexOf(category.route) === 0) this._setActivateSidebarCategory(category.route); + if (route.indexOf(category.route) === 0) + this._setActivateSidebarCategory(category.route); }); }; - } diff --git a/source/renderer/app/stores/TransactionsStore.js b/source/renderer/app/stores/TransactionsStore.js index 8f2a2479c4..8a9f6d7356 100644 --- a/source/renderer/app/stores/TransactionsStore.js +++ b/source/renderer/app/stores/TransactionsStore.js @@ -1,10 +1,19 @@ // @flow -import { observable, computed, action, extendObservable, runInAction } from 'mobx'; +import { + observable, + computed, + action, + extendObservable, + runInAction, +} from 'mobx'; import BigNumber from 'bignumber.js'; import { find, get } from 'lodash'; import Store from './lib/Store'; import Request from './lib/LocalizedRequest'; -import { WalletTransaction, transactionTypes } from '../domains/WalletTransaction'; +import { + WalletTransaction, + transactionTypes, +} from '../domains/WalletTransaction'; import type { GetTransactionsResponse } from '../api/transactions/types'; import type { UnconfirmedAmount } from '../types/unconfirmedAmountType'; import { isValidAmountInLovelaces } from '../utils/validations'; @@ -23,7 +32,6 @@ type TransactionFeeRequest = { }; export default class TransactionsStore extends Store { - INITIAL_SEARCH_LIMIT = null; // 'null' value stands for 'load all' SEARCH_LIMIT_INCREASE = 500; SEARCH_SKIP = 0; @@ -32,20 +40,19 @@ export default class TransactionsStore extends Store { @observable transactionsRequests: Array<{ walletId: string, recentRequest: Request, - allRequest: Request + allRequest: Request, }> = []; @observable _searchOptionsForWallets = {}; - @observable unconfirmedAmount: UnconfirmedAmount = this._getEmptyUnconfirmedAmount(); + @observable + unconfirmedAmount: UnconfirmedAmount = this._getEmptyUnconfirmedAmount(); setup() { // const actions = this.actions.transactions; // actions.filterTransactions.listen(this._updateSearchTerm); // actions.loadMoreTransactions.listen(this._increaseSearchLimit); - this.registerReactions([ - this._ensureSearchOptionsForActiveWallet, - ]); + this.registerReactions([this._ensureSearchOptionsForActiveWallet]); } @computed get recentTransactionsRequest(): Request { @@ -75,7 +82,8 @@ export default class TransactionsStore extends Store { const request = this._getTransactionsAllRequest(wallet.id); if (searchTerm && request.result && request.result.transactions) { return request.result.transactions.filter( - transaction => transaction.title.search(new RegExp(searchTerm, 'i')) !== -1 + transaction => + transaction.title.search(new RegExp(searchTerm, 'i')) !== -1 ); } return request.result ? request.result.transactions : []; @@ -120,7 +128,8 @@ export default class TransactionsStore extends Store { if (this.stores.networkStatus.isConnected) { const allWallets = this.stores.wallets.all; for (const wallet of allWallets) { - const isRestoreActive = get(wallet, 'syncState.tag', '') === 'restoring'; + const isRestoreActive = + get(wallet, 'syncState.tag', '') === 'restoring'; const isRestoreCompleted = restoredWalletId === wallet.id; const recentRequest = this._getTransactionsRecentRequest(wallet.id); if (isRestoreCompleted && recentRequest.isExecuting) { @@ -158,15 +167,23 @@ export default class TransactionsStore extends Store { } }; - calculateTransactionFee = async (transactionFeeRequest: TransactionFeeRequest) => { + calculateTransactionFee = async ( + transactionFeeRequest: TransactionFeeRequest + ) => { const { walletId } = transactionFeeRequest; const wallet = this.stores.wallets.getWalletById(walletId); - const accountIndex = await this.stores.addresses.getAccountIndexByWalletId(walletId); + const accountIndex = await this.stores.addresses.getAccountIndexByWalletId( + walletId + ); if (!wallet) { - throw new Error('Active wallet required before calculating transaction fees.'); + throw new Error( + 'Active wallet required before calculating transaction fees.' + ); } if (!accountIndex) { - throw new Error('Active account required before calculating transaction fees.'); + throw new Error( + 'Active account required before calculating transaction fees.' + ); } return this.api.ada.calculateTransactionFee({ ...transactionFeeRequest, @@ -175,9 +192,8 @@ export default class TransactionsStore extends Store { }); }; - validateAmount = (amountInLovelaces: string): Promise => ( - Promise.resolve(isValidAmountInLovelaces(amountInLovelaces)) - ); + validateAmount = (amountInLovelaces: string): Promise => + Promise.resolve(isValidAmountInLovelaces(amountInLovelaces)); // ======================= PRIVATE ========================== // @@ -203,13 +219,18 @@ export default class TransactionsStore extends Store { this._setUnconfirmedAmount(this._getEmptyUnconfirmedAmount()); } - _getTransactionsRecentRequest = (walletId: string): Request => { + _getTransactionsRecentRequest = ( + walletId: string + ): Request => { const foundRequest = find(this.transactionsRequests, { walletId }); - if (foundRequest && foundRequest.recentRequest) return foundRequest.recentRequest; + if (foundRequest && foundRequest.recentRequest) + return foundRequest.recentRequest; return new Request(this.api.ada.getTransactions); }; - _getTransactionsAllRequest = (walletId: string): Request => { + _getTransactionsAllRequest = ( + walletId: string + ): Request => { const foundRequest = find(this.transactionsRequests, { walletId }); if (foundRequest && foundRequest.allRequest) return foundRequest.allRequest; return new Request(this.api.ada.getTransactions); @@ -234,7 +255,9 @@ export default class TransactionsStore extends Store { const unconfirmedAmount = this._getEmptyUnconfirmedAmount(); for (const transaction of result.transactions) { if (transaction.numberOfConfirmations <= TX_UNCONFIRMED_THRESHOLD) { - unconfirmedAmount.total = unconfirmedAmount.total.plus(transaction.amount.absoluteValue()); + unconfirmedAmount.total = unconfirmedAmount.total.plus( + transaction.amount.absoluteValue() + ); if (transaction.type === transactionTypes.EXPEND) { unconfirmedAmount.outgoing = unconfirmedAmount.outgoing.plus( transaction.amount.absoluteValue() @@ -265,11 +288,10 @@ export default class TransactionsStore extends Store { [wallet.id]: { searchTerm: '', searchLimit: this.INITIAL_SEARCH_LIMIT, - searchSkip: this.SEARCH_SKIP - } + searchSkip: this.SEARCH_SKIP, + }, }); }); } - } - + }; } diff --git a/source/renderer/app/stores/UiDialogsStore.js b/source/renderer/app/stores/UiDialogsStore.js index 472d1570e4..e7225f5ece 100644 --- a/source/renderer/app/stores/UiDialogsStore.js +++ b/source/renderer/app/stores/UiDialogsStore.js @@ -3,7 +3,6 @@ import { observable, action } from 'mobx'; import Store from './lib/Store'; export default class UiDialogsStore extends Store { - @observable activeDialog: ?Function = null; @observable secondsSinceActiveDialogIsOpen: number = 0; @observable dataForActiveDialog: Object = {}; @@ -14,14 +13,15 @@ export default class UiDialogsStore extends Store { this.actions.dialogs.open.listen(this._onOpen); this.actions.dialogs.closeActiveDialog.listen(this._onClose); this.actions.dialogs.resetActiveDialog.listen(this._reset); - this.actions.dialogs.updateDataForActiveDialog.listen(this._onUpdateDataForActiveDialog); + this.actions.dialogs.updateDataForActiveDialog.listen( + this._onUpdateDataForActiveDialog + ); } isOpen = (dialog: Function): boolean => this.activeDialog === dialog; - countdownSinceDialogOpened = (countDownTo: number) => ( - Math.max(countDownTo - this.secondsSinceActiveDialogIsOpen, 0) - ); + countdownSinceDialogOpened = (countDownTo: number) => + Math.max(countDownTo - this.secondsSinceActiveDialogIsOpen, 0); @action _onOpen = ({ dialog }: { dialog: Function }) => { this._reset(); @@ -49,5 +49,4 @@ export default class UiDialogsStore extends Store { this.secondsSinceActiveDialogIsOpen = 0; this.dataForActiveDialog = {}; }; - } diff --git a/source/renderer/app/stores/UiNotificationsStore.js b/source/renderer/app/stores/UiNotificationsStore.js index 4f982bd763..3b0a14859a 100644 --- a/source/renderer/app/stores/UiNotificationsStore.js +++ b/source/renderer/app/stores/UiNotificationsStore.js @@ -5,7 +5,6 @@ import Store from './lib/Store'; import type { Notification } from '../types/notificationType'; export default class UiNotificationsStore extends Store { - @observable activeNotifications: {} = {}; setup() { @@ -19,7 +18,9 @@ export default class UiNotificationsStore extends Store { const notification = { id, duration: duration || null, - secondsTimerInterval: duration ? setInterval(this._updateSeconds, 1000, id) : null, + secondsTimerInterval: duration + ? setInterval(this._updateSeconds, 1000, id) + : null, }; if (this.isOpen(id)) { @@ -34,14 +35,15 @@ export default class UiNotificationsStore extends Store { @action _set = (notification: Notification) => { this.activeNotifications = { ...this.activeNotifications, - ...set({}, notification.id, notification) + ...set({}, notification.id, notification), }; }; @action _onClose = ({ id }: { id: string }) => { const notification = this.activeNotifications[id]; if (notification) { - if (notification.secondsTimerInterval) clearInterval(notification.secondsTimerInterval); + if (notification.secondsTimerInterval) + clearInterval(notification.secondsTimerInterval); this.activeNotifications = omit(this.activeNotifications, id); } }; @@ -53,5 +55,4 @@ export default class UiNotificationsStore extends Store { if (notification.duration === 0) this._onClose({ id }); } }; - } diff --git a/source/renderer/app/stores/WalletBackupStore.js b/source/renderer/app/stores/WalletBackupStore.js index 8ad0d5e1a3..6f21b16042 100644 --- a/source/renderer/app/stores/WalletBackupStore.js +++ b/source/renderer/app/stores/WalletBackupStore.js @@ -3,10 +3,12 @@ import { observable, action, computed } from 'mobx'; import Store from './lib/Store'; import WalletBackupDialog from '../components/wallet/WalletBackupDialog'; import { WALLET_BACKUP_STEPS } from '../types/walletBackupTypes'; -import type { RecoveryPhraseWord, walletBackupStep } from '../types/walletBackupTypes'; +import type { + RecoveryPhraseWord, + walletBackupStep, +} from '../types/walletBackupTypes'; export default class WalletBackupStore extends Store { - @observable inProgress = false; @observable currentStep: walletBackupStep = WALLET_BACKUP_STEPS.NOT_INITIATED; @observable recoveryPhrase = []; @@ -25,24 +27,36 @@ export default class WalletBackupStore extends Store { setup() { const a = this.actions.walletBackup; a.initiateWalletBackup.listen(this._initiateWalletBackup); - a.acceptPrivacyNoticeForWalletBackup.listen(this._acceptPrivacyNoticeForWalletBackup); - a.continueToRecoveryPhraseForWalletBackup.listen(this._continueToRecoveryPhraseForWalletBackup); + a.acceptPrivacyNoticeForWalletBackup.listen( + this._acceptPrivacyNoticeForWalletBackup + ); + a.continueToRecoveryPhraseForWalletBackup.listen( + this._continueToRecoveryPhraseForWalletBackup + ); a.startWalletBackup.listen(this._startWalletBackup); - a.addWordToWalletBackupVerification.listen(this._addWordToWalletBackupVerification); + a.addWordToWalletBackupVerification.listen( + this._addWordToWalletBackupVerification + ); a.clearEnteredRecoveryPhrase.listen(this._clearEnteredRecoveryPhrase); a.acceptWalletBackupTermDevice.listen(this._acceptWalletBackupTermDevice); - a.acceptWalletBackupTermRecovery.listen(this._acceptWalletBackupTermRecovery); + a.acceptWalletBackupTermRecovery.listen( + this._acceptWalletBackupTermRecovery + ); a.restartWalletBackup.listen(this._restartWalletBackup); a.cancelWalletBackup.listen(this._cancelWalletBackup); a.finishWalletBackup.listen(this._finishWalletBackup); this.actions.app.initAppEnvironment.listen(() => {}); } - @action _initiateWalletBackup = (params: { recoveryPhrase: Array }) => { + @action _initiateWalletBackup = (params: { + recoveryPhrase: Array, + }) => { this.recoveryPhrase = params.recoveryPhrase; this.inProgress = true; this.currentStep = WALLET_BACKUP_STEPS.PRIVACY_WARNING; - this.recoveryPhraseWords = this.recoveryPhrase.map((word: string) => ({ word })); + this.recoveryPhraseWords = this.recoveryPhrase.map((word: string) => ({ + word, + })); this.recoveryPhraseShuffled = this.recoveryPhrase .sort(() => 0.5 - Math.random()) .map(w => ({ word: w, isActive: true })); @@ -78,7 +92,10 @@ export default class WalletBackupStore extends Store { this.currentStep = WALLET_BACKUP_STEPS.RECOVERY_PHRASE_ENTRY; }; - @action _addWordToWalletBackupVerification = (params: { word: string, index: number }) => { + @action _addWordToWalletBackupVerification = (params: { + word: string, + index: number, + }) => { const { word, index } = params; this.enteredPhrase.push({ word }); const pickedWord = this.recoveryPhraseShuffled[index]; @@ -119,6 +136,5 @@ export default class WalletBackupStore extends Store { @action _finishWalletBackup = async () => { this.inProgress = false; - } - + }; } diff --git a/source/renderer/app/stores/WalletSettingsStore.js b/source/renderer/app/stores/WalletSettingsStore.js index d2ca4901a8..4009917fdb 100644 --- a/source/renderer/app/stores/WalletSettingsStore.js +++ b/source/renderer/app/stores/WalletSettingsStore.js @@ -8,16 +8,27 @@ import Wallet, { WalletAssuranceModeOptions } from '../domains/Wallet'; import type { WalletExportToFileParams } from '../actions/wallet-settings-actions'; export default class WalletSettingsStore extends Store { - WALLET_ASSURANCE_LEVEL_OPTIONS = [ - { value: WalletAssuranceModeOptions.NORMAL, label: globalMessages.assuranceLevelNormal }, - { value: WalletAssuranceModeOptions.STRICT, label: globalMessages.assuranceLevelStrict }, + { + value: WalletAssuranceModeOptions.NORMAL, + label: globalMessages.assuranceLevelNormal, + }, + { + value: WalletAssuranceModeOptions.STRICT, + label: globalMessages.assuranceLevelStrict, + }, ]; /* eslint-disable max-len */ - @observable updateWalletRequest: Request = new Request(this.api.ada.updateWallet); - @observable updateSpendingPasswordRequest: Request = new Request(this.api.ada.updateSpendingPassword); - @observable exportWalletToFileRequest: Request> = new Request(this.api.ada.exportWalletToFile); + @observable updateWalletRequest: Request = new Request( + this.api.ada.updateWallet + ); + @observable updateSpendingPasswordRequest: Request = new Request( + this.api.ada.updateSpendingPassword + ); + @observable exportWalletToFileRequest: Request> = new Request( + this.api.ada.exportWalletToFile + ); /* eslint-enable max-len */ @observable walletFieldBeingEdited = null; @@ -49,16 +60,32 @@ export default class WalletSettingsStore extends Store { this.walletFieldBeingEdited = null; }; - @action _updateSpendingPassword = async ({ walletId, oldPassword, newPassword }: { - walletId: string, oldPassword: ?string, newPassword: ?string, + @action _updateSpendingPassword = async ({ + walletId, + oldPassword, + newPassword, + }: { + walletId: string, + oldPassword: ?string, + newPassword: ?string, }) => { - await this.updateSpendingPasswordRequest.execute({ walletId, oldPassword, newPassword }); + await this.updateSpendingPasswordRequest.execute({ + walletId, + oldPassword, + newPassword, + }); this.actions.dialogs.closeActiveDialog.trigger(); this.updateSpendingPasswordRequest.reset(); this.stores.wallets.refreshWalletsData(); }; - @action _updateWalletField = async ({ field, value }: { field: string, value: string }) => { + @action _updateWalletField = async ({ + field, + value, + }: { + field: string, + value: string, + }) => { const activeWallet = this.stores.wallets.active; if (!activeWallet) return; @@ -69,7 +96,7 @@ export default class WalletSettingsStore extends Store { const wallet = await this.updateWalletRequest.execute({ walletId: walletData.walletId, name: walletData.name, - assuranceLevel: walletData.assurance + assuranceLevel: walletData.assurance, }).promise; if (!wallet) return; @@ -84,8 +111,11 @@ export default class WalletSettingsStore extends Store { @action _exportToFile = async (params: WalletExportToFileParams) => { const { walletId, filePath, password } = params; - await this.exportWalletToFileRequest.execute({ walletId, filePath, password }); + await this.exportWalletToFileRequest.execute({ + walletId, + filePath, + password, + }); this.actions.dialogs.closeActiveDialog.trigger(); - } - + }; } diff --git a/source/renderer/app/stores/WalletsStore.js b/source/renderer/app/stores/WalletsStore.js index 67ded1628f..09ed5c61e2 100644 --- a/source/renderer/app/stores/WalletsStore.js +++ b/source/renderer/app/stores/WalletsStore.js @@ -20,7 +20,6 @@ import type { WalletImportFromFileParams } from '../actions/wallets-actions'; */ export default class WalletsStore extends Store { - WALLET_REFRESH_INTERVAL = 5000; // REQUESTS @@ -28,21 +27,44 @@ export default class WalletsStore extends Store { @observable active: ?Wallet = null; @observable isRestoreActive: boolean = false; @observable restoringWalletId: ?string = null; - @observable walletsRequest: Request> = new Request(this.api.ada.getWallets); - @observable importFromFileRequest: Request = new Request(this.api.ada.importWalletFromFile); - @observable createWalletRequest: Request = new Request(this.api.ada.createWallet); - @observable getWalletAddressesRequest: Request = new Request(this.api.ada.getAddresses); - @observable deleteWalletRequest: Request = new Request(this.api.ada.deleteWallet); - @observable sendMoneyRequest: Request = new Request(this.api.ada.createTransaction); - @observable getWalletRecoveryPhraseRequest: Request> = new Request(this.api.ada.getWalletRecoveryPhrase); - @observable getWalletCertificateAdditionalMnemonicsRequest: Request> = new Request(this.api.ada.getWalletCertificateAdditionalMnemonics); - @observable getWalletCertificateRecoveryPhraseRequest: Request> = new Request(this.api.ada.getWalletCertificateRecoveryPhrase); - @observable getWalletRecoveryPhraseFromCertificateRequest: Request> = new Request(this.api.ada.getWalletRecoveryPhraseFromCertificate); - @observable restoreRequest: Request = new Request(this.api.ada.restoreWallet); + @observable walletsRequest: Request> = new Request( + this.api.ada.getWallets + ); + @observable importFromFileRequest: Request = new Request( + this.api.ada.importWalletFromFile + ); + @observable createWalletRequest: Request = new Request( + this.api.ada.createWallet + ); + @observable getWalletAddressesRequest: Request = new Request( + this.api.ada.getAddresses + ); + @observable deleteWalletRequest: Request = new Request( + this.api.ada.deleteWallet + ); + @observable sendMoneyRequest: Request = new Request( + this.api.ada.createTransaction + ); + @observable getWalletRecoveryPhraseRequest: Request< + Array + > = new Request(this.api.ada.getWalletRecoveryPhrase); + @observable getWalletCertificateAdditionalMnemonicsRequest: Request< + Array + > = new Request(this.api.ada.getWalletCertificateAdditionalMnemonics); + @observable getWalletCertificateRecoveryPhraseRequest: Request< + Array + > = new Request(this.api.ada.getWalletCertificateRecoveryPhrase); + @observable getWalletRecoveryPhraseFromCertificateRequest: Request< + Array + > = new Request(this.api.ada.getWalletRecoveryPhraseFromCertificate); + @observable restoreRequest: Request = new Request( + this.api.ada.restoreWallet + ); /* eslint-enable max-len */ @observable walletExportType: walletExportTypeChoices = 'paperWallet'; - @observable walletExportMnemonic = 'marine joke dry silk ticket thing sugar stereo aim'; + @observable walletExportMnemonic = + 'marine joke dry silk ticket thing sugar stereo aim'; @observable createPaperWalletCertificateStep = 0; @observable walletCertificatePassword = null; @observable walletCertificateAddress = null; @@ -52,7 +74,11 @@ export default class WalletsStore extends Store { @observable certificateTemplate = null; @observable additionalMnemonicWords = null; - _newWalletDetails: { name: string, mnemonic: string, spendingPassword: ?string } = { + _newWalletDetails: { + name: string, + mnemonic: string, + spendingPassword: ?string, + } = { name: '', mnemonic: '', spendingPassword: null, @@ -62,9 +88,7 @@ export default class WalletsStore extends Store { setup() { setInterval(this._pollRefresh, this.WALLET_REFRESH_INTERVAL); - this.registerReactions([ - this._updateActiveWalletOnRouteChanges, - ]); + this.registerReactions([this._updateActiveWalletOnRouteChanges]); const { router, walletBackup, wallets, app } = this.actions; wallets.createWallet.listen(this._create); @@ -83,17 +107,15 @@ export default class WalletsStore extends Store { app.initAppEnvironment.listen(() => {}); } - _create = async (params: { - name: string, - spendingPassword: ?string, - }) => { + _create = async (params: { name: string, spendingPassword: ?string }) => { Object.assign(this._newWalletDetails, params); try { - const recoveryPhrase: ?Array = await ( - this.getWalletRecoveryPhraseRequest.execute().promise - ); + const recoveryPhrase: ?Array = await this.getWalletRecoveryPhraseRequest.execute() + .promise; if (recoveryPhrase != null) { - this.actions.walletBackup.initiateWalletBackup.trigger({ recoveryPhrase }); + this.actions.walletBackup.initiateWalletBackup.trigger({ + recoveryPhrase, + }); } } catch (error) { throw error; @@ -101,10 +123,16 @@ export default class WalletsStore extends Store { }; _finishCreation = async () => { - this._newWalletDetails.mnemonic = this.stores.walletBackup.recoveryPhrase.join(' '); - const wallet = await this.createWalletRequest.execute(this._newWalletDetails).promise; + this._newWalletDetails.mnemonic = this.stores.walletBackup.recoveryPhrase.join( + ' ' + ); + const wallet = await this.createWalletRequest.execute( + this._newWalletDetails + ).promise; if (wallet) { - await this.walletsRequest.patch(result => { result.push(wallet); }); + await this.walletsRequest.patch(result => { + result.push(wallet); + }); this.actions.dialogs.closeActiveDialog.trigger(); this.goToWalletRoute(wallet.id); } @@ -142,7 +170,8 @@ export default class WalletsStore extends Store { spendingPassword: ?string, }) => { const restoredWallet = await this.restoreRequest.execute(params).promise; - if (!restoredWallet) throw new Error('Restored wallet was not received correctly'); + if (!restoredWallet) + throw new Error('Restored wallet was not received correctly'); await this._patchWalletRequestWithNewWallet(restoredWallet); this.actions.dialogs.closeActiveDialog.trigger(); this.restoreRequest.reset(); @@ -150,14 +179,20 @@ export default class WalletsStore extends Store { this.refreshWalletsData(); }; - _sendMoney = async ({ receiver, amount, password }: { + _sendMoney = async ({ + receiver, + amount, + password, + }: { receiver: string, amount: string, password: ?string, }) => { const wallet = this.active; if (!wallet) throw new Error('Active wallet required before sending.'); - const accountIndex = await this.stores.addresses.getAccountIndexByWalletId(wallet.id); + const accountIndex = await this.stores.addresses.getAccountIndexByWalletId( + wallet.id + ); await this.sendMoneyRequest.execute({ address: receiver, @@ -186,7 +221,9 @@ export default class WalletsStore extends Store { @computed get hasAnyWallets(): boolean { if (this.walletsRequest.result == null) return false; - return this.walletsRequest.wasExecuted && this.walletsRequest.result.length > 0; + return ( + this.walletsRequest.wasExecuted && this.walletsRequest.result.length > 0 + ); } @computed get hasMaxWallets(): boolean { @@ -215,13 +252,13 @@ export default class WalletsStore extends Store { return matchRoute(ROUTES.WALLETS.ROOT + '(/*rest)', currentRoute); } - getWalletById = (id: string): (?Wallet) => this.all.find(w => w.id === id); + getWalletById = (id: string): ?Wallet => this.all.find(w => w.id === id); - getWalletByName = (name: string): (?Wallet) => this.all.find(w => w.name === name); + getWalletByName = (name: string): ?Wallet => + this.all.find(w => w.name === name); - getWalletRoute = (walletId: string, page: string = 'summary'): string => ( - buildRoute(ROUTES.WALLETS.PAGE, { id: walletId, page }) - ); + getWalletRoute = (walletId: string, page: string = 'summary'): string => + buildRoute(ROUTES.WALLETS.PAGE, { id: walletId, page }); // ACTIONS @@ -248,7 +285,7 @@ export default class WalletsStore extends Store { _pollRefresh = async () => { const { isSynced } = this.stores.networkStatus; - return isSynced && await this.refreshWalletsData(); + return isSynced && (await this.refreshWalletsData()); }; _updateActiveWalletOnRouteChanges = () => { @@ -257,8 +294,12 @@ export default class WalletsStore extends Store { const isWalletAddPage = matchRoute(ROUTES.WALLETS.ADD, currentRoute); runInAction('WalletsStore::_updateActiveWalletOnRouteChanges', () => { // There are not wallets loaded (yet) -> unset active and return - if (isWalletAddPage || !hasAnyWalletLoaded) return this._unsetActiveWallet(); - const match = matchRoute(`${ROUTES.WALLETS.ROOT}/:id(*page)`, currentRoute); + if (isWalletAddPage || !hasAnyWalletLoaded) + return this._unsetActiveWallet(); + const match = matchRoute( + `${ROUTES.WALLETS.ROOT}/:id(*page)`, + currentRoute + ); if (match) { // We have a route for a specific wallet -> lets try to find it const walletForCurrentRoute = this.all.find(w => w.id === match.id); @@ -284,14 +325,16 @@ export default class WalletsStore extends Store { isValidAddress = (address: string) => this.api.ada.isValidAddress(address); - isValidMnemonic = (mnemonic: string) => this.api.ada.isValidMnemonic(mnemonic); + isValidMnemonic = (mnemonic: string) => + this.api.ada.isValidMnemonic(mnemonic); - isValidCertificateMnemonic = ( - mnemonic: string, - ) => this.api.ada.isValidCertificateMnemonic(mnemonic); + isValidCertificateMnemonic = (mnemonic: string) => + this.api.ada.isValidCertificateMnemonic(mnemonic); // TODO - call endpoint to check if private key is valid - isValidPrivateKey = () => { return true; }; // eslint-disable-line + isValidPrivateKey = () => { + return true; + }; // eslint-disable-line @action refreshWalletsData = async () => { // Prevent wallets data refresh if polling is blocked @@ -309,7 +352,8 @@ export default class WalletsStore extends Store { runInAction('refresh active wallet restore', () => { const restoringWallet = find(result, ['syncState.tag', 'restoring']); const restoringWalletId = get(restoringWallet, 'id', null); - restoredWalletId = restoringWalletId === null && this.restoringWalletId || null; + restoredWalletId = + (restoringWalletId === null && this.restoringWalletId) || null; this._setIsRestoreActive(restoringWalletId); }); runInAction('refresh address data', () => { @@ -322,11 +366,17 @@ export default class WalletsStore extends Store { }); runInAction('refresh transaction data', () => { const walletIds = result.map((wallet: Wallet) => wallet.id); - this.stores.transactions.transactionsRequests = walletIds.map(walletId => ({ - walletId, - recentRequest: this.stores.transactions._getTransactionsRecentRequest(walletId), - allRequest: this.stores.transactions._getTransactionsAllRequest(walletId), - })); + this.stores.transactions.transactionsRequests = walletIds.map( + walletId => ({ + walletId, + recentRequest: this.stores.transactions._getTransactionsRecentRequest( + walletId + ), + allRequest: this.stores.transactions._getTransactionsAllRequest( + walletId + ), + }) + ); this.stores.transactions._refreshTransactionData(restoredWalletId); }); } @@ -367,18 +417,19 @@ export default class WalletsStore extends Store { const spendingPassword = mnemonicToSeedHex(certificatePassword.join(' ')); // Unscramble 18-word wallet certificate mnemonic to 12-word mnemonic - const unscrambledRecoveryPhrase: Array = await ( - this.getWalletRecoveryPhraseFromCertificateRequest.execute({ + const unscrambledRecoveryPhrase: Array = await this.getWalletRecoveryPhraseFromCertificateRequest.execute( + { passphrase: spendingPassword, scrambledInput: scrambledInput.join(' '), - }).promise - ); + } + ).promise; data.recoveryPhrase = unscrambledRecoveryPhrase.join(' '); this.getWalletRecoveryPhraseFromCertificateRequest.reset(); } const restoredWallet = await this.restoreRequest.execute(data).promise; - if (!restoredWallet) throw new Error('Restored wallet was not received correctly'); + if (!restoredWallet) + throw new Error('Restored wallet was not received correctly'); await this._patchWalletRequestWithNewWallet(restoredWallet); this.actions.dialogs.closeActiveDialog.trigger(); this.restoreRequest.reset(); @@ -386,12 +437,17 @@ export default class WalletsStore extends Store { this.refreshWalletsData(); }; - @action _importWalletFromFile = async (params: WalletImportFromFileParams) => { + @action _importWalletFromFile = async ( + params: WalletImportFromFileParams + ) => { const { filePath, walletName, spendingPassword } = params; const importedWallet = await this.importFromFileRequest.execute({ - filePath, walletName, spendingPassword, + filePath, + walletName, + spendingPassword, }).promise; - if (!importedWallet) throw new Error('Imported wallet was not received correctly'); + if (!importedWallet) + throw new Error('Imported wallet was not received correctly'); await this._patchWalletRequestWithNewWallet(importedWallet); this.actions.dialogs.closeActiveDialog.trigger(); this.importFromFileRequest.reset(); @@ -423,7 +479,9 @@ export default class WalletsStore extends Store { @action _onRouteChange = (options: { route: string, params: ?Object }) => { // Reset the send request anytime we visit the send page (e.g: to remove any previous errors) - if (matchRoute(ROUTES.WALLETS.SEND, buildRoute(options.route, options.params))) { + if ( + matchRoute(ROUTES.WALLETS.SEND, buildRoute(options.route, options.params)) + ) { this.sendMoneyRequest.reset(); } }; @@ -452,9 +510,9 @@ export default class WalletsStore extends Store { * Using mobx flows: https://mobx.js.org/best/actions.html#flows * @private */ - _generateCertificate = flow(function *generateCertificate( - params: { filePath: string } - ): Generator { + _generateCertificate = flow(function* generateCertificate(params: { + filePath: string, + }): Generator { try { // Pause polling in order not to show Paper wallet in the UI this._pausePolling(); @@ -463,14 +521,12 @@ export default class WalletsStore extends Store { this._updateCertificateCreationState(true); // Generate wallet recovery phrase - const recoveryPhrase: Array = yield ( - this.getWalletRecoveryPhraseRequest.execute().promise - ); + const recoveryPhrase: Array = yield this.getWalletRecoveryPhraseRequest.execute() + .promise; // Generate 9-words (additional) mnemonic - const additionalMnemonicWords: Array = yield ( - this.getWalletCertificateAdditionalMnemonicsRequest.execute().promise - ); + const additionalMnemonicWords: Array = yield this.getWalletCertificateAdditionalMnemonicsRequest.execute() + .promise; this.additionalMnemonicWords = additionalMnemonicWords.join(' '); // Generate spending password from 9-word mnemonic and save to store @@ -478,13 +534,15 @@ export default class WalletsStore extends Store { this.walletCertificatePassword = spendingPassword; // Generate paper wallet scrambled mnemonic - const walletCertificateRecoveryPhrase: Array = yield ( - this.getWalletCertificateRecoveryPhraseRequest.execute({ + const walletCertificateRecoveryPhrase: Array = yield this.getWalletCertificateRecoveryPhraseRequest.execute( + { passphrase: spendingPassword, input: recoveryPhrase.join(' '), - }).promise + } + ).promise; + this.walletCertificateRecoveryPhrase = walletCertificateRecoveryPhrase.join( + ' ' ); - this.walletCertificateRecoveryPhrase = walletCertificateRecoveryPhrase.join(' '); // Create temporary wallet const walletData = { @@ -505,14 +563,18 @@ export default class WalletsStore extends Store { } // Set wallet certificate address - const walletAddress = get(walletAddresses, ['addresses', '0', 'id'], null); + const walletAddress = get( + walletAddresses, + ['addresses', '0', 'id'], + null + ); this.walletCertificateAddress = walletAddress; // download pdf certificate yield this._downloadCertificate( walletAddress, walletCertificateRecoveryPhrase, - params.filePath, + params.filePath ); } catch (error) { throw error; @@ -524,7 +586,7 @@ export default class WalletsStore extends Store { _downloadCertificate = async ( address: string, recoveryPhrase: Array, - filePath: string, + filePath: string ) => { const locale = this.stores.profile.currentLocale; const intl = i18nContext(locale); @@ -536,7 +598,7 @@ export default class WalletsStore extends Store { intl, filePath, isMainnet, - buildLabel + buildLabel, }); runInAction('handle successful certificate download', () => { // Reset progress @@ -557,9 +619,7 @@ export default class WalletsStore extends Store { this.generatingCertificateInProgress = state; }); - @action _setCertificateTemplate = (params: { - selectedTemplate: string, - }) => { + @action _setCertificateTemplate = (params: { selectedTemplate: string }) => { this.certificateTemplate = params.selectedTemplate; this._updateCertificateStep(); }; @@ -570,7 +630,9 @@ export default class WalletsStore extends Store { @action _updateCertificateStep = (isBack: boolean = false) => { const currrentCertificateStep = this.certificateStep || 0; - this.certificateStep = isBack ? currrentCertificateStep - 1 : currrentCertificateStep + 1; + this.certificateStep = isBack + ? currrentCertificateStep - 1 + : currrentCertificateStep + 1; }; @action _closeCertificateGeneration = () => { @@ -586,5 +648,4 @@ export default class WalletsStore extends Store { this.certificateTemplate = false; this.certificateStep = null; }; - } diff --git a/source/renderer/app/stores/WindowStore.js b/source/renderer/app/stores/WindowStore.js index e47e416cfa..14bf4cdd89 100644 --- a/source/renderer/app/stores/WindowStore.js +++ b/source/renderer/app/stores/WindowStore.js @@ -6,7 +6,6 @@ import Store from './lib/Store'; const { ipcRenderer } = global; export default class WindowStore extends Store { - _isTest: boolean = false; setup() { @@ -28,8 +27,10 @@ export default class WindowStore extends Store { _resizeWindow = ({ width, height }: { width: number, height: number }) => { // TODO: refactor to ipc channel - ipcRenderer.send('resize-window', { width, height, animate: !this._isTest }); + ipcRenderer.send('resize-window', { + width, + height, + animate: !this._isTest, + }); }; - - } diff --git a/source/renderer/app/stores/index.js b/source/renderer/app/stores/index.js index 8ecb706506..1910b3727d 100644 --- a/source/renderer/app/stores/index.js +++ b/source/renderer/app/stores/index.js @@ -61,41 +61,44 @@ const storeNames = Object.keys(storeClasses); // Helpers function executeOnEveryStore(fn: (store: Store) => void) { - storeNames.forEach((name) => { + storeNames.forEach(name => { if (stores && stores[name]) fn(stores[name]); }); } // Set up and return the stores for this app -> also used to reset all stores to defaults -export default action((api, actions, router): StoresMap => { +export default action( + (api, actions, router): StoresMap => { + function createStoreInstanceOf(StoreSubClass: Class): T { + return new StoreSubClass(api, actions); + } - function createStoreInstanceOf(StoreSubClass: Class): T { - return new StoreSubClass(api, actions); - } - - // Teardown existing stores - if (stores) executeOnEveryStore((store) => store.teardown()); + // Teardown existing stores + if (stores) executeOnEveryStore(store => store.teardown()); - // Create fresh instances of all stores - stores = observable({ - adaRedemption: createStoreInstanceOf(AdaRedemptionStore), - addresses: createStoreInstanceOf(AddressesStore), - app: createStoreInstanceOf(AppStore), - networkStatus: createStoreInstanceOf(NetworkStatusStore), - nodeUpdate: createStoreInstanceOf(NodeUpdateStore), - profile: createStoreInstanceOf(ProfileStore), - router, - sidebar: createStoreInstanceOf(SidebarStore), - transactions: createStoreInstanceOf(TransactionsStore), - uiDialogs: createStoreInstanceOf(UiDialogsStore), - uiNotifications: createStoreInstanceOf(UiNotificationsStore), - wallets: createStoreInstanceOf(WalletsStore), - walletBackup: createStoreInstanceOf(WalletBackupStore), - walletSettings: createStoreInstanceOf(WalletSettingsStore), - window: createStoreInstanceOf(WindowStore), - }); - // Configure and initialize all stores - executeOnEveryStore((store) => { if (stores) store.configure(stores); }); - executeOnEveryStore((store) => store.initialize()); - return stores; -}); + // Create fresh instances of all stores + stores = observable({ + adaRedemption: createStoreInstanceOf(AdaRedemptionStore), + addresses: createStoreInstanceOf(AddressesStore), + app: createStoreInstanceOf(AppStore), + networkStatus: createStoreInstanceOf(NetworkStatusStore), + nodeUpdate: createStoreInstanceOf(NodeUpdateStore), + profile: createStoreInstanceOf(ProfileStore), + router, + sidebar: createStoreInstanceOf(SidebarStore), + transactions: createStoreInstanceOf(TransactionsStore), + uiDialogs: createStoreInstanceOf(UiDialogsStore), + uiNotifications: createStoreInstanceOf(UiNotificationsStore), + wallets: createStoreInstanceOf(WalletsStore), + walletBackup: createStoreInstanceOf(WalletBackupStore), + walletSettings: createStoreInstanceOf(WalletSettingsStore), + window: createStoreInstanceOf(WindowStore), + }); + // Configure and initialize all stores + executeOnEveryStore(store => { + if (stores) store.configure(stores); + }); + executeOnEveryStore(store => store.initialize()); + return stores; + } +); diff --git a/source/renderer/app/stores/lib/CachedRequest.js b/source/renderer/app/stores/lib/CachedRequest.js index 93bc8d8e45..ae059f7420 100644 --- a/source/renderer/app/stores/lib/CachedRequest.js +++ b/source/renderer/app/stores/lib/CachedRequest.js @@ -4,8 +4,10 @@ import { isEqual, remove } from 'lodash'; import Request from './Request'; import type { ApiCallType } from './Request'; -export default class CachedRequest extends Request { - +export default class CachedRequest extends Request< + Result, + Error +> { _apiCalls: Array = []; _isInvalidated: boolean = true; @@ -31,39 +33,50 @@ export default class CachedRequest extends Request // This timeout is necessary to avoid warnings from mobx // regarding triggering actions as side-effect of getters - setTimeout(action(() => { - this.isExecuting = true; - // Apply the previous result from this call immediately (cached) - if (existingApiCall) { - this.result = existingApiCall.result; - } - }), 0); + setTimeout( + action(() => { + this.isExecuting = true; + // Apply the previous result from this call immediately (cached) + if (existingApiCall) { + this.result = existingApiCall.result; + } + }), + 0 + ); // Issue api call & save it as promise that is handled to update the results of the operation this.promise = new Promise((resolve, reject) => { this._method(...callArgs) - .then((result) => { - setTimeout(action(() => { - this.result = result; - if (this._currentApiCall) this._currentApiCall.result = result; - this.isExecuting = false; - this.wasExecuted = true; - this._isInvalidated = false; - this._isWaitingForResponse = false; - resolve(result); - }), 1); + .then(result => { + setTimeout( + action(() => { + this.result = result; + if (this._currentApiCall) this._currentApiCall.result = result; + this.isExecuting = false; + this.wasExecuted = true; + this._isInvalidated = false; + this._isWaitingForResponse = false; + resolve(result); + }), + 1 + ); return result; }) - .catch(action((error) => { - setTimeout(action(() => { - this.error = error; - this.isExecuting = false; - this.isError = true; - this.wasExecuted = true; - this._isWaitingForResponse = false; - reject(error); - }), 1); - })); + .catch( + action(error => { + setTimeout( + action(() => { + this.error = error; + this.isExecuting = false; + this.isError = true; + this.wasExecuted = true; + this._isWaitingForResponse = false; + reject(error); + }), + 1 + ); + }) + ); }); this._isWaitingForResponse = true; @@ -99,5 +112,4 @@ export default class CachedRequest extends Request this._isInvalidated = true; return this; } - } diff --git a/source/renderer/app/stores/lib/LocalizedCachedRequest.js b/source/renderer/app/stores/lib/LocalizedCachedRequest.js index f411071aa9..bbb091e7e4 100644 --- a/source/renderer/app/stores/lib/LocalizedCachedRequest.js +++ b/source/renderer/app/stores/lib/LocalizedCachedRequest.js @@ -2,4 +2,7 @@ import CachedRequest from './CachedRequest'; import LocalizableError from '../../i18n/LocalizableError'; // eslint-disable-next-line -export default class LocalizedCachedRequest extends CachedRequest {} +export default class LocalizedCachedRequest extends CachedRequest< + Result, + LocalizableError +> {} diff --git a/source/renderer/app/stores/lib/LocalizedRequest.js b/source/renderer/app/stores/lib/LocalizedRequest.js index df2a51f61f..27dcf75f5b 100644 --- a/source/renderer/app/stores/lib/LocalizedRequest.js +++ b/source/renderer/app/stores/lib/LocalizedRequest.js @@ -1,4 +1,7 @@ import Request from './Request'; import LocalizableError from '../../i18n/LocalizableError'; -export default class LocalizedRequest extends Request {} +export default class LocalizedRequest extends Request< + Result, + LocalizableError +> {} diff --git a/source/renderer/app/stores/lib/Reaction.js b/source/renderer/app/stores/lib/Reaction.js index db118350f7..be72a073de 100644 --- a/source/renderer/app/stores/lib/Reaction.js +++ b/source/renderer/app/stores/lib/Reaction.js @@ -2,7 +2,6 @@ import { autorun } from 'mobx'; export default class Reaction { - reaction: () => void; hasBeenStarted: boolean; dispose: () => void; diff --git a/source/renderer/app/stores/lib/Request.js b/source/renderer/app/stores/lib/Request.js index aff34db0c2..760373f757 100644 --- a/source/renderer/app/stores/lib/Request.js +++ b/source/renderer/app/stores/lib/Request.js @@ -4,7 +4,8 @@ import { isEqual } from 'lodash/fp'; import ExtendableError from 'es6-error'; class NotExecutedYetError extends ExtendableError { - message = 'You have to call Request::execute before you can access it as promise'; + message = + 'You have to call Request::execute before you can access it as promise'; } export type ApiCallType = { @@ -13,7 +14,6 @@ export type ApiCallType = { }; export default class Request { - @observable result: ?Result = null; @observable error: ?Error = null; @observable isExecuting: boolean = false; @@ -36,40 +36,55 @@ export default class Request { // This timeout is necessary to avoid warnings from mobx // regarding triggering actions as side-effect of getters - setTimeout(action('Request::execute (setting this.isExecuting)', () => { - this.isExecuting = true; - }), 0); + setTimeout( + action('Request::execute (setting this.isExecuting)', () => { + this.isExecuting = true; + }), + 0 + ); // Issue api call & save it as promise that is handled to update the results of the operation this.promise = new Promise((resolve, reject) => { if (!this._method) reject('Request method not defined'); this._method(...callArgs) - .then((result) => { - setTimeout(action('Request::execute/then', () => { - if (this.result != null && isObservableArray(this.result) && Array.isArray(result)) { - // $FlowFixMe - this.result.replace(result); - } else { - this.result = result; - } - if (this._currentApiCall) this._currentApiCall.result = result; - this.isExecuting = false; - this.wasExecuted = true; - this._isWaitingForResponse = false; - resolve(result); - }), 1); + .then(result => { + setTimeout( + action('Request::execute/then', () => { + if ( + this.result != null && + isObservableArray(this.result) && + Array.isArray(result) + ) { + // $FlowFixMe + this.result.replace(result); + } else { + this.result = result; + } + if (this._currentApiCall) this._currentApiCall.result = result; + this.isExecuting = false; + this.wasExecuted = true; + this._isWaitingForResponse = false; + resolve(result); + }), + 1 + ); return result; }) - .catch(action('Request::execute/catch', (error) => { - setTimeout(action(() => { - this.error = error; - this.isExecuting = false; - this.isError = true; - this.wasExecuted = true; - this._isWaitingForResponse = false; - reject(error); - }), 1); - })); + .catch( + action('Request::execute/catch', error => { + setTimeout( + action(() => { + this.error = error; + this.isExecuting = false; + this.isError = true; + this.wasExecuted = true; + this._isWaitingForResponse = false; + reject(error); + }), + 1 + ); + }) + ); }); this._isWaitingForResponse = true; @@ -80,8 +95,8 @@ export default class Request { isExecutingWithArgs(...args: Array): boolean { return ( this.isExecuting && - (this._currentApiCall != null) - && isEqual(this._currentApiCall.args, args) + this._currentApiCall != null && + isEqual(this._currentApiCall.args, args) ); } @@ -111,13 +126,16 @@ export default class Request { * @returns {Promise} */ patch(modify: Function): Promise> { - return new Promise((resolve) => { - setTimeout(action(() => { - const override = modify(this.result); - if (override !== undefined) this.result = override; - if (this._currentApiCall) this._currentApiCall.result = this.result; - resolve(this); - }), 0); + return new Promise(resolve => { + setTimeout( + action(() => { + const override = modify(this.result); + if (override !== undefined) this.result = override; + if (this._currentApiCall) this._currentApiCall.result = this.result; + resolve(this); + }), + 0 + ); }); } @@ -131,5 +149,4 @@ export default class Request { this._currentApiCall = null; return this; } - } diff --git a/source/renderer/app/stores/lib/Store.js b/source/renderer/app/stores/lib/Store.js index d934126469..99379d0cc5 100644 --- a/source/renderer/app/stores/lib/Store.js +++ b/source/renderer/app/stores/lib/Store.js @@ -6,7 +6,6 @@ import type { Api } from '../../api/index'; import type { Environment } from '../../../../common/types/environment.types'; export default class Store { - stores: StoresMap; api: Api; actions: ActionsMap; diff --git a/source/renderer/app/themes/daedalus/cardano.js b/source/renderer/app/themes/daedalus/cardano.js index fb87ff8b10..e6eaf158d4 100644 --- a/source/renderer/app/themes/daedalus/cardano.js +++ b/source/renderer/app/themes/daedalus/cardano.js @@ -9,7 +9,8 @@ const rpAutocomplete = { '--rp-autocomplete-placeholder-color': 'rgba(94, 96, 102, 0.5)', '--rp-autocomplete-selected-word-box-bg-color': 'rgba(44, 187, 105, 0.9)', '--rp-autocomplete-selected-word-text-color': '#fafbfc', - '--rp-autocomplete-selected-words-font-family': 'NotoSans-Regular, NotoSansCJKjp-Regular', + '--rp-autocomplete-selected-words-font-family': + 'NotoSans-Regular, NotoSansCJKjp-Regular', }; // BUBBLE @@ -178,13 +179,16 @@ export default { '--theme-ada-redemption-headline-color': '#5e6066', '--theme-ada-redemption-instructions-color': '#5e6066', - '--theme-ada-redemption-success-overlay-background-color': 'rgba(44, 187, 105, 0.88)', + '--theme-ada-redemption-success-overlay-background-color': + 'rgba(44, 187, 105, 0.88)', '--theme-ada-redemption-success-overlay-border-color': '#fafbfc', '--theme-ada-redemption-success-overlay-message-color': '#fafbfc', '--theme-ada-redemption-success-overlay-button-text-color': '#fafbfc', '--theme-ada-redemption-success-overlay-button-text-color-hover': '#2cbb69', - '--theme-ada-redemption-success-overlay-button-background-color-hover': '#fafbfc', - '--theme-ada-redemption-disclaimer-background-color': 'rgba(171, 23, 0, 0.94)', + '--theme-ada-redemption-success-overlay-button-background-color-hover': + '#fafbfc', + '--theme-ada-redemption-disclaimer-background-color': + 'rgba(171, 23, 0, 0.94)', '--theme-ada-redemption-disclaimer-text-color': '#fafbfc', '--theme-ada-redemption-disclaimer-checkbox-color-check': '#fafbfc', '--theme-ada-redemption-disclaimer-checkbox-color-checked': '#fafbfc', @@ -216,7 +220,8 @@ export default { '--theme-button-attention-background-color': '#ea4c5b', '--theme-button-attention-background-color-hover': '#ec5d6b', '--theme-button-attention-background-color-active': '#d34452', - '--theme-button-attention-background-color-disabled': 'rgba(234, 76, 91, 0.3)', + '--theme-button-attention-background-color-disabled': + 'rgba(234, 76, 91, 0.3)', '--theme-button-attention-text-color-disabled': '#fafbfc', '--theme-button-attention-text-color': '#fafbfc', '--theme-button-attention-outline-color': '#ff707e', @@ -279,8 +284,10 @@ export default { '--theme-node-update-accept-button-background-color-hover': '#2cbb69', '--theme-node-update-accept-button-background-color-active': '#239554', '--theme-node-update-deny-button-background-color': 'rgba(86, 200, 135, 0.3)', - '--theme-node-update-deny-button-background-color-hover': 'rgba(44, 187, 105, 0.3)', - '--theme-node-update-deny-button-background-color-active': 'rgba(35, 149, 84, 0.3)', + '--theme-node-update-deny-button-background-color-hover': + 'rgba(44, 187, 105, 0.3)', + '--theme-node-update-deny-button-background-color-active': + 'rgba(35, 149, 84, 0.3)', '--theme-node-update-button-text-color': '#fafbfc', '--theme-notification-message-background-color': 'rgba(44, 187, 105, 0.88)', @@ -291,9 +298,12 @@ export default { '--theme-send-confirmation-dialog-send-values-color': '#ea4c5b', - '--theme-paper-wallet-create-certificate-dialog-recovery-phrase-background-color': 'rgba(68, 91, 124, 0.05)', - '--theme-paper-wallet-create-certificate-dialog-explorer-link-color': '#5e6066', - '--theme-paper-wallet-create-certificate-dialog-explorer-link-background-color': 'rgba(68, 91, 124, 0.05)', + '--theme-paper-wallet-create-certificate-dialog-recovery-phrase-background-color': + 'rgba(68, 91, 124, 0.05)', + '--theme-paper-wallet-create-certificate-dialog-explorer-link-color': + '#5e6066', + '--theme-paper-wallet-create-certificate-dialog-explorer-link-background-color': + 'rgba(68, 91, 124, 0.05)', '--theme-settings-body-background-color': '#efefef', '--theme-settings-pane-background-color': '#fafbfc', @@ -378,7 +388,8 @@ export default { '--theme-icon-ada-redemption-certificate-color': '#9eabbb', '--theme-icon-ada-redemption-no-wallets': '#5e6066', '--theme-icon-ada-summary-wallet-amount-symbol-color': '#5e6066', - '--theme-icon-ada-summary-wallet-pending-confirmation-symbol-color': '#5e6066', + '--theme-icon-ada-summary-wallet-pending-confirmation-symbol-color': + '#5e6066', '--theme-icon-add-wallet-dialog-big-button-color': '#ababab', '--theme-icon-copy-address-color': '#5e6066', '--theme-icon-back-button-color': '#5e6066', @@ -406,7 +417,8 @@ export default { '--theme-report-issue-button-background-color': '#2cbb69', '--theme-report-issue-button-background-color-hover': '#56c887', '--theme-report-issue-button-background-color-active': '#239554', - '--theme-report-issue-connecting-background-color': 'rgba(250, 251, 252, 0.05)', + '--theme-report-issue-connecting-background-color': + 'rgba(250, 251, 252, 0.05)', '--theme-report-issue-connecting-text-color': '#fafbfc', '--theme-report-issue-syncing-background-color': 'rgba(94, 96, 102, 0.05)', '--theme-report-issue-syncing-text-color': '#5e6066', diff --git a/source/renderer/app/themes/daedalus/dark-blue.js b/source/renderer/app/themes/daedalus/dark-blue.js index 39d82ed91e..20089e311a 100644 --- a/source/renderer/app/themes/daedalus/dark-blue.js +++ b/source/renderer/app/themes/daedalus/dark-blue.js @@ -9,7 +9,8 @@ const rpAutocomplete = { '--rp-autocomplete-placeholder-color': '#8793a1', '--rp-autocomplete-selected-word-box-bg-color': 'rgba(83, 99, 112, 0.5)', '--rp-autocomplete-selected-word-text-color': '#fafbfc', - '--rp-autocomplete-selected-words-font-family': 'NotoSans-Regular, NotoSansCJKjp-Regular', + '--rp-autocomplete-selected-words-font-family': + 'NotoSans-Regular, NotoSansCJKjp-Regular', }; // BUBBLE @@ -98,7 +99,8 @@ const rpOptions = { '--rp-option-line-height': '22px', '--rp-option-text-color': '#e9f4fe', '--rp-options-border-color': '#667a8a', - '--rp-options-shadow': '0 2px 8px 0 rgba(0, 0, 0, 0.2), 0 0 4px 0 rgba(0, 0, 0, 0.1)', + '--rp-options-shadow': + '0 2px 8px 0 rgba(0, 0, 0, 0.2), 0 0 4px 0 rgba(0, 0, 0, 0.1)', }; // SELECT @@ -177,13 +179,16 @@ export default { '--theme-ada-redemption-headline-color': '#e9f4fe', '--theme-ada-redemption-instructions-color': '#e9f4fe', - '--theme-ada-redemption-success-overlay-background-color': 'rgba(38, 51, 69, 0.88)', + '--theme-ada-redemption-success-overlay-background-color': + 'rgba(38, 51, 69, 0.88)', '--theme-ada-redemption-success-overlay-border-color': '#fafbfc', '--theme-ada-redemption-success-overlay-message-color': '#e9f4fe', '--theme-ada-redemption-success-overlay-button-text-color': '#e9f4fe', '--theme-ada-redemption-success-overlay-button-text-color-hover': '#263345', - '--theme-ada-redemption-success-overlay-button-background-color-hover': '#e9f4fe', - '--theme-ada-redemption-disclaimer-background-color': 'rgba(171, 23, 0, 0.94)', + '--theme-ada-redemption-success-overlay-button-background-color-hover': + '#e9f4fe', + '--theme-ada-redemption-disclaimer-background-color': + 'rgba(171, 23, 0, 0.94)', '--theme-ada-redemption-disclaimer-text-color': '#fafbfc', '--theme-ada-redemption-disclaimer-checkbox-color-check': '#fafbfc', '--theme-ada-redemption-disclaimer-checkbox-color-checked': '#fafbfc', @@ -215,7 +220,8 @@ export default { '--theme-button-attention-background-color': '#ea4c5b', '--theme-button-attention-background-color-hover': '#ec5d6b', '--theme-button-attention-background-color-active': '#d34452', - '--theme-button-attention-background-color-disabled': 'rgba(234, 76, 91, 0.3)', + '--theme-button-attention-background-color-disabled': + 'rgba(234, 76, 91, 0.3)', '--theme-button-attention-text-color-disabled': '#fafbfc', '--theme-button-attention-text-color': '#fafbfc', '--theme-button-attention-outline-color': '#ff707e', @@ -278,8 +284,10 @@ export default { '--theme-node-update-accept-button-background-color-hover': '#34465e', '--theme-node-update-accept-button-background-color-active': '#18202b', '--theme-node-update-deny-button-background-color': 'rgba(38, 51, 69, 0.3)', - '--theme-node-update-deny-button-background-color-hover': 'rgba(52, 70, 94, 0.3)', - '--theme-node-update-deny-button-background-color-active': 'rgba(24, 32, 43, 0.3)', + '--theme-node-update-deny-button-background-color-hover': + 'rgba(52, 70, 94, 0.3)', + '--theme-node-update-deny-button-background-color-active': + 'rgba(24, 32, 43, 0.3)', '--theme-node-update-button-text-color': '#fafbfc', '--theme-notification-message-background-color': 'rgba(83, 99, 112, 0.88)', @@ -290,9 +298,12 @@ export default { '--theme-send-confirmation-dialog-send-values-color': '#ea4c5b', - '--theme-paper-wallet-create-certificate-dialog-recovery-phrase-background-color': 'rgba(233, 244, 254, 0.05)', - '--theme-paper-wallet-create-certificate-dialog-explorer-link-color': '#e9f4fe', - '--theme-paper-wallet-create-certificate-dialog-explorer-link-background-color': 'rgba(233, 244, 254, 0.05)', + '--theme-paper-wallet-create-certificate-dialog-recovery-phrase-background-color': + 'rgba(233, 244, 254, 0.05)', + '--theme-paper-wallet-create-certificate-dialog-explorer-link-color': + '#e9f4fe', + '--theme-paper-wallet-create-certificate-dialog-explorer-link-background-color': + 'rgba(233, 244, 254, 0.05)', '--theme-settings-body-background-color': '#0b1926', '--theme-settings-pane-background-color': '#263345', @@ -348,9 +359,11 @@ export default { '--theme-transactions-card-income-background-color': '#e6ebf2', '--theme-transactions-card-expend-background-color': '#f2e6e6', '--theme-transactions-card-exchange-background-color': '#f2e6e6', - '--theme-transactions-state-failed-background-color': 'rgba(189, 197, 206, 0.4)', + '--theme-transactions-state-failed-background-color': + 'rgba(189, 197, 206, 0.4)', '--theme-transactions-state-failed-text-color': 'rgba(233, 244, 254, 0.4)', - '--theme-transactions-state-pending-background-color': 'rgba(189, 197, 206, 0.4)', + '--theme-transactions-state-pending-background-color': + 'rgba(189, 197, 206, 0.4)', '--theme-transactions-state-pending-stripes-color': 'rgba(78, 98, 128, 0.5)', '--theme-transactions-priority-color': 'rgba(250, 251, 252, 0.8)', '--theme-transactions-priority-low-background-color': '#542A2B', @@ -360,7 +373,8 @@ export default { '--theme-transactions-icon-type-expend-background-color': '#4f5f7a', '--theme-transactions-icon-type-income-background-color': '#3b6956', '--theme-transactions-icon-type-exchange-background-color': '#10aca4', - '--theme-transactions-icon-type-failed-background-color': 'rgba(234, 76, 91, 0.5)', + '--theme-transactions-icon-type-failed-background-color': + 'rgba(234, 76, 91, 0.5)', '--theme-transactions-arrow-stroke-color': '#e9f4fe', '--theme-uploader-text-color': '#e9f4fe', @@ -377,7 +391,8 @@ export default { '--theme-icon-ada-redemption-certificate-color': '#9eabbb', '--theme-icon-ada-redemption-no-wallets': '#e9f4fe', '--theme-icon-ada-summary-wallet-amount-symbol-color': '#e9f4fe', - '--theme-icon-ada-summary-wallet-pending-confirmation-symbol-color': '#e9f4fe', + '--theme-icon-ada-summary-wallet-pending-confirmation-symbol-color': + '#e9f4fe', '--theme-icon-add-wallet-dialog-big-button-color': 'rgba(233, 244, 254, 0.8)', '--theme-icon-copy-address-color': '#8793a1', '--theme-icon-back-button-color': '#e9f4fe', @@ -395,7 +410,8 @@ export default { '--theme-about-window-title-varsion-color': '#e9f4fe', '--theme-about-window-title-stroke-color': '#e9f4fe', '--theme-about-window-content-text-color': '#e9f4fe', - '--theme-about-window-content-bottom-border-color': 'rgba(233, 244, 254, 0.3)', + '--theme-about-window-content-bottom-border-color': + 'rgba(233, 244, 254, 0.3)', '--theme-about-window-copyright-color': '#e9f4fe', '--theme-backup-mnemonic-background-color': 'rgba(233, 244, 254, 0.05)', @@ -405,7 +421,8 @@ export default { '--theme-report-issue-button-background-color': '#536370', '--theme-report-issue-button-background-color-hover': '#667a8a', '--theme-report-issue-button-background-color-active': '#495863', - '--theme-report-issue-connecting-background-color': 'rgba(250, 251, 252, 0.05)', + '--theme-report-issue-connecting-background-color': + 'rgba(250, 251, 252, 0.05)', '--theme-report-issue-connecting-text-color': '#e9f4fe', '--theme-report-issue-syncing-background-color': 'rgba(250, 251, 252, 0.05)', '--theme-report-issue-syncing-text-color': '#e9f4fe', diff --git a/source/renderer/app/themes/daedalus/light-blue.js b/source/renderer/app/themes/daedalus/light-blue.js index 8c643405b5..e362179ef1 100644 --- a/source/renderer/app/themes/daedalus/light-blue.js +++ b/source/renderer/app/themes/daedalus/light-blue.js @@ -9,7 +9,8 @@ const rpAutocomplete = { '--rp-autocomplete-placeholder-color': 'rgba(94, 96, 102, 0.5)', '--rp-autocomplete-selected-word-box-bg-color': 'rgba(68, 91, 124, 0.5)', '--rp-autocomplete-selected-word-text-color': '#fafbfc', - '--rp-autocomplete-selected-words-font-family': 'NotoSans-Regular, NotoSansCJKjp-Regular', + '--rp-autocomplete-selected-words-font-family': + 'NotoSans-Regular, NotoSansCJKjp-Regular', }; // BUBBLE @@ -177,13 +178,16 @@ export default { '--theme-ada-redemption-headline-color': '#5e6066', '--theme-ada-redemption-instructions-color': '#5e6066', - '--theme-ada-redemption-success-overlay-background-color': 'rgba(36, 61, 98, 0.88)', + '--theme-ada-redemption-success-overlay-background-color': + 'rgba(36, 61, 98, 0.88)', '--theme-ada-redemption-success-overlay-border-color': '#fafbfc', '--theme-ada-redemption-success-overlay-message-color': '#fafbfc', '--theme-ada-redemption-success-overlay-button-text-color': '#fafbfc', '--theme-ada-redemption-success-overlay-button-text-color-hover': '#243e62', - '--theme-ada-redemption-success-overlay-button-background-color-hover': '#fafbfc', - '--theme-ada-redemption-disclaimer-background-color': 'rgba(171, 23, 0, 0.94)', + '--theme-ada-redemption-success-overlay-button-background-color-hover': + '#fafbfc', + '--theme-ada-redemption-disclaimer-background-color': + 'rgba(171, 23, 0, 0.94)', '--theme-ada-redemption-disclaimer-text-color': '#fafbfc', '--theme-ada-redemption-disclaimer-checkbox-color-check': '#fafbfc', '--theme-ada-redemption-disclaimer-checkbox-color-checked': '#fafbfc', @@ -215,7 +219,8 @@ export default { '--theme-button-attention-background-color': '#ea4c5b', '--theme-button-attention-background-color-hover': '#ec5d6b', '--theme-button-attention-background-color-active': '#d34452', - '--theme-button-attention-background-color-disabled': 'rgba(234, 76, 91, 0.3)', + '--theme-button-attention-background-color-disabled': + 'rgba(234, 76, 91, 0.3)', '--theme-button-attention-text-color-disabled': '#fafbfc', '--theme-button-attention-text-color': '#fafbfc', '--theme-button-attention-outline-color': '#ff707e', @@ -278,8 +283,10 @@ export default { '--theme-node-update-accept-button-background-color-hover': '#243e62', '--theme-node-update-accept-button-background-color-active': '#1e304a', '--theme-node-update-deny-button-background-color': 'rgba(68, 91, 124, 0.3)', - '--theme-node-update-deny-button-background-color-hover': 'rgba(36, 62, 98, 0.3)', - '--theme-node-update-deny-button-background-color-active': 'rgba(30, 48, 74, 0.3)', + '--theme-node-update-deny-button-background-color-hover': + 'rgba(36, 62, 98, 0.3)', + '--theme-node-update-deny-button-background-color-active': + 'rgba(30, 48, 74, 0.3)', '--theme-node-update-button-text-color': '#fafbfc', '--theme-notification-message-background-color': 'rgba(36, 61, 98, 0.88)', @@ -290,9 +297,12 @@ export default { '--theme-send-confirmation-dialog-send-values-color': '#ea4c5b', - '--theme-paper-wallet-create-certificate-dialog-recovery-phrase-background-color': 'rgba(68, 91, 124, 0.05)', - '--theme-paper-wallet-create-certificate-dialog-explorer-link-color': '#5e6066', - '--theme-paper-wallet-create-certificate-dialog-explorer-link-background-color': 'rgba(68, 91, 124, 0.05)', + '--theme-paper-wallet-create-certificate-dialog-recovery-phrase-background-color': + 'rgba(68, 91, 124, 0.05)', + '--theme-paper-wallet-create-certificate-dialog-explorer-link-color': + '#5e6066', + '--theme-paper-wallet-create-certificate-dialog-explorer-link-background-color': + 'rgba(68, 91, 124, 0.05)', '--theme-settings-body-background-color': '#ebeff2', '--theme-settings-pane-background-color': '#fafbfc', @@ -377,7 +387,8 @@ export default { '--theme-icon-ada-redemption-certificate-color': '#9eabbb', '--theme-icon-ada-redemption-no-wallets': '#5e6066', '--theme-icon-ada-summary-wallet-amount-symbol-color': '#5e6066', - '--theme-icon-ada-summary-wallet-pending-confirmation-symbol-color': '#5e6066', + '--theme-icon-ada-summary-wallet-pending-confirmation-symbol-color': + '#5e6066', '--theme-icon-add-wallet-dialog-big-button-color': '#8a98ab', '--theme-icon-copy-address-color': '#5e6066', '--theme-icon-back-button-color': '#5e6066', @@ -405,7 +416,8 @@ export default { '--theme-report-issue-button-background-color': '#445b7c', '--theme-report-issue-button-background-color-hover': '#697b96', '--theme-report-issue-button-background-color-active': '#364863', - '--theme-report-issue-connecting-background-color': 'rgba(250, 251, 252, 0.05)', + '--theme-report-issue-connecting-background-color': + 'rgba(250, 251, 252, 0.05)', '--theme-report-issue-connecting-text-color': '#fafbfc', '--theme-report-issue-syncing-background-color': 'rgba(94, 96, 102, 0.05)', '--theme-report-issue-syncing-text-color': '#5e6066', diff --git a/source/renderer/app/themes/index.global.scss b/source/renderer/app/themes/index.global.scss index 2ecab96a1b..f85e1c53c2 100644 --- a/source/renderer/app/themes/index.global.scss +++ b/source/renderer/app/themes/index.global.scss @@ -3,19 +3,87 @@ // ============ RESET =========== // http://meyerweb.com/eric/tools/css/reset -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, embed, -figure, figcaption, footer, header, hgroup, -menu, nav, output, ruby, section, summary, -time, mark, audio, video { +html, +body, +div, +span, +applet, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +big, +cite, +code, +del, +dfn, +em, +img, +ins, +kbd, +q, +s, +samp, +small, +strike, +strong, +sub, +sup, +tt, +var, +b, +u, +i, +center, +dl, +dt, +dd, +ol, +ul, +li, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td, +article, +aside, +canvas, +details, +embed, +figure, +figcaption, +footer, +header, +hgroup, +menu, +nav, +output, +ruby, +section, +summary, +time, +mark, +audio, +video { margin: 0; padding: 0; border: 0; @@ -24,21 +92,34 @@ time, mark, audio, video { vertical-align: baseline; } /* HTML5 display-role reset for older browsers */ -article, aside, details, figcaption, figure, -footer, header, hgroup, menu, nav, section { +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section { display: block; } body { line-height: 1; } -ol, ul { +ol, +ul { list-style: none; } -blockquote, q { +blockquote, +q { quotes: none; } -blockquote:before, blockquote:after, -q:before, q:after { +blockquote:before, +blockquote:after, +q:before, +q:after { content: ''; content: none; } @@ -62,102 +143,105 @@ button { @font-face { font-family: 'NotoSans-ExtraLight'; - src: url("../assets/fonts/NotoSans-ExtraLight.ttf") format("truetype"); + src: url('../assets/fonts/NotoSans-ExtraLight.ttf') format('truetype'); } @font-face { font-family: 'NotoSans-Thin'; - src: url("../assets/fonts/NotoSans-Thin.ttf") format("truetype"); + src: url('../assets/fonts/NotoSans-Thin.ttf') format('truetype'); } @font-face { font-family: 'NotoSansCJKjp-Thin'; - src: url("../assets/fonts/NotoSansCJKjp-Thin.otf") format("opentype"); + src: url('../assets/fonts/NotoSansCJKjp-Thin.otf') format('opentype'); } @font-face { font-family: 'NotoSans-Light'; - src: url("../assets/fonts/NotoSans-Light.ttf") format("truetype"); + src: url('../assets/fonts/NotoSans-Light.ttf') format('truetype'); } @font-face { font-family: 'NotoSansCJKjp-Light'; - src: url("../assets/fonts/NotoSansCJKjp-Light.otf") format("opentype"); + src: url('../assets/fonts/NotoSansCJKjp-Light.otf') format('opentype'); } @font-face { font-family: 'NotoSans-Regular'; - src: url("../assets/fonts/NotoSans-Regular.ttf") format("truetype"); + src: url('../assets/fonts/NotoSans-Regular.ttf') format('truetype'); } @font-face { font-family: 'NotoSansCJKjp-Regular'; - src: url("../assets/fonts/NotoSansCJKjp-Regular.otf") format("opentype"); + src: url('../assets/fonts/NotoSansCJKjp-Regular.otf') format('opentype'); } @font-face { font-family: 'NotoSans-Medium'; - src: url("../assets/fonts/NotoSans-Medium.ttf") format("truetype"); + src: url('../assets/fonts/NotoSans-Medium.ttf') format('truetype'); } @font-face { font-family: 'NotoSansCJKjp-Medium'; - src: url("../assets/fonts/NotoSansCJKjp-Medium.otf") format("opentype"); + src: url('../assets/fonts/NotoSansCJKjp-Medium.otf') format('opentype'); } @font-face { font-family: 'NotoSans-SemiBold'; - src: url("../assets/fonts/NotoSans-SemiBold.ttf") format("truetype"); + src: url('../assets/fonts/NotoSans-SemiBold.ttf') format('truetype'); } @font-face { font-family: 'NotoSans-Bold'; - src: url("../assets/fonts/NotoSans-Bold.ttf") format("truetype"); + src: url('../assets/fonts/NotoSans-Bold.ttf') format('truetype'); } @font-face { font-family: 'NotoSansCJKjp-Bold'; - src: url("../assets/fonts/NotoSansCJKjp-Bold.otf") format("opentype"); + src: url('../assets/fonts/NotoSansCJKjp-Bold.otf') format('opentype'); } @font-face { font-family: 'NotoSans-ExtraBold'; - src: url("../assets/fonts/NotoSans-ExtraBold.ttf") format("truetype"); + src: url('../assets/fonts/NotoSans-ExtraBold.ttf') format('truetype'); } @font-face { font-family: 'NotoSans-Black'; - src: url("../assets/fonts/NotoSans-Black.ttf") format("truetype"); + src: url('../assets/fonts/NotoSans-Black.ttf') format('truetype'); } @font-face { font-family: 'NotoSansCJKjp-Black'; - src: url("../assets/fonts/NotoSansCJKjp-Black.otf") format("opentype"); + src: url('../assets/fonts/NotoSansCJKjp-Black.otf') format('opentype'); } @font-face { font-family: 'Montserrat-Medium'; - src: url("../assets/fonts/Montserrat-Medium.ttf") format("truetype"); + src: url('../assets/fonts/Montserrat-Medium.ttf') format('truetype'); } @font-face { font-family: 'SFMono-Light'; - src: url("../assets/fonts/SFMono-Light.ttf") format("truetype"); + src: url('../assets/fonts/SFMono-Light.ttf') format('truetype'); } @font-face { font-family: 'SFMonoCJKjp-Light'; - src: url("../assets/fonts/SFMono-Light.otf") format("opentype"); + src: url('../assets/fonts/SFMono-Light.otf') format('opentype'); } // ============ BASE =========== -html, body, :global(#root), :global(#root) > [data-reactroot] { +html, +body, +:global(#root), +:global(#root) > [data-reactroot] { width: 100%; height: 100%; // Make the default font ugly so we immediately see when something // is not yet defined correctly in our UI - font-family: "Times New Roman", serif; + font-family: 'Times New Roman', serif; -webkit-font-smoothing: antialiased; user-select: none; } diff --git a/source/renderer/app/themes/mixins/animations.scss b/source/renderer/app/themes/mixins/animations.scss index c93068cdb2..1098a95036 100644 --- a/source/renderer/app/themes/mixins/animations.scss +++ b/source/renderer/app/themes/mixins/animations.scss @@ -1,9 +1,9 @@ @mixin animated-ellipsis($duration: 900, $width: 20px) { &:after { :global { - animation: ellipsis steps(4,end) #{$duration}ms infinite; + animation: ellipsis steps(4, end) #{$duration}ms infinite; } - content: "\2026"; /* ascii code for the ellipsis character */ + content: '\2026'; /* ascii code for the ellipsis character */ display: inline-block; margin-right: 0; overflow: hidden; diff --git a/source/renderer/app/themes/mixins/arrow.scss b/source/renderer/app/themes/mixins/arrow.scss index 38511a95e7..a723f5cc67 100644 --- a/source/renderer/app/themes/mixins/arrow.scss +++ b/source/renderer/app/themes/mixins/arrow.scss @@ -1,11 +1,16 @@ // CSS arrow box inspired from http://www.cssarrowplease.com/ @mixin arrow($direction, $bg-color, $border-color, $size) { - &:after, &:before { - @if $direction == down { top: 100%; } - @if $direction == up { bottom: 100%; } + &:after, + &:before { + @if $direction == down { + top: 100%; + } + @if $direction == up { + bottom: 100%; + } left: 50%; border: solid transparent; - content: " "; + content: ' '; height: 0; width: 0; position: absolute; @@ -14,16 +19,24 @@ &:after { border-color: rgba($bg-color, 0); - @if $direction == down { border-top-color: $bg-color; } - @if $direction == up { border-bottom-color: $bg-color; } + @if $direction == down { + border-top-color: $bg-color; + } + @if $direction == up { + border-bottom-color: $bg-color; + } border-width: $size; margin-left: -$size; } &:before { border-color: rgba($border-color, 0); - @if $direction == down { border-top-color: $border-color; } - @if $direction == up { border-bottom-color: $border-color; } + @if $direction == down { + border-top-color: $border-color; + } + @if $direction == up { + border-bottom-color: $border-color; + } border-width: $size; margin-left: -$size; } diff --git a/source/renderer/app/themes/overrides/ButtonOverrides.scss b/source/renderer/app/themes/overrides/ButtonOverrides.scss index d9dd6e3221..323934f9b6 100644 --- a/source/renderer/app/themes/overrides/ButtonOverrides.scss +++ b/source/renderer/app/themes/overrides/ButtonOverrides.scss @@ -13,9 +13,12 @@ .disclaimer { border: 1px solid var(--theme-button-disclaimer-border-color); min-height: 50px; - transition: box-shadow 0.2s cubic-bezier(0.4, 0, 1, 1), background-color 0.2s cubic-bezier(0.4, 0, 0.2, 1), color 0.2s cubic-bezier(0.4, 0, 0.2, 1); + transition: box-shadow 0.2s cubic-bezier(0.4, 0, 1, 1), + background-color 0.2s cubic-bezier(0.4, 0, 0.2, 1), + color 0.2s cubic-bezier(0.4, 0, 0.2, 1); - &:hover, &:active { + &:hover, + &:active { color: var(--theme-button-disclaimer-background-color); } &:disabled { diff --git a/source/renderer/app/themes/overrides/ModalOverrides.scss b/source/renderer/app/themes/overrides/ModalOverrides.scss index e442239811..1abd4cfe5a 100644 --- a/source/renderer/app/themes/overrides/ModalOverrides.scss +++ b/source/renderer/app/themes/overrides/ModalOverrides.scss @@ -13,7 +13,8 @@ & > .WalletExportDialogChoices_activeButton { color: var(--theme-dialog-choice-tabs-text-color-active); - border-bottom: 2px solid var(--theme-dialog-choice-tabs-bottom-border-color-active); + border-bottom: 2px solid + var(--theme-dialog-choice-tabs-bottom-border-color-active); } } } diff --git a/source/renderer/app/types/gpuStatus.js b/source/renderer/app/types/gpuStatus.js index 74fda1ae4e..3ffd705b58 100644 --- a/source/renderer/app/types/gpuStatus.js +++ b/source/renderer/app/types/gpuStatus.js @@ -12,5 +12,5 @@ export type GpuStatus = { video_encode: string, vpx_decode: string, webgl: string, - webgl2: string + webgl2: string, }; diff --git a/source/renderer/app/types/networkTypes.js b/source/renderer/app/types/networkTypes.js index 3cb58be56c..01698738eb 100644 --- a/source/renderer/app/types/networkTypes.js +++ b/source/renderer/app/types/networkTypes.js @@ -1,2 +1,7 @@ // @flow -export type networkType = 'mainnet' | 'staging' | 'testnet' | 'development' | string; +export type networkType = + | 'mainnet' + | 'staging' + | 'testnet' + | 'development' + | string; diff --git a/source/renderer/app/types/notificationType.js b/source/renderer/app/types/notificationType.js index 50de77617e..45c1dd3669 100644 --- a/source/renderer/app/types/notificationType.js +++ b/source/renderer/app/types/notificationType.js @@ -3,4 +3,4 @@ export type Notification = { id: string, duration: ?number, secondsTimerInterval: ?IntervalID, -} +}; diff --git a/source/renderer/app/types/redemptionTypes.js b/source/renderer/app/types/redemptionTypes.js index 80ae29fb59..d81e15d53f 100644 --- a/source/renderer/app/types/redemptionTypes.js +++ b/source/renderer/app/types/redemptionTypes.js @@ -1,6 +1,10 @@ // @flow export type RedemptionTypeChoices = - 'regular' | 'forceVended' | 'paperVended' | 'recoveryRegular' | 'recoveryForceVended'; + | 'regular' + | 'forceVended' + | 'paperVended' + | 'recoveryRegular' + | 'recoveryForceVended'; export const ADA_REDEMPTION_TYPES = { REGULAR: 'regular', diff --git a/source/renderer/app/types/unconfirmedAmountType.js b/source/renderer/app/types/unconfirmedAmountType.js index ef3fd8c380..2e9f806545 100644 --- a/source/renderer/app/types/unconfirmedAmountType.js +++ b/source/renderer/app/types/unconfirmedAmountType.js @@ -5,4 +5,4 @@ export type UnconfirmedAmount = { total: BigNumber, incoming: BigNumber, outgoing: BigNumber, -} +}; diff --git a/source/renderer/app/types/walletBackupTypes.js b/source/renderer/app/types/walletBackupTypes.js index 2ae70d1533..ad726be3a7 100644 --- a/source/renderer/app/types/walletBackupTypes.js +++ b/source/renderer/app/types/walletBackupTypes.js @@ -1,5 +1,9 @@ // @flow -export type walletBackupStep = 'privacyWarning' | 'recoveryPhraseDisplay' | 'recoveryPhraseEntry' | null; +export type walletBackupStep = + | 'privacyWarning' + | 'recoveryPhraseDisplay' + | 'recoveryPhraseEntry' + | null; export const WALLET_BACKUP_STEPS = { NOT_INITIATED: null, diff --git a/source/renderer/app/utils/ReactToolboxMobxForm.js b/source/renderer/app/utils/ReactToolboxMobxForm.js index 6ef07eaea4..75386d91d1 100644 --- a/source/renderer/app/utils/ReactToolboxMobxForm.js +++ b/source/renderer/app/utils/ReactToolboxMobxForm.js @@ -1,7 +1,6 @@ import MobxReactForm from 'mobx-react-form'; export default class ReactToolboxMobxForm extends MobxReactForm { - bindings() { return { ReactToolbox: { diff --git a/source/renderer/app/utils/crypto.js b/source/renderer/app/utils/crypto.js index 67cf97140f..70ba901e16 100644 --- a/source/renderer/app/utils/crypto.js +++ b/source/renderer/app/utils/crypto.js @@ -45,18 +45,27 @@ export const generateMnemonic = (ms: ?number = 12) => { }; export const scramblePaperWalletMnemonic = ( - passphrase: string, input: string + passphrase: string, + input: string ) => { const iv = new Uint8Array(8); window.crypto.getRandomValues(iv); - const scrambledInput = CardanoCrypto.PaperWallet.scrambleStrings(iv, passphrase, input); + const scrambledInput = CardanoCrypto.PaperWallet.scrambleStrings( + iv, + passphrase, + input + ); return scrambledInput.split(' '); }; export const unscramblePaperWalletMnemonic = ( - passphrase: string, scrambledInput: string + passphrase: string, + scrambledInput: string ) => { - const input = CardanoCrypto.PaperWallet.unscrambleStrings(passphrase, scrambledInput); + const input = CardanoCrypto.PaperWallet.unscrambleStrings( + passphrase, + scrambledInput + ); return input.split(' '); }; diff --git a/source/renderer/app/utils/formatters.js b/source/renderer/app/utils/formatters.js index 17ef1d373a..e50a10fa2e 100644 --- a/source/renderer/app/utils/formatters.js +++ b/source/renderer/app/utils/formatters.js @@ -1,10 +1,13 @@ // @flow import BigNumber from 'bignumber.js'; -import { DECIMAL_PLACES_IN_ADA, LOVELACES_PER_ADA } from '../config/numbersConfig'; +import { + DECIMAL_PLACES_IN_ADA, + LOVELACES_PER_ADA, +} from '../config/numbersConfig'; export const formattedWalletAmount = ( amount: BigNumber, - withCurrency: boolean = true, + withCurrency: boolean = true ) => { let formattedAmount = amount.toFormat(DECIMAL_PLACES_IN_ADA); @@ -19,14 +22,15 @@ export const formattedAmountToBigNumber = (amount: string) => { }; export const formattedAmountToNaturalUnits = (amount: string): string => { - const cleanedAmount = amount.replace('.', '').replace(/,/g, '').replace(/^0+/, ''); + const cleanedAmount = amount + .replace('.', '') + .replace(/,/g, '') + .replace(/^0+/, ''); return cleanedAmount === '' ? '0' : cleanedAmount; }; -export const formattedAmountWithoutTrailingZeros = (amount: string): string => ( - amount.replace(/0+$/, '').replace(/\.$/, '') -); +export const formattedAmountWithoutTrailingZeros = (amount: string): string => + amount.replace(/0+$/, '').replace(/\.$/, ''); -export const formattedAmountToLovelace = (amount: string): number => ( - parseInt(formattedAmountToBigNumber(amount).times(LOVELACES_PER_ADA), 10) -); +export const formattedAmountToLovelace = (amount: string): number => + parseInt(formattedAmountToBigNumber(amount).times(LOVELACES_PER_ADA), 10); diff --git a/source/renderer/app/utils/i18nContext.js b/source/renderer/app/utils/i18nContext.js index 0c0567770f..69df9d7858 100644 --- a/source/renderer/app/utils/i18nContext.js +++ b/source/renderer/app/utils/i18nContext.js @@ -2,7 +2,7 @@ import { IntlProvider } from 'react-intl'; // context that can be used outside React Component // e.g. intl.formatMessage() directly in pdf generator -export const i18nContext = (locale) => { +export const i18nContext = locale => { const messages = require(`../i18n/locales/${locale}.json`); const intlProvider = new IntlProvider({ locale, messages }, {}); const { intl } = intlProvider.getChildContext(); diff --git a/source/renderer/app/utils/index.js b/source/renderer/app/utils/index.js index 73f9ce8c29..a8dff5a5e1 100644 --- a/source/renderer/app/utils/index.js +++ b/source/renderer/app/utils/index.js @@ -4,5 +4,5 @@ import { generateMnemonic } from './crypto'; export default { crypto: { generateMnemonic, - } + }, }; diff --git a/source/renderer/app/utils/logging.js b/source/renderer/app/utils/logging.js index 089e116998..c7615aa6ea 100644 --- a/source/renderer/app/utils/logging.js +++ b/source/renderer/app/utils/logging.js @@ -23,9 +23,12 @@ const environmentData = { version, }; -const logToLevel = (level: string) => (message: string, data: ?Object) => ( - log[level](formatContext({ ...messageContext, level }), { message, data, environmentData }) -); +const logToLevel = (level: string) => (message: string, data: ?Object) => + log[level](formatContext({ ...messageContext, level }), { + message, + data, + environmentData, + }); export const Logger = { debug: logToLevel('debug'), diff --git a/source/renderer/app/utils/network.js b/source/renderer/app/utils/network.js index ee61298d2a..89f0cba905 100644 --- a/source/renderer/app/utils/network.js +++ b/source/renderer/app/utils/network.js @@ -8,7 +8,11 @@ import { TESTNET_EKG_URL, } from '../config/urlsConfig'; import serialize from './serialize'; -import { MAINNET, STAGING, TESTNET } from '../../../common/types/environment.types'; +import { + MAINNET, + STAGING, + TESTNET, +} from '../../../common/types/environment.types'; import { START_TIME_MAINNET, START_TIME_STAGING, @@ -29,30 +33,49 @@ const localesFillForm = { }; const { - version, os, apiVersion, network: NETWORK, - build, buildNumber, installerVersion, - isMainnet, isStaging, isTestnet, + version, + os, + apiVersion, + network: NETWORK, + build, + buildNumber, + installerVersion, + isMainnet, + isStaging, + isTestnet, } = global.environment; export const getNetworkExplorerUrl = (network: string): string => { // sets default to mainnet in case env.NETWORK is undefined let explorerUrl = MAINNET_EXPLORER_URL; - if (network === MAINNET) { explorerUrl = MAINNET_EXPLORER_URL; } - if (network === STAGING) { explorerUrl = STAGING_EXPLORER_URL; } - if (network === TESTNET) { explorerUrl = TESTNET_EXPLORER_URL; } + if (network === MAINNET) { + explorerUrl = MAINNET_EXPLORER_URL; + } + if (network === STAGING) { + explorerUrl = STAGING_EXPLORER_URL; + } + if (network === TESTNET) { + explorerUrl = TESTNET_EXPLORER_URL; + } return explorerUrl; // sets default to mainnet incase env.NETWORK is undefined }; export const getNetworkEkgUrl = (env: { isDev: boolean, isStaging: boolean, - isTestnet: boolean + isTestnet: boolean, }) => { // sets default to development in case env.NETWORK is undefined let ekgUrl = DEVELOPMENT_EKG_URL; - if (env.isDev) { ekgUrl = DEVELOPMENT_EKG_URL; } - if (env.isStaging) { ekgUrl = STAGING_EKG_URL; } - if (env.isTestnet) { ekgUrl = TESTNET_EKG_URL; } + if (env.isDev) { + ekgUrl = DEVELOPMENT_EKG_URL; + } + if (env.isStaging) { + ekgUrl = STAGING_EKG_URL; + } + if (env.isTestnet) { + ekgUrl = TESTNET_EKG_URL; + } return ekgUrl; }; @@ -86,7 +109,9 @@ const getEpochData = (developmentStartTime: number) => { }; export const getCurrentEpoch = (developmentStartTime: number) => { - const { startTime, epochLengthBase, slotDuration } = getEpochData(developmentStartTime); + const { startTime, epochLengthBase, slotDuration } = getEpochData( + developmentStartTime + ); const currentTimeInUTC = Math.floor(Date.now() / 1000); const numberOfSlots = epochLengthBase * slotDuration * 10; return Math.floor((currentTimeInUTC - startTime) / numberOfSlots); diff --git a/source/renderer/app/utils/paperWalletPdfGenerator.js b/source/renderer/app/utils/paperWalletPdfGenerator.js index 7512c7dd07..fbeff2c3c7 100644 --- a/source/renderer/app/utils/paperWalletPdfGenerator.js +++ b/source/renderer/app/utils/paperWalletPdfGenerator.js @@ -6,17 +6,17 @@ const messages = defineMessages({ walletAddressLabel: { id: 'paper.wallet.pdf.walletAddress.label', defaultMessage: '!!!Wallet address', - description: 'Paper wallet pdf "Wallet address" label.' + description: 'Paper wallet pdf "Wallet address" label.', }, recoveryPhraseLabel: { id: 'paper.wallet.pdf.recoveryPhrase.label', defaultMessage: '!!!Paper wallet recovery phrase', - description: 'Paper wallet pdf "Paper wallet recovery phrase" label.' + description: 'Paper wallet pdf "Paper wallet recovery phrase" label.', }, passwordLabel: { id: 'paper.wallet.pdf.password.label', defaultMessage: '!!!Password', - description: 'Paper wallet pdf "Password" label.' + description: 'Paper wallet pdf "Password" label.', }, infoTitle: { id: 'paper.wallet.pdf.info.title', @@ -36,12 +36,17 @@ type Params = { mnemonics: Array, intl: Object, isMainnet: boolean, - buildLabel: string + buildLabel: string, }; -export const downloadPaperWalletCertificate = async ( - { address, filePath, mnemonics, intl, isMainnet, buildLabel }: Params -) => { +export const downloadPaperWalletCertificate = async ({ + address, + filePath, + mnemonics, + intl, + isMainnet, + buildLabel, +}: Params) => { await generatePaperWalletChannel.send({ address, filePath, @@ -53,6 +58,6 @@ export const downloadPaperWalletCertificate = async ( recoveryPhraseLabel: intl.formatMessage(messages.recoveryPhraseLabel), infoTitle: intl.formatMessage(messages.infoTitle), infoAuthor: intl.formatMessage(messages.infoAuthor), - } + }, }); }; diff --git a/source/renderer/app/utils/redemption-key-validation.js b/source/renderer/app/utils/redemption-key-validation.js index e1c9067a22..883fdb8266 100644 --- a/source/renderer/app/utils/redemption-key-validation.js +++ b/source/renderer/app/utils/redemption-key-validation.js @@ -3,7 +3,9 @@ import bs58 from 'bs58'; // Convert base64url into base64 function toRfc4648(str: string) { - return str.replace(new RegExp('_', 'g'), '/').replace(new RegExp('-', 'g'), '+'); + return str + .replace(new RegExp('_', 'g'), '/') + .replace(new RegExp('-', 'g'), '+'); } // Checks is input string valid base64 or base64url @@ -24,7 +26,7 @@ function isValidBase64Url(code: string) { // Implements: "Valid redemption key should be base64 and base64url decodable, // it should end with '=' and it should be 44 chars long." -export const isValidRedemptionKey = (code: string) => ( +export const isValidRedemptionKey = (code: string) => // Return true if: // * its base64 or base64url decodable - ada vending state mess // * ends with '=' - base64 padds string with optional '=' or two '=' signs. @@ -36,8 +38,7 @@ export const isValidRedemptionKey = (code: string) => ( // > base64url.toBuffer("qL8R4QIcQ_ZsRqOAbeRfcZhilN_MksRtDaEAAAArM-A").length // 32 // Later example above is 32 byte long but its not valid ada redemption key because ada redemption key ends with '=' (lib used in above example is https://www.npmjs.com/package/base64url) - isValidBase64Url(code) && code.endsWith('=') && code.length === 44 -); + isValidBase64Url(code) && code.endsWith('=') && code.length === 44; // Implements: "Valid paper vend redemption key should be base58 decodable 32 byte stream." export const isValidPaperVendRedemptionKey = (code: string) => { diff --git a/source/renderer/app/utils/routing.js b/source/renderer/app/utils/routing.js index 151a6db708..94299d29b4 100644 --- a/source/renderer/app/utils/routing.js +++ b/source/renderer/app/utils/routing.js @@ -1,6 +1,7 @@ import RouteParser from 'route-parser'; -export const matchRoute = (pattern, path) => new RouteParser(pattern).match(path); +export const matchRoute = (pattern, path) => + new RouteParser(pattern).match(path); /** * Build a route from a pattern like `/wallets/:id` to `/wallets/123` @@ -16,7 +17,9 @@ export const matchRoute = (pattern, path) => new RouteParser(pattern).match(path */ export const buildRoute = (pattern, params) => { function toArray(val) { - return Object.prototype.toString.call(val) !== '[object Array]' ? [val] : val; + return Object.prototype.toString.call(val) !== '[object Array]' + ? [val] + : val; } const reRepeatingSlashes = /\/+/g; // '/some//path' const reSplatParams = /\*{1,2}/g; // '/some/*/complex/**/path' @@ -30,7 +33,7 @@ export const buildRoute = (pattern, params) => { const tokens = {}; if (params) { - Object.keys(params).forEach((paramName) => { + Object.keys(params).forEach(paramName => { let paramValue = params[paramName]; // special param name in RR, used for '*' and '**' placeholders @@ -38,7 +41,7 @@ export const buildRoute = (pattern, params) => { // when there are multiple globs, RR defines 'splat' param as array. paramValue = toArray(paramValue); let i = 0; - routePath = routePath.replace(reSplatParams, (match) => { + routePath = routePath.replace(reSplatParams, match => { const val = paramValue[i++]; if (val == null) { return ''; @@ -63,7 +66,9 @@ export const buildRoute = (pattern, params) => { // - '/path(/:param/):another_param' // - '/path/:param(/:another_param)' // - '/path(/:param/:another_param)' - const paramRegex = new RegExp('(/|\\(|\\)|^):' + paramName + '(/|\\)|\\(|$)'); + const paramRegex = new RegExp( + '(/|\\(|\\)|^):' + paramName + '(/|\\)|\\(|$)' + ); routePath = routePath.replace(paramRegex, (match, g1, g2) => { tokens[paramName] = encodeURIComponent(paramValue); return `${g1}<${paramName}>${g2}`; @@ -72,19 +77,21 @@ export const buildRoute = (pattern, params) => { }); } - return routePath - // Remove braces around resolved optional params (i.e. '/path/(value)') - .replace(reResolvedOptionalParams, '$1') - // Remove all sequences containing at least one unresolved optional param - .replace(reUnresolvedOptionalParams, '') - // After everything related to RR syntax is removed, insert actual values - .replace(reTokens, (match, token) => tokens[token]) - // Remove repeating slashes - .replace(reRepeatingSlashes, '/') - // Always remove ending slash for consistency - .replace(/\/+$/, '') - // If there was a single slash only, keep it - .replace(/^$/, '/'); + return ( + routePath + // Remove braces around resolved optional params (i.e. '/path/(value)') + .replace(reResolvedOptionalParams, '$1') + // Remove all sequences containing at least one unresolved optional param + .replace(reUnresolvedOptionalParams, '') + // After everything related to RR syntax is removed, insert actual values + .replace(reTokens, (match, token) => tokens[token]) + // Remove repeating slashes + .replace(reRepeatingSlashes, '/') + // Always remove ending slash for consistency + .replace(/\/+$/, '') + // If there was a single slash only, keep it + .replace(/^$/, '/') + ); }; /** diff --git a/source/renderer/app/utils/serialize.js b/source/renderer/app/utils/serialize.js index fa1cd1b761..02951d8674 100644 --- a/source/renderer/app/utils/serialize.js +++ b/source/renderer/app/utils/serialize.js @@ -1,7 +1,8 @@ // @flow -export default (obj: {}) => ( - Object - .entries(obj) - .map(([key, val]: [string, any]) => `${encodeURIComponent(key)}=${encodeURIComponent(val)}`) - .join('&') -); +export default (obj: {}) => + Object.entries(obj) + .map( + ([key, val]: [string, any]) => + `${encodeURIComponent(key)}=${encodeURIComponent(val)}` + ) + .join('&'); diff --git a/source/renderer/app/utils/strings.js b/source/renderer/app/utils/strings.js index 4a91f84cbc..c275459883 100644 --- a/source/renderer/app/utils/strings.js +++ b/source/renderer/app/utils/strings.js @@ -1,11 +1,17 @@ // @flow -export const ellipsis = (str: string, minCharsInit: number, minCharsEnd?: number) => { +export const ellipsis = ( + str: string, + minCharsInit: number, + minCharsEnd?: number +) => { if (str.length <= minCharsInit) return str; const initStr = str.substr(0, minCharsInit); - const shouldHaveEndStr = () => minCharsEnd && (str.length - minCharsInit) > minCharsEnd; - const endStr = minCharsEnd && shouldHaveEndStr() - ? str.substr(str.length - minCharsEnd) - : ''; + const shouldHaveEndStr = () => + minCharsEnd && str.length - minCharsInit > minCharsEnd; + const endStr = + minCharsEnd && shouldHaveEndStr() + ? str.substr(str.length - minCharsEnd) + : ''; return initStr + '\u2026' + endStr; }; diff --git a/source/renderer/app/utils/validations.js b/source/renderer/app/utils/validations.js index d9ef624435..03f16cac25 100644 --- a/source/renderer/app/utils/validations.js +++ b/source/renderer/app/utils/validations.js @@ -18,9 +18,10 @@ export const isValidSpendingPassword = (spendingPassword: string) => { }; // eslint-disable-next-line max-len -export const isValidRepeatPassword = (spendingPassword: string, repeatPassword: string) => ( - spendingPassword === repeatPassword -); +export const isValidRepeatPassword = ( + spendingPassword: string, + repeatPassword: string +) => spendingPassword === repeatPassword; export const isNotEmptyString = (value: string) => value !== ''; diff --git a/source/renderer/webpack.config.js b/source/renderer/webpack.config.js index ddc7938b8f..051ce2a7c6 100644 --- a/source/renderer/webpack.config.js +++ b/source/renderer/webpack.config.js @@ -17,7 +17,7 @@ module.exports = { }, output: { path: path.join(__dirname, './dist/renderer'), - filename: 'index.js' + filename: 'index.js', }, // https://github.com/chentsulin/webpack-target-electron-renderer#how-this-module-works target: isTestEnv ? 'electron-renderer' : 'web', @@ -28,11 +28,8 @@ module.exports = { test: /\.jsx?$/, include: /source/, exclude: /source\/main/, - use: (isCi ? [] : [ - 'cache-loader', - 'thread-loader', - ]).concat([ - 'babel-loader' + use: (isCi ? [] : ['cache-loader', 'thread-loader']).concat([ + 'babel-loader', ]), }, { @@ -46,21 +43,21 @@ module.exports = { modules: true, localIdentName: '[name]_[local]', importLoaders: true, - } + }, }, { loader: 'sass-loader', options: { - sourceMap: true - } - } - ] + sourceMap: true, + }, + }, + ], }, { test: /\.css/, use: [ MiniCssExtractPlugin.loader, - { loader: 'css-loader', options: { sourceMap: true } } + { loader: 'css-loader', options: { sourceMap: true } }, ], }, { @@ -74,32 +71,45 @@ module.exports = { loader: 'file-loader', options: { name: '[name].[ext]', - outputPath: 'assets/' - } - } + outputPath: 'assets/', + }, + }, }, { test: /\.md$/, use: [ { loader: 'html-loader', options: { importLoaders: true } }, { loader: 'markdown-loader?gfm=false' }, - ] + ], }, - ] + ], }, plugins: [ new MiniCssExtractPlugin({ filename: 'styles.css', }), - new webpack.DefinePlugin(Object.assign({ - 'process.env.API_VERSION': JSON.stringify(process.env.API_VERSION || 'dev'), - 'process.env.NETWORK': JSON.stringify(process.env.NETWORK || 'development'), - 'process.env.MOBX_DEV_TOOLS': process.env.MOBX_DEV_TOOLS || 0, - 'process.env.BUILD_NUMBER': JSON.stringify(process.env.BUILD_NUMBER || 'dev'), - }, process.env.NODE_ENV === 'production' ? { - // Only bake in NODE_ENV value for production builds. - 'process.env.NODE_ENV': '"production"', - } : {})), + new webpack.DefinePlugin( + Object.assign( + { + 'process.env.API_VERSION': JSON.stringify( + process.env.API_VERSION || 'dev' + ), + 'process.env.NETWORK': JSON.stringify( + process.env.NETWORK || 'development' + ), + 'process.env.MOBX_DEV_TOOLS': process.env.MOBX_DEV_TOOLS || 0, + 'process.env.BUILD_NUMBER': JSON.stringify( + process.env.BUILD_NUMBER || 'dev' + ), + }, + process.env.NODE_ENV === 'production' + ? { + // Only bake in NODE_ENV value for production builds. + 'process.env.NODE_ENV': '"production"', + } + : {} + ) + ), new AutoDllPlugin({ filename: 'vendor.dll.js', context: path.join(__dirname, '..'), @@ -132,9 +142,9 @@ module.exports = { 'route-parser', 'safe-buffer', 'unorm', - 'validator' - ] - } + 'validator', + ], + }, }), - ].filter(Boolean) + ].filter(Boolean), }; diff --git a/storybook/stories/AdaRedemptionDialog.stories.js b/storybook/stories/AdaRedemptionDialog.stories.js index 3e12ea5c01..70e313b44c 100644 --- a/storybook/stories/AdaRedemptionDialog.stories.js +++ b/storybook/stories/AdaRedemptionDialog.stories.js @@ -9,12 +9,7 @@ import AdaRedemptionChoices from '../../source/renderer/app/components/wallet/ad import { ADA_REDEMPTION_TYPES } from '../../source/renderer/app/types/redemptionTypes'; storiesOf('AdaRedemptionForm', module) - - .addDecorator((story) => ( - - {story()} - - )) + .addDecorator(story => {story()}) // ====== Stories ====== diff --git a/storybook/stories/AddWallet.stories.js b/storybook/stories/AddWallet.stories.js index 9adc408e22..fee540bbcb 100644 --- a/storybook/stories/AddWallet.stories.js +++ b/storybook/stories/AddWallet.stories.js @@ -9,12 +9,7 @@ import WalletRestoreDialog from '../../source/renderer/app/components/wallet/Wal import WalletFileImportDialog from '../../source/renderer/app/components/wallet/file-import/WalletFileImportDialog'; storiesOf('AddWallet', module) - - .addDecorator((story) => ( - - {story()} - - )) + .addDecorator(story => {story()}) // ====== Stories ====== diff --git a/storybook/stories/BlockConsolidationStatus.stories.js b/storybook/stories/BlockConsolidationStatus.stories.js index be03b9f4dd..cd350637e8 100644 --- a/storybook/stories/BlockConsolidationStatus.stories.js +++ b/storybook/stories/BlockConsolidationStatus.stories.js @@ -12,11 +12,8 @@ import BlockConsolidationStatus from '../../source/renderer/app/components/statu const currentEpoch = 95; storiesOf('BlockConsolidationStatus', module) - .addDecorator((story, context) => ( - - {withKnobs(story, context)} - + {withKnobs(story, context)} )) // ====== Stories ====== @@ -24,9 +21,19 @@ storiesOf('BlockConsolidationStatus', module) .add('Default', () => ( {}} - epochsConsolidated={number('Epochs Consolidated', 57, { range: true, min: 0, max: currentEpoch - 2, step: 1, })} + epochsConsolidated={number('Epochs Consolidated', 57, { + range: true, + min: 0, + max: currentEpoch - 2, + step: 1, + })} currentEpoch={currentEpoch} - epochsSynced={number('Epochs Synced', 80, { range: true, min: 0, max: 100, step: 1, })} + epochsSynced={number('Epochs Synced', 80, { + range: true, + min: 0, + max: 100, + step: 1, + })} onClose={() => {}} /> )); diff --git a/storybook/stories/DeleteWalletConfirmationDialog.stories.js b/storybook/stories/DeleteWalletConfirmationDialog.stories.js index 2928646fc9..d72c55ff33 100644 --- a/storybook/stories/DeleteWalletConfirmationDialog.stories.js +++ b/storybook/stories/DeleteWalletConfirmationDialog.stories.js @@ -6,12 +6,7 @@ import StoryDecorator from './support/StoryDecorator'; import DeleteWalletConfirmationDialog from '../../source/renderer/app/components/wallet/settings/DeleteWalletConfirmationDialog'; storiesOf('DeleteWalletConfirmationDialog', module) - - .addDecorator((story) => ( - - {story()} - - )) + .addDecorator(story => {story()}) // ====== Stories ====== diff --git a/storybook/stories/ExportWalletToFileDialog.stories.js b/storybook/stories/ExportWalletToFileDialog.stories.js index b8fbbfcbfa..e02995bc1b 100644 --- a/storybook/stories/ExportWalletToFileDialog.stories.js +++ b/storybook/stories/ExportWalletToFileDialog.stories.js @@ -6,12 +6,7 @@ import StoryDecorator from './support/StoryDecorator'; import ExportWalletToFileDialog from '../../source/renderer/app/components/wallet/settings/ExportWalletToFileDialog'; storiesOf('ExportWalletToFileDialog', module) - - .addDecorator((story) => ( - - {story()} - - )) + .addDecorator(story => {story()}) // ====== Stories ====== diff --git a/storybook/stories/LanguageSelectionForm.stories.js b/storybook/stories/LanguageSelectionForm.stories.js index 1b8a294e5a..3bc1e4ccec 100644 --- a/storybook/stories/LanguageSelectionForm.stories.js +++ b/storybook/stories/LanguageSelectionForm.stories.js @@ -16,12 +16,7 @@ const LANGUAGES = [ ]; storiesOf('LanguageSelectionForm', module) - - .addDecorator((story) => ( - - {story()} - - )) + .addDecorator(story => {story()}) // ====== Stories ====== diff --git a/storybook/stories/PaperWallets.stories.js b/storybook/stories/PaperWallets.stories.js index 8a98320da6..ec97f6b137 100644 --- a/storybook/stories/PaperWallets.stories.js +++ b/storybook/stories/PaperWallets.stories.js @@ -11,12 +11,7 @@ import VerificationDialog from '../../source/renderer/app/components/wallet/pape import CompletionDialog from '../../source/renderer/app/components/wallet/paper-wallet-certificate/CompletionDialog'; storiesOf('PaperWallets', module) - - .addDecorator((story) => ( - - {story()} - - )) + .addDecorator(story => {story()}) // ====== Stories ====== diff --git a/storybook/stories/Sidebar.stories.js b/storybook/stories/Sidebar.stories.js index 931fb315a7..22a3d7d2d2 100644 --- a/storybook/stories/Sidebar.stories.js +++ b/storybook/stories/Sidebar.stories.js @@ -18,7 +18,7 @@ const SIDEBAR_CATEGORIES = [ name: 'SETTINGS', route: '/settings', icon: settingsIcon, - } + }, ]; const sidebarMenus = observable({ @@ -32,21 +32,16 @@ const sidebarMenus = observable({ actions: { onAddWallet: action('toggleAddWallet'), onWalletItemClick: (walletId: string) => { - runInAction(() => sidebarMenus.wallets.activeWalletId = walletId); - } - } - } + runInAction(() => (sidebarMenus.wallets.activeWalletId = walletId)); + }, + }, + }, }); let emptyMenus; storiesOf('Sidebar', module) - - .addDecorator((story) => ( - - {story()} - - )) + .addDecorator(story => {story()}) // ====== Stories ====== diff --git a/storybook/stories/SidebarCategory.stories.js b/storybook/stories/SidebarCategory.stories.js index e8c500021e..fae60d621d 100644 --- a/storybook/stories/SidebarCategory.stories.js +++ b/storybook/stories/SidebarCategory.stories.js @@ -7,8 +7,7 @@ import walletsIcon from '../../source/renderer/app/assets/images/sidebar/wallet- import StoryDecorator from './support/StoryDecorator'; storiesOf('SidebarCategory', module) - - .addDecorator((story) => ({story()})) + .addDecorator(story => {story()}) // ====== Stories ====== diff --git a/storybook/stories/SidebarWalletsMenu.stories.js b/storybook/stories/SidebarWalletsMenu.stories.js index 0f5f3820f6..11c889c0fb 100644 --- a/storybook/stories/SidebarWalletsMenu.stories.js +++ b/storybook/stories/SidebarWalletsMenu.stories.js @@ -6,8 +6,7 @@ import StoryDecorator from './support/StoryDecorator'; import SidebarWalletsMenu from '../../source/renderer/app/components/sidebar/wallets/SidebarWalletsMenu'; storiesOf('SidebarWalletsMenu', module) - - .addDecorator((story) => ( + .addDecorator(story => (
{story()}
@@ -29,12 +28,40 @@ storiesOf('SidebarWalletsMenu', module) .add('with items', () => ( id === '2'} + isActiveWallet={id => id === '2'} onWalletItemClick={action('walletItemClick')} onAddWallet={action('addWallet')} isAddWalletButtonActive={false} diff --git a/storybook/stories/Staking.stories.js b/storybook/stories/Staking.stories.js index 7a42b3e09c..1a924f353e 100644 --- a/storybook/stories/Staking.stories.js +++ b/storybook/stories/Staking.stories.js @@ -6,12 +6,7 @@ import Staking from '../../source/renderer/app/components/staking/Staking'; import StakingSwitch from '../../source/renderer/app/components/staking/StakingSwitch'; storiesOf('Staking', module) - - .addDecorator((story) => ( - - {story()} - - )) + .addDecorator(story => {story()}) // ====== Stories ====== diff --git a/storybook/stories/StakingChart.stories.js b/storybook/stories/StakingChart.stories.js index 85493b961d..f07334a310 100644 --- a/storybook/stories/StakingChart.stories.js +++ b/storybook/stories/StakingChart.stories.js @@ -9,7 +9,8 @@ import StakingChartTooltip from '../../source/renderer/app/components/staking/St const generateRandomSlots = (count: number) => { const slots = []; for (let i = 0; i < count; i += 1) { - const numberOfTransactions = i < (count / 2) ? Math.floor(Math.random() * 50) : 0; + const numberOfTransactions = + i < count / 2 ? Math.floor(Math.random() * 50) : 0; slots.push({ numberOfTransactions, slot: slots.length + 1, @@ -18,19 +19,14 @@ const generateRandomSlots = (count: number) => { commitments: 'AA', mpcPhase: 'Shares', hash: 'ad9f37d14e189f5d792aaf524a6e0a13cdc5ba13b540f231638444687526231e', - time: new Date() + time: new Date(), }); } return slots; }; storiesOf('StakingChart', module) - - .addDecorator((story) => ( - - {story()} - - )) + .addDecorator(story => {story()}) // ====== Stories ====== @@ -53,13 +49,7 @@ storiesOf('StakingChart', module) const options = observable({ data: generateRandomSlots(30), ticks: [0, 10, 20, 30, 40, 50], - activeIndex: null + activeIndex: null, }); - return ( - - ); + return ; }); diff --git a/storybook/stories/TopBar.stories.js b/storybook/stories/TopBar.stories.js index b84725a7a3..7ed738a671 100644 --- a/storybook/stories/TopBar.stories.js +++ b/storybook/stories/TopBar.stories.js @@ -44,25 +44,14 @@ const topBarProductionEnv = ( ); storiesOf('TopBar', module) - - .addDecorator((story) => ( - - {story()} - - )) + .addDecorator(story => {story()}) // ====== Stories ====== .add('Test Environment label', () => ( - } - /> + } /> )) .add('Production Environment', () => ( - } - /> + } /> )); diff --git a/storybook/stories/WalletScreens.stories.js b/storybook/stories/WalletScreens.stories.js index b286df7643..0cfbe83660 100644 --- a/storybook/stories/WalletScreens.stories.js +++ b/storybook/stories/WalletScreens.stories.js @@ -13,7 +13,12 @@ import startCase from 'lodash/startCase'; import StoryLayout from './support/StoryLayout'; import StoryProvider from './support/StoryProvider'; import StoryDecorator from './support/StoryDecorator'; -import { generateWallet, generateTransaction, generateAddress, promise } from './support/utils'; +import { + generateWallet, + generateTransaction, + generateAddress, + promise, +} from './support/utils'; import { formattedWalletAmount } from '../../source/renderer/app/utils/formatters'; import { transactionTypes } from '../../source/renderer/app/domains/WalletTransaction'; import WalletWithNavigation from '../../source/renderer/app/components/wallet/layouts/WalletWithNavigation'; @@ -30,9 +35,7 @@ import DeleteWalletConfirmationDialog from '../../source/renderer/app/components import ExportWalletToFileDialog from '../../source/renderer/app/components/wallet/settings/ExportWalletToFileDialog'; storiesOf('WalletScreens', module) - .addDecorator((story, context) => { - const storyWithKnobs = withKnobs(story, context); return ( @@ -42,18 +45,20 @@ storiesOf('WalletScreens', module) activeSidebarCategory="/wallets" storyName={context.story} > - { - context.story !== 'Empty' - ? ( - item === context.story.toLocaleLowerCase()} - onWalletNavItemClick={linkTo('WalletScreens', item => startCase(item))} - > - {storyWithKnobs} - - ) - : storyWithKnobs - } + {context.story !== 'Empty' ? ( + + item === context.story.toLocaleLowerCase() + } + onWalletNavItemClick={linkTo('WalletScreens', item => + startCase(item) + )} + > + {storyWithKnobs} + + ) : ( + storyWithKnobs + )} @@ -64,9 +69,7 @@ storiesOf('WalletScreens', module) .add('Empty', () => null) - .add('Wallet Navigation', () => ( -
 
- )) + .add('Wallet Navigation', () =>
 
) .add('Summary', () => ( ( generateAddress()), - ...Array.from(Array(number('Addresses (used)', 1))).map(() => generateAddress(true)), + ...Array.from(Array(number('Addresses', 1))).map(() => + generateAddress() + ), + ...Array.from(Array(number('Addresses (used)', 1))).map(() => + generateAddress(true) + ), ]} onGenerateAddress={() => {}} onCopyAddress={() => {}} @@ -115,31 +125,35 @@ storiesOf('WalletScreens', module) .add('Transactions', () => ( ( - generateTransaction( - transactionTypes.EXPEND, - moment().subtract(i, 'days').toDate(), - new BigNumber(faker.random.number(5)) - ) - )), - ...Array.from(Array(number('Transactions Received', 1))).map((x, i) => ( - generateTransaction( - transactionTypes.INCOME, - moment().subtract(i, 'days').toDate(), - new BigNumber(faker.random.number(5)) - ) - )), - ] - } + transactions={[ + ...Array.from(Array(number('Transactions Sent', 1))).map((x, i) => + generateTransaction( + transactionTypes.EXPEND, + moment() + .subtract(i, 'days') + .toDate(), + new BigNumber(faker.random.number(5)) + ) + ), + ...Array.from(Array(number('Transactions Received', 1))).map((x, i) => + generateTransaction( + transactionTypes.INCOME, + moment() + .subtract(i, 'days') + .toDate(), + new BigNumber(faker.random.number(5)) + ) + ), + ]} isLoadingTransactions={boolean('isLoadingTransactions', false)} isRestoreActive={boolean('isRestoreActive', false)} hasMoreToLoad={false} assuranceMode={{ low: 1, medium: 2 }} walletId="test-wallet" formattedWalletAmount={formattedWalletAmount} - totalAvailable={number('Transactions Sent', 1) + number('Transactions Received', 1)} + totalAvailable={ + number('Transactions Sent', 1) + number('Transactions Received', 1) + } /> )) @@ -152,19 +166,19 @@ storiesOf('WalletScreens', module) label: { id: 'global.assuranceLevel.normal', defaultMessage: '!!!Normal', - description: '' - } + description: '', + }, }, { value: WalletAssuranceModeOptions.STRICT, label: { id: 'global.assuranceLevel.strict', defaultMessage: '!!!Strict', - description: '' - } - } + description: '', + }, + }, ]} - isDialogOpen={(dialog) => { + isDialogOpen={dialog => { if (dialog === ChangeSpendingPasswordDialog) { return boolean('Change Password - Show dialog', false); } @@ -187,8 +201,10 @@ storiesOf('WalletScreens', module) openDialogAction={() => {}} walletAssurance={WalletAssuranceModeOptions.NORMAL} walletName={text('Wallet Name', 'Wallet Name')} - spendingPasswordUpdateDate={moment().subtract(1, 'month').toDate()} - changeSpendingPasswordDialog={( + spendingPasswordUpdateDate={moment() + .subtract(1, 'month') + .toDate()} + changeSpendingPasswordDialog={ - )} - deleteWalletDialogContainer={( + } + deleteWalletDialogContainer={ number('Delete Wallet Countdown', 9)} isBackupNoticeAccepted={boolean('isBackupNoticeAccepted', false)} @@ -212,11 +233,13 @@ storiesOf('WalletScreens', module) onContinue={action('Delete Wallet - onContinue')} onCancel={action('Delete Wallet - onCancel')} confirmationValue={text('Delete Wallet Confirmation Value')} - onConfirmationValueChange={action('Delete Wallet - onConfirmationValueChange')} + onConfirmationValueChange={action( + 'Delete Wallet - onConfirmationValueChange' + )} isSubmitting={boolean('Delete Wallet - isSubmitting', false)} /> - )} - exportWalletDialogContainer={( + } + exportWalletDialogContainer={ - )} + } /> )); diff --git a/storybook/stories/WalletSummary.stories.js b/storybook/stories/WalletSummary.stories.js index 075a1514b4..5554a6b0b0 100644 --- a/storybook/stories/WalletSummary.stories.js +++ b/storybook/stories/WalletSummary.stories.js @@ -7,12 +7,7 @@ import { generateWallet } from './support/utils'; import WalletSummary from '../../source/renderer/app/components/wallet/summary/WalletSummary'; storiesOf('WalletSummary', module) - - .addDecorator((story) => ( - - {story()} - - )) + .addDecorator(story => {story()}) // ====== Stories ====== diff --git a/storybook/stories/WalletTransactionsList.stories.js b/storybook/stories/WalletTransactionsList.stories.js index ed9b4cc1a3..3e5312fce3 100644 --- a/storybook/stories/WalletTransactionsList.stories.js +++ b/storybook/stories/WalletTransactionsList.stories.js @@ -4,32 +4,56 @@ import { storiesOf } from '@storybook/react'; import moment from 'moment'; import BigNumber from 'bignumber.js'; import StoryDecorator from './support/StoryDecorator'; -import { generateMultipleTransactions, generateTransaction } from './support/utils'; +import { + generateMultipleTransactions, + generateTransaction, +} from './support/utils'; import WalletTransactionsList from '../../source/renderer/app/components/wallet/transactions/WalletTransactionsList'; import { transactionStates, - transactionTypes + transactionTypes, } from '../../source/renderer/app/domains/WalletTransaction'; import { formattedWalletAmount } from '../../source/renderer/app/utils/formatters'; storiesOf('WalletTransactionsList', module) - - .addDecorator((story) => ( - - {story()} - - )) + .addDecorator(story => {story()}) // ====== Stories ====== .add('transactions grouped by days', () => ( { + .addDecorator(story => { const onChangeAction = action('onChange'); const state = observable({ checked: false, onChange: mobxAction((value, event) => { state.checked = value; onChangeAction(value, event); - }) + }), }); - return ( - - {story()} - - ); + return {story()}; }) // ====== Stories ====== @@ -73,17 +65,14 @@ storiesOf('Widgets', module) tokens[index] = token} + onTokenChanged={(index, token) => (tokens[index] = token)} /> ); }) .add('NotificationMessage', () => (
- + Address: 1gGHFU9VsXV89kcJNzibNo8wJugxNtWsaqbjWaZEKzLtMGD copied to clipboard @@ -91,12 +80,6 @@ storiesOf('Widgets', module)
)) - .add('TinySwitch', () => ( - - )) + .add('TinySwitch', () => ) - .add('TinySwitch - short label', () => ( - - )); + .add('TinySwitch - short label', () => ); diff --git a/storybook/stories/support/StoryDecorator.js b/storybook/stories/support/StoryDecorator.js index 12cc9acec7..d6f24c79d6 100644 --- a/storybook/stories/support/StoryDecorator.js +++ b/storybook/stories/support/StoryDecorator.js @@ -17,7 +17,6 @@ type Props = { @observer export default class StoryDecorator extends Component { - static defaultProps = { propsForChildren: {}, }; @@ -27,11 +26,18 @@ export default class StoryDecorator extends Component { return ( - + - {Children.map(children, (child) => { - const childProps = child.type === 'div' ? {} : { propsForChildren }; + {Children.map(children, child => { + const childProps = + child.type === 'div' ? {} : { propsForChildren }; return React.cloneElement(child, childProps); })} @@ -40,5 +46,4 @@ export default class StoryDecorator extends Component { ); } - } diff --git a/storybook/stories/support/StoryLayout.js b/storybook/stories/support/StoryLayout.js index 111f32f78b..c62c0dfd90 100644 --- a/storybook/stories/support/StoryLayout.js +++ b/storybook/stories/support/StoryLayout.js @@ -25,7 +25,7 @@ import SidebarLayout from '../../../source/renderer/app/components/layout/Sideba export type StoriesProps = { wallets: Array, activeWalletId: string, - setActiveWalletId: Function + setActiveWalletId: Function, }; type Props = { @@ -59,54 +59,57 @@ const sidebarCategories = [ }, ]; - -@inject('stores', 'storiesProps') @observer +@inject('stores', 'storiesProps') +@observer export default class StoryLayout extends Component { - static defaultProps = { stores: null, storiesProps: null }; render() { - const { activeSidebarCategory, storyName = '', storiesProps = {}, stores, - children + children, } = this.props; - const { - wallets, - activeWalletId, - setActiveWalletId - } = storiesProps; + const { wallets, activeWalletId, setActiveWalletId } = storiesProps; const activeWallet: Wallet = wallets[parseInt(activeWalletId, 10)]; const activeNavItem = storyName.split(' ')[0].toLowerCase(); const sidebarMenus = this.getSidebarMenus( - this.getSidebarWallets(wallets), activeWalletId, setActiveWalletId + this.getSidebarWallets(wallets), + activeWalletId, + setActiveWalletId ); return (
- { Children.map(children, (child) => React.cloneElement(child, { stores })) } + {Children.map(children, child => + React.cloneElement(child, { stores }) + )}
); } @observable - isShowingSubMenus = this.props.activeSidebarCategory === '/wallets' && !!this.props.children; + isShowingSubMenus = + this.props.activeSidebarCategory === '/wallets' && !!this.props.children; - getSidebarWallets = (wallets: Array): Array => ( + getSidebarWallets = (wallets: Array): Array => wallets.map((wallet: Wallet) => ({ id: wallet.id, title: wallet.name, @@ -114,8 +117,7 @@ export default class StoryLayout extends Component { isConnected: true, isRestoreActive: false, restoreProgress: 0, - })) - ); + })); getSidebarMenus = ( items: Array, @@ -127,15 +129,12 @@ export default class StoryLayout extends Component { activeWalletId, actions: { onAddWallet: action('toggleAddWallet'), - onWalletItemClick: setActiveWalletId - } - } + onWalletItemClick: setActiveWalletId, + }, + }, }); - getSidebar = ( - activeSidebarCategory: string, - sidebarMenus: SidebarMenus, - ) => ( + getSidebar = (activeSidebarCategory: string, sidebarMenus: SidebarMenus) => ( { /> ); - getTopbar = (activeSidebarCategory: string, activeWallet: Wallet, activeNavItem: string) => ( + getTopbar = ( + activeSidebarCategory: string, + activeWallet: Wallet, + activeNavItem: string + ) => ( { - runInAction(() => this.isShowingSubMenus = !this.isShowingSubMenus); + runInAction(() => (this.isShowingSubMenus = !this.isShowingSubMenus)); }} formattedWalletAmount={formattedWalletAmount} currentRoute={`/wallets/${activeWallet.id}/${activeNavItem}`} - activeWallet={activeSidebarCategory === '/wallets' && activeNavItem !== 'empty' ? activeWallet : null} + activeWallet={ + activeSidebarCategory === '/wallets' && activeNavItem !== 'empty' + ? activeWallet + : null + } showSubMenuToggle showSubMenus={this.isShowingSubMenus} > @@ -171,5 +178,4 @@ export default class StoryLayout extends Component { /> ); - } diff --git a/storybook/stories/support/StoryProvider.js b/storybook/stories/support/StoryProvider.js index f706ec5cb2..7619d928ff 100644 --- a/storybook/stories/support/StoryProvider.js +++ b/storybook/stories/support/StoryProvider.js @@ -19,7 +19,7 @@ const WALLETS = [ amount: new BigNumber(66.998), assurance: WalletAssuranceModeOptions.NORMAL, hasPassword: false, - passwordUpdateDate: new Date() + passwordUpdateDate: new Date(), }, { id: '1', @@ -27,47 +27,51 @@ const WALLETS = [ amount: new BigNumber(0), assurance: WalletAssuranceModeOptions.NORMAL, hasPassword: true, - passwordUpdateDate: moment().subtract(1, 'month').toDate() - } + passwordUpdateDate: moment() + .subtract(1, 'month') + .toDate(), + }, ]; @observer export default class StoryProvider extends Component { - @observable activeWalletId = '0'; @computed get storiesProps(): {} { - return ({ + return { wallets: WALLETS, activeWalletId: this.activeWalletId, - setActiveWalletId: this.setActiveWalletId - }); + setActiveWalletId: this.setActiveWalletId, + }; } @computed get stores(): {} { - return ({ + return { ada: { wallets: { active: WALLETS[parseInt(this.activeWalletId, 10)], sendMoney: () => {}, sendMoneyRequest: { isExecuting: false, - reset: () => {} - } - } - } - }); + reset: () => {}, + }, + }, + }, + }; } - setActiveWalletId = (walletId: string) => runInAction(() => this.activeWalletId = walletId); + setActiveWalletId = (walletId: string) => + runInAction(() => (this.activeWalletId = walletId)); render() { - return ( - + {this.props.children} ); } - } diff --git a/storybook/stories/support/utils.js b/storybook/stories/support/utils.js index f7eeb96a14..8257a900e8 100644 --- a/storybook/stories/support/utils.js +++ b/storybook/stories/support/utils.js @@ -6,23 +6,26 @@ import BigNumber from 'bignumber.js'; import { WalletTransaction, transactionStates, - transactionTypes + transactionTypes, } from '../../../source/renderer/app/domains/WalletTransaction'; import Wallet from '../../../source/renderer/app/domains/Wallet'; import WalletAddress from '../../../source/renderer/app/domains/WalletAddress'; import { LOVELACES_PER_ADA } from '../../../source/renderer/app/config/numbersConfig'; import type { TransactionState, - TransactionType + TransactionType, } from '../../../source/renderer/app/api/transactions/types'; export const generateHash = () => { - const now = (new Date()).valueOf().toString(); + const now = new Date().valueOf().toString(); const random = Math.random().toString(); - return hash.sha512().update(now + random).digest('hex'); + return hash + .sha512() + .update(now + random) + .digest('hex'); }; -export const generateWallet = (name: string, amount: string) => ( +export const generateWallet = (name: string, amount: string) => new Wallet({ id: generateHash(), amount: new BigNumber(amount).dividedBy(LOVELACES_PER_ADA), @@ -31,8 +34,7 @@ export const generateWallet = (name: string, amount: string) => ( hasPassword: false, passwordUpdateDate: new Date(), syncState: { data: null, tag: 'synced' }, - }) -); + }); export const generateTransaction = ( type: TransactionType = transactionTypes.INCOME, @@ -40,7 +42,7 @@ export const generateTransaction = ( amount: BigNumber = new BigNumber(faker.finance.amount()), confirmations: number = 1, state: TransactionState = transactionStates.OK -) => ( +) => new WalletTransaction({ id: faker.random.uuid(), title: '', @@ -52,40 +54,37 @@ export const generateTransaction = ( numberOfConfirmations: confirmations, addresses: { from: [faker.random.alphaNumeric(Math.round(Math.random() * 10) + 100)], - to: [faker.random.alphaNumeric(Math.round(Math.random() * 10) + 100)] + to: [faker.random.alphaNumeric(Math.round(Math.random() * 10) + 100)], }, - }) -); + }); -export const generateRandomTransaction = (index: number) => ( +export const generateRandomTransaction = (index: number) => generateTransaction( transactionTypes.INCOME, - moment().subtract(index, 'days').toDate(), + moment() + .subtract(index, 'days') + .toDate(), new BigNumber(faker.random.number(5)) - ) -); + ); -export const generateMultipleTransactions = (amount: number): WalletTransaction[] => ( - Array.from(Array(amount).keys()).map((key: number) => ( +export const generateMultipleTransactions = ( + amount: number +): WalletTransaction[] => + Array.from(Array(amount).keys()).map((key: number) => generateRandomTransaction(Math.round(Math.random() * key)) - )) -); + ); -export const generateAddress = (used: boolean = false): WalletAddress => ( +export const generateAddress = (used: boolean = false): WalletAddress => new WalletAddress({ id: generateHash(), amount: new BigNumber(faker.random.number(5)), changeAddress: false, - used - }) -); + used, + }); -export const promise = (returnValue: any): () => Promise => ( - () => ( - new Promise(resolve => { - setTimeout(() => { - resolve(returnValue); - }, 2000); - }) - ) -); +export const promise = (returnValue: any): (() => Promise) => () => + new Promise(resolve => { + setTimeout(() => { + resolve(returnValue); + }, 2000); + }); diff --git a/storybook/webpack.config.js b/storybook/webpack.config.js index 108b90df69..1b0887d536 100644 --- a/storybook/webpack.config.js +++ b/storybook/webpack.config.js @@ -5,7 +5,7 @@ module.exports = { test: /\.scss/, use: [ { - loader: 'style-loader' + loader: 'style-loader', }, { loader: 'css-loader', @@ -14,16 +14,14 @@ module.exports = { modules: true, localIdentName: '[name]_[local]', importLoaders: true, - } + }, }, - { loader: 'sass-loader', options: { sourceMap: true } } + { loader: 'sass-loader', options: { sourceMap: true } }, ], }, { test: /\.css/, - use: [ - { loader: 'css-loader', options: { sourceMap: true } }, - ], + use: [{ loader: 'css-loader', options: { sourceMap: true } }], }, { test: /\.inline\.svg$/, @@ -36,19 +34,19 @@ module.exports = { loader: 'url-loader', options: { limit: 10000, - } - } + }, + }, }, { test: /\.md$/, use: [ { loader: 'html-loader', options: { importLoaders: true } }, { loader: 'markdown-loader?gfm=false' }, - ] + ], }, - ] + ], }, node: { - fs: 'empty' - } + fs: 'empty', + }, }; diff --git a/yarn.lock b/yarn.lock index 951f58b3c9..97b36ddae0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1532,6 +1532,10 @@ arr-union@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" +array-differ@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-2.1.0.tgz#4b9c1c3f14b906757082925769e8ab904f4801b1" + array-each@^1.0.0, array-each@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" @@ -1596,7 +1600,7 @@ array-sort@^1.0.0: get-value "^2.0.6" kind-of "^5.0.2" -array-union@^1.0.1: +array-union@^1.0.1, array-union@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" dependencies: @@ -1626,6 +1630,10 @@ array.prototype.flatmap@^1.2.1: es-abstract "^1.10.0" function-bind "^1.1.1" +arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + asap@~2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" @@ -2628,6 +2636,10 @@ ci-info@^1.5.0: version "1.6.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" @@ -2983,6 +2995,16 @@ cosmiconfig@^5.0.5: js-yaml "^3.9.0" parse-json "^4.0.0" +cosmiconfig@^5.0.7: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.1.0.tgz#6c5c35e97f37f985061cdf653f114784231185cf" + dependencies: + import-fresh "^2.0.0" + is-directory "^0.3.1" + js-yaml "^3.9.0" + lodash.get "^4.4.2" + parse-json "^4.0.0" + crc32-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-2.0.0.tgz#e3cdd3b4df3168dd74e3de3fbbcb7b297fe908f4" @@ -4051,6 +4073,12 @@ eslint-config-airbnb@17.1.0: object.assign "^4.1.0" object.entries "^1.0.4" +eslint-config-prettier@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-4.1.0.tgz#181364895899fff9fd3605fecb5c4f20e7d5f395" + dependencies: + get-stdin "^6.0.0" + eslint-formatter-pretty@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/eslint-formatter-pretty/-/eslint-formatter-pretty-2.0.0.tgz#7bc011def9a01d457928988c736a8d5b8b13a00c" @@ -4336,6 +4364,18 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + execa@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" @@ -4965,6 +5005,10 @@ get-stdin@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" +get-stdin@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" + get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" @@ -5423,6 +5467,21 @@ humanize-plus@^1.8.1: version "1.8.2" resolved "https://registry.yarnpkg.com/humanize-plus/-/humanize-plus-1.8.2.tgz#a65b34459ad6367adbb3707a82a3c9f916167030" +husky@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/husky/-/husky-1.3.1.tgz#26823e399300388ca2afff11cfa8a86b0033fae0" + dependencies: + cosmiconfig "^5.0.7" + execa "^1.0.0" + find-up "^3.0.0" + get-stdin "^6.0.0" + is-ci "^2.0.0" + pkg-dir "^3.0.0" + please-upgrade-node "^3.1.1" + read-pkg "^4.0.1" + run-node "^1.0.0" + slash "^2.0.0" + iconv-lite@0.4.19: version "0.4.19" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" @@ -5473,7 +5532,7 @@ ignore-walk@^3.0.1: dependencies: minimatch "^3.0.4" -ignore@^3.3.3, ignore@^3.3.5: +ignore@^3.3.3, ignore@^3.3.5, ignore@^3.3.7: version "3.3.10" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" @@ -5721,6 +5780,12 @@ is-ci@^1.0.10: dependencies: ci-info "^1.5.0" +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + dependencies: + ci-info "^2.0.0" + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -6350,7 +6415,7 @@ lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" -lodash.get@^4.0.0: +lodash.get@^4.0.0, lodash.get@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" @@ -6764,6 +6829,10 @@ move-concurrently@^1.0.1: rimraf "^2.5.4" run-queue "^1.0.3" +mri@^1.1.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.4.tgz#7cb1dd1b9b40905f1fac053abe25b6720f44744a" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -6772,6 +6841,15 @@ ms@2.1.1, ms@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" +multimatch@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-3.0.0.tgz#0e2534cc6bc238d9ab67e1b9cd5fcd85a6dbf70b" + dependencies: + array-differ "^2.0.3" + array-union "^1.0.2" + arrify "^1.0.1" + minimatch "^3.0.4" + mute-stdout@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.1.tgz#acb0300eb4de23a7ddeec014e3e96044b3472331" @@ -7631,6 +7709,12 @@ pkg-up@2.0.0, pkg-up@^2.0.0: dependencies: find-up "^2.1.0" +please-upgrade-node@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz#ed320051dfcc5024fae696712c8288993595e8ac" + dependencies: + semver-compare "^1.0.0" + plist@^3.0.0, plist@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.1.tgz#a9b931d17c304e8912ef0ba3bdd6182baf2e1f8c" @@ -7817,6 +7901,10 @@ prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" +prettier@1.16.4: + version "1.16.4" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.16.4.tgz#73e37e73e018ad2db9c76742e2647e21790c9717" + pretty-bytes@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-1.0.4.tgz#0a22e8210609ad35542f8c8d5d2159aff0751c84" @@ -7835,6 +7923,17 @@ pretty-hrtime@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" +pretty-quick@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/pretty-quick/-/pretty-quick-1.10.0.tgz#d86cc46fe92ed8cfcfba6a082ec5949c53858198" + dependencies: + chalk "^2.3.0" + execa "^0.8.0" + find-up "^2.1.0" + ignore "^3.3.7" + mri "^1.1.0" + multimatch "^3.0.0" + prettysize@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/prettysize/-/prettysize-1.1.0.tgz#c6c52f87161ff172ea435f375f99831dd9a97bb0" @@ -8848,6 +8947,10 @@ run-async@^2.2.0: dependencies: is-promise "^2.1.0" +run-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e" + run-queue@^1.0.0, run-queue@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" @@ -8971,6 +9074,10 @@ seed-random@~2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/seed-random/-/seed-random-2.2.0.tgz#2a9b19e250a817099231a5b99a4daf80b7fbed54" +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + semver-diff@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36"