From 76a2a9bb8b6ea04025328d36404ac3b59121dfc8 Mon Sep 17 00:00:00 2001 From: Erik Marks <25517051+rekmarks@users.noreply.github.com> Date: Thu, 4 Feb 2021 10:15:23 -0800 Subject: [PATCH] @metamask/eslint config@5.0.0 (#10358) * @metamask/eslint-config@5.0.0 * Update eslintrc and prettierrc * yarn lint:fix --- .eslintrc.js | 14 +- .prettierrc.yml | 1 - .../account-import-strategies/index.js | 48 +- app/scripts/background.js | 280 +-- app/scripts/constants/contracts.js | 8 +- app/scripts/contentscript.js | 176 +- app/scripts/controllers/alert.js | 56 +- app/scripts/controllers/app-state.js | 68 +- app/scripts/controllers/cached-balances.js | 40 +- app/scripts/controllers/detect-tokens.js | 112 +- app/scripts/controllers/ens/ens.js | 12 +- app/scripts/controllers/ens/index.js | 68 +- .../controllers/incoming-transactions.js | 176 +- app/scripts/controllers/metametrics.js | 128 +- .../controllers/network/createInfuraClient.js | 36 +- .../network/createJsonRpcClient.js | 48 +- .../network/createMetamaskMiddleware.js | 10 +- app/scripts/controllers/network/index.js | 2 +- .../controllers/network/middleware/pending.js | 38 +- app/scripts/controllers/network/network.js | 198 +- app/scripts/controllers/network/util.js | 6 +- app/scripts/controllers/onboarding.js | 36 +- app/scripts/controllers/permissions/enums.js | 24 +- app/scripts/controllers/permissions/index.js | 296 +-- .../controllers/permissions/permissionsLog.js | 130 +- .../permissionsMethodMiddleware.js | 62 +- .../permissions/restrictedMethods.js | 26 +- app/scripts/controllers/preferences.js | 420 ++-- app/scripts/controllers/swaps.js | 475 ++-- app/scripts/controllers/threebox.js | 199 +- app/scripts/controllers/token-rates.js | 70 +- app/scripts/controllers/transactions/index.js | 554 ++--- .../lib/tx-state-history-helpers.js | 28 +- .../controllers/transactions/lib/util.js | 44 +- .../transactions/pending-tx-tracker.js | 132 +- .../controllers/transactions/tx-gas-utils.js | 56 +- .../transactions/tx-state-manager.js | 254 +- app/scripts/disable-console.js | 6 +- app/scripts/first-time-state.js | 4 +- app/scripts/initSentry.js | 4 +- app/scripts/inpage.js | 32 +- app/scripts/lib/ComposableObservableStore.js | 24 +- app/scripts/lib/account-tracker.js | 164 +- app/scripts/lib/buy-eth-url.js | 28 +- app/scripts/lib/cleanErrorStack.js | 16 +- app/scripts/lib/createLoggerMiddleware.js | 14 +- app/scripts/lib/createOnboardingMiddleware.js | 20 +- app/scripts/lib/createOriginMiddleware.js | 6 +- app/scripts/lib/createStreamSink.js | 14 +- app/scripts/lib/createTabIdMiddleware.js | 6 +- app/scripts/lib/decrypt-message-manager.js | 142 +- .../lib/encryption-public-key-manager.js | 122 +- .../lib/ens-ipfs/contracts/registry.js | 4 +- .../lib/ens-ipfs/contracts/resolver.js | 4 +- app/scripts/lib/ens-ipfs/resolver.js | 66 +- app/scripts/lib/ens-ipfs/setup.js | 61 +- app/scripts/lib/extractEthjsErrorMessage.js | 14 +- .../lib/get-first-preferred-lang-code.js | 26 +- app/scripts/lib/getObjStructure.js | 16 +- app/scripts/lib/local-store.js | 46 +- app/scripts/lib/message-manager.js | 110 +- app/scripts/lib/migrator/index.js | 36 +- app/scripts/lib/network-store.js | 36 +- app/scripts/lib/nodeify.js | 28 +- app/scripts/lib/notification-manager.js | 42 +- app/scripts/lib/personal-message-manager.js | 132 +- app/scripts/lib/random-id.js | 8 +- .../createMethodMiddleware.js | 14 +- .../handlers/get-provider-state.js | 10 +- .../rpc-method-middleware/handlers/index.js | 10 +- .../handlers/log-web3-shim-usage.js | 16 +- .../handlers/watch-asset.js | 12 +- .../lib/rpc-method-middleware/index.js | 2 +- app/scripts/lib/seed-phrase-verifier.js | 28 +- app/scripts/lib/segment.js | 36 +- app/scripts/lib/setupFetchDebugging.js | 22 +- app/scripts/lib/setupSentry.js | 76 +- app/scripts/lib/stream-utils.js | 12 +- app/scripts/lib/typed-message-manager.js | 180 +- app/scripts/lib/util.js | 86 +- app/scripts/metamask-controller.js | 1198 ++++----- app/scripts/migrations/002.js | 16 +- app/scripts/migrations/003.js | 18 +- app/scripts/migrations/004.js | 22 +- app/scripts/migrations/005.js | 32 +- app/scripts/migrations/006.js | 28 +- app/scripts/migrations/007.js | 28 +- app/scripts/migrations/008.js | 26 +- app/scripts/migrations/009.js | 32 +- app/scripts/migrations/010.js | 26 +- app/scripts/migrations/011.js | 28 +- app/scripts/migrations/012.js | 28 +- app/scripts/migrations/013.js | 28 +- app/scripts/migrations/014.js | 30 +- app/scripts/migrations/015.js | 38 +- app/scripts/migrations/016.js | 40 +- app/scripts/migrations/017.js | 40 +- app/scripts/migrations/018.js | 46 +- app/scripts/migrations/019.js | 75 +- app/scripts/migrations/020.js | 26 +- app/scripts/migrations/021.js | 28 +- app/scripts/migrations/022.js | 38 +- app/scripts/migrations/023.js | 46 +- app/scripts/migrations/024.js | 34 +- app/scripts/migrations/025.js | 46 +- app/scripts/migrations/026.js | 34 +- app/scripts/migrations/027.js | 28 +- app/scripts/migrations/028.js | 32 +- app/scripts/migrations/029.js | 24 +- app/scripts/migrations/030.js | 34 +- app/scripts/migrations/031.js | 26 +- app/scripts/migrations/032.js | 24 +- app/scripts/migrations/033.js | 24 +- app/scripts/migrations/034.js | 26 +- app/scripts/migrations/035.js | 18 +- app/scripts/migrations/036.js | 24 +- app/scripts/migrations/037.js | 40 +- app/scripts/migrations/038.js | 24 +- app/scripts/migrations/039.js | 42 +- app/scripts/migrations/040.js | 20 +- app/scripts/migrations/041.js | 22 +- app/scripts/migrations/042.js | 22 +- app/scripts/migrations/043.js | 20 +- app/scripts/migrations/044.js | 20 +- app/scripts/migrations/045.js | 22 +- app/scripts/migrations/046.js | 20 +- app/scripts/migrations/047.js | 24 +- app/scripts/migrations/048.js | 122 +- app/scripts/migrations/049.js | 34 +- app/scripts/migrations/050.js | 16 +- app/scripts/migrations/051.js | 26 +- app/scripts/migrations/fail-tx.js | 38 +- app/scripts/migrations/index.js | 4 +- app/scripts/migrations/template.js | 22 +- app/scripts/phishing-detect.js | 54 +- app/scripts/platforms/extension.js | 168 +- app/scripts/runLockdown.js | 6 +- app/scripts/ui.js | 132 +- babel.config.js | 6 +- development/announcer.js | 14 +- development/build/display.js | 138 +- development/build/etc.js | 38 +- development/build/index.js | 40 +- development/build/manifest.js | 83 +- development/build/scripts.js | 166 +- development/build/static.js | 66 +- development/build/styles.js | 50 +- development/build/task.js | 94 +- development/create-static-server.js | 18 +- development/lib/create-segment-server.js | 64 +- development/lib/locales.js | 30 +- development/lib/parse-port.js | 10 +- development/metamaskbot-build-announce.js | 176 +- development/missing-locale-strings.js | 50 +- development/mock-3box.js | 46 +- development/mock-segment.js | 48 +- development/require-react-devtools.js | 2 +- development/sentry-publish.js | 62 +- development/show-deps-install-scripts.js | 36 +- development/sourcemap-validator.js | 138 +- development/static-server.js | 76 +- development/verify-locale-strings.js | 175 +- nyc.config.js | 2 +- package.json | 2 +- shared/constants/alerts.js | 6 +- shared/constants/app.js | 20 +- shared/constants/metametrics.js | 4 +- shared/constants/network.js | 62 +- shared/constants/permissions.js | 2 +- shared/constants/tokens.js | 4 +- shared/constants/transaction.js | 10 +- shared/modules/fetch-with-timeout.js | 28 +- shared/modules/utils.js | 8 +- stylelint.config.js | 2 +- test/e2e/address-book.spec.js | 302 +-- test/e2e/benchmark.js | 160 +- test/e2e/ethereum-on.spec.js | 204 +- test/e2e/fixture-server.js | 64 +- test/e2e/from-import-ui.spec.js | 418 ++-- test/e2e/ganache.js | 26 +- test/e2e/helpers.js | 104 +- test/e2e/incremental-security.spec.js | 228 +- test/e2e/metamask-responsive-ui.spec.js | 276 +-- test/e2e/metamask-ui.spec.js | 1782 +++++++------- test/e2e/metrics.spec.js | 50 +- test/e2e/mock-3box/server.js | 40 +- test/e2e/permissions.spec.js | 180 +- test/e2e/send-edit.spec.js | 262 +- test/e2e/signature-request.spec.js | 188 +- test/e2e/tests/localization.spec.js | 34 +- test/e2e/tests/personal-sign.spec.js | 42 +- test/e2e/tests/simple-send.spec.js | 38 +- test/e2e/threebox.spec.js | 278 +-- test/e2e/webdriver/chrome.js | 34 +- test/e2e/webdriver/driver.js | 158 +- test/e2e/webdriver/firefox.js | 46 +- test/e2e/webdriver/index.js | 54 +- test/env.js | 2 +- test/helper.js | 90 +- test/lib/createTxMeta.js | 14 +- test/lib/mock-encryptor.js | 26 +- test/lib/render-helpers.js | 26 +- test/lib/wait-until-called.js | 32 +- test/setup.js | 8 +- test/stub/provider.js | 28 +- test/unit-global/frozenPromise.js | 50 +- test/unit-global/globalPatch.js | 2 +- test/unit/actions/config_test.js | 28 +- test/unit/actions/set_account_label_test.js | 24 +- .../unit/actions/set_selected_account_test.js | 24 +- test/unit/actions/tx_test.js | 44 +- test/unit/actions/warning_test.js | 24 +- test/unit/app/ComposableObservableStore.js | 46 +- .../app/account-import-strategies.spec.js | 60 +- test/unit/app/buy-eth-url.spec.js | 38 +- test/unit/app/cleanErrorStack.spec.js | 38 +- .../app/controllers/cached-balances-test.js | 64 +- .../app/controllers/detect-tokens-test.js | 290 +-- .../app/controllers/ens-controller-test.js | 108 +- .../controllers/incoming-transactions-test.js | 510 ++-- .../controllers/metamask-controller-test.js | 1065 ++++---- test/unit/app/controllers/metametrics-test.js | 335 +-- .../network/network-controller-test.js | 88 +- .../network/pending-middleware-test.js | 90 +- test/unit/app/controllers/network/stubs.js | 4 +- .../app/controllers/permissions/helpers.js | 56 +- .../unit/app/controllers/permissions/mocks.js | 156 +- .../permissions-controller-test.js | 908 +++---- .../permissions-log-controller-test.js | 456 ++-- .../permissions-middleware-test.js | 564 ++--- .../permissions/restricted-methods-test.js | 138 +- .../preferences-controller-test.js | 669 ++--- test/unit/app/controllers/swaps-test.js | 781 +++--- .../app/controllers/token-rates-controller.js | 38 +- .../transactions/pending-tx-tracker-test.js | 393 +-- .../transactions/tx-controller-test.js | 578 ++--- .../transactions/tx-gas-util-test.js | 76 +- .../transactions/tx-helper-test.js | 18 +- .../tx-state-history-helpers-test.js | 120 +- .../transactions/tx-state-manager-test.js | 488 ++-- .../controllers/transactions/tx-utils-test.js | 113 +- test/unit/app/fetch-with-timeout.test.js | 56 +- test/unit/app/message-manager-test.js | 118 +- test/unit/app/nodeify-test.js | 72 +- .../unit/app/personal-message-manager-test.js | 144 +- test/unit/app/seed-phrase-verifier-test.js | 146 +- test/unit/app/typed-message-manager.spec.js | 85 +- test/unit/app/util-test.js | 128 +- test/unit/balance-formatter-test.js | 30 +- test/unit/lib/account-link.test.js | 16 +- test/unit/localhostState.js | 6 +- test/unit/migrations/021-test.js | 20 +- test/unit/migrations/022-test.js | 28 +- test/unit/migrations/023-test.js | 89 +- test/unit/migrations/024-test.js | 44 +- test/unit/migrations/025-test.js | 44 +- test/unit/migrations/026-test.js | 30 +- test/unit/migrations/027-test.js | 44 +- test/unit/migrations/028-test.js | 42 +- test/unit/migrations/029-test.js | 34 +- test/unit/migrations/030-test.js | 24 +- test/unit/migrations/031-test.js | 26 +- test/unit/migrations/033-test.js | 14 +- test/unit/migrations/034-test.js | 66 +- test/unit/migrations/035-test.js | 46 +- test/unit/migrations/036-test.js | 66 +- test/unit/migrations/037-test.js | 36 +- test/unit/migrations/038-test.js | 36 +- test/unit/migrations/039-test.js | 146 +- test/unit/migrations/040-test.js | 36 +- test/unit/migrations/041-test.js | 46 +- test/unit/migrations/042-test.js | 36 +- test/unit/migrations/043-test.js | 30 +- test/unit/migrations/044-test.js | 38 +- test/unit/migrations/045-test.js | 46 +- test/unit/migrations/046-test.js | 30 +- test/unit/migrations/047-test.js | 54 +- test/unit/migrations/048-test.js | 148 +- test/unit/migrations/049-test.js | 54 +- test/unit/migrations/050-test.js | 54 +- test/unit/migrations/051-test.js | 52 +- test/unit/migrations/migrations-test.js | 152 +- test/unit/migrations/migrator-test.js | 106 +- test/unit/migrations/template-test.js | 16 +- .../responsive/components/dropdown-test.js | 34 +- test/unit/ui/app/actions.spec.js | 1364 +++++------ test/unit/ui/app/reducers/app.spec.js | 288 +-- test/unit/ui/app/reducers/metamask.spec.js | 210 +- .../ui/etherscan-prefix-for-network.spec.js | 30 +- .../account-list-item/account-list-item.js | 16 +- .../components/app/account-list-item/index.js | 2 +- .../tests/account-list-item-component.test.js | 128 +- .../account-menu/account-menu.component.js | 194 +- .../account-menu/account-menu.container.js | 42 +- ui/app/components/app/account-menu/index.js | 2 +- .../account-menu/tests/account-menu.test.js | 172 +- .../add-token-button.component.js | 24 +- .../components/app/add-token-button/index.js | 2 +- ui/app/components/app/alerts/alerts.js | 30 +- ui/app/components/app/alerts/index.js | 2 +- .../invalid-custom-network-alert/index.js | 2 +- .../invalid-custom-network-alert.js | 44 +- .../alerts/unconnected-account-alert/index.js | 2 +- .../tests/unconnected-account-alert.test.js | 92 +- .../unconnected-account-alert.js | 56 +- .../app/app-header/app-header.component.js | 48 +- .../app/app-header/app-header.container.js | 26 +- ui/app/components/app/app-header/index.js | 2 +- .../app/app-header/tests/app-header.test.js | 88 +- .../app/asset-list-item/asset-list-item.js | 66 +- .../components/app/asset-list-item/index.js | 2 +- .../components/app/asset-list/asset-list.js | 62 +- ui/app/components/app/asset-list/index.js | 2 +- .../confirm-detail-row.component.js | 20 +- .../confirm-detail-row/index.js | 2 +- .../confirm-detail-row.component.test.js | 56 +- ...onfirm-page-container-content.component.js | 30 +- ...onfirm-page-container-summary.component.js | 18 +- .../confirm-page-container-summary/index.js | 2 +- ...onfirm-page-container-warning.component.js | 12 +- .../confirm-page-container-warning/index.js | 2 +- .../confirm-page-container-content/index.js | 6 +- ...confirm-page-container-header.component.js | 30 +- .../confirm-page-container-header/index.js | 2 +- ...irm-page-container-navigation.component.js | 14 +- .../index.js | 2 +- .../confirm-page-container.component.js | 20 +- .../app/confirm-page-container/index.js | 10 +- .../connected-accounts-list-item.component.js | 18 +- .../connected-accounts-list-item/index.js | 2 +- ...nnected-accounts-list-options.component.js | 16 +- .../connected-accounts-list-options/index.js | 2 +- .../connected-accounts-list.component.js | 72 +- .../app/connected-accounts-list/index.js | 2 +- ...onnected-accounts-permissions.component.js | 30 +- .../connected-accounts-permissions/index.js | 2 +- .../connected-sites-list.component.js | 22 +- .../app/connected-sites-list/index.js | 2 +- .../connected-status-indicator.js | 58 +- .../app/connected-status-indicator/index.js | 2 +- .../contact-list/contact-list.component.js | 54 +- ui/app/components/app/contact-list/index.js | 2 +- .../app/contact-list/recipient-group/index.js | 2 +- .../recipient-group.component.js | 18 +- .../app/dropdowns/components/dropdown.js | 30 +- .../app/dropdowns/network-dropdown.js | 130 +- .../app/dropdowns/simple-dropdown.js | 44 +- .../app/dropdowns/tests/dropdown.test.js | 38 +- .../dropdowns/tests/network-dropdown.test.js | 108 +- .../advanced-gas-inputs.component.js | 92 +- .../advanced-gas-inputs.container.js | 18 +- .../advanced-gas-inputs/index.js | 2 +- .../advanced-gas-input-component.test.js | 107 +- .../advanced-tab-content.component.js | 16 +- .../advanced-tab-content/index.js | 2 +- .../advanced-tab-content-component.test.js | 74 +- .../basic-tab-content.component.js | 18 +- .../basic-tab-content/index.js | 2 +- .../tests/basic-tab-content-component.test.js | 60 +- .../gas-modal-page-container.component.js | 42 +- .../gas-modal-page-container.container.js | 164 +- .../gas-modal-page-container/index.js | 2 +- ...gas-modal-page-container-component.test.js | 192 +- ...gas-modal-page-container-container.test.js | 306 +-- .../gas-price-button-group.component.js | 34 +- .../gas-price-button-group/index.js | 2 +- .../gas-price-button-group-component.test.js | 180 +- .../gas-slider/gas-slider.component.js | 10 +- .../app/gas-customization/gas-slider/index.js | 2 +- .../home-notification.component.js | 24 +- .../components/app/home-notification/index.js | 2 +- ui/app/components/app/info-box/index.js | 4 +- .../app/info-box/info-box.component.js | 20 +- .../app/info-box/tests/info-box.test.js | 40 +- .../app/loading-network-screen/index.js | 2 +- .../loading-network-screen.component.js | 90 +- .../loading-network-screen.container.js | 30 +- .../app/menu-bar/account-options-menu.js | 86 +- ui/app/components/app/menu-bar/index.js | 2 +- ui/app/components/app/menu-bar/menu-bar.js | 46 +- .../app/menu-bar/tests/menu-bar.test.js | 56 +- ui/app/components/app/menu-droppo.js | 54 +- .../app/metamask-template-renderer/index.js | 2 +- .../metamask-template-renderer.js | 52 +- .../metamask-template-renderer.stories.js | 16 +- .../safe-component-list.js | 16 +- ui/app/components/app/modal/index.js | 4 +- .../app/modal/modal-content/index.js | 2 +- .../modal-content/modal-content.component.js | 10 +- .../tests/modal-content.component.test.js | 42 +- .../components/app/modal/modal.component.js | 16 +- .../app/modal/tests/modal.component.test.js | 144 +- .../account-details-modal.component.js | 34 +- .../account-details-modal.container.js | 21 +- .../app/modals/account-details-modal/index.js | 2 +- .../account-modal-container.component.js | 18 +- .../account-modal-container.container.js | 16 +- .../modals/account-modal-container/index.js | 2 +- .../add-to-addressbook-modal.component.js | 32 +- .../add-to-addressbook-modal.container.js | 12 +- .../modals/add-to-addressbook-modal/index.js | 2 +- .../cancel-transaction-gas-fee.component.js | 14 +- .../cancel-transaction-gas-fee/index.js | 2 +- ...ncel-transaction-gas-fee.component.test.js | 32 +- .../cancel-transaction.component.js | 42 +- .../cancel-transaction.container.js | 50 +- .../app/modals/cancel-transaction/index.js | 2 +- .../cancel-transaction.component.test.js | 66 +- .../confirm-delete-network.component.js | 22 +- .../confirm-delete-network.container.js | 16 +- .../modals/confirm-delete-network/index.js | 2 +- .../tests/confirm-delete-network.test.js | 56 +- .../confirm-remove-account.component.js | 32 +- .../confirm-remove-account.container.js | 20 +- .../modals/confirm-remove-account/index.js | 2 +- .../tests/confirm-remove-account.test.js | 68 +- .../confirm-reset-account.component.js | 18 +- .../confirm-reset-account.container.js | 16 +- .../app/modals/confirm-reset-account/index.js | 2 +- .../tests/confirm-reset-account.test.js | 46 +- .../deposit-ether-modal.component.js | 44 +- .../deposit-ether-modal.container.js | 20 +- .../app/modals/deposit-ether-modal/index.js | 2 +- .../edit-approval-permission.component.js | 84 +- .../edit-approval-permission.container.js | 18 +- .../modals/edit-approval-permission/index.js | 2 +- .../export-private-key-modal.component.js | 54 +- .../export-private-key-modal.container.js | 26 +- .../modals/export-private-key-modal/index.js | 2 +- ui/app/components/app/modals/fade-modal.js | 160 +- .../hide-token-confirmation-modal.js | 36 +- .../hide-token-confirmation-modal/index.js | 2 +- ui/app/components/app/modals/index.js | 4 +- .../app/modals/loading-network-error/index.js | 2 +- .../loading-network-error.component.js | 20 +- .../loading-network-error.container.js | 6 +- .../modals/metametrics-opt-in-modal/index.js | 2 +- .../metametrics-opt-in-modal.component.js | 30 +- .../metametrics-opt-in-modal.container.js | 22 +- .../tests/metametrics-opt-in-modal.test.js | 60 +- ui/app/components/app/modals/modal.js | 106 +- .../app/modals/new-account-modal/index.js | 2 +- .../new-account-modal.component.js | 28 +- .../new-account-modal.container.js | 26 +- .../components/app/modals/qr-scanner/index.js | 4 +- .../modals/qr-scanner/qr-scanner.component.js | 184 +- .../modals/qr-scanner/qr-scanner.container.js | 12 +- .../app/modals/reject-transactions/index.js | 2 +- .../reject-transactions.component.js | 24 +- .../reject-transactions.container.js | 16 +- .../tests/reject-transactions.test.js | 46 +- .../tests/account-details-modal.test.js | 64 +- .../app/modals/transaction-confirmed/index.js | 2 +- .../tests/transaction-confirmed.test.js | 28 +- .../transaction-confirmed.component.js | 22 +- .../transaction-confirmed.container.js | 6 +- .../app/multiple-notifications/index.js | 2 +- .../multiple-notifications.component.js | 22 +- .../components/app/network-display/index.js | 2 +- .../app/network-display/network-display.js | 30 +- .../app/permission-page-container/index.js | 4 +- .../index.js | 2 +- ...ission-page-container-content.component.js | 66 +- .../permission-page-container.component.js | 62 +- .../permission-page-container.container.js | 18 +- .../app/permissions-connect-footer/index.js | 2 +- .../permissions-connect-footer.component.js | 12 +- .../app/permissions-connect-header/index.js | 2 +- .../permissions-connect-header.component.js | 18 +- .../components/app/selected-account/index.js | 4 +- .../selected-account.component.js | 38 +- .../selected-account.container.js | 12 +- .../tests/selected-account-component.test.js | 18 +- ui/app/components/app/sidebars/index.js | 2 +- .../app/sidebars/sidebar.component.js | 32 +- .../sidebars/tests/sidebars-component.test.js | 104 +- .../app/signature-request-original/index.js | 2 +- .../signature-request-original.component.js | 166 +- .../signature-request-original.container.js | 52 +- .../components/app/signature-request/index.js | 2 +- .../signature-request-footer/index.js | 2 +- .../signature-request-footer.component.js | 14 +- .../signature-request-header/index.js | 2 +- .../signature-request-header.component.js | 14 +- .../signature-request-message/index.js | 2 +- .../signature-request-message.component.js | 16 +- .../signature-request.component.js | 42 +- .../signature-request.constants.js | 4 +- .../signature-request.container.js | 44 +- .../tests/signature-request.test.js | 24 +- ui/app/components/app/tab-bar/index.js | 2 +- ui/app/components/app/tab-bar/tab-bar.js | 16 +- .../app/tests/signature-request.test.js | 48 +- ui/app/components/app/token-cell/index.js | 2 +- .../components/app/token-cell/token-cell.js | 30 +- .../app/token-cell/token-cell.test.js | 70 +- ui/app/components/app/token-list/index.js | 2 +- .../components/app/token-list/token-list.js | 36 +- .../app/transaction-activity-log/index.js | 2 +- ...transaction-activity-log.component.test.js | 44 +- ...transaction-activity-log.container.test.js | 22 +- .../transaction-activity-log.util.test.js | 38 +- .../transaction-activity-log-icon/index.js | 2 +- ...transaction-activity-log-icon.component.js | 20 +- .../transaction-activity-log.component.js | 68 +- .../transaction-activity-log.constants.js | 24 +- .../transaction-activity-log.container.js | 32 +- .../transaction-activity-log.util.js | 106 +- .../app/transaction-breakdown/index.js | 2 +- .../transaction-breakdown.component.test.js | 22 +- .../transaction-breakdown-row/index.js | 2 +- ...ransaction-breakdown-row.component.test.js | 32 +- .../transaction-breakdown-row.component.js | 12 +- .../transaction-breakdown.component.js | 28 +- .../transaction-breakdown.container.js | 34 +- .../components/app/transaction-icon/index.js | 2 +- .../app/transaction-icon/transaction-icon.js | 36 +- .../transaction-list-item-details/index.js | 2 +- ...action-list-item-details.component.test.js | 90 +- ...transaction-list-item-details.component.js | 102 +- ...transaction-list-item-details.container.js | 46 +- .../app/transaction-list-item/index.js | 2 +- .../transaction-list-item.component.js | 88 +- .../components/app/transaction-list/index.js | 2 +- .../transaction-list.component.js | 66 +- .../app/transaction-status/index.js | 2 +- .../transaction-status.component.test.js | 70 +- .../transaction-status.component.js | 32 +- .../index.js | 2 +- ...erenced-currency-display.component.test.js | 52 +- ...-preferenced-currency-display.component.js | 20 +- .../user-preferenced-currency-input/index.js | 2 +- ...eferenced-currency-input.component.test.js | 36 +- ...eferenced-currency-input.container.test.js | 22 +- ...er-preferenced-currency-input.component.js | 12 +- ...er-preferenced-currency-input.container.js | 14 +- .../app/user-preferenced-token-input/index.js | 2 +- ...-preferenced-token-input.component.test.js | 36 +- ...-preferenced-token-input.container.test.js | 22 +- .../user-preferenced-token-input.component.js | 12 +- .../user-preferenced-token-input.container.js | 20 +- .../app/wallet-overview/eth-overview.js | 100 +- .../components/app/wallet-overview/index.js | 4 +- .../app/wallet-overview/token-overview.js | 92 +- .../app/wallet-overview/wallet-overview.js | 16 +- .../account-mismatch-warning.component.js | 26 +- ...cccount-mismatch-warning.component.test.js | 44 +- .../alert-circle-icon.component.js | 12 +- .../alert-circle-icon.stories.js | 10 +- .../components/ui/alert-circle-icon/index.js | 2 +- ui/app/components/ui/alert/index.js | 28 +- .../components/ui/alert/tests/alert.test.js | 52 +- ui/app/components/ui/box/box.js | 40 +- ui/app/components/ui/box/box.stories.js | 22 +- ui/app/components/ui/box/index.js | 2 +- .../ui/breadcrumbs/breadcrumbs.component.js | 12 +- ui/app/components/ui/breadcrumbs/index.js | 2 +- .../tests/breadcrumbs.component.test.js | 26 +- .../ui/button-group/button-group.component.js | 30 +- .../ui/button-group/button-group.stories.js | 20 +- ui/app/components/ui/button-group/index.js | 2 +- .../tests/button-group-component.test.js | 138 +- .../components/ui/button/button.component.js | 40 +- ui/app/components/ui/button/button.stories.js | 22 +- ui/app/components/ui/button/index.js | 4 +- ui/app/components/ui/callout/callout.js | 28 +- .../components/ui/callout/callout.stories.js | 34 +- ui/app/components/ui/callout/index.js | 2 +- ui/app/components/ui/card/card.component.js | 12 +- ui/app/components/ui/card/index.js | 2 +- .../ui/card/tests/card.component.test.js | 28 +- .../ui/check-box/check-box.component.js | 32 +- .../ui/check-box/check-box.stories.js | 14 +- ui/app/components/ui/check-box/index.js | 2 +- ui/app/components/ui/chip/chip.js | 20 +- ui/app/components/ui/chip/chip.stories.js | 22 +- ui/app/components/ui/chip/index.js | 2 +- .../ui/circle-icon/circle-icon.component.js | 12 +- .../ui/circle-icon/circle-icon.stories.js | 8 +- ui/app/components/ui/circle-icon/index.js | 2 +- .../ui/color-indicator/color-indicator.js | 16 +- .../color-indicator.stories.js | 14 +- ui/app/components/ui/color-indicator/index.js | 2 +- .../currency-display.component.js | 16 +- .../components/ui/currency-display/index.js | 2 +- .../tests/currency-display.component.test.js | 40 +- .../currency-input.component.js | 92 +- .../currency-input.container.js | 26 +- ui/app/components/ui/currency-input/index.js | 2 +- .../tests/currency-input.component.test.js | 322 +-- .../tests/currency-input.container.test.js | 36 +- .../ui/definition-list/definition-list.js | 18 +- .../definition-list.stories.js | 22 +- ui/app/components/ui/definition-list/index.js | 2 +- ui/app/components/ui/dialog/index.js | 12 +- ui/app/components/ui/dropdown/dropdown.js | 26 +- .../ui/dropdown/dropdown.stories.js | 30 +- ui/app/components/ui/dropdown/index.js | 2 +- .../ui/editable-label/editable-label.js | 32 +- ui/app/components/ui/editable-label/index.js | 2 +- .../error-message/error-message.component.js | 18 +- ui/app/components/ui/error-message/index.js | 2 +- .../tests/error-message.component.test.js | 36 +- .../export-text-container.component.js | 24 +- .../ui/export-text-container/index.js | 4 +- .../hex-to-decimal.component.js | 14 +- ui/app/components/ui/hex-to-decimal/index.js | 2 +- .../tests/hex-to-decimal.component.test.js | 26 +- .../components/ui/icon-border/icon-border.js | 10 +- ui/app/components/ui/icon-border/index.js | 2 +- .../components/ui/icon-button/icon-button.js | 14 +- ui/app/components/ui/icon-button/index.js | 2 +- .../icon-with-fallback.component.js | 18 +- .../components/ui/icon-with-fallback/index.js | 2 +- .../ui/icon-with-label/icon-with-label.js | 10 +- ui/app/components/ui/icon-with-label/index.js | 2 +- .../ui/icon/approve-icon.component.js | 12 +- .../components/ui/icon/copy-icon.component.js | 12 +- ui/app/components/ui/icon/icon.stories.js | 42 +- .../ui/icon/info-icon-inverted.component.js | 14 +- .../components/ui/icon/info-icon.component.js | 14 +- .../ui/icon/interaction-icon.component.js | 12 +- .../ui/icon/overview-buy-icon.component.js | 8 +- .../ui/icon/overview-send-icon.component.js | 8 +- .../components/ui/icon/paper-airplane-icon.js | 10 +- ui/app/components/ui/icon/preloader/index.js | 4 +- .../preloader/preloader-icon.component.js | 14 +- .../ui/icon/receive-icon.component.js | 12 +- .../components/ui/icon/send-icon.component.js | 12 +- .../components/ui/icon/sign-icon.component.js | 8 +- .../ui/icon/sun-check-icon.component.js | 12 +- .../ui/icon/swap-icon-for-list.component.js | 12 +- .../components/ui/icon/swap-icon.component.js | 8 +- .../blockieIdenticon.component.js | 28 +- .../ui/identicon/blockieIdenticon/index.js | 2 +- .../ui/identicon/identicon.component.js | 44 +- .../ui/identicon/identicon.container.js | 12 +- .../ui/identicon/identicon.stories.js | 20 +- ui/app/components/ui/identicon/index.js | 2 +- .../tests/identicon.component.test.js | 45 +- ui/app/components/ui/info-tooltip/index.js | 2 +- .../ui/info-tooltip/info-tooltip.js | 14 +- .../ui/info-tooltip/info-tooltip.stories.js | 16 +- ui/app/components/ui/jazzicon/index.js | 2 +- .../ui/jazzicon/jazzicon.component.js | 40 +- ui/app/components/ui/list-item/index.js | 2 +- .../ui/list-item/list-item.component.js | 12 +- .../ui/list-item/list-item.stories.js | 38 +- .../ui/list-item/tests/list-item.test.js | 84 +- .../components/ui/loading-indicator/index.js | 2 +- .../ui/loading-indicator/loading-indicator.js | 8 +- ui/app/components/ui/loading-screen/index.js | 4 +- .../loading-screen.component.js | 20 +- ui/app/components/ui/lock-icon/index.js | 2 +- .../ui/lock-icon/lock-icon.component.js | 4 +- ui/app/components/ui/mascot/index.js | 2 +- .../components/ui/mascot/mascot.component.js | 80 +- ui/app/components/ui/mascot/mascot.stories.js | 50 +- ui/app/components/ui/menu/index.js | 4 +- ui/app/components/ui/menu/menu-item.js | 14 +- ui/app/components/ui/menu/menu.js | 26 +- ui/app/components/ui/menu/menu.stories.js | 18 +- ui/app/components/ui/metafox-logo/index.js | 2 +- .../ui/metafox-logo/metafox-logo.component.js | 16 +- .../tests/metafox-logo.component.test.js | 26 +- ui/app/components/ui/page-container/index.js | 8 +- .../page-container-content.component.js | 8 +- .../page-container-footer/index.js | 2 +- .../page-container-footer.component.js | 16 +- .../page-container-footer.component.test.js | 74 +- .../page-container-header/index.js | 2 +- .../page-container-header.component.js | 22 +- .../page-container-header.component.test.js | 95 +- .../page-container.component.js | 46 +- ui/app/components/ui/popover/index.js | 4 +- .../ui/popover/popover.component.js | 36 +- .../components/ui/popover/popover.stories.js | 16 +- ui/app/components/ui/pulse-loader/index.js | 2 +- .../ui/pulse-loader/pulse-loader.js | 4 +- .../ui/pulse-loader/pulse-loader.stories.js | 8 +- ui/app/components/ui/qr-code/index.js | 2 +- ui/app/components/ui/qr-code/qr-code.js | 36 +- ui/app/components/ui/readonly-input/index.js | 2 +- .../ui/readonly-input/readonly-input.js | 14 +- ui/app/components/ui/search-icon/index.js | 2 +- .../ui/search-icon/search-icon.component.js | 4 +- .../ui/sender-to-recipient/index.js | 2 +- .../sender-to-recipient.component.js | 76 +- .../sender-to-recipient.constants.js | 6 +- ui/app/components/ui/site-icon/index.js | 2 +- ui/app/components/ui/site-icon/site-icon.js | 16 +- ui/app/components/ui/snackbar/index.js | 2 +- .../ui/snackbar/snackbar.component.js | 14 +- ui/app/components/ui/spinner/index.js | 4 +- .../ui/spinner/spinner.component.js | 12 +- ui/app/components/ui/tabs/index.js | 6 +- ui/app/components/ui/tabs/tab/index.js | 4 +- .../components/ui/tabs/tab/tab.component.js | 22 +- ui/app/components/ui/tabs/tabs.component.js | 42 +- ui/app/components/ui/tabs/tabs.stories.js | 24 +- ui/app/components/ui/text-field/index.js | 4 +- .../ui/text-field/text-field.component.js | 32 +- .../ui/text-field/text-field.stories.js | 20 +- ui/app/components/ui/toggle-button/index.js | 4 +- .../toggle-button/toggle-button.component.js | 26 +- ui/app/components/ui/token-balance/index.js | 2 +- .../ui/token-balance/token-balance.js | 18 +- .../ui/token-currency-display/index.js | 2 +- .../token-currency-display.component.js | 14 +- ui/app/components/ui/token-input/index.js | 2 +- .../tests/token-input.component.test.js | 248 +- .../ui/token-input/token-input.component.js | 88 +- .../ui/token-input/token-input.container.js | 24 +- ui/app/components/ui/tooltip/index.js | 2 +- ui/app/components/ui/tooltip/tooltip.js | 16 +- .../ui/truncated-definition-list/index.js | 2 +- .../truncated-definition-list.js | 26 +- .../truncated-definition-list.stories.js | 18 +- ui/app/components/ui/typography/index.js | 2 +- ui/app/components/ui/typography/typography.js | 24 +- .../ui/typography/typography.stories.js | 14 +- ui/app/components/ui/unit-input/index.js | 2 +- .../tests/unit-input.component.test.js | 132 +- .../ui/unit-input/unit-input.component.js | 60 +- ui/app/components/ui/url-icon/index.js | 2 +- ui/app/components/ui/url-icon/url-icon.js | 12 +- ui/app/contexts/i18n.js | 46 +- ui/app/contexts/metametrics.js | 76 +- ui/app/contexts/metametrics.new.js | 80 +- ui/app/ducks/alerts/enums.js | 2 +- ui/app/ducks/alerts/index.js | 6 +- ui/app/ducks/alerts/invalid-custom-network.js | 34 +- ui/app/ducks/alerts/unconnected-account.js | 110 +- ui/app/ducks/app/app.js | 96 +- .../confirm-transaction.duck.js | 206 +- .../confirm-transaction.duck.test.js | 297 +-- ui/app/ducks/gas/gas-duck.test.js | 191 +- ui/app/ducks/gas/gas.duck.js | 117 +- ui/app/ducks/history/history.js | 22 +- ui/app/ducks/index.js | 24 +- ui/app/ducks/locale/locale.js | 10 +- ui/app/ducks/metamask/metamask.js | 126 +- ui/app/ducks/send/send-duck.test.js | 78 +- ui/app/ducks/send/send.duck.js | 40 +- ui/app/ducks/swaps/swaps.js | 480 ++-- ui/app/helpers/constants/common.js | 12 +- ui/app/helpers/constants/connected-sites.js | 6 +- ui/app/helpers/constants/design-system.js | 32 +- ui/app/helpers/constants/error-keys.js | 8 +- ui/app/helpers/constants/routes.js | 128 +- ui/app/helpers/constants/swaps.js | 20 +- ui/app/helpers/constants/transactions.js | 8 +- .../authenticated/authenticated.component.js | 18 +- .../authenticated/authenticated.container.js | 12 +- .../authenticated/index.js | 2 +- .../feature-toggled-route.js | 12 +- .../initialized/index.js | 2 +- .../initialized/initialized.component.js | 12 +- .../initialized/initialized.container.js | 12 +- .../with-modal-props/index.js | 2 +- .../tests/with-modal-props.test.js | 42 +- .../with-modal-props/with-modal-props.js | 18 +- ui/app/helpers/utils/common.util.js | 2 +- ui/app/helpers/utils/common.util.test.js | 16 +- ui/app/helpers/utils/confirm-tx.util.js | 46 +- ui/app/helpers/utils/confirm-tx.util.test.js | 104 +- ui/app/helpers/utils/conversion-util.js | 132 +- ui/app/helpers/utils/conversion-util.test.js | 82 +- ui/app/helpers/utils/conversions.util.js | 58 +- ui/app/helpers/utils/conversions.util.test.js | 48 +- ui/app/helpers/utils/fetch-with-cache.js | 38 +- ui/app/helpers/utils/fetch-with-cache.test.js | 104 +- ui/app/helpers/utils/formatters.js | 2 +- ui/app/helpers/utils/i18n-helper.js | 90 +- ui/app/helpers/utils/i18n-helper.test.js | 118 +- ui/app/helpers/utils/switch-direction.js | 26 +- ui/app/helpers/utils/token-util.js | 128 +- ui/app/helpers/utils/transactions.util.js | 102 +- .../helpers/utils/transactions.util.test.js | 52 +- ui/app/helpers/utils/util.js | 286 +-- ui/app/helpers/utils/util.test.js | 418 ++-- .../hooks/tests/useCancelTransaction.test.js | 120 +- ui/app/hooks/tests/useCurrencyDisplay.test.js | 50 +- .../hooks/tests/useRetryTransaction.test.js | 68 +- ui/app/hooks/tests/useTokenData.test.js | 30 +- .../hooks/tests/useTokenDisplayValue.test.js | 36 +- .../tests/useTransactionDisplayData.test.js | 145 +- .../tests/useUserPreferencedCurrency.test.js | 44 +- ui/app/hooks/useCancelTransaction.js | 34 +- ui/app/hooks/useCopyToClipboard.js | 22 +- ui/app/hooks/useCurrencyDisplay.js | 28 +- ui/app/hooks/useCurrentAsset.js | 20 +- ui/app/hooks/useEqualityCheck.js | 12 +- ui/app/hooks/useEthFiatAmount.js | 24 +- ui/app/hooks/useI18nContext.js | 6 +- ui/app/hooks/useMethodData.js | 20 +- ui/app/hooks/useMetricEvent.js | 22 +- ui/app/hooks/usePrevious.js | 10 +- ui/app/hooks/useRetryTransaction.js | 40 +- ui/app/hooks/useShouldShowSpeedUp.js | 30 +- ui/app/hooks/useSwappedTokenValue.js | 28 +- ui/app/hooks/useSwapsEthToken.js | 14 +- ui/app/hooks/useTimeout.js | 34 +- ui/app/hooks/useTokenData.js | 10 +- ui/app/hooks/useTokenDisplayValue.js | 20 +- ui/app/hooks/useTokenFiatAmount.js | 26 +- ui/app/hooks/useTokenTracker.js | 78 +- ui/app/hooks/useTokensToSearch.js | 90 +- ui/app/hooks/useTransactionDisplayData.js | 180 +- ui/app/hooks/useUserPreferencedCurrency.js | 22 +- ui/app/pages/add-token/add-token.component.js | 166 +- ui/app/pages/add-token/add-token.container.js | 20 +- ui/app/pages/add-token/index.js | 4 +- .../pages/add-token/tests/add-token.test.js | 102 +- ui/app/pages/add-token/token-list/index.js | 4 +- .../token-list-placeholder/index.js | 4 +- .../token-list-placeholder.component.js | 10 +- .../token-list/token-list.component.js | 26 +- .../token-list/token-list.container.js | 12 +- ui/app/pages/add-token/token-search/index.js | 4 +- .../token-search/token-search.component.js | 44 +- ui/app/pages/asset/asset.js | 36 +- .../asset/components/asset-breadcrumb.js | 12 +- .../asset/components/asset-navigation.js | 16 +- ui/app/pages/asset/components/native-asset.js | 26 +- ui/app/pages/asset/components/token-asset.js | 44 +- .../pages/asset/components/token-options.js | 30 +- ui/app/pages/asset/index.js | 2 +- .../confirm-add-suggested-token.component.js | 72 +- .../confirm-add-suggested-token.container.js | 26 +- .../confirm-add-suggested-token/index.js | 4 +- .../confirm-add-token.component.js | 46 +- .../confirm-add-token.container.js | 20 +- ui/app/pages/confirm-add-token/index.js | 4 +- .../confirm-approve-content.component.js | 46 +- .../confirm-approve-content/index.js | 2 +- .../pages/confirm-approve/confirm-approve.js | 90 +- .../confirm-approve/confirm-approve.util.js | 37 +- ui/app/pages/confirm-approve/index.js | 2 +- .../confirm-decrypt-message.component.js | 156 +- .../confirm-decrypt-message.container.js | 50 +- ui/app/pages/confirm-decrypt-message/index.js | 2 +- .../confirm-deploy-contract.component.js | 20 +- .../confirm-deploy-contract.container.js | 12 +- ui/app/pages/confirm-deploy-contract/index.js | 2 +- ...confirm-encryption-public-key.component.js | 126 +- ...confirm-encryption-public-key.container.js | 40 +- .../confirm-encryption-public-key/index.js | 2 +- .../confirm-send-ether.component.js | 26 +- .../confirm-send-ether.container.js | 32 +- ui/app/pages/confirm-send-ether/index.js | 2 +- .../confirm-send-token.component.js | 20 +- .../confirm-send-token.container.js | 44 +- ui/app/pages/confirm-send-token/index.js | 2 +- ...onfirm-token-transaction-base.component.js | 46 +- ...onfirm-token-transaction-base.container.js | 50 +- .../confirm-token-transaction-base/index.js | 4 +- .../confirm-transaction-base.component.js | 234 +- .../confirm-transaction-base.container.js | 154 +- .../pages/confirm-transaction-base/index.js | 2 +- ...confirm-transaction-base.component.test.js | 20 +- .../confirm-transaction-switch.component.js | 62 +- .../confirm-transaction-switch.container.js | 28 +- .../pages/confirm-transaction-switch/index.js | 4 +- ui/app/pages/confirm-transaction/conf-tx.js | 149 +- .../confirm-transaction.component.js | 66 +- .../confirm-transaction.container.js | 46 +- ui/app/pages/confirm-transaction/index.js | 4 +- .../connected-accounts.component.js | 24 +- .../connected-accounts.container.js | 40 +- ui/app/pages/connected-accounts/index.js | 2 +- .../connected-sites.component.js | 72 +- .../connected-sites.container.js | 70 +- ui/app/pages/connected-sites/index.js | 2 +- .../connect-hardware/account-list.js | 58 +- .../create-account/connect-hardware/index.js | 179 +- .../connect-hardware/select-hardware.js | 60 +- .../create-account.component.js | 28 +- .../create-account/import-account/index.js | 40 +- .../create-account/import-account/json.js | 86 +- .../import-account/private-key.js | 76 +- ui/app/pages/create-account/index.js | 2 +- .../create-account/new-account.component.js | 30 +- .../create-account/new-account.container.js | 28 +- .../tests/create-account.test.js | 48 +- ui/app/pages/error/error.component.js | 26 +- ui/app/pages/error/index.js | 2 +- .../create-password.component.js | 24 +- .../create-password.container.js | 12 +- .../import-with-seed-phrase.component.js | 124 +- .../import-with-seed-phrase.container.js | 12 +- .../import-with-seed-phrase/index.js | 2 +- .../import-with-seed-phrase.component.test.js | 82 +- .../first-time-flow/create-password/index.js | 2 +- .../create-password/new-account/index.js | 2 +- .../new-account/new-account.component.js | 92 +- .../create-password/unique-image/index.js | 2 +- .../unique-image/unique-image.component.js | 22 +- .../unique-image/unique-image.container.js | 12 +- .../end-of-flow/end-of-flow.component.js | 52 +- .../end-of-flow/end-of-flow.container.js | 22 +- .../first-time-flow/end-of-flow/index.js | 2 +- .../end-of-flow/tests/end-of-flow.test.js | 40 +- .../first-time-flow-switch.component.js | 22 +- .../first-time-flow-switch.container.js | 12 +- .../first-time-flow-switch/index.js | 2 +- .../tests/first-time-flow-switch.test.js | 68 +- .../first-time-flow.component.js | 74 +- .../first-time-flow.container.js | 26 +- ui/app/pages/first-time-flow/index.js | 2 +- .../metametrics-opt-in/index.js | 2 +- .../metametrics-opt-in.component.js | 36 +- .../metametrics-opt-in.container.js | 22 +- .../tests/metametrics-opt-in.test.js | 30 +- .../onboarding-initiator-util.js | 38 +- .../confirm-seed-phrase.component.js | 136 +- .../confirm-seed-phrase.container.js | 12 +- .../draggable-seed.component.js | 56 +- .../seed-phrase/confirm-seed-phrase/index.js | 2 +- .../first-time-flow/seed-phrase/index.js | 2 +- .../seed-phrase/reveal-seed-phrase/index.js | 2 +- .../reveal-seed-phrase.component.js | 72 +- .../reveal-seed-phrase.container.js | 18 +- .../tests/reveal-seed-phrase.test.js | 46 +- .../seed-phrase/seed-phrase.component.js | 36 +- .../confirm-seed-phrase-component.test.js | 143 +- .../first-time-flow/select-action/index.js | 2 +- .../select-action/select-action.component.js | 34 +- .../select-action/select-action.container.js | 22 +- .../select-action/tests/select-action.test.js | 52 +- ui/app/pages/first-time-flow/welcome/index.js | 2 +- .../welcome/tests/welcome.test.js | 46 +- .../welcome/welcome.component.js | 34 +- .../welcome/welcome.container.js | 22 +- ui/app/pages/home/home.component.js | 114 +- ui/app/pages/home/home.container.js | 66 +- ui/app/pages/home/index.js | 2 +- ui/app/pages/index.js | 38 +- ui/app/pages/keychains/restore-vault.js | 94 +- ui/app/pages/keychains/reveal-seed.js | 66 +- .../pages/keychains/tests/reveal-seed.test.js | 22 +- ui/app/pages/lock/index.js | 2 +- ui/app/pages/lock/lock.component.js | 18 +- ui/app/pages/lock/lock.container.js | 22 +- ui/app/pages/lock/tests/lock.test.js | 36 +- ui/app/pages/mobile-sync/index.js | 2 +- .../mobile-sync/mobile-sync.component.js | 227 +- .../mobile-sync/mobile-sync.container.js | 22 +- .../choose-account.component.js | 90 +- .../choose-account/index.js | 2 +- ui/app/pages/permissions-connect/index.js | 2 +- .../permissions-connect.component.js | 122 +- .../permissions-connect.container.js | 76 +- .../permissions-connect/redirect/index.js | 2 +- .../permissions-redirect.component.js | 16 +- ui/app/pages/routes/index.js | 2 +- ui/app/pages/routes/routes.component.js | 186 +- ui/app/pages/routes/routes.container.js | 28 +- ui/app/pages/send/index.js | 2 +- .../add-recipient/add-recipient.component.js | 122 +- .../add-recipient/add-recipient.container.js | 26 +- .../add-recipient/add-recipient.js | 22 +- .../add-recipient/ens-input.component.js | 180 +- .../add-recipient/ens-input.container.js | 12 +- .../send-content/add-recipient/ens-input.js | 2 +- .../send/send-content/add-recipient/index.js | 2 +- .../tests/add-recipient-component.test.js | 152 +- .../tests/add-recipient-container.test.js | 46 +- .../tests/add-recipient-utils.test.js | 52 +- ui/app/pages/send/send-content/index.js | 2 +- .../amount-max-button.component.js | 34 +- .../amount-max-button.container.js | 24 +- .../amount-max-button.utils.js | 10 +- .../amount-max-button/index.js | 2 +- .../tests/amount-max-button-component.test.js | 82 +- .../tests/amount-max-button-container.test.js | 68 +- .../tests/amount-max-button-utils.test.js | 16 +- .../send-content/send-amount-row/index.js | 2 +- .../send-amount-row.component.js | 60 +- .../send-amount-row.container.js | 22 +- .../tests/send-amount-row-component.test.js | 150 +- .../tests/send-amount-row-container.test.js | 82 +- .../send/send-content/send-asset-row/index.js | 2 +- .../send-asset-row.component.js | 58 +- .../send-asset-row.container.js | 17 +- .../send-content/send-content.component.js | 40 +- .../send-content/send-content.container.js | 22 +- .../gas-fee-display.component.js | 16 +- .../send-gas-row/gas-fee-display/index.js | 2 +- .../tests/gas-fee-display.component.test.js | 59 +- .../send/send-content/send-gas-row/index.js | 2 +- .../send-gas-row/send-gas-row.component.js | 62 +- .../send-gas-row/send-gas-row.container.js | 71 +- .../tests/send-gas-row-component.test.js | 106 +- .../tests/send-gas-row-container.test.js | 142 +- .../send-content/send-hex-data-row/index.js | 2 +- .../send-hex-data-row.component.js | 26 +- .../send-hex-data-row.container.js | 14 +- .../send-content/send-row-wrapper/index.js | 2 +- .../send-row-error-message/index.js | 2 +- .../send-row-error-message.component.js | 16 +- .../send-row-error-message.container.js | 10 +- .../send-row-error-message-component.test.js | 32 +- .../send-row-error-message-container.test.js | 20 +- .../send-row-wrapper.component.js | 30 +- .../tests/send-row-wrapper-component.test.js | 66 +- .../tests/send-content-component.test.js | 122 +- ui/app/pages/send/send-footer/index.js | 2 +- .../send/send-footer/send-footer.component.js | 56 +- .../send/send-footer/send-footer.container.js | 45 +- .../send/send-footer/send-footer.utils.js | 34 +- .../tests/send-footer-component.test.js | 170 +- .../tests/send-footer-container.test.js | 90 +- .../tests/send-footer-utils.test.js | 62 +- ui/app/pages/send/send-header/index.js | 2 +- .../send/send-header/send-header.component.js | 18 +- .../send/send-header/send-header.container.js | 16 +- .../tests/send-header-component.test.js | 78 +- ui/app/pages/send/send.component.js | 170 +- ui/app/pages/send/send.constants.js | 38 +- ui/app/pages/send/send.container.js | 38 +- ui/app/pages/send/send.utils.js | 130 +- .../pages/send/tests/send-component.test.js | 393 +-- .../pages/send/tests/send-container.test.js | 89 +- ui/app/pages/send/tests/send-utils.test.js | 276 +-- .../advanced-tab/advanced-tab.component.js | 156 +- .../advanced-tab/advanced-tab.container.js | 38 +- ui/app/pages/settings/advanced-tab/index.js | 2 +- .../tests/advanced-tab-component.test.js | 38 +- .../pages/settings/alerts-tab/alerts-tab.js | 38 +- ui/app/pages/settings/alerts-tab/index.js | 2 +- .../add-contact/add-contact.component.js | 66 +- .../add-contact/add-contact.container.js | 22 +- .../contact-list-tab/add-contact/index.js | 2 +- .../contact-list-tab.component.js | 70 +- .../contact-list-tab.container.js | 42 +- .../edit-contact/edit-contact.component.js | 52 +- .../edit-contact/edit-contact.container.js | 42 +- .../contact-list-tab/edit-contact/index.js | 2 +- .../pages/settings/contact-list-tab/index.js | 2 +- .../contact-list-tab/my-accounts/index.js | 2 +- .../my-accounts/my-accounts.component.js | 20 +- .../my-accounts/my-accounts.container.js | 18 +- .../contact-list-tab/view-contact/index.js | 2 +- .../view-contact/view-contact.component.js | 36 +- .../view-contact/view-contact.container.js | 36 +- ui/app/pages/settings/index.js | 2 +- ui/app/pages/settings/info-tab/index.js | 2 +- .../settings/info-tab/info-tab.component.js | 18 +- ui/app/pages/settings/networks-tab/index.js | 2 +- .../networks-tab/network-form/index.js | 2 +- .../network-form/network-form.component.js | 212 +- .../networks-tab/networks-tab.component.js | 88 +- .../networks-tab/networks-tab.constants.js | 6 +- .../networks-tab/networks-tab.container.js | 68 +- ui/app/pages/settings/security-tab/index.js | 2 +- .../security-tab/security-tab.component.js | 51 +- .../security-tab/security-tab.container.js | 24 +- .../security-tab/tests/security-tab.test.js | 54 +- ui/app/pages/settings/settings-tab/index.js | 2 +- .../settings-tab/settings-tab.component.js | 60 +- .../settings-tab/settings-tab.container.js | 26 +- .../settings-tab/tests/settings-tab.test.js | 52 +- ui/app/pages/settings/settings.component.js | 76 +- ui/app/pages/settings/settings.container.js | 76 +- .../actionable-message/actionable-message.js | 10 +- .../actionable-message.stories.js | 18 +- .../pages/swaps/actionable-message/index.js | 2 +- .../swaps/awaiting-swap/awaiting-swap.js | 172 +- ui/app/pages/swaps/awaiting-swap/index.js | 2 +- .../awaiting-swap/quotes-timeout-icon.js | 4 +- .../swaps/awaiting-swap/swap-failure-icon.js | 4 +- .../swaps/awaiting-swap/swap-success-icon.js | 4 +- .../view-on-ether-scan-link/index.js | 2 +- .../view-on-ether-scan-link.js | 14 +- ui/app/pages/swaps/build-quote/build-quote.js | 184 +- .../swaps/build-quote/build-quote.stories.js | 30 +- ui/app/pages/swaps/build-quote/index.js | 2 +- .../swaps/countdown-timer/countdown-timer.js | 80 +- .../countdown-timer.stories.js | 28 +- ui/app/pages/swaps/countdown-timer/index.js | 2 +- .../dropdown-input-pair.js | 50 +- .../dropdown-input-pair.stories.js | 16 +- .../pages/swaps/dropdown-input-pair/index.js | 2 +- .../dropdown-search-list.js | 72 +- .../dropdown-search-list.stories.js | 14 +- .../pages/swaps/dropdown-search-list/index.js | 2 +- .../exchange-rate-display.js | 50 +- .../exchange-rate-display.stories.js | 16 +- .../swaps/exchange-rate-display/index.js | 2 +- ui/app/pages/swaps/fee-card/fee-card.js | 20 +- .../pages/swaps/fee-card/fee-card.stories.js | 26 +- ui/app/pages/swaps/fee-card/index.js | 2 +- ui/app/pages/swaps/fee-card/pig-icon.js | 4 +- ui/app/pages/swaps/index.js | 236 +- ui/app/pages/swaps/intro-popup/index.js | 2 +- ui/app/pages/swaps/intro-popup/intro-popup.js | 62 +- .../loading-swaps-quotes/aggregator-logo.js | 16 +- .../background-animation.js | 4 +- .../pages/swaps/loading-swaps-quotes/index.js | 2 +- .../loading-swaps-quotes-stories-metadata.js | 2 +- .../loading-swaps-quotes.js | 117 +- .../pages/swaps/main-quote-summary/index.js | 2 +- .../main-quote-summary/main-quote-summary.js | 42 +- .../main-quote-summary.stories.js | 12 +- .../main-quote-summary/quote-backdrop.js | 8 +- .../pages/swaps/searchable-item-list/index.js | 2 +- .../searchable-item-list/item-list/index.js | 2 +- .../item-list/item-list.component.js | 22 +- .../list-item-search/index.js | 2 +- .../list-item-search.component.js | 44 +- .../searchable-item-list.js | 22 +- .../pages/swaps/select-quote-popover/index.js | 2 +- .../select-quote-popover/mock-quote-data.js | 4 +- .../quote-details/index.js | 2 +- .../quote-details/quote-details.js | 20 +- .../select-quote-popover-constants.js | 4 +- .../select-quote-popover.js | 64 +- .../select-quote-popover.stories.js | 20 +- .../select-quote-popover/sort-list/index.js | 2 +- .../sort-list/sort-list.js | 56 +- ui/app/pages/swaps/slippage-buttons/index.js | 2 +- .../slippage-buttons/slippage-buttons.js | 76 +- .../slippage-buttons.stories.js | 10 +- ui/app/pages/swaps/swaps-footer/index.js | 2 +- .../pages/swaps/swaps-footer/swaps-footer.js | 16 +- .../swaps-gas-customization-modal/index.js | 2 +- ...swaps-gas-customization-modal.component.js | 71 +- ...swaps-gas-customization-modal.container.js | 84 +- .../pages/swaps/swaps-util-test-constants.js | 21 +- ui/app/pages/swaps/swaps.util.js | 263 +- ui/app/pages/swaps/swaps.util.test.js | 88 +- ui/app/pages/swaps/view-quote/index.js | 2 +- .../tests/view-quote-price-difference.test.js | 84 +- .../view-quote/view-quote-price-difference.js | 46 +- ui/app/pages/swaps/view-quote/view-quote.js | 312 +-- ui/app/pages/unlock-page/index.js | 4 +- .../unlock-page/tests/unlock-page.test.js | 62 +- .../unlock-page/unlock-page.component.js | 84 +- .../unlock-page/unlock-page.container.js | 50 +- ui/app/selectors/confirm-transaction.js | 133 +- ui/app/selectors/custom-gas.js | 116 +- ui/app/selectors/first-time-flow.js | 26 +- ui/app/selectors/index.js | 14 +- ui/app/selectors/permissions.js | 146 +- ui/app/selectors/selectors.js | 216 +- ui/app/selectors/send.js | 98 +- .../tests/confirm-transaction.test.js | 52 +- ui/app/selectors/tests/custom-gas.test.js | 44 +- ui/app/selectors/tests/permissions.test.js | 40 +- ui/app/selectors/tests/selectors.test.js | 86 +- .../tests/send-selectors-test-data.js | 6 +- ui/app/selectors/tests/send.test.js | 276 +-- ui/app/selectors/tests/transactions.test.js | 104 +- ui/app/selectors/transactions.js | 158 +- ui/app/store/actionConstants.js | 160 +- ui/app/store/actions.js | 2150 +++++++++-------- ui/app/store/store.js | 12 +- ui/index.js | 160 +- ui/lib/account-link.js | 18 +- ui/lib/etherscan-prefix-for-network.js | 12 +- ui/lib/icon-factory.js | 64 +- ui/lib/is-mobile-view.js | 4 +- ui/lib/shallow-with-context.js | 4 +- ui/lib/storage-helpers.js | 16 +- ui/lib/test-timeout.js | 4 +- ui/lib/tx-helper.js | 48 +- ui/lib/webcam-utils.js | 32 +- yarn.lock | 8 +- 1169 files changed, 32914 insertions(+), 32568 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 445ee523c4..5bebbe0736 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -53,13 +53,6 @@ module.exports = { 'prettier/prettier': 'error', - // Our usage of spaces before *named* function parens is unusual, and - // doesn't match the prettier spec. prettier does not offer an option - // to configure this - 'space-before-function-paren': [ - 'error', - { anonymous: 'always', named: 'never' }, - ], // Our eslint config has the default setting for this as error. This // include beforeBlockComment: true, but in order to match the prettier // spec you have to enable before and after blocks, objects and arrays @@ -147,7 +140,10 @@ module.exports = { 'no-invalid-this': 'off', '@babel/no-invalid-this': 'error', - '@babel/semi': ['error', 'never'], + // prettier handles these + semi: 'off', + '@babel/semi': 'off', + 'mocha/no-setup-in-describe': 'off', 'node/no-process-env': 'off', @@ -213,4 +209,4 @@ module.exports = { version: 'detect', }, }, -} +}; diff --git a/.prettierrc.yml b/.prettierrc.yml index 0d65e758a4..3e9d085ced 100644 --- a/.prettierrc.yml +++ b/.prettierrc.yml @@ -1,3 +1,2 @@ singleQuote: true -semi: false trailingComma: all diff --git a/app/scripts/account-import-strategies/index.js b/app/scripts/account-import-strategies/index.js index 49444c7adb..89fd0b8c1f 100644 --- a/app/scripts/account-import-strategies/index.js +++ b/app/scripts/account-import-strategies/index.js @@ -1,53 +1,53 @@ -import log from 'loglevel' -import Wallet from 'ethereumjs-wallet' -import importers from 'ethereumjs-wallet/thirdparty' -import ethUtil from 'ethereumjs-util' -import { addHexPrefix } from '../lib/util' +import log from 'loglevel'; +import Wallet from 'ethereumjs-wallet'; +import importers from 'ethereumjs-wallet/thirdparty'; +import ethUtil from 'ethereumjs-util'; +import { addHexPrefix } from '../lib/util'; const accountImporter = { importAccount(strategy, args) { try { - const importer = this.strategies[strategy] - const privateKeyHex = importer(...args) - return Promise.resolve(privateKeyHex) + const importer = this.strategies[strategy]; + const privateKeyHex = importer(...args); + return Promise.resolve(privateKeyHex); } catch (e) { - return Promise.reject(e) + return Promise.reject(e); } }, strategies: { 'Private Key': (privateKey) => { if (!privateKey) { - throw new Error('Cannot import an empty key.') + throw new Error('Cannot import an empty key.'); } - const prefixed = addHexPrefix(privateKey) - const buffer = ethUtil.toBuffer(prefixed) + const prefixed = addHexPrefix(privateKey); + const buffer = ethUtil.toBuffer(prefixed); if (!ethUtil.isValidPrivate(buffer)) { - throw new Error('Cannot import invalid private key.') + throw new Error('Cannot import invalid private key.'); } - const stripped = ethUtil.stripHexPrefix(prefixed) - return stripped + const stripped = ethUtil.stripHexPrefix(prefixed); + return stripped; }, 'JSON File': (input, password) => { - let wallet + let wallet; try { - wallet = importers.fromEtherWallet(input, password) + wallet = importers.fromEtherWallet(input, password); } catch (e) { - log.debug('Attempt to import as EtherWallet format failed, trying V3') - wallet = Wallet.fromV3(input, password, true) + log.debug('Attempt to import as EtherWallet format failed, trying V3'); + wallet = Wallet.fromV3(input, password, true); } - return walletToPrivateKey(wallet) + return walletToPrivateKey(wallet); }, }, -} +}; function walletToPrivateKey(wallet) { - const privateKeyBuffer = wallet.getPrivateKey() - return ethUtil.bufferToHex(privateKeyBuffer) + const privateKeyBuffer = wallet.getPrivateKey(); + return ethUtil.bufferToHex(privateKeyBuffer); } -export default accountImporter +export default accountImporter; diff --git a/app/scripts/background.js b/app/scripts/background.js index c63c4ade0f..55a8f5a634 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -3,68 +3,68 @@ */ // these need to run before anything else /* eslint-disable import/first,import/order */ -import setupFetchDebugging from './lib/setupFetchDebugging' +import setupFetchDebugging from './lib/setupFetchDebugging'; /* eslint-enable import/order */ -setupFetchDebugging() +setupFetchDebugging(); // polyfills -import 'abortcontroller-polyfill/dist/polyfill-patch-fetch' +import 'abortcontroller-polyfill/dist/polyfill-patch-fetch'; -import endOfStream from 'end-of-stream' -import pump from 'pump' -import debounce from 'debounce-stream' -import log from 'loglevel' -import extension from 'extensionizer' -import { storeAsStream, storeTransformStream } from '@metamask/obs-store' -import PortStream from 'extension-port-stream' -import { captureException } from '@sentry/browser' +import endOfStream from 'end-of-stream'; +import pump from 'pump'; +import debounce from 'debounce-stream'; +import log from 'loglevel'; +import extension from 'extensionizer'; +import { storeAsStream, storeTransformStream } from '@metamask/obs-store'; +import PortStream from 'extension-port-stream'; +import { captureException } from '@sentry/browser'; import { ENVIRONMENT_TYPE_POPUP, ENVIRONMENT_TYPE_NOTIFICATION, ENVIRONMENT_TYPE_FULLSCREEN, -} from '../../shared/constants/app' -import migrations from './migrations' -import Migrator from './lib/migrator' -import ExtensionPlatform from './platforms/extension' -import LocalStore from './lib/local-store' -import ReadOnlyNetworkStore from './lib/network-store' -import createStreamSink from './lib/createStreamSink' -import NotificationManager from './lib/notification-manager' -import MetamaskController from './metamask-controller' -import rawFirstTimeState from './first-time-state' -import getFirstPreferredLangCode from './lib/get-first-preferred-lang-code' -import getObjStructure from './lib/getObjStructure' -import setupEnsIpfsResolver from './lib/ens-ipfs/setup' +} from '../../shared/constants/app'; +import migrations from './migrations'; +import Migrator from './lib/migrator'; +import ExtensionPlatform from './platforms/extension'; +import LocalStore from './lib/local-store'; +import ReadOnlyNetworkStore from './lib/network-store'; +import createStreamSink from './lib/createStreamSink'; +import NotificationManager from './lib/notification-manager'; +import MetamaskController from './metamask-controller'; +import rawFirstTimeState from './first-time-state'; +import getFirstPreferredLangCode from './lib/get-first-preferred-lang-code'; +import getObjStructure from './lib/getObjStructure'; +import setupEnsIpfsResolver from './lib/ens-ipfs/setup'; /* eslint-enable import/first */ -const { sentry } = global -const firstTimeState = { ...rawFirstTimeState } +const { sentry } = global; +const firstTimeState = { ...rawFirstTimeState }; -log.setDefaultLevel(process.env.METAMASK_DEBUG ? 'debug' : 'warn') +log.setDefaultLevel(process.env.METAMASK_DEBUG ? 'debug' : 'warn'); -const platform = new ExtensionPlatform() +const platform = new ExtensionPlatform(); -const notificationManager = new NotificationManager() -global.METAMASK_NOTIFIER = notificationManager +const notificationManager = new NotificationManager(); +global.METAMASK_NOTIFIER = notificationManager; -let popupIsOpen = false -let notificationIsOpen = false -const openMetamaskTabsIDs = {} -const requestAccountTabIds = {} +let popupIsOpen = false; +let notificationIsOpen = false; +const openMetamaskTabsIDs = {}; +const requestAccountTabIds = {}; // state persistence -const inTest = process.env.IN_TEST === 'true' -const localStore = inTest ? new ReadOnlyNetworkStore() : new LocalStore() -let versionedData +const inTest = process.env.IN_TEST === 'true'; +const localStore = inTest ? new ReadOnlyNetworkStore() : new LocalStore(); +let versionedData; if (inTest || process.env.METAMASK_DEBUG) { - global.metamaskGetState = localStore.get.bind(localStore) + global.metamaskGetState = localStore.get.bind(localStore); } // initialization flow -initialize().catch(log.error) +initialize().catch(log.error); /** * An object representing a transaction, in whatever state it is in. @@ -139,10 +139,10 @@ initialize().catch(log.error) * @returns {Promise} Setup complete. */ async function initialize() { - const initState = await loadStateFromPersistence() - const initLangCode = await getFirstPreferredLangCode() - await setupController(initState, initLangCode) - log.debug('MetaMask initialization complete.') + const initState = await loadStateFromPersistence(); + const initLangCode = await getFirstPreferredLangCode(); + await setupController(initState, initLangCode); + log.debug('MetaMask initialization complete.'); } // @@ -156,13 +156,13 @@ async function initialize() { */ async function loadStateFromPersistence() { // migrations - const migrator = new Migrator({ migrations }) - migrator.on('error', console.warn) + const migrator = new Migrator({ migrations }); + migrator.on('error', console.warn); // read from disk // first from preferred, async API: versionedData = - (await localStore.get()) || migrator.generateInitialState(firstTimeState) + (await localStore.get()) || migrator.generateInitialState(firstTimeState); // check if somehow state is empty // this should never happen but new error reporting suggests that it has @@ -170,38 +170,38 @@ async function loadStateFromPersistence() { // https://github.com/metamask/metamask-extension/issues/3919 if (versionedData && !versionedData.data) { // unable to recover, clear state - versionedData = migrator.generateInitialState(firstTimeState) - sentry.captureMessage('MetaMask - Empty vault found - unable to recover') + versionedData = migrator.generateInitialState(firstTimeState); + sentry.captureMessage('MetaMask - Empty vault found - unable to recover'); } // report migration errors to sentry migrator.on('error', (err) => { // get vault structure without secrets - const vaultStructure = getObjStructure(versionedData) + const vaultStructure = getObjStructure(versionedData); sentry.captureException(err, { // "extra" key is required by Sentry extra: { vaultStructure }, - }) - }) + }); + }); // migrate data - versionedData = await migrator.migrateData(versionedData) + versionedData = await migrator.migrateData(versionedData); if (!versionedData) { - throw new Error('MetaMask - migrator returned undefined') + throw new Error('MetaMask - migrator returned undefined'); } // write to disk if (localStore.isSupported) { - localStore.set(versionedData) + localStore.set(versionedData); } else { // throw in setTimeout so as to not block boot setTimeout(() => { - throw new Error('MetaMask - Localstore not supported') - }) + throw new Error('MetaMask - Localstore not supported'); + }); } // return just the data - return versionedData.data + return versionedData.data; } /** @@ -232,12 +232,12 @@ function setupController(initState, initLangCode) { platform, extension, getRequestAccountTabIds: () => { - return requestAccountTabIds + return requestAccountTabIds; }, getOpenMetamaskTabsIds: () => { - return openMetamaskTabsIDs + return openMetamaskTabsIDs; }, - }) + }); setupEnsIpfsResolver({ getCurrentNetwork: controller.getCurrentNetwork, @@ -245,7 +245,7 @@ function setupController(initState, initLangCode) { controller.preferencesController, ), provider: controller.provider, - }) + }); // setup state persistence pump( @@ -254,9 +254,9 @@ function setupController(initState, initLangCode) { storeTransformStream(versionifyData), createStreamSink(persistData), (error) => { - log.error('MetaMask - Persistence pipeline failed', error) + log.error('MetaMask - Persistence pipeline failed', error); }, - ) + ); /** * Assigns the given state to the versioned object (with metadata), and returns that. @@ -264,32 +264,32 @@ function setupController(initState, initLangCode) { * @returns {VersionedData} The state object wrapped in an object that includes a metadata key. */ function versionifyData(state) { - versionedData.data = state - return versionedData + versionedData.data = state; + return versionedData; } - let dataPersistenceFailing = false + let dataPersistenceFailing = false; async function persistData(state) { if (!state) { - throw new Error('MetaMask - updated state is missing') + throw new Error('MetaMask - updated state is missing'); } if (!state.data) { - throw new Error('MetaMask - updated state does not have data') + throw new Error('MetaMask - updated state does not have data'); } if (localStore.isSupported) { try { - await localStore.set(state) + await localStore.set(state); if (dataPersistenceFailing) { - dataPersistenceFailing = false + dataPersistenceFailing = false; } } catch (err) { // log error so we dont break the pipeline if (!dataPersistenceFailing) { - dataPersistenceFailing = true - captureException(err) + dataPersistenceFailing = true; + captureException(err); } - log.error('error setting state in local store:', err) + log.error('error setting state in local store:', err); } } } @@ -297,24 +297,24 @@ function setupController(initState, initLangCode) { // // connect to other contexts // - extension.runtime.onConnect.addListener(connectRemote) - extension.runtime.onConnectExternal.addListener(connectExternal) + extension.runtime.onConnect.addListener(connectRemote); + extension.runtime.onConnectExternal.addListener(connectExternal); const metamaskInternalProcessHash = { [ENVIRONMENT_TYPE_POPUP]: true, [ENVIRONMENT_TYPE_NOTIFICATION]: true, [ENVIRONMENT_TYPE_FULLSCREEN]: true, - } + }; - const metamaskBlockedPorts = ['trezor-connect'] + const metamaskBlockedPorts = ['trezor-connect']; const isClientOpenStatus = () => { return ( popupIsOpen || Boolean(Object.keys(openMetamaskTabsIDs).length) || notificationIsOpen - ) - } + ); + }; /** * A runtime.Port object, as provided by the browser: @@ -329,99 +329,99 @@ function setupController(initState, initLangCode) { * @param {Port} remotePort - The port provided by a new context. */ function connectRemote(remotePort) { - const processName = remotePort.name - const isMetaMaskInternalProcess = metamaskInternalProcessHash[processName] + const processName = remotePort.name; + const isMetaMaskInternalProcess = metamaskInternalProcessHash[processName]; if (metamaskBlockedPorts.includes(remotePort.name)) { - return + return; } if (isMetaMaskInternalProcess) { - const portStream = new PortStream(remotePort) + const portStream = new PortStream(remotePort); // communication with popup - controller.isClientOpen = true - controller.setupTrustedCommunication(portStream, remotePort.sender) + controller.isClientOpen = true; + controller.setupTrustedCommunication(portStream, remotePort.sender); if (processName === ENVIRONMENT_TYPE_POPUP) { - popupIsOpen = true + popupIsOpen = true; endOfStream(portStream, () => { - popupIsOpen = false - controller.isClientOpen = isClientOpenStatus() - }) + popupIsOpen = false; + controller.isClientOpen = isClientOpenStatus(); + }); } if (processName === ENVIRONMENT_TYPE_NOTIFICATION) { - notificationIsOpen = true + notificationIsOpen = true; endOfStream(portStream, () => { - notificationIsOpen = false - controller.isClientOpen = isClientOpenStatus() - }) + notificationIsOpen = false; + controller.isClientOpen = isClientOpenStatus(); + }); } if (processName === ENVIRONMENT_TYPE_FULLSCREEN) { - const tabId = remotePort.sender.tab.id - openMetamaskTabsIDs[tabId] = true + const tabId = remotePort.sender.tab.id; + openMetamaskTabsIDs[tabId] = true; endOfStream(portStream, () => { - delete openMetamaskTabsIDs[tabId] - controller.isClientOpen = isClientOpenStatus() - }) + delete openMetamaskTabsIDs[tabId]; + controller.isClientOpen = isClientOpenStatus(); + }); } } else { if (remotePort.sender && remotePort.sender.tab && remotePort.sender.url) { - const tabId = remotePort.sender.tab.id - const url = new URL(remotePort.sender.url) - const { origin } = url + const tabId = remotePort.sender.tab.id; + const url = new URL(remotePort.sender.url); + const { origin } = url; remotePort.onMessage.addListener((msg) => { if (msg.data && msg.data.method === 'eth_requestAccounts') { - requestAccountTabIds[origin] = tabId + requestAccountTabIds[origin] = tabId; } - }) + }); } - connectExternal(remotePort) + connectExternal(remotePort); } } // communication with page or other extension function connectExternal(remotePort) { - const portStream = new PortStream(remotePort) - controller.setupUntrustedCommunication(portStream, remotePort.sender) + const portStream = new PortStream(remotePort); + controller.setupUntrustedCommunication(portStream, remotePort.sender); } // // User Interface setup // - updateBadge() - controller.txController.on('update:badge', updateBadge) - controller.messageManager.on('updateBadge', updateBadge) - controller.personalMessageManager.on('updateBadge', updateBadge) - controller.decryptMessageManager.on('updateBadge', updateBadge) - controller.encryptionPublicKeyManager.on('updateBadge', updateBadge) - controller.typedMessageManager.on('updateBadge', updateBadge) - controller.approvalController.subscribe(updateBadge) - controller.appStateController.on('updateBadge', updateBadge) + updateBadge(); + controller.txController.on('update:badge', updateBadge); + controller.messageManager.on('updateBadge', updateBadge); + controller.personalMessageManager.on('updateBadge', updateBadge); + controller.decryptMessageManager.on('updateBadge', updateBadge); + controller.encryptionPublicKeyManager.on('updateBadge', updateBadge); + controller.typedMessageManager.on('updateBadge', updateBadge); + controller.approvalController.subscribe(updateBadge); + controller.appStateController.on('updateBadge', updateBadge); /** * Updates the Web Extension's "badge" number, on the little fox in the toolbar. * The number reflects the current number of pending transactions or message signatures needing user approval. */ function updateBadge() { - let label = '' - const unapprovedTxCount = controller.txController.getUnapprovedTxCount() - const { unapprovedMsgCount } = controller.messageManager - const { unapprovedPersonalMsgCount } = controller.personalMessageManager - const { unapprovedDecryptMsgCount } = controller.decryptMessageManager + let label = ''; + const unapprovedTxCount = controller.txController.getUnapprovedTxCount(); + const { unapprovedMsgCount } = controller.messageManager; + const { unapprovedPersonalMsgCount } = controller.personalMessageManager; + const { unapprovedDecryptMsgCount } = controller.decryptMessageManager; const { unapprovedEncryptionPublicKeyMsgCount, - } = controller.encryptionPublicKeyManager - const { unapprovedTypedMessagesCount } = controller.typedMessageManager - const pendingApprovalCount = controller.approvalController.getTotalApprovalCount() + } = controller.encryptionPublicKeyManager; + const { unapprovedTypedMessagesCount } = controller.typedMessageManager; + const pendingApprovalCount = controller.approvalController.getTotalApprovalCount(); const waitingForUnlockCount = - controller.appStateController.waitingForUnlock.length + controller.appStateController.waitingForUnlock.length; const count = unapprovedTxCount + unapprovedMsgCount + @@ -430,15 +430,15 @@ function setupController(initState, initLangCode) { unapprovedEncryptionPublicKeyMsgCount + unapprovedTypedMessagesCount + pendingApprovalCount + - waitingForUnlockCount + waitingForUnlockCount; if (count) { - label = String(count) + label = String(count); } - extension.browserAction.setBadgeText({ text: label }) - extension.browserAction.setBadgeBackgroundColor({ color: '#037DD6' }) + extension.browserAction.setBadgeText({ text: label }); + extension.browserAction.setBadgeBackgroundColor({ color: '#037DD6' }); } - return Promise.resolve() + return Promise.resolve(); } // @@ -449,18 +449,18 @@ function setupController(initState, initLangCode) { * Opens the browser popup for user confirmation */ async function triggerUi() { - const tabs = await platform.getActiveTabs() + const tabs = await platform.getActiveTabs(); const currentlyActiveMetamaskTab = Boolean( tabs.find((tab) => openMetamaskTabsIDs[tab.id]), - ) + ); // Vivaldi is not closing port connection on popup close, so popupIsOpen does not work correctly // To be reviewed in the future if this behaviour is fixed - also the way we determine isVivaldi variable might change at some point const isVivaldi = tabs.length > 0 && tabs[0].extData && - tabs[0].extData.indexOf('vivaldi_tab') > -1 + tabs[0].extData.indexOf('vivaldi_tab') > -1; if ((isVivaldi || !popupIsOpen) && !currentlyActiveMetamaskTab) { - await notificationManager.showPopup() + await notificationManager.showPopup(); } } @@ -469,15 +469,15 @@ async function triggerUi() { * then it waits until user interact with the UI */ async function openPopup() { - await triggerUi() + await triggerUi(); await new Promise((resolve) => { const interval = setInterval(() => { if (!notificationIsOpen) { - clearInterval(interval) - resolve() + clearInterval(interval); + resolve(); } - }, 1000) - }) + }, 1000); + }); } // On first install, open a new tab with MetaMask @@ -486,6 +486,6 @@ extension.runtime.onInstalled.addListener(({ reason }) => { reason === 'install' && !(process.env.METAMASK_DEBUG || process.env.IN_TEST) ) { - platform.openExtensionInBrowser() + platform.openExtensionInBrowser(); } -}) +}); diff --git a/app/scripts/constants/contracts.js b/app/scripts/constants/contracts.js index c2a8c9737e..90df403c2b 100644 --- a/app/scripts/constants/contracts.js +++ b/app/scripts/constants/contracts.js @@ -1,8 +1,8 @@ export const SINGLE_CALL_BALANCES_ADDRESS = - '0xb1f8e55c7f64d203c1400b9d8555d050f94adf39' + '0xb1f8e55c7f64d203c1400b9d8555d050f94adf39'; export const SINGLE_CALL_BALANCES_ADDRESS_RINKEBY = - '0x9f510b19f1ad66f0dcf6e45559fab0d6752c1db7' + '0x9f510b19f1ad66f0dcf6e45559fab0d6752c1db7'; export const SINGLE_CALL_BALANCES_ADDRESS_ROPSTEN = - '0xb8e671734ce5c8d7dfbbea5574fa4cf39f7a54a4' + '0xb8e671734ce5c8d7dfbbea5574fa4cf39f7a54a4'; export const SINGLE_CALL_BALANCES_ADDRESS_KOVAN = - '0xb1d3fbb2f83aecd196f474c16ca5d9cffa0d0ffc' + '0xb1d3fbb2f83aecd196f474c16ca5d9cffa0d0ffc'; diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js index 116cad02df..a404a9cd8c 100644 --- a/app/scripts/contentscript.js +++ b/app/scripts/contentscript.js @@ -1,35 +1,35 @@ -import querystring from 'querystring' -import pump from 'pump' -import LocalMessageDuplexStream from 'post-message-stream' -import ObjectMultiplex from 'obj-multiplex' -import extension from 'extensionizer' -import PortStream from 'extension-port-stream' -import { obj as createThoughStream } from 'through2' +import querystring from 'querystring'; +import pump from 'pump'; +import LocalMessageDuplexStream from 'post-message-stream'; +import ObjectMultiplex from 'obj-multiplex'; +import extension from 'extensionizer'; +import PortStream from 'extension-port-stream'; +import { obj as createThoughStream } from 'through2'; // These require calls need to use require to be statically recognized by browserify -const fs = require('fs') -const path = require('path') +const fs = require('fs'); +const path = require('path'); const inpageContent = fs.readFileSync( path.join(__dirname, '..', '..', 'dist', 'chrome', 'inpage.js'), 'utf8', -) -const inpageSuffix = `//# sourceURL=${extension.runtime.getURL('inpage.js')}\n` -const inpageBundle = inpageContent + inpageSuffix +); +const inpageSuffix = `//# sourceURL=${extension.runtime.getURL('inpage.js')}\n`; +const inpageBundle = inpageContent + inpageSuffix; -const CONTENT_SCRIPT = 'metamask-contentscript' -const INPAGE = 'metamask-inpage' -const PROVIDER = 'metamask-provider' +const CONTENT_SCRIPT = 'metamask-contentscript'; +const INPAGE = 'metamask-inpage'; +const PROVIDER = 'metamask-provider'; // TODO:LegacyProvider: Delete -const LEGACY_CONTENT_SCRIPT = 'contentscript' -const LEGACY_INPAGE = 'inpage' -const LEGACY_PROVIDER = 'provider' -const LEGACY_PUBLIC_CONFIG = 'publicConfig' +const LEGACY_CONTENT_SCRIPT = 'contentscript'; +const LEGACY_INPAGE = 'inpage'; +const LEGACY_PROVIDER = 'provider'; +const LEGACY_PUBLIC_CONFIG = 'publicConfig'; if (shouldInjectProvider()) { - injectScript(inpageBundle) - setupStreams() + injectScript(inpageBundle); + setupStreams(); } /** @@ -39,14 +39,14 @@ if (shouldInjectProvider()) { */ function injectScript(content) { try { - const container = document.head || document.documentElement - const scriptTag = document.createElement('script') - scriptTag.setAttribute('async', 'false') - scriptTag.textContent = content - container.insertBefore(scriptTag, container.children[0]) - container.removeChild(scriptTag) + const container = document.head || document.documentElement; + const scriptTag = document.createElement('script'); + scriptTag.setAttribute('async', 'false'); + scriptTag.textContent = content; + container.insertBefore(scriptTag, container.children[0]); + container.removeChild(scriptTag); } catch (error) { - console.error('MetaMask: Provider injection failed.', error) + console.error('MetaMask: Provider injection failed.', error); } } @@ -60,81 +60,81 @@ async function setupStreams() { const pageStream = new LocalMessageDuplexStream({ name: CONTENT_SCRIPT, target: INPAGE, - }) - const extensionPort = extension.runtime.connect({ name: CONTENT_SCRIPT }) - const extensionStream = new PortStream(extensionPort) + }); + const extensionPort = extension.runtime.connect({ name: CONTENT_SCRIPT }); + const extensionStream = new PortStream(extensionPort); // create and connect channel muxers // so we can handle the channels individually - const pageMux = new ObjectMultiplex() - pageMux.setMaxListeners(25) - const extensionMux = new ObjectMultiplex() - extensionMux.setMaxListeners(25) - extensionMux.ignoreStream(LEGACY_PUBLIC_CONFIG) // TODO:LegacyProvider: Delete + const pageMux = new ObjectMultiplex(); + pageMux.setMaxListeners(25); + const extensionMux = new ObjectMultiplex(); + extensionMux.setMaxListeners(25); + extensionMux.ignoreStream(LEGACY_PUBLIC_CONFIG); // TODO:LegacyProvider: Delete pump(pageMux, pageStream, pageMux, (err) => logStreamDisconnectWarning('MetaMask Inpage Multiplex', err), - ) + ); pump(extensionMux, extensionStream, extensionMux, (err) => { - logStreamDisconnectWarning('MetaMask Background Multiplex', err) - notifyInpageOfStreamFailure() - }) + logStreamDisconnectWarning('MetaMask Background Multiplex', err); + notifyInpageOfStreamFailure(); + }); // forward communication across inpage-background for these channels only - forwardTrafficBetweenMuxes(PROVIDER, pageMux, extensionMux) + forwardTrafficBetweenMuxes(PROVIDER, pageMux, extensionMux); // connect "phishing" channel to warning system - const phishingStream = extensionMux.createStream('phishing') - phishingStream.once('data', redirectToPhishingWarning) + const phishingStream = extensionMux.createStream('phishing'); + phishingStream.once('data', redirectToPhishingWarning); // TODO:LegacyProvider: Delete // handle legacy provider const legacyPageStream = new LocalMessageDuplexStream({ name: LEGACY_CONTENT_SCRIPT, target: LEGACY_INPAGE, - }) + }); - const legacyPageMux = new ObjectMultiplex() - legacyPageMux.setMaxListeners(25) - const legacyExtensionMux = new ObjectMultiplex() - legacyExtensionMux.setMaxListeners(25) + const legacyPageMux = new ObjectMultiplex(); + legacyPageMux.setMaxListeners(25); + const legacyExtensionMux = new ObjectMultiplex(); + legacyExtensionMux.setMaxListeners(25); pump(legacyPageMux, legacyPageStream, legacyPageMux, (err) => logStreamDisconnectWarning('MetaMask Legacy Inpage Multiplex', err), - ) + ); pump( legacyExtensionMux, extensionStream, getNotificationTransformStream(), legacyExtensionMux, (err) => { - logStreamDisconnectWarning('MetaMask Background Legacy Multiplex', err) - notifyInpageOfStreamFailure() + logStreamDisconnectWarning('MetaMask Background Legacy Multiplex', err); + notifyInpageOfStreamFailure(); }, - ) + ); forwardNamedTrafficBetweenMuxes( LEGACY_PROVIDER, PROVIDER, legacyPageMux, legacyExtensionMux, - ) + ); forwardTrafficBetweenMuxes( LEGACY_PUBLIC_CONFIG, legacyPageMux, legacyExtensionMux, - ) + ); } function forwardTrafficBetweenMuxes(channelName, muxA, muxB) { - const channelA = muxA.createStream(channelName) - const channelB = muxB.createStream(channelName) + const channelA = muxA.createStream(channelName); + const channelB = muxB.createStream(channelName); pump(channelA, channelB, channelA, (error) => console.debug( `MetaMask: Muxed traffic for channel "${channelName}" failed.`, error, ), - ) + ); } // TODO:LegacyProvider: Delete @@ -144,14 +144,14 @@ function forwardNamedTrafficBetweenMuxes( muxA, muxB, ) { - const channelA = muxA.createStream(channelAName) - const channelB = muxB.createStream(channelBName) + const channelA = muxA.createStream(channelAName); + const channelB = muxB.createStream(channelBName); pump(channelA, channelB, channelA, (error) => console.debug( `MetaMask: Muxed traffic between channels "${channelAName}" and "${channelBName}" failed.`, error, ), - ) + ); } // TODO:LegacyProvider: Delete @@ -159,13 +159,13 @@ function getNotificationTransformStream() { return createThoughStream((chunk, _, cb) => { if (chunk?.name === PROVIDER) { if (chunk.data?.method === 'metamask_accountsChanged') { - chunk.data.method = 'wallet_accountsChanged' - chunk.data.result = chunk.data.params - delete chunk.data.params + chunk.data.method = 'wallet_accountsChanged'; + chunk.data.result = chunk.data.params; + delete chunk.data.params; } } - cb(null, chunk) - }) + cb(null, chunk); + }); } /** @@ -178,7 +178,7 @@ function logStreamDisconnectWarning(remoteLabel, error) { console.debug( `MetaMask: Content script lost connection to "${remoteLabel}".`, error, - ) + ); } /** @@ -200,7 +200,7 @@ function notifyInpageOfStreamFailure() { }, }, window.location.origin, - ) + ); } /** @@ -214,7 +214,7 @@ function shouldInjectProvider() { suffixCheck() && documentElementCheck() && !blockedDomainCheck() - ) + ); } /** @@ -223,11 +223,11 @@ function shouldInjectProvider() { * @returns {boolean} {@code true} if the doctype is html or if none exists */ function doctypeCheck() { - const { doctype } = window.document + const { doctype } = window.document; if (doctype) { - return doctype.name === 'html' + return doctype.name === 'html'; } - return true + return true; } /** @@ -240,14 +240,14 @@ function doctypeCheck() { * @returns {boolean} whether or not the extension of the current document is prohibited */ function suffixCheck() { - const prohibitedTypes = [/\.xml$/u, /\.pdf$/u] - const currentUrl = window.location.pathname + const prohibitedTypes = [/\.xml$/u, /\.pdf$/u]; + const currentUrl = window.location.pathname; for (let i = 0; i < prohibitedTypes.length; i++) { if (prohibitedTypes[i].test(currentUrl)) { - return false + return false; } } - return true + return true; } /** @@ -256,11 +256,11 @@ function suffixCheck() { * @returns {boolean} {@code true} if the documentElement is an html node or if none exists */ function documentElementCheck() { - const documentElement = document.documentElement.nodeName + const documentElement = document.documentElement.nodeName; if (documentElement) { - return documentElement.toLowerCase() === 'html' + return documentElement.toLowerCase() === 'html'; } - return true + return true; } /** @@ -280,30 +280,30 @@ function blockedDomainCheck() { 'ani.gamer.com.tw', 'blueskybooking.com', 'sharefile.com', - ] - const currentUrl = window.location.href - let currentRegex + ]; + const currentUrl = window.location.href; + let currentRegex; for (let i = 0; i < blockedDomains.length; i++) { - const blockedDomain = blockedDomains[i].replace('.', '\\.') + const blockedDomain = blockedDomains[i].replace('.', '\\.'); currentRegex = new RegExp( `(?:https?:\\/\\/)(?:(?!${blockedDomain}).)*$`, 'u', - ) + ); if (!currentRegex.test(currentUrl)) { - return true + return true; } } - return false + return false; } /** * Redirects the current page to a phishing information page */ function redirectToPhishingWarning() { - console.debug('MetaMask: Routing to Phishing Warning component.') - const extensionURL = extension.runtime.getURL('phishing.html') + console.debug('MetaMask: Routing to Phishing Warning component.'); + const extensionURL = extension.runtime.getURL('phishing.html'); window.location.href = `${extensionURL}#${querystring.stringify({ hostname: window.location.hostname, href: window.location.href, - })}` + })}`; } diff --git a/app/scripts/controllers/alert.js b/app/scripts/controllers/alert.js index a58276d888..c7c78c04af 100644 --- a/app/scripts/controllers/alert.js +++ b/app/scripts/controllers/alert.js @@ -1,8 +1,8 @@ -import { ObservableStore } from '@metamask/obs-store' +import { ObservableStore } from '@metamask/obs-store'; import { TOGGLEABLE_ALERT_TYPES, WEB3_SHIM_USAGE_ALERT_STATES, -} from '../../../shared/constants/alerts' +} from '../../../shared/constants/alerts'; /** * @typedef {Object} AlertControllerInitState @@ -21,14 +21,14 @@ import { const defaultState = { alertEnabledness: TOGGLEABLE_ALERT_TYPES.reduce( (alertEnabledness, alertType) => { - alertEnabledness[alertType] = true - return alertEnabledness + alertEnabledness[alertType] = true; + return alertEnabledness; }, {}, ), unconnectedAccountAlertShownOrigins: {}, web3ShimUsageOrigins: {}, -} +}; /** * Controller responsible for maintaining alert-related state. @@ -39,36 +39,36 @@ export default class AlertController { * @param {AlertControllerOptions} [opts] - Controller configuration parameters */ constructor(opts = {}) { - const { initState = {}, preferencesStore } = opts + const { initState = {}, preferencesStore } = opts; const state = { ...defaultState, alertEnabledness: { ...defaultState.alertEnabledness, ...initState.alertEnabledness, }, - } + }; - this.store = new ObservableStore(state) + this.store = new ObservableStore(state); - this.selectedAddress = preferencesStore.getState().selectedAddress + this.selectedAddress = preferencesStore.getState().selectedAddress; preferencesStore.subscribe(({ selectedAddress }) => { - const currentState = this.store.getState() + const currentState = this.store.getState(); if ( currentState.unconnectedAccountAlertShownOrigins && this.selectedAddress !== selectedAddress ) { - this.selectedAddress = selectedAddress - this.store.updateState({ unconnectedAccountAlertShownOrigins: {} }) + this.selectedAddress = selectedAddress; + this.store.updateState({ unconnectedAccountAlertShownOrigins: {} }); } - }) + }); } setAlertEnabledness(alertId, enabledness) { - let { alertEnabledness } = this.store.getState() - alertEnabledness = { ...alertEnabledness } - alertEnabledness[alertId] = enabledness - this.store.updateState({ alertEnabledness }) + let { alertEnabledness } = this.store.getState(); + alertEnabledness = { ...alertEnabledness }; + alertEnabledness[alertId] = enabledness; + this.store.updateState({ alertEnabledness }); } /** @@ -76,12 +76,12 @@ export default class AlertController { * @param {string} origin - The origin the alert has been shown for */ setUnconnectedAccountAlertShown(origin) { - let { unconnectedAccountAlertShownOrigins } = this.store.getState() + let { unconnectedAccountAlertShownOrigins } = this.store.getState(); unconnectedAccountAlertShownOrigins = { ...unconnectedAccountAlertShownOrigins, - } - unconnectedAccountAlertShownOrigins[origin] = true - this.store.updateState({ unconnectedAccountAlertShownOrigins }) + }; + unconnectedAccountAlertShownOrigins[origin] = true; + this.store.updateState({ unconnectedAccountAlertShownOrigins }); } /** @@ -92,7 +92,7 @@ export default class AlertController { * origin, or undefined. */ getWeb3ShimUsageState(origin) { - return this.store.getState().web3ShimUsageOrigins[origin] + return this.store.getState().web3ShimUsageOrigins[origin]; } /** @@ -101,7 +101,7 @@ export default class AlertController { * @param {string} origin - The origin the that used the web3 shim. */ setWeb3ShimUsageRecorded(origin) { - this._setWeb3ShimUsageState(origin, WEB3_SHIM_USAGE_ALERT_STATES.RECORDED) + this._setWeb3ShimUsageState(origin, WEB3_SHIM_USAGE_ALERT_STATES.RECORDED); } /** @@ -111,7 +111,7 @@ export default class AlertController { * dismissed for. */ setWeb3ShimUsageAlertDismissed(origin) { - this._setWeb3ShimUsageState(origin, WEB3_SHIM_USAGE_ALERT_STATES.DISMISSED) + this._setWeb3ShimUsageState(origin, WEB3_SHIM_USAGE_ALERT_STATES.DISMISSED); } /** @@ -120,11 +120,11 @@ export default class AlertController { * @param {number} value - The state value to set. */ _setWeb3ShimUsageState(origin, value) { - let { web3ShimUsageOrigins } = this.store.getState() + let { web3ShimUsageOrigins } = this.store.getState(); web3ShimUsageOrigins = { ...web3ShimUsageOrigins, - } - web3ShimUsageOrigins[origin] = value - this.store.updateState({ web3ShimUsageOrigins }) + }; + web3ShimUsageOrigins[origin] = value; + this.store.updateState({ web3ShimUsageOrigins }); } } diff --git a/app/scripts/controllers/app-state.js b/app/scripts/controllers/app-state.js index 207ce96e48..0bf7918213 100644 --- a/app/scripts/controllers/app-state.js +++ b/app/scripts/controllers/app-state.js @@ -1,5 +1,5 @@ -import EventEmitter from 'events' -import { ObservableStore } from '@metamask/obs-store' +import EventEmitter from 'events'; +import { ObservableStore } from '@metamask/obs-store'; export default class AppStateController extends EventEmitter { /** @@ -14,34 +14,34 @@ export default class AppStateController extends EventEmitter { onInactiveTimeout, showUnlockRequest, preferencesStore, - } = opts - super() + } = opts; + super(); - this.onInactiveTimeout = onInactiveTimeout || (() => undefined) + this.onInactiveTimeout = onInactiveTimeout || (() => undefined); this.store = new ObservableStore({ timeoutMinutes: 0, connectedStatusPopoverHasBeenShown: true, swapsWelcomeMessageHasBeenShown: false, defaultHomeActiveTabName: null, ...initState, - }) - this.timer = null + }); + this.timer = null; - this.isUnlocked = isUnlocked - this.waitingForUnlock = [] - addUnlockListener(this.handleUnlock.bind(this)) + this.isUnlocked = isUnlocked; + this.waitingForUnlock = []; + addUnlockListener(this.handleUnlock.bind(this)); - this._showUnlockRequest = showUnlockRequest + this._showUnlockRequest = showUnlockRequest; preferencesStore.subscribe(({ preferences }) => { - const currentState = this.store.getState() + const currentState = this.store.getState(); if (currentState.timeoutMinutes !== preferences.autoLockTimeLimit) { - this._setInactiveTimeout(preferences.autoLockTimeLimit) + this._setInactiveTimeout(preferences.autoLockTimeLimit); } - }) + }); - const { preferences } = preferencesStore.getState() - this._setInactiveTimeout(preferences.autoLockTimeLimit) + const { preferences } = preferencesStore.getState(); + this._setInactiveTimeout(preferences.autoLockTimeLimit); } /** @@ -56,11 +56,11 @@ export default class AppStateController extends EventEmitter { getUnlockPromise(shouldShowUnlockRequest) { return new Promise((resolve) => { if (this.isUnlocked()) { - resolve() + resolve(); } else { - this.waitForUnlock(resolve, shouldShowUnlockRequest) + this.waitForUnlock(resolve, shouldShowUnlockRequest); } - }) + }); } /** @@ -73,10 +73,10 @@ export default class AppStateController extends EventEmitter { * popup should be opened. */ waitForUnlock(resolve, shouldShowUnlockRequest) { - this.waitingForUnlock.push({ resolve }) - this.emit('updateBadge') + this.waitingForUnlock.push({ resolve }); + this.emit('updateBadge'); if (shouldShowUnlockRequest) { - this._showUnlockRequest() + this._showUnlockRequest(); } } @@ -86,9 +86,9 @@ export default class AppStateController extends EventEmitter { handleUnlock() { if (this.waitingForUnlock.length > 0) { while (this.waitingForUnlock.length > 0) { - this.waitingForUnlock.shift().resolve() + this.waitingForUnlock.shift().resolve(); } - this.emit('updateBadge') + this.emit('updateBadge'); } } @@ -99,7 +99,7 @@ export default class AppStateController extends EventEmitter { setDefaultHomeActiveTabName(defaultHomeActiveTabName) { this.store.updateState({ defaultHomeActiveTabName, - }) + }); } /** @@ -108,7 +108,7 @@ export default class AppStateController extends EventEmitter { setConnectedStatusPopoverHasBeenShown() { this.store.updateState({ connectedStatusPopoverHasBeenShown: true, - }) + }); } /** @@ -117,7 +117,7 @@ export default class AppStateController extends EventEmitter { setSwapsWelcomeMessageHasBeenShown() { this.store.updateState({ swapsWelcomeMessageHasBeenShown: true, - }) + }); } /** @@ -125,7 +125,7 @@ export default class AppStateController extends EventEmitter { * @returns {void} */ setLastActiveTime() { - this._resetTimer() + this._resetTimer(); } /** @@ -137,9 +137,9 @@ export default class AppStateController extends EventEmitter { _setInactiveTimeout(timeoutMinutes) { this.store.updateState({ timeoutMinutes, - }) + }); - this._resetTimer() + this._resetTimer(); } /** @@ -152,19 +152,19 @@ export default class AppStateController extends EventEmitter { * @private */ _resetTimer() { - const { timeoutMinutes } = this.store.getState() + const { timeoutMinutes } = this.store.getState(); if (this.timer) { - clearTimeout(this.timer) + clearTimeout(this.timer); } if (!timeoutMinutes) { - return + return; } this.timer = setTimeout( () => this.onInactiveTimeout(), timeoutMinutes * 60 * 1000, - ) + ); } } diff --git a/app/scripts/controllers/cached-balances.js b/app/scripts/controllers/cached-balances.js index 16ef40e88d..d4762f84f5 100644 --- a/app/scripts/controllers/cached-balances.js +++ b/app/scripts/controllers/cached-balances.js @@ -1,4 +1,4 @@ -import { ObservableStore } from '@metamask/obs-store' +import { ObservableStore } from '@metamask/obs-store'; /** * @typedef {Object} CachedBalancesOptions @@ -18,15 +18,15 @@ export default class CachedBalancesController { * @param {CachedBalancesOptions} [opts] - Controller configuration parameters */ constructor(opts = {}) { - const { accountTracker, getNetwork } = opts + const { accountTracker, getNetwork } = opts; - this.accountTracker = accountTracker - this.getNetwork = getNetwork + this.accountTracker = accountTracker; + this.getNetwork = getNetwork; - const initState = { cachedBalances: {}, ...opts.initState } - this.store = new ObservableStore(initState) + const initState = { cachedBalances: {}, ...opts.initState }; + this.store = new ObservableStore(initState); - this._registerUpdates() + this._registerUpdates(); } /** @@ -37,33 +37,33 @@ export default class CachedBalancesController { * @returns {Promise} */ async updateCachedBalances({ accounts }) { - const network = await this.getNetwork() + const network = await this.getNetwork(); const balancesToCache = await this._generateBalancesToCache( accounts, network, - ) + ); this.store.updateState({ cachedBalances: balancesToCache, - }) + }); } _generateBalancesToCache(newAccounts, currentNetwork) { - const { cachedBalances } = this.store.getState() - const currentNetworkBalancesToCache = { ...cachedBalances[currentNetwork] } + const { cachedBalances } = this.store.getState(); + const currentNetworkBalancesToCache = { ...cachedBalances[currentNetwork] }; Object.keys(newAccounts).forEach((accountID) => { - const account = newAccounts[accountID] + const account = newAccounts[accountID]; if (account.balance) { - currentNetworkBalancesToCache[accountID] = account.balance + currentNetworkBalancesToCache[accountID] = account.balance; } - }) + }); const balancesToCache = { ...cachedBalances, [currentNetwork]: currentNetworkBalancesToCache, - } + }; - return balancesToCache + return balancesToCache; } /** @@ -71,7 +71,7 @@ export default class CachedBalancesController { */ clearCachedBalances() { - this.store.updateState({ cachedBalances: {} }) + this.store.updateState({ cachedBalances: {} }); } /** @@ -83,7 +83,7 @@ export default class CachedBalancesController { * */ _registerUpdates() { - const update = this.updateCachedBalances.bind(this) - this.accountTracker.store.subscribe(update) + const update = this.updateCachedBalances.bind(this); + this.accountTracker.store.subscribe(update); } } diff --git a/app/scripts/controllers/detect-tokens.js b/app/scripts/controllers/detect-tokens.js index d91fdb989c..3115f94d3c 100644 --- a/app/scripts/controllers/detect-tokens.js +++ b/app/scripts/controllers/detect-tokens.js @@ -1,12 +1,12 @@ -import Web3 from 'web3' -import contracts from '@metamask/contract-metadata' -import { warn } from 'loglevel' -import SINGLE_CALL_BALANCES_ABI from 'single-call-balance-checker-abi' -import { MAINNET_CHAIN_ID } from '../../../shared/constants/network' -import { SINGLE_CALL_BALANCES_ADDRESS } from '../constants/contracts' +import Web3 from 'web3'; +import contracts from '@metamask/contract-metadata'; +import { warn } from 'loglevel'; +import SINGLE_CALL_BALANCES_ABI from 'single-call-balance-checker-abi'; +import { MAINNET_CHAIN_ID } from '../../../shared/constants/network'; +import { SINGLE_CALL_BALANCES_ADDRESS } from '../constants/contracts'; // By default, poll every 3 minutes -const DEFAULT_INTERVAL = 180 * 1000 +const DEFAULT_INTERVAL = 180 * 1000; /** * A controller that polls for token exchange @@ -24,10 +24,10 @@ export default class DetectTokensController { network, keyringMemStore, } = {}) { - this.preferences = preferences - this.interval = interval - this.network = network - this.keyringMemStore = keyringMemStore + this.preferences = preferences; + this.interval = interval; + this.network = network; + this.keyringMemStore = keyringMemStore; } /** @@ -35,59 +35,59 @@ export default class DetectTokensController { */ async detectNewTokens() { if (!this.isActive) { - return + return; } if (this._network.store.getState().provider.chainId !== MAINNET_CHAIN_ID) { - return + return; } - const tokensToDetect = [] - this.web3.setProvider(this._network._provider) + const tokensToDetect = []; + this.web3.setProvider(this._network._provider); for (const contractAddress in contracts) { if ( contracts[contractAddress].erc20 && !this.tokenAddresses.includes(contractAddress.toLowerCase()) && !this.hiddenTokens.includes(contractAddress.toLowerCase()) ) { - tokensToDetect.push(contractAddress) + tokensToDetect.push(contractAddress); } } - let result + let result; try { - result = await this._getTokenBalances(tokensToDetect) + result = await this._getTokenBalances(tokensToDetect); } catch (error) { warn( `MetaMask - DetectTokensController single call balance fetch failed`, error, - ) - return + ); + return; } tokensToDetect.forEach((tokenAddress, index) => { - const balance = result[index] + const balance = result[index]; if (balance && !balance.isZero()) { this._preferences.addToken( tokenAddress, contracts[tokenAddress].symbol, contracts[tokenAddress].decimals, - ) + ); } - }) + }); } async _getTokenBalances(tokens) { const ethContract = this.web3.eth .contract(SINGLE_CALL_BALANCES_ABI) - .at(SINGLE_CALL_BALANCES_ADDRESS) + .at(SINGLE_CALL_BALANCES_ADDRESS); return new Promise((resolve, reject) => { ethContract.balances([this.selectedAddress], tokens, (error, result) => { if (error) { - return reject(error) + return reject(error); } - return resolve(result) - }) - }) + return resolve(result); + }); + }); } /** @@ -97,10 +97,10 @@ export default class DetectTokensController { */ restartTokenDetection() { if (!(this.isActive && this.selectedAddress)) { - return + return; } - this.detectNewTokens() - this.interval = DEFAULT_INTERVAL + this.detectNewTokens(); + this.interval = DEFAULT_INTERVAL; } /* eslint-disable accessor-pairs */ @@ -108,13 +108,13 @@ export default class DetectTokensController { * @type {Number} */ set interval(interval) { - this._handle && clearInterval(this._handle) + this._handle && clearInterval(this._handle); if (!interval) { - return + return; } this._handle = setInterval(() => { - this.detectNewTokens() - }, interval) + this.detectNewTokens(); + }, interval); } /** @@ -123,26 +123,26 @@ export default class DetectTokensController { */ set preferences(preferences) { if (!preferences) { - return + return; } - this._preferences = preferences - const currentTokens = preferences.store.getState().tokens + this._preferences = preferences; + const currentTokens = preferences.store.getState().tokens; this.tokenAddresses = currentTokens ? currentTokens.map((token) => token.address) - : [] - this.hiddenTokens = preferences.store.getState().hiddenTokens + : []; + this.hiddenTokens = preferences.store.getState().hiddenTokens; preferences.store.subscribe(({ tokens = [], hiddenTokens = [] }) => { this.tokenAddresses = tokens.map((token) => { - return token.address - }) - this.hiddenTokens = hiddenTokens - }) + return token.address; + }); + this.hiddenTokens = hiddenTokens; + }); preferences.store.subscribe(({ selectedAddress }) => { if (this.selectedAddress !== selectedAddress) { - this.selectedAddress = selectedAddress - this.restartTokenDetection() + this.selectedAddress = selectedAddress; + this.restartTokenDetection(); } - }) + }); } /** @@ -150,10 +150,10 @@ export default class DetectTokensController { */ set network(network) { if (!network) { - return + return; } - this._network = network - this.web3 = new Web3(network._provider) + this._network = network; + this.web3 = new Web3(network._provider); } /** @@ -162,17 +162,17 @@ export default class DetectTokensController { */ set keyringMemStore(keyringMemStore) { if (!keyringMemStore) { - return + return; } - this._keyringMemStore = keyringMemStore + this._keyringMemStore = keyringMemStore; this._keyringMemStore.subscribe(({ isUnlocked }) => { if (this.isUnlocked !== isUnlocked) { - this.isUnlocked = isUnlocked + this.isUnlocked = isUnlocked; if (isUnlocked) { - this.restartTokenDetection() + this.restartTokenDetection(); } } - }) + }); } /** @@ -180,7 +180,7 @@ export default class DetectTokensController { * @type {Object} */ get isActive() { - return this.isOpen && this.isUnlocked + return this.isOpen && this.isUnlocked; } /* eslint-enable accessor-pairs */ } diff --git a/app/scripts/controllers/ens/ens.js b/app/scripts/controllers/ens/ens.js index f29d46aaa8..0a629dd407 100644 --- a/app/scripts/controllers/ens/ens.js +++ b/app/scripts/controllers/ens/ens.js @@ -1,23 +1,23 @@ -import EthJsEns from 'ethjs-ens' -import ensNetworkMap from 'ethereum-ens-network-map' +import EthJsEns from 'ethjs-ens'; +import ensNetworkMap from 'ethereum-ens-network-map'; export default class Ens { static getNetworkEnsSupport(network) { - return Boolean(ensNetworkMap[network]) + return Boolean(ensNetworkMap[network]); } constructor({ network, provider } = {}) { this._ethJsEns = new EthJsEns({ network, provider, - }) + }); } lookup(ensName) { - return this._ethJsEns.lookup(ensName) + return this._ethJsEns.lookup(ensName); } reverse(address) { - return this._ethJsEns.reverse(address) + return this._ethJsEns.reverse(address); } } diff --git a/app/scripts/controllers/ens/index.js b/app/scripts/controllers/ens/index.js index 08647b12ff..05d5311037 100644 --- a/app/scripts/controllers/ens/index.js +++ b/app/scripts/controllers/ens/index.js @@ -1,95 +1,95 @@ -import punycode from 'punycode/punycode' -import ethUtil from 'ethereumjs-util' -import { ObservableStore } from '@metamask/obs-store' -import log from 'loglevel' -import Ens from './ens' +import punycode from 'punycode/punycode'; +import ethUtil from 'ethereumjs-util'; +import { ObservableStore } from '@metamask/obs-store'; +import log from 'loglevel'; +import Ens from './ens'; -const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' -const ZERO_X_ERROR_ADDRESS = '0x' +const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; +const ZERO_X_ERROR_ADDRESS = '0x'; export default class EnsController { constructor({ ens, provider, networkStore } = {}) { const initState = { ensResolutionsByAddress: {}, - } + }; - this._ens = ens + this._ens = ens; if (!this._ens) { - const network = networkStore.getState() + const network = networkStore.getState(); if (Ens.getNetworkEnsSupport(network)) { this._ens = new Ens({ network, provider, - }) + }); } } - this.store = new ObservableStore(initState) + this.store = new ObservableStore(initState); networkStore.subscribe((network) => { - this.store.putState(initState) + this.store.putState(initState); if (Ens.getNetworkEnsSupport(network)) { this._ens = new Ens({ network, provider, - }) + }); } else { - delete this._ens + delete this._ens; } - }) + }); } reverseResolveAddress(address) { - return this._reverseResolveAddress(ethUtil.toChecksumAddress(address)) + return this._reverseResolveAddress(ethUtil.toChecksumAddress(address)); } async _reverseResolveAddress(address) { if (!this._ens) { - return undefined + return undefined; } - const state = this.store.getState() + const state = this.store.getState(); if (state.ensResolutionsByAddress[address]) { - return state.ensResolutionsByAddress[address] + return state.ensResolutionsByAddress[address]; } - let domain + let domain; try { - domain = await this._ens.reverse(address) + domain = await this._ens.reverse(address); } catch (error) { - log.debug(error) - return undefined + log.debug(error); + return undefined; } - let registeredAddress + let registeredAddress; try { - registeredAddress = await this._ens.lookup(domain) + registeredAddress = await this._ens.lookup(domain); } catch (error) { - log.debug(error) - return undefined + log.debug(error); + return undefined; } if ( registeredAddress === ZERO_ADDRESS || registeredAddress === ZERO_X_ERROR_ADDRESS ) { - return undefined + return undefined; } if (ethUtil.toChecksumAddress(registeredAddress) !== address) { - return undefined + return undefined; } - this._updateResolutionsByAddress(address, punycode.toASCII(domain)) - return domain + this._updateResolutionsByAddress(address, punycode.toASCII(domain)); + return domain; } _updateResolutionsByAddress(address, domain) { - const oldState = this.store.getState() + const oldState = this.store.getState(); this.store.putState({ ensResolutionsByAddress: { ...oldState.ensResolutionsByAddress, [address]: domain, }, - }) + }); } } diff --git a/app/scripts/controllers/incoming-transactions.js b/app/scripts/controllers/incoming-transactions.js index e1ff688956..481810ec12 100644 --- a/app/scripts/controllers/incoming-transactions.js +++ b/app/scripts/controllers/incoming-transactions.js @@ -1,14 +1,14 @@ -import { ObservableStore } from '@metamask/obs-store' -import log from 'loglevel' -import BN from 'bn.js' -import createId from '../lib/random-id' -import { bnToHex } from '../lib/util' -import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout' +import { ObservableStore } from '@metamask/obs-store'; +import log from 'loglevel'; +import BN from 'bn.js'; +import createId from '../lib/random-id'; +import { bnToHex } from '../lib/util'; +import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout'; import { TRANSACTION_CATEGORIES, TRANSACTION_STATUSES, -} from '../../../shared/constants/transaction' +} from '../../../shared/constants/transaction'; import { CHAIN_ID_TO_NETWORK_ID_MAP, CHAIN_ID_TO_TYPE_MAP, @@ -22,9 +22,9 @@ import { RINKEBY_CHAIN_ID, ROPSTEN, ROPSTEN_CHAIN_ID, -} from '../../../shared/constants/network' +} from '../../../shared/constants/network'; -const fetchWithTimeout = getFetchWithTimeout(30000) +const fetchWithTimeout = getFetchWithTimeout(30000); /** * This controller is responsible for retrieving incoming transactions. Etherscan is polled once every block to check @@ -39,23 +39,23 @@ const etherscanSupportedNetworks = [ MAINNET_CHAIN_ID, RINKEBY_CHAIN_ID, ROPSTEN_CHAIN_ID, -] +]; export default class IncomingTransactionsController { constructor(opts = {}) { - const { blockTracker, networkController, preferencesController } = opts - this.blockTracker = blockTracker - this.networkController = networkController - this.preferencesController = preferencesController + const { blockTracker, networkController, preferencesController } = opts; + this.blockTracker = blockTracker; + this.networkController = networkController; + this.preferencesController = preferencesController; this._onLatestBlock = async (newBlockNumberHex) => { - const selectedAddress = this.preferencesController.getSelectedAddress() - const newBlockNumberDec = parseInt(newBlockNumberHex, 16) + const selectedAddress = this.preferencesController.getSelectedAddress(); + const newBlockNumberDec = parseInt(newBlockNumberHex, 16); await this._update({ address: selectedAddress, newBlockNumberDec, - }) - } + }); + }; const initState = { incomingTransactions: {}, @@ -67,8 +67,8 @@ export default class IncomingTransactionsController { [ROPSTEN]: null, }, ...opts.initState, - } - this.store = new ObservableStore(initState) + }; + this.store = new ObservableStore(initState); this.preferencesController.store.subscribe( pairwise((prevState, currState) => { @@ -76,79 +76,79 @@ export default class IncomingTransactionsController { featureFlags: { showIncomingTransactions: prevShowIncomingTransactions, } = {}, - } = prevState + } = prevState; const { featureFlags: { showIncomingTransactions: currShowIncomingTransactions, } = {}, - } = currState + } = currState; if (currShowIncomingTransactions === prevShowIncomingTransactions) { - return + return; } if (prevShowIncomingTransactions && !currShowIncomingTransactions) { - this.stop() - return + this.stop(); + return; } - this.start() + this.start(); }), - ) + ); this.preferencesController.store.subscribe( pairwise(async (prevState, currState) => { - const { selectedAddress: prevSelectedAddress } = prevState - const { selectedAddress: currSelectedAddress } = currState + const { selectedAddress: prevSelectedAddress } = prevState; + const { selectedAddress: currSelectedAddress } = currState; if (currSelectedAddress === prevSelectedAddress) { - return + return; } await this._update({ address: currSelectedAddress, - }) + }); }), - ) + ); this.networkController.on('networkDidChange', async () => { - const address = this.preferencesController.getSelectedAddress() + const address = this.preferencesController.getSelectedAddress(); await this._update({ address, - }) - }) + }); + }); } start() { - const { featureFlags = {} } = this.preferencesController.store.getState() - const { showIncomingTransactions } = featureFlags + const { featureFlags = {} } = this.preferencesController.store.getState(); + const { showIncomingTransactions } = featureFlags; if (!showIncomingTransactions) { - return + return; } - this.blockTracker.removeListener('latest', this._onLatestBlock) - this.blockTracker.addListener('latest', this._onLatestBlock) + this.blockTracker.removeListener('latest', this._onLatestBlock); + this.blockTracker.addListener('latest', this._onLatestBlock); } stop() { - this.blockTracker.removeListener('latest', this._onLatestBlock) + this.blockTracker.removeListener('latest', this._onLatestBlock); } async _update({ address, newBlockNumberDec } = {}) { - const chainId = this.networkController.getCurrentChainId() + const chainId = this.networkController.getCurrentChainId(); if (!etherscanSupportedNetworks.includes(chainId)) { - return + return; } try { const dataForUpdate = await this._getDataForUpdate({ address, chainId, newBlockNumberDec, - }) - this._updateStateWithNewTxData(dataForUpdate) + }); + this._updateStateWithNewTxData(dataForUpdate); } catch (err) { - log.error(err) + log.error(err); } } @@ -156,20 +156,20 @@ export default class IncomingTransactionsController { const { incomingTransactions: currentIncomingTxs, incomingTxLastFetchedBlocksByNetwork: currentBlocksByNetwork, - } = this.store.getState() + } = this.store.getState(); const lastFetchBlockByCurrentNetwork = - currentBlocksByNetwork[CHAIN_ID_TO_TYPE_MAP[chainId]] - let blockToFetchFrom = lastFetchBlockByCurrentNetwork || newBlockNumberDec + currentBlocksByNetwork[CHAIN_ID_TO_TYPE_MAP[chainId]]; + let blockToFetchFrom = lastFetchBlockByCurrentNetwork || newBlockNumberDec; if (blockToFetchFrom === undefined) { - blockToFetchFrom = parseInt(this.blockTracker.getCurrentBlock(), 16) + blockToFetchFrom = parseInt(this.blockTracker.getCurrentBlock(), 16); } const { latestIncomingTxBlockNumber, txs: newTxs } = await this._fetchAll( address, blockToFetchFrom, chainId, - ) + ); return { latestIncomingTxBlockNumber, @@ -178,7 +178,7 @@ export default class IncomingTransactionsController { currentBlocksByNetwork, fetchedBlockNumber: blockToFetchFrom, chainId, - } + }; } _updateStateWithNewTxData({ @@ -191,13 +191,13 @@ export default class IncomingTransactionsController { }) { const newLatestBlockHashByNetwork = latestIncomingTxBlockNumber ? parseInt(latestIncomingTxBlockNumber, 10) + 1 - : fetchedBlockNumber + 1 + : fetchedBlockNumber + 1; const newIncomingTransactions = { ...currentIncomingTxs, - } + }; newTxs.forEach((tx) => { - newIncomingTransactions[tx.hash] = tx - }) + newIncomingTransactions[tx.hash] = tx; + }); this.store.updateState({ incomingTxLastFetchedBlocksByNetwork: { @@ -205,53 +205,53 @@ export default class IncomingTransactionsController { [CHAIN_ID_TO_TYPE_MAP[chainId]]: newLatestBlockHashByNetwork, }, incomingTransactions: newIncomingTransactions, - }) + }); } async _fetchAll(address, fromBlock, chainId) { - const fetchedTxResponse = await this._fetchTxs(address, fromBlock, chainId) - return this._processTxFetchResponse(fetchedTxResponse) + const fetchedTxResponse = await this._fetchTxs(address, fromBlock, chainId); + return this._processTxFetchResponse(fetchedTxResponse); } async _fetchTxs(address, fromBlock, chainId) { const etherscanSubdomain = chainId === MAINNET_CHAIN_ID ? 'api' - : `api-${CHAIN_ID_TO_TYPE_MAP[chainId]}` + : `api-${CHAIN_ID_TO_TYPE_MAP[chainId]}`; - const apiUrl = `https://${etherscanSubdomain}.etherscan.io` - let url = `${apiUrl}/api?module=account&action=txlist&address=${address}&tag=latest&page=1` + const apiUrl = `https://${etherscanSubdomain}.etherscan.io`; + let url = `${apiUrl}/api?module=account&action=txlist&address=${address}&tag=latest&page=1`; if (fromBlock) { - url += `&startBlock=${parseInt(fromBlock, 10)}` + url += `&startBlock=${parseInt(fromBlock, 10)}`; } - const response = await fetchWithTimeout(url) - const parsedResponse = await response.json() + const response = await fetchWithTimeout(url); + const parsedResponse = await response.json(); return { ...parsedResponse, address, chainId, - } + }; } _processTxFetchResponse({ status, result = [], address, chainId }) { if (status === '1' && Array.isArray(result) && result.length > 0) { - const remoteTxList = {} - const remoteTxs = [] + const remoteTxList = {}; + const remoteTxs = []; result.forEach((tx) => { if (!remoteTxList[tx.hash]) { - remoteTxs.push(this._normalizeTxFromEtherscan(tx, chainId)) - remoteTxList[tx.hash] = 1 + remoteTxs.push(this._normalizeTxFromEtherscan(tx, chainId)); + remoteTxList[tx.hash] = 1; } - }) + }); const incomingTxs = remoteTxs.filter( (tx) => tx.txParams?.to?.toLowerCase() === address.toLowerCase(), - ) - incomingTxs.sort((a, b) => (a.time < b.time ? -1 : 1)) + ); + incomingTxs.sort((a, b) => (a.time < b.time ? -1 : 1)); - let latestIncomingTxBlockNumber = null + let latestIncomingTxBlockNumber = null; incomingTxs.forEach((tx) => { if ( tx.blockNumber && @@ -259,26 +259,26 @@ export default class IncomingTransactionsController { parseInt(latestIncomingTxBlockNumber, 10) < parseInt(tx.blockNumber, 10)) ) { - latestIncomingTxBlockNumber = tx.blockNumber + latestIncomingTxBlockNumber = tx.blockNumber; } - }) + }); return { latestIncomingTxBlockNumber, txs: incomingTxs, - } + }; } return { latestIncomingTxBlockNumber: null, txs: [], - } + }; } _normalizeTxFromEtherscan(txMeta, chainId) { - const time = parseInt(txMeta.timeStamp, 10) * 1000 + const time = parseInt(txMeta.timeStamp, 10) * 1000; const status = txMeta.isError === '0' ? TRANSACTION_STATUSES.CONFIRMED - : TRANSACTION_STATUSES.FAILED + : TRANSACTION_STATUSES.FAILED; return { blockNumber: txMeta.blockNumber, id: createId(), @@ -295,22 +295,22 @@ export default class IncomingTransactionsController { }, hash: txMeta.hash, transactionCategory: TRANSACTION_CATEGORIES.INCOMING, - } + }; } } function pairwise(fn) { - let first = true - let cache + let first = true; + let cache; return (value) => { try { if (first) { - first = false - return fn(value, value) + first = false; + return fn(value, value); } - return fn(cache, value) + return fn(cache, value); } finally { - cache = value + cache = value; } - } + }; } diff --git a/app/scripts/controllers/metametrics.js b/app/scripts/controllers/metametrics.js index 2c84ee78c0..4bb1c4f462 100644 --- a/app/scripts/controllers/metametrics.js +++ b/app/scripts/controllers/metametrics.js @@ -1,11 +1,11 @@ -import { merge, omit } from 'lodash' -import { ObservableStore } from '@metamask/obs-store' -import { bufferToHex, sha3 } from 'ethereumjs-util' -import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../shared/constants/app' +import { merge, omit } from 'lodash'; +import { ObservableStore } from '@metamask/obs-store'; +import { bufferToHex, sha3 } from 'ethereumjs-util'; +import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../shared/constants/app'; import { METAMETRICS_ANONYMOUS_ID, METAMETRICS_BACKGROUND_PAGE_OBJECT, -} from '../../../shared/constants/metametrics' +} from '../../../shared/constants/metametrics'; /** * Used to determine whether or not to attach a user's metametrics id @@ -25,10 +25,10 @@ const trackableSendCounts = { 5000: true, 10000: true, 25000: true, -} +}; export function sendCountIsTrackable(sendCount) { - return Boolean(trackableSendCounts[sendCount]) + return Boolean(trackableSendCounts[sendCount]); } /** @@ -82,30 +82,30 @@ export default class MetaMetricsController { environment, initState, }) { - const prefState = preferencesStore.getState() - this.chainId = getCurrentChainId() - this.network = getNetworkIdentifier() - this.locale = prefState.currentLocale.replace('_', '-') + const prefState = preferencesStore.getState(); + this.chainId = getCurrentChainId(); + this.network = getNetworkIdentifier(); + this.locale = prefState.currentLocale.replace('_', '-'); this.version = - environment === 'production' ? version : `${version}-${environment}` + environment === 'production' ? version : `${version}-${environment}`; this.store = new ObservableStore({ participateInMetaMetrics: null, metaMetricsId: null, metaMetricsSendCount: 0, ...initState, - }) + }); preferencesStore.subscribe(({ currentLocale }) => { - this.locale = currentLocale.replace('_', '-') - }) + this.locale = currentLocale.replace('_', '-'); + }); onNetworkDidChange(() => { - this.chainId = getCurrentChainId() - this.network = getNetworkIdentifier() - }) - this.segment = segment - this.segmentLegacy = segmentLegacy + this.chainId = getCurrentChainId(); + this.network = getNetworkIdentifier(); + }); + this.segment = segment; + this.segmentLegacy = segmentLegacy; } generateMetaMetricsId() { @@ -114,7 +114,7 @@ export default class MetaMetricsController { String(Date.now()) + String(Math.round(Math.random() * Number.MAX_SAFE_INTEGER)), ), - ) + ); } /** @@ -126,22 +126,22 @@ export default class MetaMetricsController { * if not set */ setParticipateInMetaMetrics(participateInMetaMetrics) { - let { metaMetricsId } = this.state + let { metaMetricsId } = this.state; if (participateInMetaMetrics && !metaMetricsId) { - metaMetricsId = this.generateMetaMetricsId() + metaMetricsId = this.generateMetaMetricsId(); } else if (participateInMetaMetrics === false) { - metaMetricsId = null + metaMetricsId = null; } - this.store.updateState({ participateInMetaMetrics, metaMetricsId }) - return metaMetricsId + this.store.updateState({ participateInMetaMetrics, metaMetricsId }); + return metaMetricsId; } get state() { - return this.store.getState() + return this.store.getState(); } setMetaMetricsSendCount(val) { - this.store.updateState({ metaMetricsSendCount: val }) + this.store.updateState({ metaMetricsSendCount: val }); } /** @@ -162,7 +162,7 @@ export default class MetaMetricsController { userAgent: window.navigator.userAgent, page, referrer, - } + }; } /** @@ -185,7 +185,7 @@ export default class MetaMetricsController { page, referrer, environmentType = ENVIRONMENT_TYPE_BACKGROUND, - } = rawPayload + } = rawPayload; return { event, properties: { @@ -206,7 +206,7 @@ export default class MetaMetricsController { environment_type: environmentType, }, context: this._buildContext(referrer, page), - } + }; } /** @@ -225,20 +225,20 @@ export default class MetaMetricsController { metaMetricsId: metaMetricsIdOverride, matomoEvent, flushImmediately, - } = options || {} - let idType = 'userId' - let idValue = this.state.metaMetricsId - let excludeMetaMetricsId = options?.excludeMetaMetricsId ?? false + } = options || {}; + let idType = 'userId'; + let idValue = this.state.metaMetricsId; + let excludeMetaMetricsId = options?.excludeMetaMetricsId ?? false; // This is carried over from the old implementation, and will likely need // to be updated to work with the new tracking plan. I think we should use // a config setting for this instead of trying to match the event name - const isSendFlow = Boolean(payload.event.match(/^send|^confirm/iu)) + const isSendFlow = Boolean(payload.event.match(/^send|^confirm/iu)); if ( isSendFlow && this.state.metaMetricsSendCount && !sendCountIsTrackable(this.state.metaMetricsSendCount + 1) ) { - excludeMetaMetricsId = true + excludeMetaMetricsId = true; } // If we are tracking sensitive data we will always use the anonymousId // property as well as our METAMETRICS_ANONYMOUS_ID. This prevents us from @@ -251,12 +251,12 @@ export default class MetaMetricsController { // case we will track the opt in event to the user's id. In all other cases // we use the metaMetricsId from state. if (excludeMetaMetricsId || (isOptIn && !metaMetricsIdOverride)) { - idType = 'anonymousId' - idValue = METAMETRICS_ANONYMOUS_ID + idType = 'anonymousId'; + idValue = METAMETRICS_ANONYMOUS_ID; } else if (isOptIn && metaMetricsIdOverride) { - idValue = metaMetricsIdOverride + idValue = metaMetricsIdOverride; } - payload[idType] = idValue + payload[idType] = idValue; // Promises will only resolve when the event is sent to segment. For any // event that relies on this promise being fulfilled before performing UI @@ -269,20 +269,20 @@ export default class MetaMetricsController { // that seemingly breaks with lockdown enabled. Creating a new error // here prevents the system from freezing when the network request to // segment fails for any reason. - const safeError = new Error(err.message) - safeError.stack = err.stack - return reject(safeError) + const safeError = new Error(err.message); + safeError.stack = err.stack; + return reject(safeError); } - return resolve() - } + return resolve(); + }; - const target = matomoEvent === true ? this.segmentLegacy : this.segment + const target = matomoEvent === true ? this.segmentLegacy : this.segment; - target.track(payload, callback) + target.track(payload, callback); if (flushImmediately) { - target.flush() + target.flush(); } - }) + }); } /** @@ -293,15 +293,15 @@ export default class MetaMetricsController { */ trackPage({ name, params, environmentType, page, referrer }, options) { if (this.state.participateInMetaMetrics === false) { - return + return; } if (this.state.participateInMetaMetrics === null && !options?.isOptInPath) { - return + return; } - const { metaMetricsId } = this.state - const idTrait = metaMetricsId ? 'userId' : 'anonymousId' - const idValue = metaMetricsId ?? METAMETRICS_ANONYMOUS_ID + const { metaMetricsId } = this.state; + const idTrait = metaMetricsId ? 'userId' : 'anonymousId'; + const idValue = metaMetricsId ?? METAMETRICS_ANONYMOUS_ID; this.segment.page({ [idTrait]: idValue, name, @@ -313,7 +313,7 @@ export default class MetaMetricsController { environment_type: environmentType, }, context: this._buildContext(referrer, page), - }) + }); } /** @@ -328,16 +328,16 @@ export default class MetaMetricsController { async trackEvent(payload, options) { // event and category are required fields for all payloads if (!payload.event || !payload.category) { - throw new Error('Must specify event and category.') + throw new Error('Must specify event and category.'); } if (!this.state.participateInMetaMetrics && !options?.isOptIn) { - return + return; } // We might track multiple events if sensitiveProperties is included, this array will hold // the promises returned from this._track. - const events = [] + const events = []; if (payload.sensitiveProperties) { // sensitiveProperties will only be tracked using the anonymousId property and generic id @@ -346,13 +346,13 @@ export default class MetaMetricsController { if (options?.excludeMetaMetricsId === true) { throw new Error( 'sensitiveProperties was specified in an event payload that also set the excludeMetaMetricsId flag', - ) + ); } const combinedProperties = merge( payload.sensitiveProperties, payload.properties, - ) + ); events.push( this._track( @@ -362,11 +362,11 @@ export default class MetaMetricsController { }), { ...options, excludeMetaMetricsId: true }, ), - ) + ); } - events.push(this._track(this._buildEventPayload(payload), options)) + events.push(this._track(this._buildEventPayload(payload), options)); - await Promise.all(events) + await Promise.all(events); } } diff --git a/app/scripts/controllers/network/createInfuraClient.js b/app/scripts/controllers/network/createInfuraClient.js index 0f37ea4ca7..00f5d8c68a 100644 --- a/app/scripts/controllers/network/createInfuraClient.js +++ b/app/scripts/controllers/network/createInfuraClient.js @@ -1,14 +1,14 @@ -import { createScaffoldMiddleware, mergeMiddleware } from 'json-rpc-engine' -import createBlockReRefMiddleware from 'eth-json-rpc-middleware/block-ref' -import createRetryOnEmptyMiddleware from 'eth-json-rpc-middleware/retryOnEmpty' -import createBlockCacheMiddleware from 'eth-json-rpc-middleware/block-cache' -import createInflightMiddleware from 'eth-json-rpc-middleware/inflight-cache' -import createBlockTrackerInspectorMiddleware from 'eth-json-rpc-middleware/block-tracker-inspector' -import providerFromMiddleware from 'eth-json-rpc-middleware/providerFromMiddleware' -import createInfuraMiddleware from 'eth-json-rpc-infura' -import BlockTracker from 'eth-block-tracker' +import { createScaffoldMiddleware, mergeMiddleware } from 'json-rpc-engine'; +import createBlockReRefMiddleware from 'eth-json-rpc-middleware/block-ref'; +import createRetryOnEmptyMiddleware from 'eth-json-rpc-middleware/retryOnEmpty'; +import createBlockCacheMiddleware from 'eth-json-rpc-middleware/block-cache'; +import createInflightMiddleware from 'eth-json-rpc-middleware/inflight-cache'; +import createBlockTrackerInspectorMiddleware from 'eth-json-rpc-middleware/block-tracker-inspector'; +import providerFromMiddleware from 'eth-json-rpc-middleware/providerFromMiddleware'; +import createInfuraMiddleware from 'eth-json-rpc-infura'; +import BlockTracker from 'eth-block-tracker'; -import { NETWORK_TYPE_TO_ID_MAP } from '../../../../shared/constants/network' +import { NETWORK_TYPE_TO_ID_MAP } from '../../../../shared/constants/network'; export default function createInfuraClient({ network, projectId }) { const infuraMiddleware = createInfuraMiddleware({ @@ -16,9 +16,9 @@ export default function createInfuraClient({ network, projectId }) { projectId, maxAttempts: 5, source: 'metamask', - }) - const infuraProvider = providerFromMiddleware(infuraMiddleware) - const blockTracker = new BlockTracker({ provider: infuraProvider }) + }); + const infuraProvider = providerFromMiddleware(infuraMiddleware); + const blockTracker = new BlockTracker({ provider: infuraProvider }); const networkMiddleware = mergeMiddleware([ createNetworkAndChainIdMiddleware({ network }), @@ -28,19 +28,19 @@ export default function createInfuraClient({ network, projectId }) { createRetryOnEmptyMiddleware({ blockTracker, provider: infuraProvider }), createBlockTrackerInspectorMiddleware({ blockTracker }), infuraMiddleware, - ]) - return { networkMiddleware, blockTracker } + ]); + return { networkMiddleware, blockTracker }; } function createNetworkAndChainIdMiddleware({ network }) { if (!NETWORK_TYPE_TO_ID_MAP[network]) { - throw new Error(`createInfuraClient - unknown network "${network}"`) + throw new Error(`createInfuraClient - unknown network "${network}"`); } - const { chainId, networkId } = NETWORK_TYPE_TO_ID_MAP[network] + const { chainId, networkId } = NETWORK_TYPE_TO_ID_MAP[network]; return createScaffoldMiddleware({ eth_chainId: chainId, net_version: networkId, - }) + }); } diff --git a/app/scripts/controllers/network/createJsonRpcClient.js b/app/scripts/controllers/network/createJsonRpcClient.js index cc8e9edc5d..836801a0ff 100644 --- a/app/scripts/controllers/network/createJsonRpcClient.js +++ b/app/scripts/controllers/network/createJsonRpcClient.js @@ -1,25 +1,25 @@ -import { createAsyncMiddleware, mergeMiddleware } from 'json-rpc-engine' -import createFetchMiddleware from 'eth-json-rpc-middleware/fetch' -import createBlockRefRewriteMiddleware from 'eth-json-rpc-middleware/block-ref-rewrite' -import createBlockCacheMiddleware from 'eth-json-rpc-middleware/block-cache' -import createInflightMiddleware from 'eth-json-rpc-middleware/inflight-cache' -import createBlockTrackerInspectorMiddleware from 'eth-json-rpc-middleware/block-tracker-inspector' -import providerFromMiddleware from 'eth-json-rpc-middleware/providerFromMiddleware' -import BlockTracker from 'eth-block-tracker' +import { createAsyncMiddleware, mergeMiddleware } from 'json-rpc-engine'; +import createFetchMiddleware from 'eth-json-rpc-middleware/fetch'; +import createBlockRefRewriteMiddleware from 'eth-json-rpc-middleware/block-ref-rewrite'; +import createBlockCacheMiddleware from 'eth-json-rpc-middleware/block-cache'; +import createInflightMiddleware from 'eth-json-rpc-middleware/inflight-cache'; +import createBlockTrackerInspectorMiddleware from 'eth-json-rpc-middleware/block-tracker-inspector'; +import providerFromMiddleware from 'eth-json-rpc-middleware/providerFromMiddleware'; +import BlockTracker from 'eth-block-tracker'; -const inTest = process.env.IN_TEST === 'true' -const blockTrackerOpts = inTest ? { pollingInterval: 1000 } : {} +const inTest = process.env.IN_TEST === 'true'; +const blockTrackerOpts = inTest ? { pollingInterval: 1000 } : {}; const getTestMiddlewares = () => { - return inTest ? [createEstimateGasDelayTestMiddleware()] : [] -} + return inTest ? [createEstimateGasDelayTestMiddleware()] : []; +}; export default function createJsonRpcClient({ rpcUrl, chainId }) { - const fetchMiddleware = createFetchMiddleware({ rpcUrl }) - const blockProvider = providerFromMiddleware(fetchMiddleware) + const fetchMiddleware = createFetchMiddleware({ rpcUrl }); + const blockProvider = providerFromMiddleware(fetchMiddleware); const blockTracker = new BlockTracker({ ...blockTrackerOpts, provider: blockProvider, - }) + }); const networkMiddleware = mergeMiddleware([ ...getTestMiddlewares(), @@ -29,19 +29,19 @@ export default function createJsonRpcClient({ rpcUrl, chainId }) { createInflightMiddleware(), createBlockTrackerInspectorMiddleware({ blockTracker }), fetchMiddleware, - ]) + ]); - return { networkMiddleware, blockTracker } + return { networkMiddleware, blockTracker }; } function createChainIdMiddleware(chainId) { return (req, res, next, end) => { if (req.method === 'eth_chainId') { - res.result = chainId - return end() + res.result = chainId; + return end(); } - return next() - } + return next(); + }; } /** @@ -51,8 +51,8 @@ function createChainIdMiddleware(chainId) { function createEstimateGasDelayTestMiddleware() { return createAsyncMiddleware(async (req, _, next) => { if (req.method === 'eth_estimateGas') { - await new Promise((resolve) => setTimeout(resolve, 2000)) + await new Promise((resolve) => setTimeout(resolve, 2000)); } - return next() - }) + return next(); + }); } diff --git a/app/scripts/controllers/network/createMetamaskMiddleware.js b/app/scripts/controllers/network/createMetamaskMiddleware.js index f4e9c5d1a0..c3803a061f 100644 --- a/app/scripts/controllers/network/createMetamaskMiddleware.js +++ b/app/scripts/controllers/network/createMetamaskMiddleware.js @@ -1,9 +1,9 @@ -import { createScaffoldMiddleware, mergeMiddleware } from 'json-rpc-engine' -import createWalletSubprovider from 'eth-json-rpc-middleware/wallet' +import { createScaffoldMiddleware, mergeMiddleware } from 'json-rpc-engine'; +import createWalletSubprovider from 'eth-json-rpc-middleware/wallet'; import { createPendingNonceMiddleware, createPendingTxMiddleware, -} from './middleware/pending' +} from './middleware/pending'; export default function createMetamaskMiddleware({ version, @@ -38,6 +38,6 @@ export default function createMetamaskMiddleware({ }), createPendingNonceMiddleware({ getPendingNonce }), createPendingTxMiddleware({ getPendingTransactionByHash }), - ]) - return metamaskMiddleware + ]); + return metamaskMiddleware; } diff --git a/app/scripts/controllers/network/index.js b/app/scripts/controllers/network/index.js index a090538f5c..a0a43faa5a 100644 --- a/app/scripts/controllers/network/index.js +++ b/app/scripts/controllers/network/index.js @@ -1 +1 @@ -export { default } from './network' +export { default } from './network'; diff --git a/app/scripts/controllers/network/middleware/pending.js b/app/scripts/controllers/network/middleware/pending.js index 905e441291..9852d55528 100644 --- a/app/scripts/controllers/network/middleware/pending.js +++ b/app/scripts/controllers/network/middleware/pending.js @@ -1,35 +1,35 @@ -import { createAsyncMiddleware } from 'json-rpc-engine' -import { formatTxMetaForRpcResult } from '../util' +import { createAsyncMiddleware } from 'json-rpc-engine'; +import { formatTxMetaForRpcResult } from '../util'; export function createPendingNonceMiddleware({ getPendingNonce }) { return createAsyncMiddleware(async (req, res, next) => { - const { method, params } = req + const { method, params } = req; if (method !== 'eth_getTransactionCount') { - next() - return + next(); + return; } - const [param, blockRef] = params + const [param, blockRef] = params; if (blockRef !== 'pending') { - next() - return + next(); + return; } - res.result = await getPendingNonce(param) - }) + res.result = await getPendingNonce(param); + }); } export function createPendingTxMiddleware({ getPendingTransactionByHash }) { return createAsyncMiddleware(async (req, res, next) => { - const { method, params } = req + const { method, params } = req; if (method !== 'eth_getTransactionByHash') { - next() - return + next(); + return; } - const [hash] = params - const txMeta = getPendingTransactionByHash(hash) + const [hash] = params; + const txMeta = getPendingTransactionByHash(hash); if (!txMeta) { - next() - return + next(); + return; } - res.result = formatTxMetaForRpcResult(txMeta) - }) + res.result = formatTxMetaForRpcResult(txMeta); + }); } diff --git a/app/scripts/controllers/network/network.js b/app/scripts/controllers/network/network.js index 605d01ade4..605b0063a0 100644 --- a/app/scripts/controllers/network/network.js +++ b/app/scripts/controllers/network/network.js @@ -1,14 +1,14 @@ -import assert from 'assert' -import EventEmitter from 'events' -import { ComposedStore, ObservableStore } from '@metamask/obs-store' -import { JsonRpcEngine } from 'json-rpc-engine' -import providerFromEngine from 'eth-json-rpc-middleware/providerFromEngine' -import log from 'loglevel' +import assert from 'assert'; +import EventEmitter from 'events'; +import { ComposedStore, ObservableStore } from '@metamask/obs-store'; +import { JsonRpcEngine } from 'json-rpc-engine'; +import providerFromEngine from 'eth-json-rpc-middleware/providerFromEngine'; +import log from 'loglevel'; import { createSwappableProxy, createEventEmitterProxy, -} from 'swappable-obj-proxy' -import EthQuery from 'eth-query' +} from 'swappable-obj-proxy'; +import EthQuery from 'eth-query'; import { RINKEBY, MAINNET, @@ -17,63 +17,63 @@ import { NETWORK_TYPE_TO_ID_MAP, MAINNET_CHAIN_ID, RINKEBY_CHAIN_ID, -} from '../../../../shared/constants/network' +} from '../../../../shared/constants/network'; import { isPrefixedFormattedHexString, isSafeChainId, -} from '../../../../shared/modules/utils' -import createMetamaskMiddleware from './createMetamaskMiddleware' -import createInfuraClient from './createInfuraClient' -import createJsonRpcClient from './createJsonRpcClient' +} from '../../../../shared/modules/utils'; +import createMetamaskMiddleware from './createMetamaskMiddleware'; +import createInfuraClient from './createInfuraClient'; +import createJsonRpcClient from './createJsonRpcClient'; -const env = process.env.METAMASK_ENV +const env = process.env.METAMASK_ENV; -let defaultProviderConfigOpts +let defaultProviderConfigOpts; if (process.env.IN_TEST === 'true') { defaultProviderConfigOpts = { type: NETWORK_TYPE_RPC, rpcUrl: 'http://localhost:8545', chainId: '0x539', nickname: 'Localhost 8545', - } + }; } else if (process.env.METAMASK_DEBUG || env === 'test') { - defaultProviderConfigOpts = { type: RINKEBY, chainId: RINKEBY_CHAIN_ID } + defaultProviderConfigOpts = { type: RINKEBY, chainId: RINKEBY_CHAIN_ID }; } else { - defaultProviderConfigOpts = { type: MAINNET, chainId: MAINNET_CHAIN_ID } + defaultProviderConfigOpts = { type: MAINNET, chainId: MAINNET_CHAIN_ID }; } const defaultProviderConfig = { ticker: 'ETH', ...defaultProviderConfigOpts, -} +}; export default class NetworkController extends EventEmitter { constructor(opts = {}) { - super() + super(); // create stores this.providerStore = new ObservableStore( opts.provider || { ...defaultProviderConfig }, - ) + ); this.previousProviderStore = new ObservableStore( this.providerStore.getState(), - ) - this.networkStore = new ObservableStore('loading') + ); + this.networkStore = new ObservableStore('loading'); this.store = new ComposedStore({ provider: this.providerStore, previousProviderStore: this.previousProviderStore, network: this.networkStore, - }) + }); // provider and block tracker - this._provider = null - this._blockTracker = null + this._provider = null; + this._blockTracker = null; // provider and block tracker proxies - because the network changes - this._providerProxy = null - this._blockTrackerProxy = null + this._providerProxy = null; + this._blockTrackerProxy = null; - this.on('networkDidChange', this.lookupNetwork) + this.on('networkDidChange', this.lookupNetwork); } /** @@ -85,43 +85,43 @@ export default class NetworkController extends EventEmitter { */ setInfuraProjectId(projectId) { if (!projectId || typeof projectId !== 'string') { - throw new Error('Invalid Infura project ID') + throw new Error('Invalid Infura project ID'); } - this._infuraProjectId = projectId + this._infuraProjectId = projectId; } initializeProvider(providerParams) { - this._baseProviderParams = providerParams - const { type, rpcUrl, chainId } = this.getProviderConfig() - this._configureProvider({ type, rpcUrl, chainId }) - this.lookupNetwork() + this._baseProviderParams = providerParams; + const { type, rpcUrl, chainId } = this.getProviderConfig(); + this._configureProvider({ type, rpcUrl, chainId }); + this.lookupNetwork(); } // return the proxies so the references will always be good getProviderAndBlockTracker() { - const provider = this._providerProxy - const blockTracker = this._blockTrackerProxy - return { provider, blockTracker } + const provider = this._providerProxy; + const blockTracker = this._blockTrackerProxy; + return { provider, blockTracker }; } verifyNetwork() { // Check network when restoring connectivity: if (this.isNetworkLoading()) { - this.lookupNetwork() + this.lookupNetwork(); } } getNetworkState() { - return this.networkStore.getState() + return this.networkStore.getState(); } setNetworkState(network) { - this.networkStore.putState(network) + this.networkStore.putState(network); } isNetworkLoading() { - return this.getNetworkState() === 'loading' + return this.getNetworkState() === 'loading'; } lookupNetwork() { @@ -129,49 +129,49 @@ export default class NetworkController extends EventEmitter { if (!this._provider) { log.warn( 'NetworkController - lookupNetwork aborted due to missing provider', - ) - return + ); + return; } - const chainId = this.getCurrentChainId() + const chainId = this.getCurrentChainId(); if (!chainId) { log.warn( 'NetworkController - lookupNetwork aborted due to missing chainId', - ) - this.setNetworkState('loading') - return + ); + this.setNetworkState('loading'); + return; } // Ping the RPC endpoint so we can confirm that it works - const ethQuery = new EthQuery(this._provider) - const initialNetwork = this.getNetworkState() + const ethQuery = new EthQuery(this._provider); + const initialNetwork = this.getNetworkState(); ethQuery.sendAsync({ method: 'net_version' }, (err, networkVersion) => { - const currentNetwork = this.getNetworkState() + const currentNetwork = this.getNetworkState(); if (initialNetwork === currentNetwork) { if (err) { - this.setNetworkState('loading') - return + this.setNetworkState('loading'); + return; } - this.setNetworkState(networkVersion) + this.setNetworkState(networkVersion); } - }) + }); } getCurrentChainId() { - const { type, chainId: configChainId } = this.getProviderConfig() - return NETWORK_TYPE_TO_ID_MAP[type]?.chainId || configChainId + const { type, chainId: configChainId } = this.getProviderConfig(); + return NETWORK_TYPE_TO_ID_MAP[type]?.chainId || configChainId; } setRpcTarget(rpcUrl, chainId, ticker = 'ETH', nickname = '', rpcPrefs) { assert.ok( isPrefixedFormattedHexString(chainId), `Invalid chain ID "${chainId}": invalid hex string.`, - ) + ); assert.ok( isSafeChainId(parseInt(chainId, 16)), `Invalid chain ID "${chainId}": numerical value greater than max safe value.`, - ) + ); this.setProviderConfig({ type: NETWORK_TYPE_RPC, rpcUrl, @@ -179,7 +179,7 @@ export default class NetworkController extends EventEmitter { ticker, nickname, rpcPrefs, - }) + }); } async setProviderType(type, rpcUrl = '', ticker = 'ETH', nickname = '') { @@ -187,41 +187,41 @@ export default class NetworkController extends EventEmitter { type, NETWORK_TYPE_RPC, `NetworkController - cannot call "setProviderType" with type "${NETWORK_TYPE_RPC}". Use "setRpcTarget"`, - ) + ); assert.ok( INFURA_PROVIDER_TYPES.includes(type), `Unknown Infura provider type "${type}".`, - ) - const { chainId } = NETWORK_TYPE_TO_ID_MAP[type] - this.setProviderConfig({ type, rpcUrl, chainId, ticker, nickname }) + ); + const { chainId } = NETWORK_TYPE_TO_ID_MAP[type]; + this.setProviderConfig({ type, rpcUrl, chainId, ticker, nickname }); } resetConnection() { - this.setProviderConfig(this.getProviderConfig()) + this.setProviderConfig(this.getProviderConfig()); } /** * Sets the provider config and switches the network. */ setProviderConfig(config) { - this.previousProviderStore.updateState(this.getProviderConfig()) - this.providerStore.updateState(config) - this._switchNetwork(config) + this.previousProviderStore.updateState(this.getProviderConfig()); + this.providerStore.updateState(config); + this._switchNetwork(config); } rollbackToPreviousProvider() { - const config = this.previousProviderStore.getState() - this.providerStore.updateState(config) - this._switchNetwork(config) + const config = this.previousProviderStore.getState(); + this.providerStore.updateState(config); + this._switchNetwork(config); } getProviderConfig() { - return this.providerStore.getState() + return this.providerStore.getState(); } getNetworkIdentifier() { - const provider = this.providerStore.getState() - return provider.type === NETWORK_TYPE_RPC ? provider.rpcUrl : provider.type + const provider = this.providerStore.getState(); + return provider.type === NETWORK_TYPE_RPC ? provider.rpcUrl : provider.type; } // @@ -229,68 +229,68 @@ export default class NetworkController extends EventEmitter { // _switchNetwork(opts) { - this.setNetworkState('loading') - this._configureProvider(opts) - this.emit('networkDidChange', opts.type) + this.setNetworkState('loading'); + this._configureProvider(opts); + this.emit('networkDidChange', opts.type); } _configureProvider({ type, rpcUrl, chainId }) { // infura type-based endpoints - const isInfura = INFURA_PROVIDER_TYPES.includes(type) + const isInfura = INFURA_PROVIDER_TYPES.includes(type); if (isInfura) { - this._configureInfuraProvider(type, this._infuraProjectId) + this._configureInfuraProvider(type, this._infuraProjectId); // url-based rpc endpoints } else if (type === NETWORK_TYPE_RPC) { - this._configureStandardProvider(rpcUrl, chainId) + this._configureStandardProvider(rpcUrl, chainId); } else { throw new Error( `NetworkController - _configureProvider - unknown type "${type}"`, - ) + ); } } _configureInfuraProvider(type, projectId) { - log.info('NetworkController - configureInfuraProvider', type) + log.info('NetworkController - configureInfuraProvider', type); const networkClient = createInfuraClient({ network: type, projectId, - }) - this._setNetworkClient(networkClient) + }); + this._setNetworkClient(networkClient); } _configureStandardProvider(rpcUrl, chainId) { - log.info('NetworkController - configureStandardProvider', rpcUrl) - const networkClient = createJsonRpcClient({ rpcUrl, chainId }) - this._setNetworkClient(networkClient) + log.info('NetworkController - configureStandardProvider', rpcUrl); + const networkClient = createJsonRpcClient({ rpcUrl, chainId }); + this._setNetworkClient(networkClient); } _setNetworkClient({ networkMiddleware, blockTracker }) { const metamaskMiddleware = createMetamaskMiddleware( this._baseProviderParams, - ) - const engine = new JsonRpcEngine() - engine.push(metamaskMiddleware) - engine.push(networkMiddleware) - const provider = providerFromEngine(engine) - this._setProviderAndBlockTracker({ provider, blockTracker }) + ); + const engine = new JsonRpcEngine(); + engine.push(metamaskMiddleware); + engine.push(networkMiddleware); + const provider = providerFromEngine(engine); + this._setProviderAndBlockTracker({ provider, blockTracker }); } _setProviderAndBlockTracker({ provider, blockTracker }) { // update or intialize proxies if (this._providerProxy) { - this._providerProxy.setTarget(provider) + this._providerProxy.setTarget(provider); } else { - this._providerProxy = createSwappableProxy(provider) + this._providerProxy = createSwappableProxy(provider); } if (this._blockTrackerProxy) { - this._blockTrackerProxy.setTarget(blockTracker) + this._blockTrackerProxy.setTarget(blockTracker); } else { this._blockTrackerProxy = createEventEmitterProxy(blockTracker, { eventFilter: 'skipInternal', - }) + }); } // set new provider and blockTracker - this._provider = provider - this._blockTracker = blockTracker + this._provider = provider; + this._blockTracker = blockTracker; } } diff --git a/app/scripts/controllers/network/util.js b/app/scripts/controllers/network/util.js index 9c80db5516..7f55f2521c 100644 --- a/app/scripts/controllers/network/util.js +++ b/app/scripts/controllers/network/util.js @@ -1,6 +1,6 @@ -import { NETWORK_TO_NAME_MAP } from '../../../../shared/constants/network' +import { NETWORK_TO_NAME_MAP } from '../../../../shared/constants/network'; -export const getNetworkDisplayName = (key) => NETWORK_TO_NAME_MAP[key] +export const getNetworkDisplayName = (key) => NETWORK_TO_NAME_MAP[key]; export function formatTxMetaForRpcResult(txMeta) { return { @@ -20,5 +20,5 @@ export function formatTxMetaForRpcResult(txMeta) { v: txMeta.v, r: txMeta.r, s: txMeta.s, - } + }; } diff --git a/app/scripts/controllers/onboarding.js b/app/scripts/controllers/onboarding.js index 011edbfc3a..5e55d0e0f2 100644 --- a/app/scripts/controllers/onboarding.js +++ b/app/scripts/controllers/onboarding.js @@ -1,5 +1,5 @@ -import { ObservableStore } from '@metamask/obs-store' -import log from 'loglevel' +import { ObservableStore } from '@metamask/obs-store'; +import log from 'loglevel'; /** * @typedef {Object} InitState @@ -25,30 +25,30 @@ export default class OnboardingController { constructor(opts = {}) { const initialTransientState = { onboardingTabs: {}, - } + }; const initState = { seedPhraseBackedUp: null, ...opts.initState, ...initialTransientState, - } - this.store = new ObservableStore(initState) - this.preferencesController = opts.preferencesController - this.completedOnboarding = this.preferencesController.store.getState().completedOnboarding + }; + this.store = new ObservableStore(initState); + this.preferencesController = opts.preferencesController; + this.completedOnboarding = this.preferencesController.store.getState().completedOnboarding; this.preferencesController.store.subscribe(({ completedOnboarding }) => { if (completedOnboarding !== this.completedOnboarding) { - this.completedOnboarding = completedOnboarding + this.completedOnboarding = completedOnboarding; if (completedOnboarding) { - this.store.updateState(initialTransientState) + this.store.updateState(initialTransientState); } } - }) + }); } setSeedPhraseBackedUp(newSeedPhraseBackUpState) { this.store.updateState({ seedPhraseBackedUp: newSeedPhraseBackUpState, - }) + }); } /** @@ -59,16 +59,16 @@ export default class OnboardingController { */ registerOnboarding = async (location, tabId) => { if (this.completedOnboarding) { - log.debug('Ignoring registerOnboarding; user already onboarded') - return + log.debug('Ignoring registerOnboarding; user already onboarded'); + return; } - const onboardingTabs = { ...this.store.getState().onboardingTabs } + const onboardingTabs = { ...this.store.getState().onboardingTabs }; if (!onboardingTabs[location] || onboardingTabs[location] !== tabId) { log.debug( `Registering onboarding tab at location '${location}' with tabId '${tabId}'`, - ) - onboardingTabs[location] = tabId - this.store.updateState({ onboardingTabs }) + ); + onboardingTabs[location] = tabId; + this.store.updateState({ onboardingTabs }); } - } + }; } diff --git a/app/scripts/controllers/permissions/enums.js b/app/scripts/controllers/permissions/enums.js index 21356804fe..447040bed6 100644 --- a/app/scripts/controllers/permissions/enums.js +++ b/app/scripts/controllers/permissions/enums.js @@ -1,37 +1,37 @@ -export const APPROVAL_TYPE = 'wallet_requestPermissions' +export const APPROVAL_TYPE = 'wallet_requestPermissions'; -export const WALLET_PREFIX = 'wallet_' +export const WALLET_PREFIX = 'wallet_'; -export const HISTORY_STORE_KEY = 'permissionsHistory' +export const HISTORY_STORE_KEY = 'permissionsHistory'; -export const LOG_STORE_KEY = 'permissionsLog' +export const LOG_STORE_KEY = 'permissionsLog'; -export const METADATA_STORE_KEY = 'domainMetadata' +export const METADATA_STORE_KEY = 'domainMetadata'; -export const METADATA_CACHE_MAX_SIZE = 100 +export const METADATA_CACHE_MAX_SIZE = 100; export const CAVEAT_TYPES = { limitResponseLength: 'limitResponseLength', filterResponse: 'filterResponse', -} +}; export const NOTIFICATION_NAMES = { accountsChanged: 'metamask_accountsChanged', unlockStateChanged: 'metamask_unlockStateChanged', chainChanged: 'metamask_chainChanged', -} +}; export const LOG_IGNORE_METHODS = [ 'wallet_registerOnboarding', 'wallet_watchAsset', -] +]; export const LOG_METHOD_TYPES = { restricted: 'restricted', internal: 'internal', -} +}; -export const LOG_LIMIT = 100 +export const LOG_LIMIT = 100; export const SAFE_METHODS = [ 'eth_blockNumber', @@ -90,4 +90,4 @@ export const SAFE_METHODS = [ 'wallet_watchAsset', 'web3_clientVersion', 'web3_sha3', -] +]; diff --git a/app/scripts/controllers/permissions/index.js b/app/scripts/controllers/permissions/index.js index 5d22a69c47..c10a950cbf 100644 --- a/app/scripts/controllers/permissions/index.js +++ b/app/scripts/controllers/permissions/index.js @@ -1,12 +1,12 @@ -import nanoid from 'nanoid' -import { JsonRpcEngine } from 'json-rpc-engine' -import { ObservableStore } from '@metamask/obs-store' -import log from 'loglevel' -import { CapabilitiesController as RpcCap } from 'rpc-cap' -import { ethErrors } from 'eth-rpc-errors' -import { cloneDeep } from 'lodash' - -import { CAVEAT_NAMES } from '../../../../shared/constants/permissions' +import nanoid from 'nanoid'; +import { JsonRpcEngine } from 'json-rpc-engine'; +import { ObservableStore } from '@metamask/obs-store'; +import log from 'loglevel'; +import { CapabilitiesController as RpcCap } from 'rpc-cap'; +import { ethErrors } from 'eth-rpc-errors'; +import { cloneDeep } from 'lodash'; + +import { CAVEAT_NAMES } from '../../../../shared/constants/permissions'; import { APPROVAL_TYPE, SAFE_METHODS, // methods that do not require any permissions to use @@ -17,13 +17,13 @@ import { HISTORY_STORE_KEY, NOTIFICATION_NAMES, CAVEAT_TYPES, -} from './enums' +} from './enums'; -import createPermissionsMethodMiddleware from './permissionsMethodMiddleware' -import PermissionsLogController from './permissionsLog' +import createPermissionsMethodMiddleware from './permissionsMethodMiddleware'; +import PermissionsLogController from './permissionsLog'; // instanbul ignore next -const noop = () => undefined +const noop = () => undefined; export class PermissionsController { constructor( @@ -44,56 +44,56 @@ export class PermissionsController { this.store = new ObservableStore({ [LOG_STORE_KEY]: restoredState[LOG_STORE_KEY] || [], [HISTORY_STORE_KEY]: restoredState[HISTORY_STORE_KEY] || {}, - }) + }); - this.getKeyringAccounts = getKeyringAccounts - this._getUnlockPromise = getUnlockPromise - this._notifyDomain = notifyDomain - this._notifyAllDomains = notifyAllDomains - this._isUnlocked = isUnlocked + this.getKeyringAccounts = getKeyringAccounts; + this._getUnlockPromise = getUnlockPromise; + this._notifyDomain = notifyDomain; + this._notifyAllDomains = notifyAllDomains; + this._isUnlocked = isUnlocked; this._restrictedMethods = getRestrictedMethods({ getKeyringAccounts: this.getKeyringAccounts.bind(this), getIdentities: this._getIdentities.bind(this), - }) + }); this.permissionsLog = new PermissionsLogController({ restrictedMethods: Object.keys(this._restrictedMethods), store: this.store, - }) + }); /** * @type {import('@metamask/controllers').ApprovalController} * @public */ - this.approvals = approvals - this._initializePermissions(restoredPermissions) - this._lastSelectedAddress = preferences.getState().selectedAddress - this.preferences = preferences + this.approvals = approvals; + this._initializePermissions(restoredPermissions); + this._lastSelectedAddress = preferences.getState().selectedAddress; + this.preferences = preferences; - this._initializeMetadataStore(restoredState) + this._initializeMetadataStore(restoredState); preferences.subscribe(async ({ selectedAddress }) => { if (selectedAddress && selectedAddress !== this._lastSelectedAddress) { - this._lastSelectedAddress = selectedAddress - await this._handleAccountSelected(selectedAddress) + this._lastSelectedAddress = selectedAddress; + await this._handleAccountSelected(selectedAddress); } - }) + }); } createMiddleware({ origin, extensionId }) { if (typeof origin !== 'string' || !origin.length) { - throw new Error('Must provide non-empty string origin.') + throw new Error('Must provide non-empty string origin.'); } - const metadataState = this.store.getState()[METADATA_STORE_KEY] + const metadataState = this.store.getState()[METADATA_STORE_KEY]; if (extensionId && metadataState[origin]?.extensionId !== extensionId) { - this.addDomainMetadata(origin, { extensionId }) + this.addDomainMetadata(origin, { extensionId }); } - const engine = new JsonRpcEngine() + const engine = new JsonRpcEngine(); - engine.push(this.permissionsLog.createMiddleware()) + engine.push(this.permissionsLog.createMiddleware()); engine.push( createPermissionsMethodMiddleware({ @@ -108,15 +108,15 @@ export class PermissionsController { { eth_accounts: {} }, ), }), - ) + ); engine.push( this.permissions.providerMiddlewareFunction.bind(this.permissions, { origin, }), - ) + ); - return engine.asMiddleware() + return engine.asMiddleware(); } /** @@ -125,9 +125,9 @@ export class PermissionsController { * @returns {Promise} The permissions request ID */ async requestAccountsPermissionWithId(origin) { - const id = nanoid() - this._requestPermissions({ origin }, { eth_accounts: {} }, id) - return id + const id = nanoid(); + this._requestPermissions({ origin }, { eth_accounts: {} }, id); + return id; } /** @@ -139,24 +139,24 @@ export class PermissionsController { */ getAccounts(origin) { return new Promise((resolve, _) => { - const req = { method: 'eth_accounts' } - const res = {} + const req = { method: 'eth_accounts' }; + const res = {}; this.permissions.providerMiddlewareFunction( { origin }, req, res, noop, _end, - ) + ); function _end() { if (res.error || !Array.isArray(res.result)) { - resolve([]) + resolve([]); } else { - resolve(res.result) + resolve(res.result); } } - }) + }); } /** @@ -167,7 +167,7 @@ export class PermissionsController { * @returns {boolean} Whether the origin has the permission. */ hasPermission(origin, permission) { - return Boolean(this.permissions.getPermission(origin, permission)) + return Boolean(this.permissions.getPermission(origin, permission)); } /** @@ -176,7 +176,7 @@ export class PermissionsController { * @returns {Object} identities */ _getIdentities() { - return this.preferences.getState().identities + return this.preferences.getState().identities; } /** @@ -196,20 +196,20 @@ export class PermissionsController { id, method: 'wallet_requestPermissions', params: [permissions], - } - const res = {} + }; + const res = {}; - this.permissions.providerMiddlewareFunction(domain, req, res, noop, _end) + this.permissions.providerMiddlewareFunction(domain, req, res, noop, _end); function _end(_err) { - const err = _err || res.error + const err = _err || res.error; if (err) { - reject(err) + reject(err); } else { - resolve(res.result) + resolve(res.result); } } - }) + }); } /** @@ -222,11 +222,11 @@ export class PermissionsController { * @param {Array} accounts - The accounts to expose, if any */ async approvePermissionsRequest(approved, accounts) { - const { id } = approved.metadata + const { id } = approved.metadata; if (!this.approvals.has({ id })) { - log.debug(`Permissions request with id '${id}' not found.`) - return + log.debug(`Permissions request with id '${id}' not found.`); + return; } try { @@ -236,15 +236,15 @@ export class PermissionsController { ethErrors.rpc.invalidRequest({ message: 'Must request at least one permission.', }), - ) + ); } else { // attempt to finalize the request and resolve it, // settings caveats as necessary approved.permissions = await this.finalizePermissionsRequest( approved.permissions, accounts, - ) - this.approvals.resolve(id, approved.permissions) + ); + this.approvals.resolve(id, approved.permissions); } } catch (err) { // if finalization fails, reject the request @@ -254,7 +254,7 @@ export class PermissionsController { message: err.message, data: err, }), - ) + ); } } @@ -267,11 +267,11 @@ export class PermissionsController { */ async rejectPermissionsRequest(id) { if (!this.approvals.has({ id })) { - log.debug(`Permissions request with id '${id}' not found.`) - return + log.debug(`Permissions request with id '${id}' not found.`); + return; } - this.approvals.reject(id, ethErrors.provider.userRejectedRequest()) + this.approvals.reject(id, ethErrors.provider.userRejectedRequest()); } /** @@ -284,18 +284,18 @@ export class PermissionsController { * @param {string} account - The new account to expose. */ async addPermittedAccount(origin, account) { - const domains = this.permissions.getDomains() + const domains = this.permissions.getDomains(); if (!domains[origin]) { - throw new Error('Unrecognized domain') + throw new Error('Unrecognized domain'); } - this.validatePermittedAccounts([account]) + this.validatePermittedAccounts([account]); - const oldPermittedAccounts = this._getPermittedAccounts(origin) + const oldPermittedAccounts = this._getPermittedAccounts(origin); if (!oldPermittedAccounts) { - throw new Error(`Origin does not have 'eth_accounts' permission`) + throw new Error(`Origin does not have 'eth_accounts' permission`); } else if (oldPermittedAccounts.includes(account)) { - throw new Error('Account is already permitted for origin') + throw new Error('Account is already permitted for origin'); } this.permissions.updateCaveatFor( @@ -303,11 +303,11 @@ export class PermissionsController { 'eth_accounts', CAVEAT_NAMES.exposedAccounts, [...oldPermittedAccounts, account], - ) + ); - const permittedAccounts = await this.getAccounts(origin) + const permittedAccounts = await this.getAccounts(origin); - this.notifyAccountsChanged(origin, permittedAccounts) + this.notifyAccountsChanged(origin, permittedAccounts); } /** @@ -322,38 +322,38 @@ export class PermissionsController { * @param {string} account - The account to remove. */ async removePermittedAccount(origin, account) { - const domains = this.permissions.getDomains() + const domains = this.permissions.getDomains(); if (!domains[origin]) { - throw new Error('Unrecognized domain') + throw new Error('Unrecognized domain'); } - this.validatePermittedAccounts([account]) + this.validatePermittedAccounts([account]); - const oldPermittedAccounts = this._getPermittedAccounts(origin) + const oldPermittedAccounts = this._getPermittedAccounts(origin); if (!oldPermittedAccounts) { - throw new Error(`Origin does not have 'eth_accounts' permission`) + throw new Error(`Origin does not have 'eth_accounts' permission`); } else if (!oldPermittedAccounts.includes(account)) { - throw new Error('Account is not permitted for origin') + throw new Error('Account is not permitted for origin'); } let newPermittedAccounts = oldPermittedAccounts.filter( (acc) => acc !== account, - ) + ); if (newPermittedAccounts.length === 0) { - this.removePermissionsFor({ [origin]: ['eth_accounts'] }) + this.removePermissionsFor({ [origin]: ['eth_accounts'] }); } else { this.permissions.updateCaveatFor( origin, 'eth_accounts', CAVEAT_NAMES.exposedAccounts, newPermittedAccounts, - ) + ); - newPermittedAccounts = await this.getAccounts(origin) + newPermittedAccounts = await this.getAccounts(origin); } - this.notifyAccountsChanged(origin, newPermittedAccounts) + this.notifyAccountsChanged(origin, newPermittedAccounts); } /** @@ -365,18 +365,18 @@ export class PermissionsController { * @param {string} account - The account to remove. */ async removeAllAccountPermissions(account) { - this.validatePermittedAccounts([account]) + this.validatePermittedAccounts([account]); - const domains = this.permissions.getDomains() + const domains = this.permissions.getDomains(); const connectedOrigins = Object.keys(domains).filter((origin) => this._getPermittedAccounts(origin).includes(account), - ) + ); await Promise.all( connectedOrigins.map((origin) => this.removePermittedAccount(origin, account), ), - ) + ); } /** @@ -390,16 +390,16 @@ export class PermissionsController { * @returns {Object} The finalized permissions request object. */ async finalizePermissionsRequest(requestedPermissions, requestedAccounts) { - const finalizedPermissions = cloneDeep(requestedPermissions) - const finalizedAccounts = cloneDeep(requestedAccounts) + const finalizedPermissions = cloneDeep(requestedPermissions); + const finalizedAccounts = cloneDeep(requestedAccounts); - const { eth_accounts: ethAccounts } = finalizedPermissions + const { eth_accounts: ethAccounts } = finalizedPermissions; if (ethAccounts) { - this.validatePermittedAccounts(finalizedAccounts) + this.validatePermittedAccounts(finalizedAccounts); if (!ethAccounts.caveats) { - ethAccounts.caveats = [] + ethAccounts.caveats = []; } // caveat names are unique, and we will only construct this caveat here @@ -407,22 +407,22 @@ export class PermissionsController { (c) => c.name !== CAVEAT_NAMES.exposedAccounts && c.name !== CAVEAT_NAMES.primaryAccountOnly, - ) + ); ethAccounts.caveats.push({ type: CAVEAT_TYPES.limitResponseLength, value: 1, name: CAVEAT_NAMES.primaryAccountOnly, - }) + }); ethAccounts.caveats.push({ type: CAVEAT_TYPES.filterResponse, value: finalizedAccounts, name: CAVEAT_NAMES.exposedAccounts, - }) + }); } - return finalizedPermissions + return finalizedPermissions; } /** @@ -433,16 +433,16 @@ export class PermissionsController { */ validatePermittedAccounts(accounts) { if (!Array.isArray(accounts) || accounts.length === 0) { - throw new Error('Must provide non-empty array of account(s).') + throw new Error('Must provide non-empty array of account(s).'); } // assert accounts exist - const allIdentities = this._getIdentities() + const allIdentities = this._getIdentities(); accounts.forEach((acc) => { if (!allIdentities[acc]) { - throw new Error(`Unknown account: ${acc}`) + throw new Error(`Unknown account: ${acc}`); } - }) + }); } /** @@ -454,11 +454,11 @@ export class PermissionsController { */ notifyAccountsChanged(origin, newAccounts) { if (typeof origin !== 'string' || !origin) { - throw new Error(`Invalid origin: '${origin}'`) + throw new Error(`Invalid origin: '${origin}'`); } if (!Array.isArray(newAccounts)) { - throw new Error('Invalid accounts', newAccounts) + throw new Error('Invalid accounts', newAccounts); } // We do not share accounts when the extension is locked. @@ -466,8 +466,8 @@ export class PermissionsController { this._notifyDomain(origin, { method: NOTIFICATION_NAMES.accountsChanged, params: newAccounts, - }) - this.permissionsLog.updateAccountsHistory(origin, newAccounts) + }); + this.permissionsLog.updateAccountsHistory(origin, newAccounts); } // NOTE: @@ -491,26 +491,26 @@ export class PermissionsController { origin, perms.map((methodName) => { if (methodName === 'eth_accounts') { - this.notifyAccountsChanged(origin, []) + this.notifyAccountsChanged(origin, []); } - return { parentCapability: methodName } + return { parentCapability: methodName }; }), - ) - }) + ); + }); } /** * Removes all known domains and their related permissions. */ clearPermissions() { - this.permissions.clearDomains() + this.permissions.clearDomains(); // It's safe to notify that no accounts are available, regardless of // extension lock state this._notifyAllDomains({ method: NOTIFICATION_NAMES.accountsChanged, params: [], - }) + }); } /** @@ -524,18 +524,18 @@ export class PermissionsController { * @param {Object} metadata - The domain's metadata that will be stored. */ addDomainMetadata(origin, metadata) { - const oldMetadataState = this.store.getState()[METADATA_STORE_KEY] - const newMetadataState = { ...oldMetadataState } + const oldMetadataState = this.store.getState()[METADATA_STORE_KEY]; + const newMetadataState = { ...oldMetadataState }; // delete pending metadata origin from queue, and delete its metadata if // it doesn't have any permissions if (this._pendingSiteMetadata.size >= METADATA_CACHE_MAX_SIZE) { - const permissionsDomains = this.permissions.getDomains() + const permissionsDomains = this.permissions.getDomains(); - const oldOrigin = this._pendingSiteMetadata.values().next().value - this._pendingSiteMetadata.delete(oldOrigin) + const oldOrigin = this._pendingSiteMetadata.values().next().value; + this._pendingSiteMetadata.delete(oldOrigin); if (!permissionsDomains[oldOrigin]) { - delete newMetadataState[oldOrigin] + delete newMetadataState[oldOrigin]; } } @@ -544,17 +544,17 @@ export class PermissionsController { ...oldMetadataState[origin], ...metadata, lastUpdated: Date.now(), - } + }; if ( !newMetadataState[origin].extensionId && !newMetadataState[origin].host ) { - newMetadataState[origin].host = new URL(origin).host + newMetadataState[origin].host = new URL(origin).host; } - this._pendingSiteMetadata.add(origin) - this._setDomainMetadata(newMetadataState) + this._pendingSiteMetadata.add(origin); + this._setDomainMetadata(newMetadataState); } /** @@ -566,11 +566,11 @@ export class PermissionsController { * @param {Object} restoredState - The restored permissions controller state. */ _initializeMetadataStore(restoredState) { - const metadataState = restoredState[METADATA_STORE_KEY] || {} - const newMetadataState = this._trimDomainMetadata(metadataState) + const metadataState = restoredState[METADATA_STORE_KEY] || {}; + const newMetadataState = this._trimDomainMetadata(metadataState); - this._pendingSiteMetadata = new Set() - this._setDomainMetadata(newMetadataState) + this._pendingSiteMetadata = new Set(); + this._setDomainMetadata(newMetadataState); } /** @@ -582,17 +582,17 @@ export class PermissionsController { * @returns {Object} The new metadata state object. */ _trimDomainMetadata(metadataState) { - const newMetadataState = { ...metadataState } - const origins = Object.keys(metadataState) - const permissionsDomains = this.permissions.getDomains() + const newMetadataState = { ...metadataState }; + const origins = Object.keys(metadataState); + const permissionsDomains = this.permissions.getDomains(); origins.forEach((origin) => { if (!permissionsDomains[origin]) { - delete newMetadataState[origin] + delete newMetadataState[origin]; } - }) + }); - return newMetadataState + return newMetadataState; } /** @@ -600,7 +600,7 @@ export class PermissionsController { * @param {Object} newMetadataState - The new metadata to set. */ _setDomainMetadata(newMetadataState) { - this.store.updateState({ [METADATA_STORE_KEY]: newMetadataState }) + this.store.updateState({ [METADATA_STORE_KEY]: newMetadataState }); } /** @@ -613,9 +613,9 @@ export class PermissionsController { const permittedAccounts = this.permissions .getPermission(origin, 'eth_accounts') ?.caveats?.find((caveat) => caveat.name === CAVEAT_NAMES.exposedAccounts) - ?.value + ?.value; - return permittedAccounts || null + return permittedAccounts || null; } /** @@ -629,27 +629,27 @@ export class PermissionsController { */ async _handleAccountSelected(account) { if (typeof account !== 'string') { - throw new Error('Selected account should be a non-empty string.') + throw new Error('Selected account should be a non-empty string.'); } - const domains = this.permissions.getDomains() || {} + const domains = this.permissions.getDomains() || {}; const connectedDomains = Object.entries(domains) .filter(([_, { permissions }]) => { const ethAccounts = permissions.find( (permission) => permission.parentCapability === 'eth_accounts', - ) + ); const exposedAccounts = ethAccounts?.caveats.find( (caveat) => caveat.name === 'exposedAccounts', - )?.value - return exposedAccounts?.includes(account) + )?.value; + return exposedAccounts?.includes(account); }) - .map(([domain]) => domain) + .map(([domain]) => domain); await Promise.all( connectedDomains.map((origin) => this._handleConnectedAccountSelected(origin), ), - ) + ); } /** @@ -661,9 +661,9 @@ export class PermissionsController { * @param {string} origin - The origin */ async _handleConnectedAccountSelected(origin) { - const permittedAccounts = await this.getAccounts(origin) + const permittedAccounts = await this.getAccounts(origin); - this.notifyAccountsChanged(origin, permittedAccounts) + this.notifyAccountsChanged(origin, permittedAccounts); } /** @@ -674,7 +674,7 @@ export class PermissionsController { */ _initializePermissions(restoredState) { // these permission requests are almost certainly stale - const initState = { ...restoredState, permissionsRequests: [] } + const initState = { ...restoredState, permissionsRequests: [] }; this.permissions = new RpcCap( { @@ -698,16 +698,16 @@ export class PermissionsController { requestUserApproval: async (req) => { const { metadata: { id, origin }, - } = req + } = req; return this.approvals.addAndShowApprovalRequest({ id, origin, type: APPROVAL_TYPE, - }) + }); }, }, initState, - ) + ); } } diff --git a/app/scripts/controllers/permissions/permissionsLog.js b/app/scripts/controllers/permissions/permissionsLog.js index 28c87af6b1..d0ab55d23c 100644 --- a/app/scripts/controllers/permissions/permissionsLog.js +++ b/app/scripts/controllers/permissions/permissionsLog.js @@ -1,5 +1,5 @@ -import { cloneDeep } from 'lodash' -import { CAVEAT_NAMES } from '../../../../shared/constants/permissions' +import { cloneDeep } from 'lodash'; +import { CAVEAT_NAMES } from '../../../../shared/constants/permissions'; import { HISTORY_STORE_KEY, LOG_IGNORE_METHODS, @@ -7,7 +7,7 @@ import { LOG_METHOD_TYPES, LOG_STORE_KEY, WALLET_PREFIX, -} from './enums' +} from './enums'; /** * Controller with middleware for logging requests and responses to restricted @@ -15,8 +15,8 @@ import { */ export default class PermissionsLogController { constructor({ restrictedMethods, store }) { - this.restrictedMethods = restrictedMethods - this.store = store + this.restrictedMethods = restrictedMethods; + this.store = store; } /** @@ -25,7 +25,7 @@ export default class PermissionsLogController { * @returns {Array} The activity log. */ getActivityLog() { - return this.store.getState()[LOG_STORE_KEY] || [] + return this.store.getState()[LOG_STORE_KEY] || []; } /** @@ -34,7 +34,7 @@ export default class PermissionsLogController { * @param {Array} logs - The new activity log array. */ updateActivityLog(logs) { - this.store.updateState({ [LOG_STORE_KEY]: logs }) + this.store.updateState({ [LOG_STORE_KEY]: logs }); } /** @@ -43,7 +43,7 @@ export default class PermissionsLogController { * @returns {Object} The permissions history log. */ getHistory() { - return this.store.getState()[HISTORY_STORE_KEY] || {} + return this.store.getState()[HISTORY_STORE_KEY] || {}; } /** @@ -52,7 +52,7 @@ export default class PermissionsLogController { * @param {Object} history - The new permissions history log object. */ updateHistory(history) { - this.store.updateState({ [HISTORY_STORE_KEY]: history }) + this.store.updateState({ [HISTORY_STORE_KEY]: history }); } /** @@ -65,16 +65,16 @@ export default class PermissionsLogController { */ updateAccountsHistory(origin, accounts) { if (accounts.length === 0) { - return + return; } - const accountToTimeMap = getAccountToTimeMap(accounts, Date.now()) + const accountToTimeMap = getAccountToTimeMap(accounts, Date.now()); this.commitNewHistory(origin, { eth_accounts: { accounts: accountToTimeMap, }, - }) + }); } /** @@ -89,37 +89,37 @@ export default class PermissionsLogController { */ createMiddleware() { return (req, res, next, _end) => { - let activityEntry, requestedMethods - const { origin, method } = req - const isInternal = method.startsWith(WALLET_PREFIX) + let activityEntry, requestedMethods; + const { origin, method } = req; + const isInternal = method.startsWith(WALLET_PREFIX); // we only log certain methods if ( !LOG_IGNORE_METHODS.includes(method) && (isInternal || this.restrictedMethods.includes(method)) ) { - activityEntry = this.logRequest(req, isInternal) + activityEntry = this.logRequest(req, isInternal); if (method === `${WALLET_PREFIX}requestPermissions`) { // get the corresponding methods from the requested permissions so // that we can record permissions history - requestedMethods = this.getRequestedMethods(req) + requestedMethods = this.getRequestedMethods(req); } } else if (method === 'eth_requestAccounts') { // eth_requestAccounts is a special case; we need to extract the accounts // from it - activityEntry = this.logRequest(req, isInternal) - requestedMethods = ['eth_accounts'] + activityEntry = this.logRequest(req, isInternal); + requestedMethods = ['eth_accounts']; } else { // no-op - next() - return + next(); + return; } // call next with a return handler for capturing the response next((cb) => { - const time = Date.now() - this.logResponse(activityEntry, res, time) + const time = Date.now(); + this.logResponse(activityEntry, res, time); if (requestedMethods && !res.error && res.result) { // any permissions or accounts changes will be recorded on the response, @@ -130,11 +130,11 @@ export default class PermissionsLogController { res.result, time, method === 'eth_requestAccounts', - ) + ); } - cb() - }) - } + cb(); + }); + }; } /** @@ -156,9 +156,9 @@ export default class PermissionsLogController { response: null, responseTime: null, success: null, - } - this.commitNewActivity(activityEntry) - return activityEntry + }; + this.commitNewActivity(activityEntry); + return activityEntry; } /** @@ -171,12 +171,12 @@ export default class PermissionsLogController { */ logResponse(entry, response, time) { if (!entry || !response) { - return + return; } - entry.response = cloneDeep(response) - entry.responseTime = time - entry.success = !response.error + entry.response = cloneDeep(response); + entry.responseTime = time; + entry.success = !response.error; } /** @@ -186,17 +186,17 @@ export default class PermissionsLogController { * @param {Object} entry - The activity log entry. */ commitNewActivity(entry) { - const logs = this.getActivityLog() + const logs = this.getActivityLog(); // add new entry to end of log - logs.push(entry) + logs.push(entry); // remove oldest log if exceeding size limit if (logs.length > LOG_LIMIT) { - logs.shift() + logs.shift(); } - this.updateActivityLog(logs) + this.updateActivityLog(logs); } /** @@ -215,18 +215,18 @@ export default class PermissionsLogController { time, isEthRequestAccounts, ) { - let accounts, newEntries + let accounts, newEntries; if (isEthRequestAccounts) { - accounts = result - const accountToTimeMap = getAccountToTimeMap(accounts, time) + accounts = result; + const accountToTimeMap = getAccountToTimeMap(accounts, time); newEntries = { eth_accounts: { accounts: accountToTimeMap, lastApproved: time, }, - } + }; } else { // Records new "lastApproved" times for the granted permissions, if any. // Special handling for eth_accounts, in order to record the time the @@ -234,33 +234,33 @@ export default class PermissionsLogController { newEntries = result .map((perm) => { if (perm.parentCapability === 'eth_accounts') { - accounts = this.getAccountsFromPermission(perm) + accounts = this.getAccountsFromPermission(perm); } - return perm.parentCapability + return perm.parentCapability; }) .reduce((acc, method) => { // all approved permissions will be included in the response, // not just the newly requested ones if (requestedMethods.includes(method)) { if (method === 'eth_accounts') { - const accountToTimeMap = getAccountToTimeMap(accounts, time) + const accountToTimeMap = getAccountToTimeMap(accounts, time); acc[method] = { lastApproved: time, accounts: accountToTimeMap, - } + }; } else { - acc[method] = { lastApproved: time } + acc[method] = { lastApproved: time }; } } - return acc - }, {}) + return acc; + }, {}); } if (Object.keys(newEntries).length > 0) { - this.commitNewHistory(origin, newEntries) + this.commitNewHistory(origin, newEntries); } } @@ -274,24 +274,24 @@ export default class PermissionsLogController { */ commitNewHistory(origin, newEntries) { // a simple merge updates most permissions - const history = this.getHistory() + const history = this.getHistory(); const newOriginHistory = { ...history[origin], ...newEntries, - } + }; // eth_accounts requires special handling, because of information // we store about the accounts const existingEthAccountsEntry = - history[origin] && history[origin].eth_accounts - const newEthAccountsEntry = newEntries.eth_accounts + history[origin] && history[origin].eth_accounts; + const newEthAccountsEntry = newEntries.eth_accounts; if (existingEthAccountsEntry && newEthAccountsEntry) { // we may intend to update just the accounts, not the permission // itself const lastApproved = newEthAccountsEntry.lastApproved || - existingEthAccountsEntry.lastApproved + existingEthAccountsEntry.lastApproved; // merge old and new eth_accounts history entries newOriginHistory.eth_accounts = { @@ -300,12 +300,12 @@ export default class PermissionsLogController { ...existingEthAccountsEntry.accounts, ...newEthAccountsEntry.accounts, }, - } + }; } - history[origin] = newOriginHistory + history[origin] = newOriginHistory; - this.updateHistory(history) + this.updateHistory(history); } /** @@ -321,9 +321,9 @@ export default class PermissionsLogController { typeof request.params[0] !== 'object' || Array.isArray(request.params[0]) ) { - return null + return null; } - return Object.keys(request.params[0]) + return Object.keys(request.params[0]); } /** @@ -335,21 +335,21 @@ export default class PermissionsLogController { */ getAccountsFromPermission(perm) { if (perm.parentCapability !== 'eth_accounts' || !perm.caveats) { - return [] + return []; } - const accounts = new Set() + const accounts = new Set(); for (const caveat of perm.caveats) { if ( caveat.name === CAVEAT_NAMES.exposedAccounts && Array.isArray(caveat.value) ) { for (const value of caveat.value) { - accounts.add(value) + accounts.add(value); } } } - return [...accounts] + return [...accounts]; } } @@ -363,5 +363,5 @@ export default class PermissionsLogController { * @returns {Object} A string:number map of addresses to time. */ function getAccountToTimeMap(accounts, time) { - return accounts.reduce((acc, account) => ({ ...acc, [account]: time }), {}) + return accounts.reduce((acc, account) => ({ ...acc, [account]: time }), {}); } diff --git a/app/scripts/controllers/permissions/permissionsMethodMiddleware.js b/app/scripts/controllers/permissions/permissionsMethodMiddleware.js index a4bac3976c..10e5e1fa07 100644 --- a/app/scripts/controllers/permissions/permissionsMethodMiddleware.js +++ b/app/scripts/controllers/permissions/permissionsMethodMiddleware.js @@ -1,5 +1,5 @@ -import { createAsyncMiddleware } from 'json-rpc-engine' -import { ethErrors } from 'eth-rpc-errors' +import { createAsyncMiddleware } from 'json-rpc-engine'; +import { ethErrors } from 'eth-rpc-errors'; /** * Create middleware for handling certain methods and preprocessing permissions requests. @@ -12,73 +12,73 @@ export default function createPermissionsMethodMiddleware({ notifyAccountsChanged, requestAccountsPermission, }) { - let isProcessingRequestAccounts = false + let isProcessingRequestAccounts = false; return createAsyncMiddleware(async (req, res, next) => { - let responseHandler + let responseHandler; switch (req.method) { // Intercepting eth_accounts requests for backwards compatibility: // The getAccounts call below wraps the rpc-cap middleware, and returns // an empty array in case of errors (such as 4100:unauthorized) case 'eth_accounts': { - res.result = await getAccounts() - return + res.result = await getAccounts(); + return; } case 'eth_requestAccounts': { if (isProcessingRequestAccounts) { res.error = ethErrors.rpc.resourceUnavailable( 'Already processing eth_requestAccounts. Please wait.', - ) - return + ); + return; } if (hasPermission('eth_accounts')) { - isProcessingRequestAccounts = true - await getUnlockPromise() - isProcessingRequestAccounts = false + isProcessingRequestAccounts = true; + await getUnlockPromise(); + isProcessingRequestAccounts = false; } // first, just try to get accounts - let accounts = await getAccounts() + let accounts = await getAccounts(); if (accounts.length > 0) { - res.result = accounts - return + res.result = accounts; + return; } // if no accounts, request the accounts permission try { - await requestAccountsPermission() + await requestAccountsPermission(); } catch (err) { - res.error = err - return + res.error = err; + return; } // get the accounts again - accounts = await getAccounts() + accounts = await getAccounts(); /* istanbul ignore else: too hard to induce, see below comment */ if (accounts.length > 0) { - res.result = accounts + res.result = accounts; } else { // this should never happen, because it should be caught in the // above catch clause res.error = ethErrors.rpc.internal( 'Accounts unexpectedly unavailable. Please report this bug.', - ) + ); } - return + return; } // custom method for getting metadata from the requesting domain, // sent automatically by the inpage provider when it's initialized case 'metamask_sendDomainMetadata': { if (typeof req.params?.name === 'string') { - addDomainMetadata(req.origin, req.params) + addDomainMetadata(req.origin, req.params); } - res.result = true - return + res.result = true; + return; } // register return handler to send accountsChanged notification @@ -88,25 +88,25 @@ export default function createPermissionsMethodMiddleware({ if (Array.isArray(res.result)) { for (const permission of res.result) { if (permission.parentCapability === 'eth_accounts') { - notifyAccountsChanged(await getAccounts()) + notifyAccountsChanged(await getAccounts()); } } } - } + }; } - break + break; } default: - break + break; } // when this promise resolves, the response is on its way back // eslint-disable-next-line node/callback-return - await next() + await next(); if (responseHandler) { - responseHandler() + responseHandler(); } - }) + }); } diff --git a/app/scripts/controllers/permissions/restrictedMethods.js b/app/scripts/controllers/permissions/restrictedMethods.js index b8dd39c711..05e42cabc6 100644 --- a/app/scripts/controllers/permissions/restrictedMethods.js +++ b/app/scripts/controllers/permissions/restrictedMethods.js @@ -6,35 +6,35 @@ export default function getRestrictedMethods({ eth_accounts: { method: async (_, res, __, end) => { try { - const accounts = await getKeyringAccounts() - const identities = getIdentities() + const accounts = await getKeyringAccounts(); + const identities = getIdentities(); res.result = accounts.sort((firstAddress, secondAddress) => { if (!identities[firstAddress]) { - throw new Error(`Missing identity for address ${firstAddress}`) + throw new Error(`Missing identity for address ${firstAddress}`); } else if (!identities[secondAddress]) { - throw new Error(`Missing identity for address ${secondAddress}`) + throw new Error(`Missing identity for address ${secondAddress}`); } else if ( identities[firstAddress].lastSelected === identities[secondAddress].lastSelected ) { - return 0 + return 0; } else if (identities[firstAddress].lastSelected === undefined) { - return 1 + return 1; } else if (identities[secondAddress].lastSelected === undefined) { - return -1 + return -1; } return ( identities[secondAddress].lastSelected - identities[firstAddress].lastSelected - ) - }) - end() + ); + }); + end(); } catch (err) { - res.error = err - end(err) + res.error = err; + end(err); } }, }, - } + }; } diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 605400c4c9..fc02a317f0 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -1,13 +1,13 @@ -import { strict as assert } from 'assert' -import { ObservableStore } from '@metamask/obs-store' -import { ethErrors } from 'eth-rpc-errors' -import { normalize as normalizeAddress } from 'eth-sig-util' -import { isValidAddress } from 'ethereumjs-util' -import ethers from 'ethers' -import log from 'loglevel' -import { LISTED_CONTRACT_ADDRESSES } from '../../../shared/constants/tokens' -import { NETWORK_TYPE_TO_ID_MAP } from '../../../shared/constants/network' -import { isPrefixedFormattedHexString } from '../../../shared/modules/utils' +import { strict as assert } from 'assert'; +import { ObservableStore } from '@metamask/obs-store'; +import { ethErrors } from 'eth-rpc-errors'; +import { normalize as normalizeAddress } from 'eth-sig-util'; +import { isValidAddress } from 'ethereumjs-util'; +import ethers from 'ethers'; +import log from 'loglevel'; +import { LISTED_CONTRACT_ADDRESSES } from '../../../shared/constants/tokens'; +import { NETWORK_TYPE_TO_ID_MAP } from '../../../shared/constants/network'; +import { isPrefixedFormattedHexString } from '../../../shared/modules/utils'; export default class PreferencesController { /** @@ -65,18 +65,18 @@ export default class PreferencesController { // ENS decentralized website resolution ipfsGateway: 'dweb.link', ...opts.initState, - } + }; - this.network = opts.network - this.store = new ObservableStore(initState) - this.store.setMaxListeners(12) - this.openPopup = opts.openPopup - this.migrateAddressBookState = opts.migrateAddressBookState - this._subscribeProviderType() + this.network = opts.network; + this.store = new ObservableStore(initState); + this.store.setMaxListeners(12); + this.openPopup = opts.openPopup; + this.migrateAddressBookState = opts.migrateAddressBookState; + this._subscribeProviderType(); global.setPreference = (key, value) => { - return this.setFeatureFlag(key, value) - } + return this.setFeatureFlag(key, value); + }; } // PUBLIC METHODS @@ -85,7 +85,7 @@ export default class PreferencesController { * @param {boolean} forgottenPassword - whether or not the user has forgotten their password */ setPasswordForgotten(forgottenPassword) { - this.store.updateState({ forgottenPassword }) + this.store.updateState({ forgottenPassword }); } /** @@ -95,7 +95,7 @@ export default class PreferencesController { * */ setUseBlockie(val) { - this.store.updateState({ useBlockie: val }) + this.store.updateState({ useBlockie: val }); } /** @@ -105,7 +105,7 @@ export default class PreferencesController { * */ setUseNonceField(val) { - this.store.updateState({ useNonceField: val }) + this.store.updateState({ useNonceField: val }); } /** @@ -115,7 +115,7 @@ export default class PreferencesController { * */ setUsePhishDetect(val) { - this.store.updateState({ usePhishDetect: val }) + this.store.updateState({ usePhishDetect: val }); } /** @@ -125,15 +125,15 @@ export default class PreferencesController { * */ setFirstTimeFlowType(type) { - this.store.updateState({ firstTimeFlowType: type }) + this.store.updateState({ firstTimeFlowType: type }); } getSuggestedTokens() { - return this.store.getState().suggestedTokens + return this.store.getState().suggestedTokens; } getAssetImages() { - return this.store.getState().assetImages + return this.store.getState().assetImages; } /** @@ -143,9 +143,9 @@ export default class PreferencesController { * @param {string} methodData - Corresponding data method */ addKnownMethodData(fourBytePrefix, methodData) { - const { knownMethodData } = this.store.getState() - knownMethodData[fourBytePrefix] = methodData - this.store.updateState({ knownMethodData }) + const { knownMethodData } = this.store.getState(); + knownMethodData[fourBytePrefix] = methodData; + this.store.updateState({ knownMethodData }); } /** @@ -154,15 +154,15 @@ export default class PreferencesController { * @param {Object} req - The watchAsset JSON-RPC request object. */ async requestWatchAsset(req) { - const { type, options } = req.params + const { type, options } = req.params; switch (type) { case 'ERC20': - return await this._handleWatchAssetERC20(options) + return await this._handleWatchAssetERC20(options); default: throw ethErrors.rpc.invalidParams( `Asset of type "${type}" not supported.`, - ) + ); } } @@ -175,12 +175,12 @@ export default class PreferencesController { setCurrentLocale(key) { const textDirection = ['ar', 'dv', 'fa', 'he', 'ku'].includes(key) ? 'rtl' - : 'auto' + : 'auto'; this.store.updateState({ currentLocale: key, textDirection, - }) - return textDirection + }); + return textDirection; } /** @@ -191,26 +191,26 @@ export default class PreferencesController { * */ setAddresses(addresses) { - const oldIdentities = this.store.getState().identities - const oldAccountTokens = this.store.getState().accountTokens - const oldAccountHiddenTokens = this.store.getState().accountHiddenTokens + const oldIdentities = this.store.getState().identities; + const oldAccountTokens = this.store.getState().accountTokens; + const oldAccountHiddenTokens = this.store.getState().accountHiddenTokens; const identities = addresses.reduce((ids, address, index) => { - const oldId = oldIdentities[address] || {} - ids[address] = { name: `Account ${index + 1}`, address, ...oldId } - return ids - }, {}) + const oldId = oldIdentities[address] || {}; + ids[address] = { name: `Account ${index + 1}`, address, ...oldId }; + return ids; + }, {}); const accountTokens = addresses.reduce((tokens, address) => { - const oldTokens = oldAccountTokens[address] || {} - tokens[address] = oldTokens - return tokens - }, {}) + const oldTokens = oldAccountTokens[address] || {}; + tokens[address] = oldTokens; + return tokens; + }, {}); const accountHiddenTokens = addresses.reduce((hiddenTokens, address) => { - const oldHiddenTokens = oldAccountHiddenTokens[address] || {} - hiddenTokens[address] = oldHiddenTokens - return hiddenTokens - }, {}) - this.store.updateState({ identities, accountTokens, accountHiddenTokens }) + const oldHiddenTokens = oldAccountHiddenTokens[address] || {}; + hiddenTokens[address] = oldHiddenTokens; + return hiddenTokens; + }, {}); + this.store.updateState({ identities, accountTokens, accountHiddenTokens }); } /** @@ -224,23 +224,23 @@ export default class PreferencesController { identities, accountTokens, accountHiddenTokens, - } = this.store.getState() + } = this.store.getState(); if (!identities[address]) { - throw new Error(`${address} can't be deleted cause it was not found`) + throw new Error(`${address} can't be deleted cause it was not found`); } - delete identities[address] - delete accountTokens[address] - delete accountHiddenTokens[address] - this.store.updateState({ identities, accountTokens, accountHiddenTokens }) + delete identities[address]; + delete accountTokens[address]; + delete accountHiddenTokens[address]; + this.store.updateState({ identities, accountTokens, accountHiddenTokens }); // If the selected account is no longer valid, // select an arbitrary other account: if (address === this.getSelectedAddress()) { - const selected = Object.keys(identities)[0] - this.setSelectedAddress(selected) + const selected = Object.keys(identities)[0]; + this.setSelectedAddress(selected); } - return address + return address; } /** @@ -254,20 +254,20 @@ export default class PreferencesController { identities, accountTokens, accountHiddenTokens, - } = this.store.getState() + } = this.store.getState(); addresses.forEach((address) => { // skip if already exists if (identities[address]) { - return + return; } // add missing identity - const identityCount = Object.keys(identities).length + const identityCount = Object.keys(identities).length; - accountTokens[address] = {} - accountHiddenTokens[address] = {} - identities[address] = { name: `Account ${identityCount + 1}`, address } - }) - this.store.updateState({ identities, accountTokens, accountHiddenTokens }) + accountTokens[address] = {}; + accountHiddenTokens[address] = {}; + identities[address] = { name: `Account ${identityCount + 1}`, address }; + }); + this.store.updateState({ identities, accountTokens, accountHiddenTokens }); } /** @@ -279,46 +279,46 @@ export default class PreferencesController { */ syncAddresses(addresses) { if (!Array.isArray(addresses) || addresses.length === 0) { - throw new Error('Expected non-empty array of addresses.') + throw new Error('Expected non-empty array of addresses.'); } - const { identities, lostIdentities } = this.store.getState() + const { identities, lostIdentities } = this.store.getState(); - const newlyLost = {} + const newlyLost = {}; Object.keys(identities).forEach((identity) => { if (!addresses.includes(identity)) { - newlyLost[identity] = identities[identity] - delete identities[identity] + newlyLost[identity] = identities[identity]; + delete identities[identity]; } - }) + }); // Identities are no longer present. if (Object.keys(newlyLost).length > 0) { // store lost accounts Object.keys(newlyLost).forEach((key) => { - lostIdentities[key] = newlyLost[key] - }) + lostIdentities[key] = newlyLost[key]; + }); } - this.store.updateState({ identities, lostIdentities }) - this.addAddresses(addresses) + this.store.updateState({ identities, lostIdentities }); + this.addAddresses(addresses); // If the selected account is no longer valid, // select an arbitrary other account: - let selected = this.getSelectedAddress() + let selected = this.getSelectedAddress(); if (!addresses.includes(selected)) { - selected = addresses[0] - this.setSelectedAddress(selected) + selected = addresses[0]; + this.setSelectedAddress(selected); } - return selected + return selected; } removeSuggestedTokens() { return new Promise((resolve) => { - this.store.updateState({ suggestedTokens: {} }) - resolve({}) - }) + this.store.updateState({ suggestedTokens: {} }); + resolve({}); + }); } /** @@ -329,18 +329,18 @@ export default class PreferencesController { * */ setSelectedAddress(_address) { - const address = normalizeAddress(_address) - this._updateTokens(address) + const address = normalizeAddress(_address); + this._updateTokens(address); - const { identities, tokens } = this.store.getState() - const selectedIdentity = identities[address] + const { identities, tokens } = this.store.getState(); + const selectedIdentity = identities[address]; if (!selectedIdentity) { - throw new Error(`Identity for '${address} not found`) + throw new Error(`Identity for '${address} not found`); } - selectedIdentity.lastSelected = Date.now() - this.store.updateState({ identities, selectedAddress: address }) - return Promise.resolve(tokens) + selectedIdentity.lastSelected = Date.now(); + this.store.updateState({ identities, selectedAddress: address }); + return Promise.resolve(tokens); } /** @@ -350,7 +350,7 @@ export default class PreferencesController { * */ getSelectedAddress() { - return this.store.getState().selectedAddress + return this.store.getState().selectedAddress; } /** @@ -375,26 +375,26 @@ export default class PreferencesController { * */ async addToken(rawAddress, symbol, decimals, image) { - const address = normalizeAddress(rawAddress) - const newEntry = { address, symbol, decimals } - const { tokens, hiddenTokens } = this.store.getState() - const assetImages = this.getAssetImages() + const address = normalizeAddress(rawAddress); + const newEntry = { address, symbol, decimals }; + const { tokens, hiddenTokens } = this.store.getState(); + const assetImages = this.getAssetImages(); const updatedHiddenTokens = hiddenTokens.filter( (tokenAddress) => tokenAddress !== rawAddress.toLowerCase(), - ) + ); const previousEntry = tokens.find((token) => { - return token.address === address - }) - const previousIndex = tokens.indexOf(previousEntry) + return token.address === address; + }); + const previousIndex = tokens.indexOf(previousEntry); if (previousEntry) { - tokens[previousIndex] = newEntry + tokens[previousIndex] = newEntry; } else { - tokens.push(newEntry) + tokens.push(newEntry); } - assetImages[address] = image - this._updateAccountTokens(tokens, assetImages, updatedHiddenTokens) - return Promise.resolve(tokens) + assetImages[address] = image; + this._updateAccountTokens(tokens, assetImages, updatedHiddenTokens); + return Promise.resolve(tokens); } /** @@ -405,13 +405,15 @@ export default class PreferencesController { * */ removeToken(rawAddress) { - const { tokens, hiddenTokens } = this.store.getState() - const assetImages = this.getAssetImages() - const updatedTokens = tokens.filter((token) => token.address !== rawAddress) - const updatedHiddenTokens = [...hiddenTokens, rawAddress.toLowerCase()] - delete assetImages[rawAddress] - this._updateAccountTokens(updatedTokens, assetImages, updatedHiddenTokens) - return Promise.resolve(updatedTokens) + const { tokens, hiddenTokens } = this.store.getState(); + const assetImages = this.getAssetImages(); + const updatedTokens = tokens.filter( + (token) => token.address !== rawAddress, + ); + const updatedHiddenTokens = [...hiddenTokens, rawAddress.toLowerCase()]; + delete assetImages[rawAddress]; + this._updateAccountTokens(updatedTokens, assetImages, updatedHiddenTokens); + return Promise.resolve(updatedTokens); } /** @@ -421,7 +423,7 @@ export default class PreferencesController { * */ getTokens() { - return this.store.getState().tokens + return this.store.getState().tokens; } /** @@ -434,14 +436,14 @@ export default class PreferencesController { if (!account) { throw new Error( `setAccountLabel requires a valid address, got ${String(account)}`, - ) + ); } - const address = normalizeAddress(account) - const { identities } = this.store.getState() - identities[address] = identities[address] || {} - identities[address].name = label - this.store.updateState({ identities }) - return Promise.resolve(label) + const address = normalizeAddress(account); + const { identities } = this.store.getState(); + identities[address] = identities[address] || {}; + identities[address].name = label; + this.store.updateState({ identities }); + return Promise.resolve(label); } /** @@ -456,33 +458,33 @@ export default class PreferencesController { * */ async updateRpc(newRpcDetails) { - const rpcList = this.getFrequentRpcListDetail() + const rpcList = this.getFrequentRpcListDetail(); const index = rpcList.findIndex((element) => { - return element.rpcUrl === newRpcDetails.rpcUrl - }) + return element.rpcUrl === newRpcDetails.rpcUrl; + }); if (index > -1) { - const rpcDetail = rpcList[index] - const updatedRpc = { ...rpcDetail, ...newRpcDetails } + const rpcDetail = rpcList[index]; + const updatedRpc = { ...rpcDetail, ...newRpcDetails }; if (rpcDetail.chainId !== updatedRpc.chainId) { // When the chainId is changed, associated address book entries should // also be migrated. The address book entries are keyed by the `network` state, // which for custom networks is the chainId with a fallback to the networkId // if the chainId is not set. - let addressBookKey = rpcDetail.chainId + let addressBookKey = rpcDetail.chainId; if (!addressBookKey) { // We need to find the networkId to determine what these addresses were keyed by const provider = new ethers.providers.JsonRpcProvider( rpcDetail.rpcUrl, - ) + ); try { - addressBookKey = await provider.send('net_version') - assert(typeof addressBookKey === 'string') + addressBookKey = await provider.send('net_version'); + assert(typeof addressBookKey === 'string'); } catch (error) { - log.debug(error) + log.debug(error); log.warn( `Failed to get networkId from ${rpcDetail.rpcUrl}; skipping address book migration`, - ) + ); } } @@ -490,31 +492,37 @@ export default class PreferencesController { // value. In this case, the contact book entries are duplicated so that they remain // on both networks, since we don't know which network each contact is intended for. - let duplicate = false + let duplicate = false; const builtInProviderNetworkIds = Object.values( NETWORK_TYPE_TO_ID_MAP, - ).map((ids) => ids.networkId) + ).map((ids) => ids.networkId); const otherRpcEntries = rpcList.filter( (entry) => entry.rpcUrl !== newRpcDetails.rpcUrl, - ) + ); if ( builtInProviderNetworkIds.includes(addressBookKey) || otherRpcEntries.some((entry) => entry.chainId === addressBookKey) ) { - duplicate = true + duplicate = true; } this.migrateAddressBookState( addressBookKey, updatedRpc.chainId, duplicate, - ) + ); } - rpcList[index] = updatedRpc - this.store.updateState({ frequentRpcListDetail: rpcList }) + rpcList[index] = updatedRpc; + this.store.updateState({ frequentRpcListDetail: rpcList }); } else { - const { rpcUrl, chainId, ticker, nickname, rpcPrefs = {} } = newRpcDetails - this.addToFrequentRpcList(rpcUrl, chainId, ticker, nickname, rpcPrefs) + const { + rpcUrl, + chainId, + ticker, + nickname, + rpcPrefs = {}, + } = newRpcDetails; + this.addToFrequentRpcList(rpcUrl, chainId, ticker, nickname, rpcPrefs); } } @@ -535,21 +543,21 @@ export default class PreferencesController { nickname = '', rpcPrefs = {}, ) { - const rpcList = this.getFrequentRpcListDetail() + const rpcList = this.getFrequentRpcListDetail(); const index = rpcList.findIndex((element) => { - return element.rpcUrl === rpcUrl - }) + return element.rpcUrl === rpcUrl; + }); if (index !== -1) { - rpcList.splice(index, 1) + rpcList.splice(index, 1); } if (!isPrefixedFormattedHexString(chainId)) { - throw new Error(`Invalid chainId: "${chainId}"`) + throw new Error(`Invalid chainId: "${chainId}"`); } - rpcList.push({ rpcUrl, chainId, ticker, nickname, rpcPrefs }) - this.store.updateState({ frequentRpcListDetail: rpcList }) + rpcList.push({ rpcUrl, chainId, ticker, nickname, rpcPrefs }); + this.store.updateState({ frequentRpcListDetail: rpcList }); } /** @@ -560,15 +568,15 @@ export default class PreferencesController { * */ removeFromFrequentRpcList(url) { - const rpcList = this.getFrequentRpcListDetail() + const rpcList = this.getFrequentRpcListDetail(); const index = rpcList.findIndex((element) => { - return element.rpcUrl === url - }) + return element.rpcUrl === url; + }); if (index !== -1) { - rpcList.splice(index, 1) + rpcList.splice(index, 1); } - this.store.updateState({ frequentRpcListDetail: rpcList }) - return Promise.resolve(rpcList) + this.store.updateState({ frequentRpcListDetail: rpcList }); + return Promise.resolve(rpcList); } /** @@ -578,7 +586,7 @@ export default class PreferencesController { * */ getFrequentRpcListDetail() { - return this.store.getState().frequentRpcListDetail + return this.store.getState().frequentRpcListDetail; } /** @@ -590,15 +598,15 @@ export default class PreferencesController { * */ setFeatureFlag(feature, activated) { - const currentFeatureFlags = this.store.getState().featureFlags + const currentFeatureFlags = this.store.getState().featureFlags; const updatedFeatureFlags = { ...currentFeatureFlags, [feature]: activated, - } + }; - this.store.updateState({ featureFlags: updatedFeatureFlags }) + this.store.updateState({ featureFlags: updatedFeatureFlags }); - return Promise.resolve(updatedFeatureFlags) + return Promise.resolve(updatedFeatureFlags); } /** @@ -609,14 +617,14 @@ export default class PreferencesController { * @returns {Promise} Promises a new object; the updated preferences object. */ setPreference(preference, value) { - const currentPreferences = this.getPreferences() + const currentPreferences = this.getPreferences(); const updatedPreferences = { ...currentPreferences, [preference]: value, - } + }; - this.store.updateState({ preferences: updatedPreferences }) - return Promise.resolve(updatedPreferences) + this.store.updateState({ preferences: updatedPreferences }); + return Promise.resolve(updatedPreferences); } /** @@ -624,7 +632,7 @@ export default class PreferencesController { * @returns {Object} A key-boolean map of user-selected preferences. */ getPreferences() { - return this.store.getState().preferences + return this.store.getState().preferences; } /** @@ -632,8 +640,8 @@ export default class PreferencesController { * onboarding process. */ completeOnboarding() { - this.store.updateState({ completedOnboarding: true }) - return Promise.resolve(true) + this.store.updateState({ completedOnboarding: true }); + return Promise.resolve(true); } /** @@ -641,7 +649,7 @@ export default class PreferencesController { * @returns {string} The current IPFS gateway domain */ getIpfsGateway() { - return this.store.getState().ipfsGateway + return this.store.getState().ipfsGateway; } /** @@ -650,8 +658,8 @@ export default class PreferencesController { * @returns {Promise} A promise of the update IPFS gateway domain */ setIpfsGateway(domain) { - this.store.updateState({ ipfsGateway: domain }) - return Promise.resolve(domain) + this.store.updateState({ ipfsGateway: domain }); + return Promise.resolve(domain); } // @@ -665,9 +673,9 @@ export default class PreferencesController { */ _subscribeProviderType() { this.network.providerStore.subscribe(() => { - const { tokens, hiddenTokens } = this._getTokenRelatedStates() - this._updateAccountTokens(tokens, this.getAssetImages(), hiddenTokens) - }) + const { tokens, hiddenTokens } = this._getTokenRelatedStates(); + this._updateAccountTokens(tokens, this.getAssetImages(), hiddenTokens); + }); } /** @@ -684,16 +692,16 @@ export default class PreferencesController { providerType, selectedAddress, accountHiddenTokens, - } = this._getTokenRelatedStates() - accountTokens[selectedAddress][providerType] = tokens - accountHiddenTokens[selectedAddress][providerType] = hiddenTokens + } = this._getTokenRelatedStates(); + accountTokens[selectedAddress][providerType] = tokens; + accountHiddenTokens[selectedAddress][providerType] = hiddenTokens; this.store.updateState({ accountTokens, tokens, assetImages, accountHiddenTokens, hiddenTokens, - }) + }); } /** @@ -705,8 +713,8 @@ export default class PreferencesController { _updateTokens(selectedAddress) { const { tokens, hiddenTokens } = this._getTokenRelatedStates( selectedAddress, - ) - this.store.updateState({ tokens, hiddenTokens }) + ); + this.store.updateState({ tokens, hiddenTokens }); } /** @@ -717,26 +725,26 @@ export default class PreferencesController { * */ _getTokenRelatedStates(selectedAddress) { - const { accountTokens, accountHiddenTokens } = this.store.getState() + const { accountTokens, accountHiddenTokens } = this.store.getState(); if (!selectedAddress) { // eslint-disable-next-line no-param-reassign - selectedAddress = this.store.getState().selectedAddress + selectedAddress = this.store.getState().selectedAddress; } - const providerType = this.network.providerStore.getState().type + const providerType = this.network.providerStore.getState().type; if (!(selectedAddress in accountTokens)) { - accountTokens[selectedAddress] = {} + accountTokens[selectedAddress] = {}; } if (!(selectedAddress in accountHiddenTokens)) { - accountHiddenTokens[selectedAddress] = {} + accountHiddenTokens[selectedAddress] = {}; } if (!(providerType in accountTokens[selectedAddress])) { - accountTokens[selectedAddress][providerType] = [] + accountTokens[selectedAddress][providerType] = []; } if (!(providerType in accountHiddenTokens[selectedAddress])) { - accountHiddenTokens[selectedAddress][providerType] = [] + accountHiddenTokens[selectedAddress][providerType] = []; } - const tokens = accountTokens[selectedAddress][providerType] - const hiddenTokens = accountHiddenTokens[selectedAddress][providerType] + const tokens = accountTokens[selectedAddress][providerType]; + const hiddenTokens = accountHiddenTokens[selectedAddress][providerType]; return { tokens, accountTokens, @@ -744,7 +752,7 @@ export default class PreferencesController { accountHiddenTokens, providerType, selectedAddress, - } + }; } /** @@ -754,17 +762,17 @@ export default class PreferencesController { * */ async _handleWatchAssetERC20(tokenMetadata) { - this._validateERC20AssetParams(tokenMetadata) + this._validateERC20AssetParams(tokenMetadata); - const address = normalizeAddress(tokenMetadata.address) - const { symbol, decimals, image } = tokenMetadata - this._addSuggestedERC20Asset(address, symbol, decimals, image) + const address = normalizeAddress(tokenMetadata.address); + const { symbol, decimals, image } = tokenMetadata; + this._addSuggestedERC20Asset(address, symbol, decimals, image); - await this.openPopup() + await this.openPopup(); const tokenAddresses = this.getTokens().filter( (token) => token.address === address, - ) - return tokenAddresses.length > 0 + ); + return tokenAddresses.length > 0; } /** @@ -779,24 +787,24 @@ export default class PreferencesController { if (!address || !symbol || typeof decimals === 'undefined') { throw ethErrors.rpc.invalidParams( `Must specify address, symbol, and decimals.`, - ) + ); } if (typeof symbol !== 'string') { - throw ethErrors.rpc.invalidParams(`Invalid symbol: not a string.`) + throw ethErrors.rpc.invalidParams(`Invalid symbol: not a string.`); } if (!(symbol.length < 7)) { throw ethErrors.rpc.invalidParams( `Invalid symbol "${symbol}": longer than 6 characters.`, - ) + ); } - const numDecimals = parseInt(decimals, 10) + const numDecimals = parseInt(decimals, 10); if (isNaN(numDecimals) || numDecimals > 36 || numDecimals < 0) { throw ethErrors.rpc.invalidParams( `Invalid decimals "${decimals}": must be 0 <= 36.`, - ) + ); } if (!isValidAddress(address)) { - throw ethErrors.rpc.invalidParams(`Invalid address "${address}".`) + throw ethErrors.rpc.invalidParams(`Invalid address "${address}".`); } } @@ -807,9 +815,9 @@ export default class PreferencesController { decimals, image, unlisted: !LISTED_CONTRACT_ADDRESSES.includes(address), - } - const suggested = this.getSuggestedTokens() - suggested[address] = newEntry - this.store.updateState({ suggestedTokens: suggested }) + }; + const suggested = this.getSuggestedTokens(); + suggested[address] = newEntry; + this.store.updateState({ suggestedTokens: suggested }); } } diff --git a/app/scripts/controllers/swaps.js b/app/scripts/controllers/swaps.js index 0f599bb07b..992af5578f 100644 --- a/app/scripts/controllers/swaps.js +++ b/app/scripts/controllers/swaps.js @@ -1,54 +1,57 @@ -import { ethers } from 'ethers' -import log from 'loglevel' -import BigNumber from 'bignumber.js' -import { ObservableStore } from '@metamask/obs-store' -import { mapValues, cloneDeep } from 'lodash' -import abi from 'human-standard-token-abi' -import { calcTokenAmount } from '../../../ui/app/helpers/utils/token-util' -import { calcGasTotal } from '../../../ui/app/pages/send/send.utils' -import { conversionUtil } from '../../../ui/app/helpers/utils/conversion-util' +import { ethers } from 'ethers'; +import log from 'loglevel'; +import BigNumber from 'bignumber.js'; +import { ObservableStore } from '@metamask/obs-store'; +import { mapValues, cloneDeep } from 'lodash'; +import abi from 'human-standard-token-abi'; +import { calcTokenAmount } from '../../../ui/app/helpers/utils/token-util'; +import { calcGasTotal } from '../../../ui/app/pages/send/send.utils'; +import { conversionUtil } from '../../../ui/app/helpers/utils/conversion-util'; import { ETH_SWAPS_TOKEN_ADDRESS, DEFAULT_ERC20_APPROVE_GAS, QUOTES_EXPIRED_ERROR, QUOTES_NOT_AVAILABLE_ERROR, SWAPS_FETCH_ORDER_CONFLICT, -} from '../../../ui/app/helpers/constants/swaps' +} from '../../../ui/app/helpers/constants/swaps'; import { fetchTradesInfo as defaultFetchTradesInfo, fetchSwapsFeatureLiveness as defaultFetchSwapsFeatureLiveness, fetchSwapsQuoteRefreshTime as defaultFetchSwapsQuoteRefreshTime, -} from '../../../ui/app/pages/swaps/swaps.util' +} from '../../../ui/app/pages/swaps/swaps.util'; -const METASWAP_ADDRESS = '0x881d40237659c251811cec9c364ef91dc08d300c' +const METASWAP_ADDRESS = '0x881d40237659c251811cec9c364ef91dc08d300c'; // The MAX_GAS_LIMIT is a number that is higher than the maximum gas costs we have observed on any aggregator -const MAX_GAS_LIMIT = 2500000 +const MAX_GAS_LIMIT = 2500000; // To ensure that our serves are not spammed if MetaMask is left idle, we limit the number of fetches for quotes that are made on timed intervals. // 3 seems to be an appropriate balance of giving users the time they need when MetaMask is not left idle, and turning polling off when it is. -const POLL_COUNT_LIMIT = 3 +const POLL_COUNT_LIMIT = 3; // If for any reason the MetaSwap API fails to provide a refresh time, // provide a reasonable fallback to avoid further errors -const FALLBACK_QUOTE_REFRESH_TIME = 60000 +const FALLBACK_QUOTE_REFRESH_TIME = 60000; // This is the amount of time to wait, after successfully fetching quotes // and their gas estimates, before fetching for new quotes -const QUOTE_POLLING_DIFFERENCE_INTERVAL = 10 * 1000 +const QUOTE_POLLING_DIFFERENCE_INTERVAL = 10 * 1000; function calculateGasEstimateWithRefund( maxGas = MAX_GAS_LIMIT, estimatedRefund = 0, estimatedGas = 0, ) { - const maxGasMinusRefund = new BigNumber(maxGas, 10).minus(estimatedRefund, 10) + const maxGasMinusRefund = new BigNumber(maxGas, 10).minus( + estimatedRefund, + 10, + ); const gasEstimateWithRefund = maxGasMinusRefund.lt(estimatedGas, 16) ? maxGasMinusRefund.toString(16) - : estimatedGas + : estimatedGas; - return gasEstimateWithRefund + return gasEstimateWithRefund; } const initialState = { @@ -69,7 +72,7 @@ const initialState = { swapsFeatureIsLive: false, swapsQuoteRefreshTime: FALLBACK_QUOTE_REFRESH_TIME, }, -} +}; export default class SwapsController { constructor({ @@ -84,46 +87,46 @@ export default class SwapsController { }) { this.store = new ObservableStore({ swapsState: { ...initialState.swapsState }, - }) + }); - this._fetchTradesInfo = fetchTradesInfo - this._fetchSwapsFeatureLiveness = fetchSwapsFeatureLiveness - this._fetchSwapsQuoteRefreshTime = fetchSwapsQuoteRefreshTime + this._fetchTradesInfo = fetchTradesInfo; + this._fetchSwapsFeatureLiveness = fetchSwapsFeatureLiveness; + this._fetchSwapsQuoteRefreshTime = fetchSwapsQuoteRefreshTime; - this.getBufferedGasLimit = getBufferedGasLimit - this.tokenRatesStore = tokenRatesStore + this.getBufferedGasLimit = getBufferedGasLimit; + this.tokenRatesStore = tokenRatesStore; - this.pollCount = 0 - this.getProviderConfig = getProviderConfig + this.pollCount = 0; + this.getProviderConfig = getProviderConfig; - this.indexOfNewestCallInFlight = 0 + this.indexOfNewestCallInFlight = 0; - this.ethersProvider = new ethers.providers.Web3Provider(provider) - this._currentNetwork = networkController.store.getState().network + this.ethersProvider = new ethers.providers.Web3Provider(provider); + this._currentNetwork = networkController.store.getState().network; networkController.on('networkDidChange', (network) => { if (network !== 'loading' && network !== this._currentNetwork) { - this._currentNetwork = network - this.ethersProvider = new ethers.providers.Web3Provider(provider) + this._currentNetwork = network; + this.ethersProvider = new ethers.providers.Web3Provider(provider); } - }) + }); - this._setupSwapsLivenessFetching() + this._setupSwapsLivenessFetching(); } // Sets the refresh rate for quote updates from the MetaSwap API async _setSwapsQuoteRefreshTime() { // Default to fallback time unless API returns valid response - let swapsQuoteRefreshTime = FALLBACK_QUOTE_REFRESH_TIME + let swapsQuoteRefreshTime = FALLBACK_QUOTE_REFRESH_TIME; try { - swapsQuoteRefreshTime = await this._fetchSwapsQuoteRefreshTime() + swapsQuoteRefreshTime = await this._fetchSwapsQuoteRefreshTime(); } catch (e) { - console.error('Request for swaps quote refresh time failed: ', e) + console.error('Request for swaps quote refresh time failed: ', e); } - const { swapsState } = this.store.getState() + const { swapsState } = this.store.getState(); this.store.updateState({ swapsState: { ...swapsState, swapsQuoteRefreshTime }, - }) + }); } // Once quotes are fetched, we poll for new ones to keep the quotes up to date. Market and aggregator contract conditions can change fast enough @@ -133,20 +136,20 @@ export default class SwapsController { pollForNewQuotes() { const { swapsState: { swapsQuoteRefreshTime }, - } = this.store.getState() + } = this.store.getState(); this.pollingTimeout = setTimeout(() => { - const { swapsState } = this.store.getState() + const { swapsState } = this.store.getState(); this.fetchAndSetQuotes( swapsState.fetchParams, swapsState.fetchParams?.metaData, true, - ) - }, swapsQuoteRefreshTime - QUOTE_POLLING_DIFFERENCE_INTERVAL) + ); + }, swapsQuoteRefreshTime - QUOTE_POLLING_DIFFERENCE_INTERVAL); } stopPollingForQuotes() { - clearTimeout(this.pollingTimeout) + clearTimeout(this.pollingTimeout); } async fetchAndSetQuotes( @@ -155,37 +158,37 @@ export default class SwapsController { isPolledRequest, ) { if (!fetchParams) { - return null + return null; } // Every time we get a new request that is not from the polling, we reset the poll count so we can poll for up to three more sets of quotes with these new params. if (!isPolledRequest) { - this.pollCount = 0 + this.pollCount = 0; } // If there are any pending poll requests, clear them so that they don't get call while this new fetch is in process - clearTimeout(this.pollingTimeout) + clearTimeout(this.pollingTimeout); if (!isPolledRequest) { - this.setSwapsErrorKey('') + this.setSwapsErrorKey(''); } - const indexOfCurrentCall = this.indexOfNewestCallInFlight + 1 - this.indexOfNewestCallInFlight = indexOfCurrentCall + const indexOfCurrentCall = this.indexOfNewestCallInFlight + 1; + this.indexOfNewestCallInFlight = indexOfCurrentCall; let [newQuotes] = await Promise.all([ this._fetchTradesInfo(fetchParams), this._setSwapsQuoteRefreshTime(), - ]) + ]); newQuotes = mapValues(newQuotes, (quote) => ({ ...quote, sourceTokenInfo: fetchParamsMetaData.sourceTokenInfo, destinationTokenInfo: fetchParamsMetaData.destinationTokenInfo, - })) + })); - const quotesLastFetched = Date.now() + const quotesLastFetched = Date.now(); - let approvalRequired = false + let approvalRequired = false; if ( fetchParams.sourceToken !== ETH_SWAPS_TOKEN_ADDRESS && Object.values(newQuotes).length @@ -193,22 +196,22 @@ export default class SwapsController { const allowance = await this._getERC20Allowance( fetchParams.sourceToken, fetchParams.fromAddress, - ) + ); // For a user to be able to swap a token, they need to have approved the MetaSwap contract to withdraw that token. // _getERC20Allowance() returns the amount of the token they have approved for withdrawal. If that amount is greater // than 0, it means that approval has already occured and is not needed. Otherwise, for tokens to be swapped, a new // call of the ERC-20 approve method is required. - approvalRequired = allowance.eq(0) + approvalRequired = allowance.eq(0); if (!approvalRequired) { newQuotes = mapValues(newQuotes, (quote) => ({ ...quote, approvalNeeded: null, - })) + })); } else if (!isPolledRequest) { const { gasLimit: approvalGas } = await this.timedoutGasReturn( Object.values(newQuotes)[0].approvalNeeded, - ) + ); newQuotes = mapValues(newQuotes, (quote) => ({ ...quote, @@ -216,39 +219,39 @@ export default class SwapsController { ...quote.approvalNeeded, gas: approvalGas || DEFAULT_ERC20_APPROVE_GAS, }, - })) + })); } } - let topAggId = null + let topAggId = null; // We can reduce time on the loading screen by only doing this after the // loading screen and best quote have rendered. if (!approvalRequired && !fetchParams?.balanceError) { - newQuotes = await this.getAllQuotesWithGasEstimates(newQuotes) + newQuotes = await this.getAllQuotesWithGasEstimates(newQuotes); } if (Object.values(newQuotes).length === 0) { - this.setSwapsErrorKey(QUOTES_NOT_AVAILABLE_ERROR) + this.setSwapsErrorKey(QUOTES_NOT_AVAILABLE_ERROR); } else { const [ _topAggId, quotesWithSavingsAndFeeData, - ] = await this._findTopQuoteAndCalculateSavings(newQuotes) - topAggId = _topAggId - newQuotes = quotesWithSavingsAndFeeData + ] = await this._findTopQuoteAndCalculateSavings(newQuotes); + topAggId = _topAggId; + newQuotes = quotesWithSavingsAndFeeData; } // If a newer call has been made, don't update state with old information // Prevents timing conflicts between fetches if (this.indexOfNewestCallInFlight !== indexOfCurrentCall) { - throw new Error(SWAPS_FETCH_ORDER_CONFLICT) + throw new Error(SWAPS_FETCH_ORDER_CONFLICT); } - const { swapsState } = this.store.getState() - let { selectedAggId } = swapsState + const { swapsState } = this.store.getState(); + let { selectedAggId } = swapsState; if (!newQuotes[selectedAggId]) { - selectedAggId = null + selectedAggId = null; } this.store.updateState({ @@ -260,41 +263,41 @@ export default class SwapsController { selectedAggId, topAggId, }, - }) + }); // We only want to do up to a maximum of three requests from polling. - this.pollCount += 1 + this.pollCount += 1; if (this.pollCount < POLL_COUNT_LIMIT + 1) { - this.pollForNewQuotes() + this.pollForNewQuotes(); } else { - this.resetPostFetchState() - this.setSwapsErrorKey(QUOTES_EXPIRED_ERROR) - return null + this.resetPostFetchState(); + this.setSwapsErrorKey(QUOTES_EXPIRED_ERROR); + return null; } - return [newQuotes, topAggId] + return [newQuotes, topAggId]; } safeRefetchQuotes() { - const { swapsState } = this.store.getState() + const { swapsState } = this.store.getState(); if (!this.pollingTimeout && swapsState.fetchParams) { - this.fetchAndSetQuotes(swapsState.fetchParams) + this.fetchAndSetQuotes(swapsState.fetchParams); } } setSelectedQuoteAggId(selectedAggId) { - const { swapsState } = this.store.getState() - this.store.updateState({ swapsState: { ...swapsState, selectedAggId } }) + const { swapsState } = this.store.getState(); + this.store.updateState({ swapsState: { ...swapsState, selectedAggId } }); } setSwapsTokens(tokens) { - const { swapsState } = this.store.getState() - this.store.updateState({ swapsState: { ...swapsState, tokens } }) + const { swapsState } = this.store.getState(); + this.store.updateState({ swapsState: { ...swapsState, tokens } }); } setSwapsErrorKey(errorKey) { - const { swapsState } = this.store.getState() - this.store.updateState({ swapsState: { ...swapsState, errorKey } }) + const { swapsState } = this.store.getState(); + this.store.updateState({ swapsState: { ...swapsState, errorKey } }); } async getAllQuotesWithGasEstimates(quotes) { @@ -302,43 +305,43 @@ export default class SwapsController { Object.values(quotes).map(async (quote) => { const { gasLimit, simulationFails } = await this.timedoutGasReturn( quote.trade, - ) - return [gasLimit, simulationFails, quote.aggregator] + ); + return [gasLimit, simulationFails, quote.aggregator]; }), - ) + ); - const newQuotes = {} + const newQuotes = {}; quoteGasData.forEach(([gasLimit, simulationFails, aggId]) => { if (gasLimit && !simulationFails) { const gasEstimateWithRefund = calculateGasEstimateWithRefund( quotes[aggId].maxGas, quotes[aggId].estimatedRefund, gasLimit, - ) + ); newQuotes[aggId] = { ...quotes[aggId], gasEstimate: gasLimit, gasEstimateWithRefund, - } + }; } else if (quotes[aggId].approvalNeeded) { // If gas estimation fails, but an ERC-20 approve is needed, then we do not add any estimate property to the quote object // Such quotes will rely on the maxGas and averageGas properties from the api - newQuotes[aggId] = quotes[aggId] + newQuotes[aggId] = quotes[aggId]; } // If gas estimation fails and no approval is needed, then we filter that quote out, so that it is not shown to the user - }) - return newQuotes + }); + return newQuotes; } timedoutGasReturn(tradeTxParams) { return new Promise((resolve) => { - let gasTimedOut = false + let gasTimedOut = false; const gasTimeout = setTimeout(() => { - gasTimedOut = true - resolve({ gasLimit: null, simulationFails: true }) - }, 5000) + gasTimedOut = true; + resolve({ gasLimit: null, simulationFails: true }); + }, 5000); // Remove gas from params that will be passed to the `estimateGas` call // Including it can cause the estimate to fail if the actual gas needed @@ -348,44 +351,44 @@ export default class SwapsController { from: tradeTxParams.from, to: tradeTxParams.to, value: tradeTxParams.value, - } + }; this.getBufferedGasLimit({ txParams: tradeTxParamsForGasEstimate }, 1) .then(({ gasLimit, simulationFails }) => { if (!gasTimedOut) { - clearTimeout(gasTimeout) - resolve({ gasLimit, simulationFails }) + clearTimeout(gasTimeout); + resolve({ gasLimit, simulationFails }); } }) .catch((e) => { - log.error(e) + log.error(e); if (!gasTimedOut) { - clearTimeout(gasTimeout) - resolve({ gasLimit: null, simulationFails: true }) + clearTimeout(gasTimeout); + resolve({ gasLimit: null, simulationFails: true }); } - }) - }) + }); + }); } async setInitialGasEstimate(initialAggId) { - const { swapsState } = this.store.getState() + const { swapsState } = this.store.getState(); - const quoteToUpdate = { ...swapsState.quotes[initialAggId] } + const quoteToUpdate = { ...swapsState.quotes[initialAggId] }; const { gasLimit: newGasEstimate, simulationFails, - } = await this.timedoutGasReturn(quoteToUpdate.trade) + } = await this.timedoutGasReturn(quoteToUpdate.trade); if (newGasEstimate && !simulationFails) { const gasEstimateWithRefund = calculateGasEstimateWithRefund( quoteToUpdate.maxGas, quoteToUpdate.estimatedRefund, newGasEstimate, - ) + ); - quoteToUpdate.gasEstimate = newGasEstimate - quoteToUpdate.gasEstimateWithRefund = gasEstimateWithRefund + quoteToUpdate.gasEstimate = newGasEstimate; + quoteToUpdate.gasEstimateWithRefund = gasEstimateWithRefund; } this.store.updateState({ @@ -393,59 +396,61 @@ export default class SwapsController { ...swapsState, quotes: { ...swapsState.quotes, [initialAggId]: quoteToUpdate }, }, - }) + }); } setApproveTxId(approveTxId) { - const { swapsState } = this.store.getState() - this.store.updateState({ swapsState: { ...swapsState, approveTxId } }) + const { swapsState } = this.store.getState(); + this.store.updateState({ swapsState: { ...swapsState, approveTxId } }); } setTradeTxId(tradeTxId) { - const { swapsState } = this.store.getState() - this.store.updateState({ swapsState: { ...swapsState, tradeTxId } }) + const { swapsState } = this.store.getState(); + this.store.updateState({ swapsState: { ...swapsState, tradeTxId } }); } setQuotesLastFetched(quotesLastFetched) { - const { swapsState } = this.store.getState() - this.store.updateState({ swapsState: { ...swapsState, quotesLastFetched } }) + const { swapsState } = this.store.getState(); + this.store.updateState({ + swapsState: { ...swapsState, quotesLastFetched }, + }); } setSwapsTxGasPrice(gasPrice) { - const { swapsState } = this.store.getState() + const { swapsState } = this.store.getState(); this.store.updateState({ swapsState: { ...swapsState, customGasPrice: gasPrice }, - }) + }); } setSwapsTxGasLimit(gasLimit) { - const { swapsState } = this.store.getState() + const { swapsState } = this.store.getState(); this.store.updateState({ swapsState: { ...swapsState, customMaxGas: gasLimit }, - }) + }); } setCustomApproveTxData(data) { - const { swapsState } = this.store.getState() + const { swapsState } = this.store.getState(); this.store.updateState({ swapsState: { ...swapsState, customApproveTxData: data }, - }) + }); } setBackgroundSwapRouteState(routeState) { - const { swapsState } = this.store.getState() - this.store.updateState({ swapsState: { ...swapsState, routeState } }) + const { swapsState } = this.store.getState(); + this.store.updateState({ swapsState: { ...swapsState, routeState } }); } setSwapsLiveness(swapsFeatureIsLive) { - const { swapsState } = this.store.getState() + const { swapsState } = this.store.getState(); this.store.updateState({ swapsState: { ...swapsState, swapsFeatureIsLive }, - }) + }); } resetPostFetchState() { - const { swapsState } = this.store.getState() + const { swapsState } = this.store.getState(); this.store.updateState({ swapsState: { @@ -455,12 +460,12 @@ export default class SwapsController { swapsFeatureIsLive: swapsState.swapsFeatureIsLive, swapsQuoteRefreshTime: swapsState.swapsQuoteRefreshTime, }, - }) - clearTimeout(this.pollingTimeout) + }); + clearTimeout(this.pollingTimeout); } resetSwapsState() { - const { swapsState } = this.store.getState() + const { swapsState } = this.store.getState(); this.store.updateState({ swapsState: { @@ -469,33 +474,33 @@ export default class SwapsController { swapsFeatureIsLive: swapsState.swapsFeatureIsLive, swapsQuoteRefreshTime: swapsState.swapsQuoteRefreshTime, }, - }) - clearTimeout(this.pollingTimeout) + }); + clearTimeout(this.pollingTimeout); } async _getEthersGasPrice() { - const ethersGasPrice = await this.ethersProvider.getGasPrice() - return ethersGasPrice.toHexString() + const ethersGasPrice = await this.ethersProvider.getGasPrice(); + return ethersGasPrice.toHexString(); } async _findTopQuoteAndCalculateSavings(quotes = {}) { const tokenConversionRates = this.tokenRatesStore.getState() - .contractExchangeRates + .contractExchangeRates; const { swapsState: { customGasPrice }, - } = this.store.getState() + } = this.store.getState(); - const numQuotes = Object.keys(quotes).length + const numQuotes = Object.keys(quotes).length; if (!numQuotes) { - return {} + return {}; } - const newQuotes = cloneDeep(quotes) + const newQuotes = cloneDeep(quotes); - const usedGasPrice = customGasPrice || (await this._getEthersGasPrice()) + const usedGasPrice = customGasPrice || (await this._getEthersGasPrice()); - let topAggId = null - let overallValueOfBestQuoteForSorting = null + let topAggId = null; + let overallValueOfBestQuoteForSorting = null; Object.values(newQuotes).forEach((quote) => { const { @@ -510,20 +515,20 @@ export default class SwapsController { sourceToken, trade, fee: metaMaskFee, - } = quote + } = quote; const tradeGasLimitForCalculation = gasEstimate ? new BigNumber(gasEstimate, 16) - : new BigNumber(averageGas || MAX_GAS_LIMIT, 10) + : new BigNumber(averageGas || MAX_GAS_LIMIT, 10); const totalGasLimitForCalculation = tradeGasLimitForCalculation .plus(approvalNeeded?.gas || '0x0', 16) - .toString(16) + .toString(16); const gasTotalInWeiHex = calcGasTotal( totalGasLimitForCalculation, usedGasPrice, - ) + ); // trade.value is a sum of different values depending on the transaction. // It always includes any external fees charged by the quote source. In @@ -532,7 +537,7 @@ export default class SwapsController { const totalWeiCost = new BigNumber(gasTotalInWeiHex, 16).plus( trade.value, 16, - ) + ); const totalEthCost = conversionUtil(totalWeiCost, { fromCurrency: 'ETH', @@ -540,7 +545,7 @@ export default class SwapsController { toDenomination: 'ETH', fromNumericBase: 'BN', numberOfDecimals: 6, - }) + }); // The total fee is aggregator/exchange fees plus gas fees. // If the swap is from ETH, subtract the sourceAmount from the total cost. @@ -557,103 +562,103 @@ export default class SwapsController { numberOfDecimals: 6, }, ) - : totalEthCost + : totalEthCost; const decimalAdjustedDestinationAmount = calcTokenAmount( destinationAmount, destinationTokenInfo.decimals, - ) + ); const tokenPercentageOfPreFeeDestAmount = new BigNumber(100, 10) .minus(metaMaskFee, 10) - .div(100) + .div(100); const destinationAmountBeforeMetaMaskFee = decimalAdjustedDestinationAmount.div( tokenPercentageOfPreFeeDestAmount, - ) + ); const metaMaskFeeInTokens = destinationAmountBeforeMetaMaskFee.minus( decimalAdjustedDestinationAmount, - ) + ); - const tokenConversionRate = tokenConversionRates[destinationToken] - const conversionRateForSorting = tokenConversionRate || 1 + const tokenConversionRate = tokenConversionRates[destinationToken]; + const conversionRateForSorting = tokenConversionRate || 1; const ethValueOfTokens = decimalAdjustedDestinationAmount.times( conversionRateForSorting, 10, - ) + ); const conversionRateForCalculations = - destinationToken === ETH_SWAPS_TOKEN_ADDRESS ? 1 : tokenConversionRate + destinationToken === ETH_SWAPS_TOKEN_ADDRESS ? 1 : tokenConversionRate; const overallValueOfQuoteForSorting = conversionRateForCalculations === undefined ? ethValueOfTokens - : ethValueOfTokens.minus(ethFee, 10) + : ethValueOfTokens.minus(ethFee, 10); - quote.ethFee = ethFee.toString(10) + quote.ethFee = ethFee.toString(10); if (conversionRateForCalculations !== undefined) { - quote.ethValueOfTokens = ethValueOfTokens.toString(10) - quote.overallValueOfQuote = overallValueOfQuoteForSorting.toString(10) + quote.ethValueOfTokens = ethValueOfTokens.toString(10); + quote.overallValueOfQuote = overallValueOfQuoteForSorting.toString(10); quote.metaMaskFeeInEth = metaMaskFeeInTokens .times(conversionRateForCalculations) - .toString(10) + .toString(10); } if ( overallValueOfBestQuoteForSorting === null || overallValueOfQuoteForSorting.gt(overallValueOfBestQuoteForSorting) ) { - topAggId = aggregator - overallValueOfBestQuoteForSorting = overallValueOfQuoteForSorting + topAggId = aggregator; + overallValueOfBestQuoteForSorting = overallValueOfQuoteForSorting; } - }) + }); const isBest = newQuotes[topAggId].destinationToken === ETH_SWAPS_TOKEN_ADDRESS || - Boolean(tokenConversionRates[newQuotes[topAggId]?.destinationToken]) + Boolean(tokenConversionRates[newQuotes[topAggId]?.destinationToken]); - let savings = null + let savings = null; if (isBest) { - const bestQuote = newQuotes[topAggId] + const bestQuote = newQuotes[topAggId]; - savings = {} + savings = {}; const { ethFee: medianEthFee, metaMaskFeeInEth: medianMetaMaskFee, ethValueOfTokens: medianEthValueOfTokens, - } = getMedianEthValueQuote(Object.values(newQuotes)) + } = getMedianEthValueQuote(Object.values(newQuotes)); // Performance savings are calculated as: // (ethValueOfTokens for the best trade) - (ethValueOfTokens for the media trade) savings.performance = new BigNumber(bestQuote.ethValueOfTokens, 10).minus( medianEthValueOfTokens, 10, - ) + ); // Fee savings are calculated as: // (fee for the median trade) - (fee for the best trade) - savings.fee = new BigNumber(medianEthFee).minus(bestQuote.ethFee, 10) + savings.fee = new BigNumber(medianEthFee).minus(bestQuote.ethFee, 10); - savings.metaMaskFee = bestQuote.metaMaskFeeInEth + savings.metaMaskFee = bestQuote.metaMaskFeeInEth; // Total savings are calculated as: // performance savings + fee savings - metamask fee savings.total = savings.performance .plus(savings.fee) .minus(savings.metaMaskFee) - .toString(10) - savings.performance = savings.performance.toString(10) - savings.fee = savings.fee.toString(10) - savings.medianMetaMaskFee = medianMetaMaskFee + .toString(10); + savings.performance = savings.performance.toString(10); + savings.fee = savings.fee.toString(10); + savings.medianMetaMaskFee = medianMetaMaskFee; - newQuotes[topAggId].isBestQuote = true - newQuotes[topAggId].savings = savings + newQuotes[topAggId].isBestQuote = true; + newQuotes[topAggId].savings = savings; } - return [topAggId, newQuotes] + return [topAggId, newQuotes]; } async _getERC20Allowance(contractAddress, walletAddress) { @@ -661,8 +666,8 @@ export default class SwapsController { contractAddress, abi, this.ethersProvider, - ) - return await contract.allowance(walletAddress, METASWAP_ADDRESS) + ); + return await contract.allowance(walletAddress, METASWAP_ADDRESS); } /** @@ -674,8 +679,8 @@ export default class SwapsController { * until the value can be fetched again. */ _setupSwapsLivenessFetching() { - const TEN_MINUTES_MS = 10 * 60 * 1000 - let intervalId = null + const TEN_MINUTES_MS = 10 * 60 * 1000; + let intervalId = null; const fetchAndSetupInterval = () => { if (window.navigator.onLine && intervalId === null) { @@ -684,25 +689,25 @@ export default class SwapsController { intervalId = setInterval( this._fetchAndSetSwapsLiveness.bind(this), TEN_MINUTES_MS, - ) - this._fetchAndSetSwapsLiveness() + ); + this._fetchAndSetSwapsLiveness(); } - } + }; - window.addEventListener('online', fetchAndSetupInterval) + window.addEventListener('online', fetchAndSetupInterval); window.addEventListener('offline', () => { if (intervalId !== null) { - clearInterval(intervalId) - intervalId = null + clearInterval(intervalId); + intervalId = null; - const { swapsState } = this.store.getState() + const { swapsState } = this.store.getState(); if (swapsState.swapsFeatureIsLive) { - this.setSwapsLiveness(false) + this.setSwapsLiveness(false); } } - }) + }); - fetchAndSetupInterval() + fetchAndSetupInterval(); } /** @@ -716,41 +721,41 @@ export default class SwapsController { * state. */ async _fetchAndSetSwapsLiveness() { - const { swapsState } = this.store.getState() - const { swapsFeatureIsLive: oldSwapsFeatureIsLive } = swapsState - let swapsFeatureIsLive = false - let successfullyFetched = false - let numAttempts = 0 + const { swapsState } = this.store.getState(); + const { swapsFeatureIsLive: oldSwapsFeatureIsLive } = swapsState; + let swapsFeatureIsLive = false; + let successfullyFetched = false; + let numAttempts = 0; const fetchAndIncrementNumAttempts = async () => { try { - swapsFeatureIsLive = Boolean(await this._fetchSwapsFeatureLiveness()) - successfullyFetched = true + swapsFeatureIsLive = Boolean(await this._fetchSwapsFeatureLiveness()); + successfullyFetched = true; } catch (err) { - log.error(err) - numAttempts += 1 + log.error(err); + numAttempts += 1; } - } + }; - await fetchAndIncrementNumAttempts() + await fetchAndIncrementNumAttempts(); // The loop conditions are modified by fetchAndIncrementNumAttempts. // eslint-disable-next-line no-unmodified-loop-condition while (!successfullyFetched && numAttempts < 3) { await new Promise((resolve) => { - setTimeout(resolve, 5000) // 5 seconds - }) - await fetchAndIncrementNumAttempts() + setTimeout(resolve, 5000); // 5 seconds + }); + await fetchAndIncrementNumAttempts(); } if (!successfullyFetched) { log.error( 'Failed to fetch swaps feature flag 3 times. Setting to false and trying again next interval.', - ) + ); } if (swapsFeatureIsLive !== oldSwapsFeatureIsLive) { - this.setSwapsLiveness(swapsFeatureIsLive) + this.setSwapsLiveness(swapsFeatureIsLive); } } } @@ -763,50 +768,50 @@ export default class SwapsController { */ function getMedianEthValueQuote(_quotes) { if (!Array.isArray(_quotes) || _quotes.length === 0) { - throw new Error('Expected non-empty array param.') + throw new Error('Expected non-empty array param.'); } - const quotes = [..._quotes] + const quotes = [..._quotes]; quotes.sort((quoteA, quoteB) => { - const overallValueOfQuoteA = new BigNumber(quoteA.overallValueOfQuote, 10) - const overallValueOfQuoteB = new BigNumber(quoteB.overallValueOfQuote, 10) + const overallValueOfQuoteA = new BigNumber(quoteA.overallValueOfQuote, 10); + const overallValueOfQuoteB = new BigNumber(quoteB.overallValueOfQuote, 10); if (overallValueOfQuoteA.equals(overallValueOfQuoteB)) { - return 0 + return 0; } - return overallValueOfQuoteA.lessThan(overallValueOfQuoteB) ? -1 : 1 - }) + return overallValueOfQuoteA.lessThan(overallValueOfQuoteB) ? -1 : 1; + }); if (quotes.length % 2 === 1) { // return middle values const medianOverallValue = - quotes[(quotes.length - 1) / 2].overallValueOfQuote + quotes[(quotes.length - 1) / 2].overallValueOfQuote; const quotesMatchingMedianQuoteValue = quotes.filter( (quote) => medianOverallValue === quote.overallValueOfQuote, - ) - return meansOfQuotesFeesAndValue(quotesMatchingMedianQuoteValue) + ); + return meansOfQuotesFeesAndValue(quotesMatchingMedianQuoteValue); } // return mean of middle two values - const upperIndex = quotes.length / 2 - const lowerIndex = upperIndex - 1 + const upperIndex = quotes.length / 2; + const lowerIndex = upperIndex - 1; - const overallValueAtUpperIndex = quotes[upperIndex].overallValueOfQuote - const overallValueAtLowerIndex = quotes[lowerIndex].overallValueOfQuote + const overallValueAtUpperIndex = quotes[upperIndex].overallValueOfQuote; + const overallValueAtLowerIndex = quotes[lowerIndex].overallValueOfQuote; const quotesMatchingUpperIndexValue = quotes.filter( (quote) => overallValueAtUpperIndex === quote.overallValueOfQuote, - ) + ); const quotesMatchingLowerIndexValue = quotes.filter( (quote) => overallValueAtLowerIndex === quote.overallValueOfQuote, - ) + ); const feesAndValueAtUpperIndex = meansOfQuotesFeesAndValue( quotesMatchingUpperIndexValue, - ) + ); const feesAndValueAtLowerIndex = meansOfQuotesFeesAndValue( quotesMatchingLowerIndexValue, - ) + ); return { ethFee: new BigNumber(feesAndValueAtUpperIndex.ethFee, 10) @@ -827,7 +832,7 @@ function getMedianEthValueQuote(_quotes) { .plus(feesAndValueAtLowerIndex.ethValueOfTokens, 10) .dividedBy(2) .toString(10), - } + }; } /** @@ -857,7 +862,7 @@ function meansOfQuotesFeesAndValue(quotes) { metaMaskFeeInEth: new BigNumber(0, 10), ethValueOfTokens: new BigNumber(0, 10), }, - ) + ); return { ethFee: feeAndValueSumsAsBigNumbers.ethFee @@ -869,10 +874,10 @@ function meansOfQuotesFeesAndValue(quotes) { ethValueOfTokens: feeAndValueSumsAsBigNumbers.ethValueOfTokens .div(quotes.length, 10) .toString(10), - } + }; } export const utils = { getMedianEthValueQuote, meansOfQuotesFeesAndValue, -} +}; diff --git a/app/scripts/controllers/threebox.js b/app/scripts/controllers/threebox.js index d7503b589e..8355fb4fea 100644 --- a/app/scripts/controllers/threebox.js +++ b/app/scripts/controllers/threebox.js @@ -1,21 +1,21 @@ -import { ObservableStore } from '@metamask/obs-store' +import { ObservableStore } from '@metamask/obs-store'; /* eslint-disable import/first,import/order */ const Box = process.env.IN_TEST ? require('../../../development/mock-3box') - : require('3box') + : require('3box'); /* eslint-enable import/order */ -import log from 'loglevel' -import { JsonRpcEngine } from 'json-rpc-engine' -import providerFromEngine from 'eth-json-rpc-middleware/providerFromEngine' -import Migrator from '../lib/migrator' -import migrations from '../migrations' -import createOriginMiddleware from '../lib/createOriginMiddleware' -import createMetamaskMiddleware from './network/createMetamaskMiddleware' +import log from 'loglevel'; +import { JsonRpcEngine } from 'json-rpc-engine'; +import providerFromEngine from 'eth-json-rpc-middleware/providerFromEngine'; +import Migrator from '../lib/migrator'; +import migrations from '../migrations'; +import createOriginMiddleware from '../lib/createOriginMiddleware'; +import createMetamaskMiddleware from './network/createMetamaskMiddleware'; /* eslint-enable import/first */ -const SYNC_TIMEOUT = 60 * 1000 // one minute +const SYNC_TIMEOUT = 60 * 1000; // one minute export default class ThreeBoxController { constructor(opts = {}) { @@ -25,40 +25,40 @@ export default class ThreeBoxController { addressBookController, version, getKeyringControllerState, - } = opts + } = opts; - this.preferencesController = preferencesController - this.addressBookController = addressBookController - this.keyringController = keyringController + this.preferencesController = preferencesController; + this.addressBookController = addressBookController; + this.keyringController = keyringController; this.provider = this._createProvider({ version, getAccounts: async ({ origin }) => { if (origin !== '3Box') { - return [] + return []; } - const { isUnlocked } = getKeyringControllerState() + const { isUnlocked } = getKeyringControllerState(); - const accounts = await this.keyringController.getAccounts() + const accounts = await this.keyringController.getAccounts(); if (isUnlocked && accounts[0]) { const appKeyAddress = await this.keyringController.getAppKeyAddress( accounts[0], 'wallet://3box.metamask.io', - ) - return [appKeyAddress] + ); + return [appKeyAddress]; } - return [] + return []; }, processPersonalMessage: async (msgParams) => { - const accounts = await this.keyringController.getAccounts() + const accounts = await this.keyringController.getAccounts(); return keyringController.signPersonalMessage( { ...msgParams, from: accounts[0] }, { withAppKeyOrigin: 'wallet://3box.metamask.io', }, - ) + ); }, - }) + }); const initState = { threeBoxSyncingAllowed: false, @@ -68,193 +68,196 @@ export default class ThreeBoxController { threeBoxAddress: null, threeBoxSynced: false, threeBoxDisabled: false, - } - this.store = new ObservableStore(initState) - this.registeringUpdates = false + }; + this.store = new ObservableStore(initState); + this.registeringUpdates = false; this.lastMigration = migrations .sort((a, b) => a.version - b.version) - .slice(-1)[0] + .slice(-1)[0]; if (initState.threeBoxSyncingAllowed) { - this.init() + this.init(); } } async init() { - const accounts = await this.keyringController.getAccounts() - this.address = accounts[0] + const accounts = await this.keyringController.getAccounts(); + this.address = accounts[0]; if (this.address && !(this.box && this.store.getState().threeBoxSynced)) { - await this.new3Box() + await this.new3Box(); } } async _update3Box() { try { - const { threeBoxSyncingAllowed, threeBoxSynced } = this.store.getState() + const { threeBoxSyncingAllowed, threeBoxSynced } = this.store.getState(); if (threeBoxSyncingAllowed && threeBoxSynced) { const newState = { preferences: this.preferencesController.store.getState(), addressBook: this.addressBookController.state, lastUpdated: Date.now(), lastMigration: this.lastMigration, - } + }; - await this.space.private.set('metamaskBackup', JSON.stringify(newState)) - await this.setShowRestorePromptToFalse() + await this.space.private.set( + 'metamaskBackup', + JSON.stringify(newState), + ); + await this.setShowRestorePromptToFalse(); } } catch (error) { - console.error(error) + console.error(error); } } _createProvider(providerOpts) { - const metamaskMiddleware = createMetamaskMiddleware(providerOpts) - const engine = new JsonRpcEngine() - engine.push(createOriginMiddleware({ origin: '3Box' })) - engine.push(metamaskMiddleware) - const provider = providerFromEngine(engine) - return provider + const metamaskMiddleware = createMetamaskMiddleware(providerOpts); + const engine = new JsonRpcEngine(); + engine.push(createOriginMiddleware({ origin: '3Box' })); + engine.push(metamaskMiddleware); + const provider = providerFromEngine(engine); + return provider; } _waitForOnSyncDone() { return new Promise((resolve) => { this.box.onSyncDone(() => { - log.debug('3Box box sync done') - return resolve() - }) - }) + log.debug('3Box box sync done'); + return resolve(); + }); + }); } async new3Box() { - const accounts = await this.keyringController.getAccounts() + const accounts = await this.keyringController.getAccounts(); this.address = await this.keyringController.getAppKeyAddress( accounts[0], 'wallet://3box.metamask.io', - ) - let backupExists + ); + let backupExists; try { - const threeBoxConfig = await Box.getConfig(this.address) - backupExists = threeBoxConfig.spaces && threeBoxConfig.spaces.metamask + const threeBoxConfig = await Box.getConfig(this.address); + backupExists = threeBoxConfig.spaces && threeBoxConfig.spaces.metamask; } catch (e) { if (e.message.match(/^Error: Invalid response \(404\)/u)) { - backupExists = false + backupExists = false; } else { - throw e + throw e; } } if (this.getThreeBoxSyncingState() || backupExists) { - this.store.updateState({ threeBoxSynced: false }) + this.store.updateState({ threeBoxSynced: false }); - let timedOut = false + let timedOut = false; const syncTimeout = setTimeout(() => { - log.error(`3Box sync timed out after ${SYNC_TIMEOUT} ms`) - timedOut = true + log.error(`3Box sync timed out after ${SYNC_TIMEOUT} ms`); + timedOut = true; this.store.updateState({ threeBoxDisabled: true, threeBoxSyncingAllowed: false, - }) - }, SYNC_TIMEOUT) + }); + }, SYNC_TIMEOUT); try { - this.box = await Box.openBox(this.address, this.provider) - await this._waitForOnSyncDone() + this.box = await Box.openBox(this.address, this.provider); + await this._waitForOnSyncDone(); this.space = await this.box.openSpace('metamask', { onSyncDone: async () => { const stateUpdate = { threeBoxSynced: true, threeBoxAddress: this.address, - } + }; if (timedOut) { - log.info(`3Box sync completed after timeout; no longer disabled`) - stateUpdate.threeBoxDisabled = false + log.info(`3Box sync completed after timeout; no longer disabled`); + stateUpdate.threeBoxDisabled = false; } - clearTimeout(syncTimeout) - this.store.updateState(stateUpdate) + clearTimeout(syncTimeout); + this.store.updateState(stateUpdate); - log.debug('3Box space sync done') + log.debug('3Box space sync done'); }, - }) + }); } catch (e) { - console.error(e) - throw e + console.error(e); + throw e; } } } async getLastUpdated() { - const res = await this.space.private.get('metamaskBackup') - const parsedRes = JSON.parse(res || '{}') - return parsedRes.lastUpdated + const res = await this.space.private.get('metamaskBackup'); + const parsedRes = JSON.parse(res || '{}'); + return parsedRes.lastUpdated; } async migrateBackedUpState(backedUpState) { - const migrator = new Migrator({ migrations }) - const { preferences, addressBook } = JSON.parse(backedUpState) + const migrator = new Migrator({ migrations }); + const { preferences, addressBook } = JSON.parse(backedUpState); const formattedStateBackup = { PreferencesController: preferences, AddressBookController: addressBook, - } + }; const initialMigrationState = migrator.generateInitialState( formattedStateBackup, - ) - const migratedState = await migrator.migrateData(initialMigrationState) + ); + const migratedState = await migrator.migrateData(initialMigrationState); return { preferences: migratedState.data.PreferencesController, addressBook: migratedState.data.AddressBookController, - } + }; } async restoreFromThreeBox() { - const backedUpState = await this.space.private.get('metamaskBackup') + const backedUpState = await this.space.private.get('metamaskBackup'); const { preferences, addressBook } = await this.migrateBackedUpState( backedUpState, - ) - this.store.updateState({ threeBoxLastUpdated: backedUpState.lastUpdated }) - preferences && this.preferencesController.store.updateState(preferences) - addressBook && this.addressBookController.update(addressBook, true) - this.setShowRestorePromptToFalse() + ); + this.store.updateState({ threeBoxLastUpdated: backedUpState.lastUpdated }); + preferences && this.preferencesController.store.updateState(preferences); + addressBook && this.addressBookController.update(addressBook, true); + this.setShowRestorePromptToFalse(); } turnThreeBoxSyncingOn() { - this._registerUpdates() + this._registerUpdates(); } turnThreeBoxSyncingOff() { - this.box.logout() + this.box.logout(); } setShowRestorePromptToFalse() { - this.store.updateState({ showRestorePrompt: false }) + this.store.updateState({ showRestorePrompt: false }); } setThreeBoxSyncingPermission(newThreeboxSyncingState) { if (this.store.getState().threeBoxDisabled) { - return + return; } this.store.updateState({ threeBoxSyncingAllowed: newThreeboxSyncingState, - }) + }); if (newThreeboxSyncingState && this.box) { - this.turnThreeBoxSyncingOn() + this.turnThreeBoxSyncingOn(); } if (!newThreeboxSyncingState && this.box) { - this.turnThreeBoxSyncingOff() + this.turnThreeBoxSyncingOff(); } } getThreeBoxSyncingState() { - return this.store.getState().threeBoxSyncingAllowed + return this.store.getState().threeBoxSyncingAllowed; } _registerUpdates() { if (!this.registeringUpdates) { - const updatePreferences = this._update3Box.bind(this) - this.preferencesController.store.subscribe(updatePreferences) - const updateAddressBook = this._update3Box.bind(this) - this.addressBookController.subscribe(updateAddressBook) - this.registeringUpdates = true + const updatePreferences = this._update3Box.bind(this); + this.preferencesController.store.subscribe(updatePreferences); + const updateAddressBook = this._update3Box.bind(this); + this.addressBookController.subscribe(updateAddressBook); + this.registeringUpdates = true; } } } diff --git a/app/scripts/controllers/token-rates.js b/app/scripts/controllers/token-rates.js index 031017c838..a3f0f67109 100644 --- a/app/scripts/controllers/token-rates.js +++ b/app/scripts/controllers/token-rates.js @@ -1,13 +1,13 @@ -import { ObservableStore } from '@metamask/obs-store' -import log from 'loglevel' -import { normalize as normalizeAddress } from 'eth-sig-util' -import ethUtil from 'ethereumjs-util' -import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout' +import { ObservableStore } from '@metamask/obs-store'; +import log from 'loglevel'; +import { normalize as normalizeAddress } from 'eth-sig-util'; +import ethUtil from 'ethereumjs-util'; +import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout'; -const fetchWithTimeout = getFetchWithTimeout(30000) +const fetchWithTimeout = getFetchWithTimeout(30000); // By default, poll every 3 minutes -const DEFAULT_INTERVAL = 180 * 1000 +const DEFAULT_INTERVAL = 180 * 1000; /** * A controller that polls for token exchange @@ -20,43 +20,43 @@ export default class TokenRatesController { * @param {Object} [config] - Options to configure controller */ constructor({ currency, preferences } = {}) { - this.store = new ObservableStore() - this.currency = currency - this.preferences = preferences + this.store = new ObservableStore(); + this.currency = currency; + this.preferences = preferences; } /** * Updates exchange rates for all tokens */ async updateExchangeRates() { - const contractExchangeRates = {} + const contractExchangeRates = {}; const nativeCurrency = this.currency ? this.currency.state.nativeCurrency.toLowerCase() - : 'eth' - const pairs = this._tokens.map((token) => token.address).join(',') - const query = `contract_addresses=${pairs}&vs_currencies=${nativeCurrency}` + : 'eth'; + const pairs = this._tokens.map((token) => token.address).join(','); + const query = `contract_addresses=${pairs}&vs_currencies=${nativeCurrency}`; if (this._tokens.length > 0) { try { const response = await fetchWithTimeout( `https://api.coingecko.com/api/v3/simple/token_price/ethereum?${query}`, - ) - const prices = await response.json() + ); + const prices = await response.json(); this._tokens.forEach((token) => { const price = prices[token.address.toLowerCase()] || - prices[ethUtil.toChecksumAddress(token.address)] + prices[ethUtil.toChecksumAddress(token.address)]; contractExchangeRates[normalizeAddress(token.address)] = price ? price[nativeCurrency] - : 0 - }) + : 0; + }); } catch (error) { log.warn( `MetaMask - TokenRatesController exchange rate fetch failed.`, error, - ) + ); } } - this.store.putState({ contractExchangeRates }) + this.store.putState({ contractExchangeRates }); } /* eslint-disable accessor-pairs */ @@ -64,38 +64,38 @@ export default class TokenRatesController { * @type {Object} */ set preferences(preferences) { - this._preferences && this._preferences.unsubscribe() + this._preferences && this._preferences.unsubscribe(); if (!preferences) { - return + return; } - this._preferences = preferences - this.tokens = preferences.getState().tokens + this._preferences = preferences; + this.tokens = preferences.getState().tokens; preferences.subscribe(({ tokens = [] }) => { - this.tokens = tokens - }) + this.tokens = tokens; + }); } /** * @type {Array} */ set tokens(tokens) { - this._tokens = tokens - this.updateExchangeRates() + this._tokens = tokens; + this.updateExchangeRates(); } /* eslint-enable accessor-pairs */ start(interval = DEFAULT_INTERVAL) { - this._handle && clearInterval(this._handle) + this._handle && clearInterval(this._handle); if (!interval) { - return + return; } this._handle = setInterval(() => { - this.updateExchangeRates() - }, interval) - this.updateExchangeRates() + this.updateExchangeRates(); + }, interval); + this.updateExchangeRates(); } stop() { - this._handle && clearInterval(this._handle) + this._handle && clearInterval(this._handle); } } diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js index a88cfff649..36864c509f 100644 --- a/app/scripts/controllers/transactions/index.js +++ b/app/scripts/controllers/transactions/index.js @@ -1,37 +1,37 @@ -import EventEmitter from 'safe-event-emitter' -import { ObservableStore } from '@metamask/obs-store' -import ethUtil from 'ethereumjs-util' -import Transaction from 'ethereumjs-tx' -import EthQuery from 'ethjs-query' -import { ethErrors } from 'eth-rpc-errors' -import abi from 'human-standard-token-abi' -import { ethers } from 'ethers' -import NonceTracker from 'nonce-tracker' -import log from 'loglevel' -import BigNumber from 'bignumber.js' -import cleanErrorStack from '../../lib/cleanErrorStack' +import EventEmitter from 'safe-event-emitter'; +import { ObservableStore } from '@metamask/obs-store'; +import ethUtil from 'ethereumjs-util'; +import Transaction from 'ethereumjs-tx'; +import EthQuery from 'ethjs-query'; +import { ethErrors } from 'eth-rpc-errors'; +import abi from 'human-standard-token-abi'; +import { ethers } from 'ethers'; +import NonceTracker from 'nonce-tracker'; +import log from 'loglevel'; +import BigNumber from 'bignumber.js'; +import cleanErrorStack from '../../lib/cleanErrorStack'; import { hexToBn, bnToHex, BnMultiplyByFraction, addHexPrefix, -} from '../../lib/util' -import { TRANSACTION_NO_CONTRACT_ERROR_KEY } from '../../../../ui/app/helpers/constants/error-keys' -import { getSwapsTokensReceivedFromTxMeta } from '../../../../ui/app/pages/swaps/swaps.util' +} from '../../lib/util'; +import { TRANSACTION_NO_CONTRACT_ERROR_KEY } from '../../../../ui/app/helpers/constants/error-keys'; +import { getSwapsTokensReceivedFromTxMeta } from '../../../../ui/app/pages/swaps/swaps.util'; import { TRANSACTION_CATEGORIES, TRANSACTION_STATUSES, TRANSACTION_TYPES, -} from '../../../../shared/constants/transaction' -import TransactionStateManager from './tx-state-manager' -import TxGasUtil from './tx-gas-utils' -import PendingTransactionTracker from './pending-tx-tracker' -import * as txUtils from './lib/util' +} from '../../../../shared/constants/transaction'; +import TransactionStateManager from './tx-state-manager'; +import TxGasUtil from './tx-gas-utils'; +import PendingTransactionTracker from './pending-tx-tracker'; +import * as txUtils from './lib/util'; -const hstInterface = new ethers.utils.Interface(abi) +const hstInterface = new ethers.utils.Interface(abi); -const SIMPLE_GAS_COST = '0x5208' // Hex for 21000, cost of a simple send. -const MAX_MEMSTORE_TX_LIST_SIZE = 100 // Number of transactions (by unique nonces) to keep in memory +const SIMPLE_GAS_COST = '0x5208'; // Hex for 21000, cost of a simple send. +const MAX_MEMSTORE_TX_LIST_SIZE = 100; // Number of transactions (by unique nonces) to keep in memory /** Transaction Controller is an aggregate of sub-controllers and trackers @@ -62,31 +62,31 @@ const MAX_MEMSTORE_TX_LIST_SIZE = 100 // Number of transactions (by unique nonce export default class TransactionController extends EventEmitter { constructor(opts) { - super() - this.networkStore = opts.networkStore || new ObservableStore({}) - this._getCurrentChainId = opts.getCurrentChainId - this.preferencesStore = opts.preferencesStore || new ObservableStore({}) - this.provider = opts.provider - this.getPermittedAccounts = opts.getPermittedAccounts - this.blockTracker = opts.blockTracker - this.signEthTx = opts.signTransaction - this.inProcessOfSigning = new Set() - this._trackMetaMetricsEvent = opts.trackMetaMetricsEvent - this._getParticipateInMetrics = opts.getParticipateInMetrics - - this.memStore = new ObservableStore({}) - this.query = new EthQuery(this.provider) - - this.txGasUtil = new TxGasUtil(this.provider) - this._mapMethods() + super(); + this.networkStore = opts.networkStore || new ObservableStore({}); + this._getCurrentChainId = opts.getCurrentChainId; + this.preferencesStore = opts.preferencesStore || new ObservableStore({}); + this.provider = opts.provider; + this.getPermittedAccounts = opts.getPermittedAccounts; + this.blockTracker = opts.blockTracker; + this.signEthTx = opts.signTransaction; + this.inProcessOfSigning = new Set(); + this._trackMetaMetricsEvent = opts.trackMetaMetricsEvent; + this._getParticipateInMetrics = opts.getParticipateInMetrics; + + this.memStore = new ObservableStore({}); + this.query = new EthQuery(this.provider); + + this.txGasUtil = new TxGasUtil(this.provider); + this._mapMethods(); this.txStateManager = new TransactionStateManager({ initState: opts.initState, txHistoryLimit: opts.txHistoryLimit, getNetwork: this.getNetwork.bind(this), - }) - this._onBootCleanUp() + }); + this._onBootCleanUp(); - this.store = this.txStateManager.store + this.store = this.txStateManager.store; this.nonceTracker = new NonceTracker({ provider: this.provider, blockTracker: this.blockTracker, @@ -96,35 +96,35 @@ export default class TransactionController extends EventEmitter { getConfirmedTransactions: this.txStateManager.getConfirmedTransactions.bind( this.txStateManager, ), - }) + }); this.pendingTxTracker = new PendingTransactionTracker({ provider: this.provider, nonceTracker: this.nonceTracker, publishTransaction: (rawTx) => this.query.sendRawTransaction(rawTx), getPendingTransactions: () => { - const pending = this.txStateManager.getPendingTransactions() - const approved = this.txStateManager.getApprovedTransactions() - return [...pending, ...approved] + const pending = this.txStateManager.getPendingTransactions(); + const approved = this.txStateManager.getApprovedTransactions(); + return [...pending, ...approved]; }, approveTransaction: this.approveTransaction.bind(this), getCompletedTransactions: this.txStateManager.getConfirmedTransactions.bind( this.txStateManager, ), - }) + }); - this.txStateManager.store.subscribe(() => this.emit('update:badge')) - this._setupListeners() + this.txStateManager.store.subscribe(() => this.emit('update:badge')); + this._setupListeners(); // memstore is computed from a few different stores - this._updateMemstore() - this.txStateManager.store.subscribe(() => this._updateMemstore()) + this._updateMemstore(); + this.txStateManager.store.subscribe(() => this._updateMemstore()); this.networkStore.subscribe(() => { - this._onBootCleanUp() - this._updateMemstore() - }) + this._onBootCleanUp(); + this._updateMemstore(); + }); // request state update to finalize initialization - this._updatePendingTxsAfterFirstBlock() + this._updatePendingTxsAfterFirstBlock(); } /** @@ -134,13 +134,13 @@ export default class TransactionController extends EventEmitter { * @returns {number} The numerical chainId. */ getChainId() { - const networkState = this.networkStore.getState() - const chainId = this._getCurrentChainId() - const integerChainId = parseInt(chainId, 16) + const networkState = this.networkStore.getState(); + const chainId = this._getCurrentChainId(); + const integerChainId = parseInt(chainId, 16); if (networkState === 'loading' || Number.isNaN(integerChainId)) { - return 0 + return 0; } - return integerChainId + return integerChainId; } /** @@ -148,8 +148,8 @@ export default class TransactionController extends EventEmitter { @emits ${txMeta.id}:unapproved */ addTx(txMeta) { - this.txStateManager.addTx(txMeta) - this.emit(`${txMeta.id}:unapproved`, txMeta) + this.txStateManager.addTx(txMeta); + this.emit(`${txMeta.id}:unapproved`, txMeta); } /** @@ -157,7 +157,7 @@ export default class TransactionController extends EventEmitter { @param {string} address - hex string of the from address for txs being removed */ wipeTransactions(address) { - this.txStateManager.wipeTransactions(address) + this.txStateManager.wipeTransactions(address); } /** @@ -170,12 +170,12 @@ export default class TransactionController extends EventEmitter { async newUnapprovedTransaction(txParams, opts = {}) { log.debug( `MetaMaskController newUnapprovedTransaction ${JSON.stringify(txParams)}`, - ) + ); const initialTxMeta = await this.addUnapprovedTransaction( txParams, opts.origin, - ) + ); // listen for tx completion (success, fail) return new Promise((resolve, reject) => { @@ -184,7 +184,7 @@ export default class TransactionController extends EventEmitter { (finishedTxMeta) => { switch (finishedTxMeta.status) { case TRANSACTION_STATUSES.SUBMITTED: - return resolve(finishedTxMeta.hash) + return resolve(finishedTxMeta.hash); case TRANSACTION_STATUSES.REJECTED: return reject( cleanErrorStack( @@ -192,13 +192,13 @@ export default class TransactionController extends EventEmitter { 'MetaMask Tx Signature: User denied transaction signature.', ), ), - ) + ); case TRANSACTION_STATUSES.FAILED: return reject( cleanErrorStack( ethErrors.rpc.internal(finishedTxMeta.err.message), ), - ) + ); default: return reject( cleanErrorStack( @@ -208,11 +208,11 @@ export default class TransactionController extends EventEmitter { )}`, ), ), - ) + ); } }, - ) - }) + ); + }); } /** @@ -223,9 +223,9 @@ export default class TransactionController extends EventEmitter { */ async addUnapprovedTransaction(txParams, origin) { // validate - const normalizedTxParams = txUtils.normalizeTxParams(txParams) + const normalizedTxParams = txUtils.normalizeTxParams(txParams); - txUtils.validateTxParams(normalizedTxParams) + txUtils.validateTxParams(normalizedTxParams); /** `generateTxMeta` adds the default txMeta properties to the passed object. @@ -236,7 +236,7 @@ export default class TransactionController extends EventEmitter { let txMeta = this.txStateManager.generateTxMeta({ txParams: normalizedTxParams, type: TRANSACTION_TYPES.STANDARD, - }) + }); if (origin === 'metamask') { // Assert the from address is the selected address @@ -248,48 +248,48 @@ export default class TransactionController extends EventEmitter { fromAddress: normalizedTxParams.from, selectedAddress: this.getSelectedAddress(), }, - }) + }); } } else { // Assert that the origin has permissions to initiate transactions from // the specified address - const permittedAddresses = await this.getPermittedAccounts(origin) + const permittedAddresses = await this.getPermittedAccounts(origin); if (!permittedAddresses.includes(normalizedTxParams.from)) { - throw ethErrors.provider.unauthorized({ data: { origin } }) + throw ethErrors.provider.unauthorized({ data: { origin } }); } } - txMeta.origin = origin + txMeta.origin = origin; const { transactionCategory, getCodeResponse, - } = await this._determineTransactionCategory(txParams) - txMeta.transactionCategory = transactionCategory + } = await this._determineTransactionCategory(txParams); + txMeta.transactionCategory = transactionCategory; // ensure value txMeta.txParams.value = txMeta.txParams.value ? addHexPrefix(txMeta.txParams.value) - : '0x0' + : '0x0'; - this.addTx(txMeta) - this.emit('newUnapprovedTx', txMeta) + this.addTx(txMeta); + this.emit('newUnapprovedTx', txMeta); try { - txMeta = await this.addTxGasDefaults(txMeta, getCodeResponse) + txMeta = await this.addTxGasDefaults(txMeta, getCodeResponse); } catch (error) { - log.warn(error) - txMeta = this.txStateManager.getTx(txMeta.id) - txMeta.loadingDefaults = false - this.txStateManager.updateTx(txMeta, 'Failed to calculate gas defaults.') - throw error + log.warn(error); + txMeta = this.txStateManager.getTx(txMeta.id); + txMeta.loadingDefaults = false; + this.txStateManager.updateTx(txMeta, 'Failed to calculate gas defaults.'); + throw error; } - txMeta.loadingDefaults = false + txMeta.loadingDefaults = false; // save txMeta - this.txStateManager.updateTx(txMeta, 'Added new unapproved transaction.') + this.txStateManager.updateTx(txMeta, 'Added new unapproved transaction.'); - return txMeta + return txMeta; } /** @@ -298,24 +298,24 @@ export default class TransactionController extends EventEmitter { * @returns {Promise} resolves with txMeta */ async addTxGasDefaults(txMeta, getCodeResponse) { - const defaultGasPrice = await this._getDefaultGasPrice(txMeta) + const defaultGasPrice = await this._getDefaultGasPrice(txMeta); const { gasLimit: defaultGasLimit, simulationFails, - } = await this._getDefaultGasLimit(txMeta, getCodeResponse) + } = await this._getDefaultGasLimit(txMeta, getCodeResponse); // eslint-disable-next-line no-param-reassign - txMeta = this.txStateManager.getTx(txMeta.id) + txMeta = this.txStateManager.getTx(txMeta.id); if (simulationFails) { - txMeta.simulationFails = simulationFails + txMeta.simulationFails = simulationFails; } if (defaultGasPrice && !txMeta.txParams.gasPrice) { - txMeta.txParams.gasPrice = defaultGasPrice + txMeta.txParams.gasPrice = defaultGasPrice; } if (defaultGasLimit && !txMeta.txParams.gas) { - txMeta.txParams.gas = defaultGasLimit + txMeta.txParams.gas = defaultGasLimit; } - return txMeta + return txMeta; } /** @@ -325,11 +325,11 @@ export default class TransactionController extends EventEmitter { */ async _getDefaultGasPrice(txMeta) { if (txMeta.txParams.gasPrice) { - return undefined + return undefined; } - const gasPrice = await this.query.gasPrice() + const gasPrice = await this.query.gasPrice(); - return addHexPrefix(gasPrice.toString(16)) + return addHexPrefix(gasPrice.toString(16)); } /** @@ -340,7 +340,7 @@ export default class TransactionController extends EventEmitter { */ async _getDefaultGasLimit(txMeta, getCodeResponse) { if (txMeta.txParams.gas) { - return {} + return {}; } else if ( txMeta.txParams.to && txMeta.transactionCategory === TRANSACTION_CATEGORIES.SENT_ETHER @@ -349,31 +349,31 @@ export default class TransactionController extends EventEmitter { if (txMeta.txParams.data) { const err = new Error( 'TxGasUtil - Trying to call a function on a non-contract address', - ) + ); // set error key so ui can display localized error message - err.errorKey = TRANSACTION_NO_CONTRACT_ERROR_KEY + err.errorKey = TRANSACTION_NO_CONTRACT_ERROR_KEY; // set the response on the error so that we can see in logs what the actual response was - err.getCodeResponse = getCodeResponse - throw err + err.getCodeResponse = getCodeResponse; + throw err; } // This is a standard ether simple send, gas requirement is exactly 21k - return { gasLimit: SIMPLE_GAS_COST } + return { gasLimit: SIMPLE_GAS_COST }; } const { blockGasLimit, estimatedGasHex, simulationFails, - } = await this.txGasUtil.analyzeGasUsage(txMeta) + } = await this.txGasUtil.analyzeGasUsage(txMeta); // add additional gas buffer to our estimation for safety const gasLimit = this.txGasUtil.addGasBuffer( addHexPrefix(estimatedGasHex), blockGasLimit, - ) - return { gasLimit, simulationFails } + ); + return { gasLimit, simulationFails }; } /** @@ -385,13 +385,13 @@ export default class TransactionController extends EventEmitter { * @returns {txMeta} */ async createCancelTransaction(originalTxId, customGasPrice) { - const originalTxMeta = this.txStateManager.getTx(originalTxId) - const { txParams } = originalTxMeta - const { gasPrice: lastGasPrice, from, nonce } = txParams + const originalTxMeta = this.txStateManager.getTx(originalTxId); + const { txParams } = originalTxMeta; + const { gasPrice: lastGasPrice, from, nonce } = txParams; const newGasPrice = customGasPrice || - bnToHex(BnMultiplyByFraction(hexToBn(lastGasPrice), 11, 10)) + bnToHex(BnMultiplyByFraction(hexToBn(lastGasPrice), 11, 10)); const newTxMeta = this.txStateManager.generateTxMeta({ txParams: { from, @@ -405,11 +405,11 @@ export default class TransactionController extends EventEmitter { loadingDefaults: false, status: TRANSACTION_STATUSES.APPROVED, type: TRANSACTION_TYPES.CANCEL, - }) + }); - this.addTx(newTxMeta) - await this.approveTransaction(newTxMeta.id) - return newTxMeta + this.addTx(newTxMeta); + await this.approveTransaction(newTxMeta.id); + return newTxMeta; } /** @@ -423,13 +423,13 @@ export default class TransactionController extends EventEmitter { * @returns {txMeta} */ async createSpeedUpTransaction(originalTxId, customGasPrice, customGasLimit) { - const originalTxMeta = this.txStateManager.getTx(originalTxId) - const { txParams } = originalTxMeta - const { gasPrice: lastGasPrice } = txParams + const originalTxMeta = this.txStateManager.getTx(originalTxId); + const { txParams } = originalTxMeta; + const { gasPrice: lastGasPrice } = txParams; const newGasPrice = customGasPrice || - bnToHex(BnMultiplyByFraction(hexToBn(lastGasPrice), 11, 10)) + bnToHex(BnMultiplyByFraction(hexToBn(lastGasPrice), 11, 10)); const newTxMeta = this.txStateManager.generateTxMeta({ txParams: { @@ -440,15 +440,15 @@ export default class TransactionController extends EventEmitter { loadingDefaults: false, status: TRANSACTION_STATUSES.APPROVED, type: TRANSACTION_TYPES.RETRY, - }) + }); if (customGasLimit) { - newTxMeta.txParams.gas = customGasLimit + newTxMeta.txParams.gas = customGasLimit; } - this.addTx(newTxMeta) - await this.approveTransaction(newTxMeta.id) - return newTxMeta + this.addTx(newTxMeta); + await this.approveTransaction(newTxMeta.id); + return newTxMeta; } /** @@ -456,7 +456,7 @@ export default class TransactionController extends EventEmitter { @param {Object} txMeta - the updated txMeta */ async updateTransaction(txMeta) { - this.txStateManager.updateTx(txMeta, 'confTx: user updated transaction') + this.txStateManager.updateTx(txMeta, 'confTx: user updated transaction'); } /** @@ -464,8 +464,8 @@ export default class TransactionController extends EventEmitter { @param {Object} txMeta */ async updateAndApproveTransaction(txMeta) { - this.txStateManager.updateTx(txMeta, 'confTx: user approved transaction') - await this.approveTransaction(txMeta.id) + this.txStateManager.updateTx(txMeta, 'confTx: user approved transaction'); + await this.approveTransaction(txMeta.id); } /** @@ -483,56 +483,56 @@ export default class TransactionController extends EventEmitter { // So that we do not increment nonce + resubmit something // that is already being incremented & signed. if (this.inProcessOfSigning.has(txId)) { - return + return; } - this.inProcessOfSigning.add(txId) - let nonceLock + this.inProcessOfSigning.add(txId); + let nonceLock; try { // approve - this.txStateManager.setTxStatusApproved(txId) + this.txStateManager.setTxStatusApproved(txId); // get next nonce - const txMeta = this.txStateManager.getTx(txId) - const fromAddress = txMeta.txParams.from + const txMeta = this.txStateManager.getTx(txId); + const fromAddress = txMeta.txParams.from; // wait for a nonce - let { customNonceValue } = txMeta - customNonceValue = Number(customNonceValue) - nonceLock = await this.nonceTracker.getNonceLock(fromAddress) + let { customNonceValue } = txMeta; + customNonceValue = Number(customNonceValue); + nonceLock = await this.nonceTracker.getNonceLock(fromAddress); // add nonce to txParams // if txMeta has lastGasPrice then it is a retry at same nonce with higher // gas price transaction and their for the nonce should not be calculated const nonce = txMeta.lastGasPrice ? txMeta.txParams.nonce - : nonceLock.nextNonce + : nonceLock.nextNonce; const customOrNonce = - customNonceValue === 0 ? customNonceValue : customNonceValue || nonce + customNonceValue === 0 ? customNonceValue : customNonceValue || nonce; - txMeta.txParams.nonce = addHexPrefix(customOrNonce.toString(16)) + txMeta.txParams.nonce = addHexPrefix(customOrNonce.toString(16)); // add nonce debugging information to txMeta - txMeta.nonceDetails = nonceLock.nonceDetails + txMeta.nonceDetails = nonceLock.nonceDetails; if (customNonceValue) { - txMeta.nonceDetails.customNonceValue = customNonceValue + txMeta.nonceDetails.customNonceValue = customNonceValue; } - this.txStateManager.updateTx(txMeta, 'transactions#approveTransaction') + this.txStateManager.updateTx(txMeta, 'transactions#approveTransaction'); // sign transaction - const rawTx = await this.signTransaction(txId) - await this.publishTransaction(txId, rawTx) + const rawTx = await this.signTransaction(txId); + await this.publishTransaction(txId, rawTx); // must set transaction to submitted/failed before releasing lock - nonceLock.releaseLock() + nonceLock.releaseLock(); } catch (err) { // this is try-catch wrapped so that we can guarantee that the nonceLock is released try { - this.txStateManager.setTxStatusFailed(txId, err) + this.txStateManager.setTxStatusFailed(txId, err); } catch (err2) { - log.error(err2) + log.error(err2); } // must set transaction to submitted/failed before releasing lock if (nonceLock) { - nonceLock.releaseLock() + nonceLock.releaseLock(); } // continue with error chain - throw err + throw err; } finally { - this.inProcessOfSigning.delete(txId) + this.inProcessOfSigning.delete(txId); } } @@ -542,30 +542,30 @@ export default class TransactionController extends EventEmitter { @returns {string} rawTx */ async signTransaction(txId) { - const txMeta = this.txStateManager.getTx(txId) + const txMeta = this.txStateManager.getTx(txId); // add network/chain id - const chainId = this.getChainId() - const txParams = { ...txMeta.txParams, chainId } + const chainId = this.getChainId(); + const txParams = { ...txMeta.txParams, chainId }; // sign tx - const fromAddress = txParams.from - const ethTx = new Transaction(txParams) - await this.signEthTx(ethTx, fromAddress) + const fromAddress = txParams.from; + const ethTx = new Transaction(txParams); + await this.signEthTx(ethTx, fromAddress); // add r,s,v values for provider request purposes see createMetamaskMiddleware // and JSON rpc standard for further explanation - txMeta.r = ethUtil.bufferToHex(ethTx.r) - txMeta.s = ethUtil.bufferToHex(ethTx.s) - txMeta.v = ethUtil.bufferToHex(ethTx.v) + txMeta.r = ethUtil.bufferToHex(ethTx.r); + txMeta.s = ethUtil.bufferToHex(ethTx.s); + txMeta.v = ethUtil.bufferToHex(ethTx.v); this.txStateManager.updateTx( txMeta, 'transactions#signTransaction: add r, s, v values', - ) + ); // set state to signed - this.txStateManager.setTxStatusSigned(txMeta.id) - const rawTx = ethUtil.bufferToHex(ethTx.serialize()) - return rawTx + this.txStateManager.setTxStatusSigned(txMeta.id); + const rawTx = ethUtil.bufferToHex(ethTx.serialize()); + return rawTx; } /** @@ -575,27 +575,27 @@ export default class TransactionController extends EventEmitter { @returns {Promise} */ async publishTransaction(txId, rawTx) { - const txMeta = this.txStateManager.getTx(txId) - txMeta.rawTx = rawTx + const txMeta = this.txStateManager.getTx(txId); + txMeta.rawTx = rawTx; if (txMeta.transactionCategory === TRANSACTION_CATEGORIES.SWAP) { - const preTxBalance = await this.query.getBalance(txMeta.txParams.from) - txMeta.preTxBalance = preTxBalance.toString(16) + const preTxBalance = await this.query.getBalance(txMeta.txParams.from); + txMeta.preTxBalance = preTxBalance.toString(16); } - this.txStateManager.updateTx(txMeta, 'transactions#publishTransaction') - let txHash + this.txStateManager.updateTx(txMeta, 'transactions#publishTransaction'); + let txHash; try { - txHash = await this.query.sendRawTransaction(rawTx) + txHash = await this.query.sendRawTransaction(rawTx); } catch (error) { if (error.message.toLowerCase().includes('known transaction')) { - txHash = ethUtil.sha3(addHexPrefix(rawTx)).toString('hex') - txHash = addHexPrefix(txHash) + txHash = ethUtil.sha3(addHexPrefix(rawTx)).toString('hex'); + txHash = addHexPrefix(txHash); } else { - throw error + throw error; } } - this.setTxHash(txId, txHash) + this.setTxHash(txId, txHash); - this.txStateManager.setTxStatusSubmitted(txId) + this.txStateManager.setTxStatusSubmitted(txId); } /** @@ -607,10 +607,10 @@ export default class TransactionController extends EventEmitter { async confirmTransaction(txId, txReceipt) { // get the txReceipt before marking the transaction confirmed // to ensure the receipt is gotten before the ui revives the tx - const txMeta = this.txStateManager.getTx(txId) + const txMeta = this.txStateManager.getTx(txId); if (!txMeta) { - return + return; } try { @@ -619,39 +619,39 @@ export default class TransactionController extends EventEmitter { const gasUsed = typeof txReceipt.gasUsed === 'string' ? txReceipt.gasUsed - : txReceipt.gasUsed.toString(16) + : txReceipt.gasUsed.toString(16); txMeta.txReceipt = { ...txReceipt, gasUsed, - } - this.txStateManager.setTxStatusConfirmed(txId) - this._markNonceDuplicatesDropped(txId) + }; + this.txStateManager.setTxStatusConfirmed(txId); + this._markNonceDuplicatesDropped(txId); this.txStateManager.updateTx( txMeta, 'transactions#confirmTransaction - add txReceipt', - ) + ); if (txMeta.transactionCategory === TRANSACTION_CATEGORIES.SWAP) { - const postTxBalance = await this.query.getBalance(txMeta.txParams.from) - const latestTxMeta = this.txStateManager.getTx(txId) + const postTxBalance = await this.query.getBalance(txMeta.txParams.from); + const latestTxMeta = this.txStateManager.getTx(txId); const approvalTxMeta = latestTxMeta.approvalTxId ? this.txStateManager.getTx(latestTxMeta.approvalTxId) - : null + : null; - latestTxMeta.postTxBalance = postTxBalance.toString(16) + latestTxMeta.postTxBalance = postTxBalance.toString(16); this.txStateManager.updateTx( latestTxMeta, 'transactions#confirmTransaction - add postTxBalance', - ) + ); - this._trackSwapsMetrics(latestTxMeta, approvalTxMeta) + this._trackSwapsMetrics(latestTxMeta, approvalTxMeta); } } catch (err) { - log.error(err) + log.error(err); } } @@ -661,7 +661,7 @@ export default class TransactionController extends EventEmitter { @returns {Promise} */ async cancelTransaction(txId) { - this.txStateManager.setTxStatusRejected(txId) + this.txStateManager.setTxStatusRejected(txId); } /** @@ -671,9 +671,9 @@ export default class TransactionController extends EventEmitter { */ setTxHash(txId, txHash) { // Add the tx hash to the persisted meta-tx object - const txMeta = this.txStateManager.getTx(txId) - txMeta.hash = txHash - this.txStateManager.updateTx(txMeta, 'transactions#setTxHash') + const txMeta = this.txStateManager.getTx(txId); + txMeta.hash = txHash; + this.txStateManager.updateTx(txMeta, 'transactions#setTxHash'); } // @@ -682,37 +682,37 @@ export default class TransactionController extends EventEmitter { /** maps methods for convenience*/ _mapMethods() { /** @returns {Object} the state in transaction controller */ - this.getState = () => this.memStore.getState() + this.getState = () => this.memStore.getState(); /** @returns {string|number} the network number stored in networkStore */ - this.getNetwork = () => this.networkStore.getState() + this.getNetwork = () => this.networkStore.getState(); /** @returns {string} the user selected address */ this.getSelectedAddress = () => - this.preferencesStore.getState().selectedAddress + this.preferencesStore.getState().selectedAddress; /** @returns {Array} transactions whos status is unapproved */ this.getUnapprovedTxCount = () => - Object.keys(this.txStateManager.getUnapprovedTxList()).length + Object.keys(this.txStateManager.getUnapprovedTxList()).length; /** @returns {number} number of transactions that have the status submitted @param {string} account - hex prefixed account */ this.getPendingTxCount = (account) => - this.txStateManager.getPendingTransactions(account).length + this.txStateManager.getPendingTransactions(account).length; /** see txStateManager */ this.getFilteredTxList = (opts) => - this.txStateManager.getFilteredTxList(opts) + this.txStateManager.getFilteredTxList(opts); } // called once on startup async _updatePendingTxsAfterFirstBlock() { // wait for first block so we know we're ready - await this.blockTracker.getLatestBlock() + await this.blockTracker.getLatestBlock(); // get status update for all pending transactions (for the current network) - await this.pendingTxTracker.updatePendingTxs() + await this.pendingTxTracker.updatePendingTxs(); } /** @@ -730,22 +730,22 @@ export default class TransactionController extends EventEmitter { .forEach((tx) => { this.addTxGasDefaults(tx) .then((txMeta) => { - txMeta.loadingDefaults = false + txMeta.loadingDefaults = false; this.txStateManager.updateTx( txMeta, 'transactions: gas estimation for tx on boot', - ) + ); }) .catch((error) => { - const txMeta = this.txStateManager.getTx(tx.id) - txMeta.loadingDefaults = false + const txMeta = this.txStateManager.getTx(tx.id); + txMeta.loadingDefaults = false; this.txStateManager.updateTx( txMeta, 'failed to estimate gas during boot cleanup.', - ) - this.txStateManager.setTxStatusFailed(txMeta.id, error) - }) - }) + ); + this.txStateManager.setTxStatusFailed(txMeta.id, error); + }); + }); this.txStateManager .getFilteredTxList({ @@ -754,9 +754,9 @@ export default class TransactionController extends EventEmitter { .forEach((txMeta) => { const txSignError = new Error( 'Transaction found as "approved" during boot - possibly stuck during signing', - ) - this.txStateManager.setTxStatusFailed(txMeta.id, txSignError) - }) + ); + this.txStateManager.setTxStatusFailed(txMeta.id, txSignError); + }); } /** @@ -767,44 +767,44 @@ export default class TransactionController extends EventEmitter { this.txStateManager.on( 'tx:status-update', this.emit.bind(this, 'tx:status-update'), - ) - this._setupBlockTrackerListener() + ); + this._setupBlockTrackerListener(); this.pendingTxTracker.on('tx:warning', (txMeta) => { this.txStateManager.updateTx( txMeta, 'transactions/pending-tx-tracker#event: tx:warning', - ) - }) + ); + }); this.pendingTxTracker.on( 'tx:failed', this.txStateManager.setTxStatusFailed.bind(this.txStateManager), - ) + ); this.pendingTxTracker.on('tx:confirmed', (txId, transactionReceipt) => this.confirmTransaction(txId, transactionReceipt), - ) + ); this.pendingTxTracker.on( 'tx:dropped', this.txStateManager.setTxStatusDropped.bind(this.txStateManager), - ) + ); this.pendingTxTracker.on('tx:block-update', (txMeta, latestBlockNumber) => { if (!txMeta.firstRetryBlockNumber) { - txMeta.firstRetryBlockNumber = latestBlockNumber + txMeta.firstRetryBlockNumber = latestBlockNumber; this.txStateManager.updateTx( txMeta, 'transactions/pending-tx-tracker#event: tx:block-update', - ) + ); } - }) + }); this.pendingTxTracker.on('tx:retry', (txMeta) => { if (!('retryCount' in txMeta)) { - txMeta.retryCount = 0 + txMeta.retryCount = 0; } - txMeta.retryCount += 1 + txMeta.retryCount += 1; this.txStateManager.updateTx( txMeta, 'transactions/pending-tx-tracker#event: tx:retry', - ) - }) + ); + }); } /** @@ -812,44 +812,44 @@ export default class TransactionController extends EventEmitter { contractDeployment, contractMethodCall */ async _determineTransactionCategory(txParams) { - const { data, to } = txParams - let name + const { data, to } = txParams; + let name; try { - name = data && hstInterface.parseTransaction({ data }).name + name = data && hstInterface.parseTransaction({ data }).name; } catch (error) { - log.debug('Failed to parse transaction data.', error, data) + log.debug('Failed to parse transaction data.', error, data); } const tokenMethodName = [ TRANSACTION_CATEGORIES.TOKEN_METHOD_APPROVE, TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER, TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER_FROM, - ].find((methodName) => methodName === name && name.toLowerCase()) + ].find((methodName) => methodName === name && name.toLowerCase()); - let result + let result; if (data && tokenMethodName) { - result = tokenMethodName + result = tokenMethodName; } else if (data && !to) { - result = TRANSACTION_CATEGORIES.DEPLOY_CONTRACT + result = TRANSACTION_CATEGORIES.DEPLOY_CONTRACT; } - let code + let code; if (!result) { try { - code = await this.query.getCode(to) + code = await this.query.getCode(to); } catch (e) { - code = null - log.warn(e) + code = null; + log.warn(e); } - const codeIsEmpty = !code || code === '0x' || code === '0x0' + const codeIsEmpty = !code || code === '0x' || code === '0x0'; result = codeIsEmpty ? TRANSACTION_CATEGORIES.SENT_ETHER - : TRANSACTION_CATEGORIES.CONTRACT_INTERACTION + : TRANSACTION_CATEGORIES.CONTRACT_INTERACTION; } - return { transactionCategory: result, getCodeResponse: code } + return { transactionCategory: result, getCodeResponse: code }; } /** @@ -860,56 +860,56 @@ export default class TransactionController extends EventEmitter { */ _markNonceDuplicatesDropped(txId) { // get the confirmed transactions nonce and from address - const txMeta = this.txStateManager.getTx(txId) - const { nonce, from } = txMeta.txParams - const sameNonceTxs = this.txStateManager.getFilteredTxList({ nonce, from }) + const txMeta = this.txStateManager.getTx(txId); + const { nonce, from } = txMeta.txParams; + const sameNonceTxs = this.txStateManager.getFilteredTxList({ nonce, from }); if (!sameNonceTxs.length) { - return + return; } // mark all same nonce transactions as dropped and give i a replacedBy hash sameNonceTxs.forEach((otherTxMeta) => { if (otherTxMeta.id === txId) { - return + return; } - otherTxMeta.replacedBy = txMeta.hash + otherTxMeta.replacedBy = txMeta.hash; this.txStateManager.updateTx( txMeta, 'transactions/pending-tx-tracker#event: tx:confirmed reference to confirmed txHash with same nonce', - ) - this.txStateManager.setTxStatusDropped(otherTxMeta.id) - }) + ); + this.txStateManager.setTxStatusDropped(otherTxMeta.id); + }); } _setupBlockTrackerListener() { - let listenersAreActive = false - const latestBlockHandler = this._onLatestBlock.bind(this) - const { blockTracker, txStateManager } = this + let listenersAreActive = false; + const latestBlockHandler = this._onLatestBlock.bind(this); + const { blockTracker, txStateManager } = this; - txStateManager.on('tx:status-update', updateSubscription) - updateSubscription() + txStateManager.on('tx:status-update', updateSubscription); + updateSubscription(); function updateSubscription() { - const pendingTxs = txStateManager.getPendingTransactions() + const pendingTxs = txStateManager.getPendingTransactions(); if (!listenersAreActive && pendingTxs.length > 0) { - blockTracker.on('latest', latestBlockHandler) - listenersAreActive = true + blockTracker.on('latest', latestBlockHandler); + listenersAreActive = true; } else if (listenersAreActive && !pendingTxs.length) { - blockTracker.removeListener('latest', latestBlockHandler) - listenersAreActive = false + blockTracker.removeListener('latest', latestBlockHandler); + listenersAreActive = false; } } } async _onLatestBlock(blockNumber) { try { - await this.pendingTxTracker.updatePendingTxs() + await this.pendingTxTracker.updatePendingTxs(); } catch (err) { - log.error(err) + log.error(err); } try { - await this.pendingTxTracker.resubmitPendingTxs(blockNumber) + await this.pendingTxTracker.resubmitPendingTxs(blockNumber); } catch (err) { - log.error(err) + log.error(err); } } @@ -917,11 +917,11 @@ export default class TransactionController extends EventEmitter { Updates the memStore in transaction controller */ _updateMemstore() { - const unapprovedTxs = this.txStateManager.getUnapprovedTxList() + const unapprovedTxs = this.txStateManager.getUnapprovedTxList(); const currentNetworkTxList = this.txStateManager.getTxList( MAX_MEMSTORE_TX_LIST_SIZE, - ) - this.memStore.updateState({ unapprovedTxs, currentNetworkTxList }) + ); + this.memStore.updateState({ unapprovedTxs, currentNetworkTxList }); } _trackSwapsMetrics(txMeta, approvalTxMeta) { @@ -931,7 +931,7 @@ export default class TransactionController extends EventEmitter { event: 'Swap Failed', sensitiveProperties: { ...txMeta.swapMetaData }, category: 'swaps', - }) + }); } else { const tokensReceived = getSwapsTokensReceivedFromTxMeta( txMeta.destinationTokenSymbol, @@ -940,12 +940,12 @@ export default class TransactionController extends EventEmitter { txMeta.txParams.from, txMeta.destinationTokenDecimals, approvalTxMeta, - ) + ); const quoteVsExecutionRatio = `${new BigNumber(tokensReceived, 10) .div(txMeta.swapMetaData.token_to_amount, 10) .times(100) - .round(2)}%` + .round(2)}%`; const estimatedVsUsedGasRatio = `${new BigNumber( txMeta.txReceipt.gasUsed, @@ -953,7 +953,7 @@ export default class TransactionController extends EventEmitter { ) .div(txMeta.swapMetaData.estimated_gas, 10) .times(100) - .round(2)}%` + .round(2)}%`; this._trackMetaMetricsEvent({ event: 'Swap Completed', @@ -964,7 +964,7 @@ export default class TransactionController extends EventEmitter { quote_vs_executionRatio: quoteVsExecutionRatio, estimated_vs_used_gasRatio: estimatedVsUsedGasRatio, }, - }) + }); } } } diff --git a/app/scripts/controllers/transactions/lib/tx-state-history-helpers.js b/app/scripts/controllers/transactions/lib/tx-state-history-helpers.js index 4a757c2ff4..ea3f91bf15 100644 --- a/app/scripts/controllers/transactions/lib/tx-state-history-helpers.js +++ b/app/scripts/controllers/transactions/lib/tx-state-history-helpers.js @@ -1,5 +1,5 @@ -import jsonDiffer from 'fast-json-patch' -import { cloneDeep } from 'lodash' +import jsonDiffer from 'fast-json-patch'; +import { cloneDeep } from 'lodash'; /** converts non-initial history entries into diffs @@ -12,11 +12,11 @@ export function migrateFromSnapshotsToDiffs(longHistory) { // convert non-initial history entries into diffs .map((entry, index) => { if (index === 0) { - return entry + return entry; } - return generateHistoryEntry(longHistory[index - 1], entry) + return generateHistoryEntry(longHistory[index - 1], entry); }) - ) + ); } /** @@ -32,16 +32,16 @@ export function migrateFromSnapshotsToDiffs(longHistory) { @returns {Array} */ export function generateHistoryEntry(previousState, newState, note) { - const entry = jsonDiffer.compare(previousState, newState) + const entry = jsonDiffer.compare(previousState, newState); // Add a note to the first op, since it breaks if we append it to the entry if (entry[0]) { if (note) { - entry[0].note = note + entry[0].note = note; } - entry[0].timestamp = Date.now() + entry[0].timestamp = Date.now(); } - return entry + return entry; } /** @@ -49,10 +49,10 @@ export function generateHistoryEntry(previousState, newState, note) { @returns {Object} */ export function replayHistory(_shortHistory) { - const shortHistory = cloneDeep(_shortHistory) + const shortHistory = cloneDeep(_shortHistory); return shortHistory.reduce( (val, entry) => jsonDiffer.applyPatch(val, entry).newDocument, - ) + ); } /** @@ -61,7 +61,7 @@ export function replayHistory(_shortHistory) { * @returns {Object} a deep clone without history */ export function snapshotFromTxMeta(txMeta) { - const shallow = { ...txMeta } - delete shallow.history - return cloneDeep(shallow) + const shallow = { ...txMeta }; + delete shallow.history; + return cloneDeep(shallow); } diff --git a/app/scripts/controllers/transactions/lib/util.js b/app/scripts/controllers/transactions/lib/util.js index fbb975c83e..f1cb1f661f 100644 --- a/app/scripts/controllers/transactions/lib/util.js +++ b/app/scripts/controllers/transactions/lib/util.js @@ -1,7 +1,7 @@ -import { isValidAddress } from 'ethereumjs-util' -import { ethErrors } from 'eth-rpc-errors' -import { addHexPrefix } from '../../../lib/util' -import { TRANSACTION_STATUSES } from '../../../../../shared/constants/transaction' +import { isValidAddress } from 'ethereumjs-util'; +import { ethErrors } from 'eth-rpc-errors'; +import { addHexPrefix } from '../../../lib/util'; +import { TRANSACTION_STATUSES } from '../../../../../shared/constants/transaction'; const normalizers = { from: (from) => addHexPrefix(from), @@ -12,7 +12,7 @@ const normalizers = { data: (data) => addHexPrefix(data), gas: (gas) => addHexPrefix(gas), gasPrice: (gasPrice) => addHexPrefix(gasPrice), -} +}; /** * Normalizes the given txParams @@ -23,13 +23,13 @@ const normalizers = { */ export function normalizeTxParams(txParams, lowerCase = true) { // apply only keys in the normalizers - const normalizedTxParams = {} + const normalizedTxParams = {}; for (const key in normalizers) { if (txParams[key]) { - normalizedTxParams[key] = normalizers[key](txParams[key], lowerCase) + normalizedTxParams[key] = normalizers[key](txParams[key], lowerCase); } } - return normalizedTxParams + return normalizedTxParams; } /** @@ -41,28 +41,28 @@ export function validateTxParams(txParams) { if (!txParams || typeof txParams !== 'object' || Array.isArray(txParams)) { throw ethErrors.rpc.invalidParams( 'Invalid transaction params: must be an object.', - ) + ); } if (!txParams.to && !txParams.data) { throw ethErrors.rpc.invalidParams( 'Invalid transaction params: must specify "data" for contract deployments, or "to" (and optionally "data") for all other types of transactions.', - ) + ); } - validateFrom(txParams) - validateRecipient(txParams) + validateFrom(txParams); + validateRecipient(txParams); if ('value' in txParams) { - const value = txParams.value.toString() + const value = txParams.value.toString(); if (value.includes('-')) { throw ethErrors.rpc.invalidParams( `Invalid transaction value "${txParams.value}": not a positive number.`, - ) + ); } if (value.includes('.')) { throw ethErrors.rpc.invalidParams( `Invalid transaction value of "${txParams.value}": number must be in wei.`, - ) + ); } } } @@ -76,10 +76,10 @@ export function validateFrom(txParams) { if (!(typeof txParams.from === 'string')) { throw ethErrors.rpc.invalidParams( `Invalid "from" address "${txParams.from}": not a string.`, - ) + ); } if (!isValidAddress(txParams.from)) { - throw ethErrors.rpc.invalidParams('Invalid "from" address.') + throw ethErrors.rpc.invalidParams('Invalid "from" address.'); } } @@ -92,14 +92,14 @@ export function validateFrom(txParams) { export function validateRecipient(txParams) { if (txParams.to === '0x' || txParams.to === null) { if (txParams.data) { - delete txParams.to + delete txParams.to; } else { - throw ethErrors.rpc.invalidParams('Invalid "to" address.') + throw ethErrors.rpc.invalidParams('Invalid "to" address.'); } } else if (txParams.to !== undefined && !isValidAddress(txParams.to)) { - throw ethErrors.rpc.invalidParams('Invalid "to" address.') + throw ethErrors.rpc.invalidParams('Invalid "to" address.'); } - return txParams + return txParams; } /** @@ -112,5 +112,5 @@ export function getFinalStates() { TRANSACTION_STATUSES.CONFIRMED, // the tx has been included in a block. TRANSACTION_STATUSES.FAILED, // the tx failed for some reason, included on tx data. TRANSACTION_STATUSES.DROPPED, // the tx nonce was already used - ] + ]; } diff --git a/app/scripts/controllers/transactions/pending-tx-tracker.js b/app/scripts/controllers/transactions/pending-tx-tracker.js index 2194ca495c..cb0067445c 100644 --- a/app/scripts/controllers/transactions/pending-tx-tracker.js +++ b/app/scripts/controllers/transactions/pending-tx-tracker.js @@ -1,7 +1,7 @@ -import EventEmitter from 'safe-event-emitter' -import log from 'loglevel' -import EthQuery from 'ethjs-query' -import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction' +import EventEmitter from 'safe-event-emitter'; +import log from 'loglevel'; +import EthQuery from 'ethjs-query'; +import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'; /** @@ -27,7 +27,7 @@ export default class PendingTransactionTracker extends EventEmitter { * * @type {number} */ - DROPPED_BUFFER_COUNT = 3 + DROPPED_BUFFER_COUNT = 3; /** * A map of transaction hashes to the number of blocks we've seen @@ -35,17 +35,17 @@ export default class PendingTransactionTracker extends EventEmitter { * * @type {Map} */ - droppedBlocksBufferByHash = new Map() + droppedBlocksBufferByHash = new Map(); constructor(config) { - super() - this.query = config.query || new EthQuery(config.provider) - this.nonceTracker = config.nonceTracker - this.getPendingTransactions = config.getPendingTransactions - this.getCompletedTransactions = config.getCompletedTransactions - this.publishTransaction = config.publishTransaction - this.approveTransaction = config.approveTransaction - this.confirmTransaction = config.confirmTransaction + super(); + this.query = config.query || new EthQuery(config.provider); + this.nonceTracker = config.nonceTracker; + this.getPendingTransactions = config.getPendingTransactions; + this.getCompletedTransactions = config.getCompletedTransactions; + this.publishTransaction = config.publishTransaction; + this.approveTransaction = config.approveTransaction; + this.confirmTransaction = config.confirmTransaction; } /** @@ -53,19 +53,19 @@ export default class PendingTransactionTracker extends EventEmitter { */ async updatePendingTxs() { // in order to keep the nonceTracker accurate we block it while updating pending transactions - const nonceGlobalLock = await this.nonceTracker.getGlobalLock() + const nonceGlobalLock = await this.nonceTracker.getGlobalLock(); try { - const pendingTxs = this.getPendingTransactions() + const pendingTxs = this.getPendingTransactions(); await Promise.all( pendingTxs.map((txMeta) => this._checkPendingTx(txMeta)), - ) + ); } catch (err) { log.error( 'PendingTransactionTracker - Error updating pending transactions', - ) - log.error(err) + ); + log.error(err); } - nonceGlobalLock.releaseLock() + nonceGlobalLock.releaseLock(); } /** @@ -75,16 +75,16 @@ export default class PendingTransactionTracker extends EventEmitter { * @returns {Promise} */ async resubmitPendingTxs(blockNumber) { - const pending = this.getPendingTransactions() + const pending = this.getPendingTransactions(); if (!pending.length) { - return + return; } for (const txMeta of pending) { try { - await this._resubmitTx(txMeta, blockNumber) + await this._resubmitTx(txMeta, blockNumber); } catch (err) { const errorMessage = - err.value?.message?.toLowerCase() || err.message.toLowerCase() + err.value?.message?.toLowerCase() || err.message.toLowerCase(); const isKnownTx = // geth errorMessage.includes('replacement transaction underpriced') || @@ -96,17 +96,17 @@ export default class PendingTransactionTracker extends EventEmitter { ) || // other errorMessage.includes('gateway timeout') || - errorMessage.includes('nonce too low') + errorMessage.includes('nonce too low'); // ignore resubmit warnings, return early if (isKnownTx) { - return + return; } // encountered real error - transition to error state txMeta.warning = { error: errorMessage, message: 'There was an error when resubmitting this transaction.', - } - this.emit('tx:warning', txMeta, err) + }; + this.emit('tx:warning', txMeta, err); } } } @@ -125,33 +125,33 @@ export default class PendingTransactionTracker extends EventEmitter { */ async _resubmitTx(txMeta, latestBlockNumber) { if (!txMeta.firstRetryBlockNumber) { - this.emit('tx:block-update', txMeta, latestBlockNumber) + this.emit('tx:block-update', txMeta, latestBlockNumber); } const firstRetryBlockNumber = - txMeta.firstRetryBlockNumber || latestBlockNumber + txMeta.firstRetryBlockNumber || latestBlockNumber; const txBlockDistance = Number.parseInt(latestBlockNumber, 16) - - Number.parseInt(firstRetryBlockNumber, 16) + Number.parseInt(firstRetryBlockNumber, 16); - const retryCount = txMeta.retryCount || 0 + const retryCount = txMeta.retryCount || 0; // Exponential backoff to limit retries at publishing if (txBlockDistance <= Math.pow(2, retryCount) - 1) { - return undefined + return undefined; } // Only auto-submit already-signed txs: if (!('rawTx' in txMeta)) { - return this.approveTransaction(txMeta.id) + return this.approveTransaction(txMeta.id); } - const { rawTx } = txMeta - const txHash = await this.publishTransaction(rawTx) + const { rawTx } = txMeta; + const txHash = await this.publishTransaction(rawTx); // Increment successful tries: - this.emit('tx:retry', txMeta) - return txHash + this.emit('tx:retry', txMeta); + return txHash; } /** @@ -165,12 +165,12 @@ export default class PendingTransactionTracker extends EventEmitter { * @private */ async _checkPendingTx(txMeta) { - const txHash = txMeta.hash - const txId = txMeta.id + const txHash = txMeta.hash; + const txId = txMeta.id; // Only check submitted txs if (txMeta.status !== TRANSACTION_STATUSES.SUBMITTED) { - return + return; } // extra check in case there was an uncaught error during the @@ -178,35 +178,35 @@ export default class PendingTransactionTracker extends EventEmitter { if (!txHash) { const noTxHashErr = new Error( 'We had an error while submitting this transaction, please try again.', - ) - noTxHashErr.name = 'NoTxHashError' - this.emit('tx:failed', txId, noTxHashErr) + ); + noTxHashErr.name = 'NoTxHashError'; + this.emit('tx:failed', txId, noTxHashErr); - return + return; } if (await this._checkIfNonceIsTaken(txMeta)) { - this.emit('tx:dropped', txId) - return + this.emit('tx:dropped', txId); + return; } try { - const transactionReceipt = await this.query.getTransactionReceipt(txHash) + const transactionReceipt = await this.query.getTransactionReceipt(txHash); if (transactionReceipt?.blockNumber) { - this.emit('tx:confirmed', txId, transactionReceipt) - return + this.emit('tx:confirmed', txId, transactionReceipt); + return; } } catch (err) { txMeta.warning = { error: err.message, message: 'There was a problem loading this transaction.', - } - this.emit('tx:warning', txMeta, err) - return + }; + this.emit('tx:warning', txMeta, err); + return; } if (await this._checkIfTxWasDropped(txMeta)) { - this.emit('tx:dropped', txId) + this.emit('tx:dropped', txId); } } @@ -221,26 +221,26 @@ export default class PendingTransactionTracker extends EventEmitter { const { hash: txHash, txParams: { nonce, from }, - } = txMeta - const networkNextNonce = await this.query.getTransactionCount(from) + } = txMeta; + const networkNextNonce = await this.query.getTransactionCount(from); if (parseInt(nonce, 16) >= networkNextNonce.toNumber()) { - return false + return false; } if (!this.droppedBlocksBufferByHash.has(txHash)) { - this.droppedBlocksBufferByHash.set(txHash, 0) + this.droppedBlocksBufferByHash.set(txHash, 0); } - const currentBlockBuffer = this.droppedBlocksBufferByHash.get(txHash) + const currentBlockBuffer = this.droppedBlocksBufferByHash.get(txHash); if (currentBlockBuffer < this.DROPPED_BUFFER_COUNT) { - this.droppedBlocksBufferByHash.set(txHash, currentBlockBuffer + 1) - return false + this.droppedBlocksBufferByHash.set(txHash, currentBlockBuffer + 1); + return false; } - this.droppedBlocksBufferByHash.delete(txHash) - return true + this.droppedBlocksBufferByHash.delete(txHash); + return true; } /** @@ -250,8 +250,8 @@ export default class PendingTransactionTracker extends EventEmitter { * @private */ async _checkIfNonceIsTaken(txMeta) { - const address = txMeta.txParams.from - const completed = this.getCompletedTransactions(address) + const address = txMeta.txParams.from; + const completed = this.getCompletedTransactions(address); return completed.some( // This is called while the transaction is in-flight, so it is possible that the // list of completed transactions now includes the transaction we were looking at @@ -259,6 +259,6 @@ export default class PendingTransactionTracker extends EventEmitter { (other) => !(other.id === txMeta.id) && other.txParams.nonce === txMeta.txParams.nonce, - ) + ); } } diff --git a/app/scripts/controllers/transactions/tx-gas-utils.js b/app/scripts/controllers/transactions/tx-gas-utils.js index cf75d89194..75eb60d838 100644 --- a/app/scripts/controllers/transactions/tx-gas-utils.js +++ b/app/scripts/controllers/transactions/tx-gas-utils.js @@ -1,8 +1,8 @@ -import EthQuery from 'ethjs-query' -import log from 'loglevel' -import ethUtil from 'ethereumjs-util' -import { cloneDeep } from 'lodash' -import { hexToBn, BnMultiplyByFraction, bnToHex } from '../../lib/util' +import EthQuery from 'ethjs-query'; +import log from 'loglevel'; +import ethUtil from 'ethereumjs-util'; +import { cloneDeep } from 'lodash'; +import { hexToBn, BnMultiplyByFraction, bnToHex } from '../../lib/util'; /** * Result of gas analysis, including either a gas estimate for a successful analysis, or @@ -22,7 +22,7 @@ and used to do things like calculate gas of a tx. export default class TxGasUtil { constructor(provider) { - this.query = new EthQuery(provider) + this.query = new EthQuery(provider); } /** @@ -30,25 +30,25 @@ export default class TxGasUtil { @returns {GasAnalysisResult} The result of the gas analysis */ async analyzeGasUsage(txMeta) { - const block = await this.query.getBlockByNumber('latest', false) + const block = await this.query.getBlockByNumber('latest', false); // fallback to block gasLimit - const blockGasLimitBN = hexToBn(block.gasLimit) - const saferGasLimitBN = BnMultiplyByFraction(blockGasLimitBN, 19, 20) - let estimatedGasHex = bnToHex(saferGasLimitBN) - let simulationFails + const blockGasLimitBN = hexToBn(block.gasLimit); + const saferGasLimitBN = BnMultiplyByFraction(blockGasLimitBN, 19, 20); + let estimatedGasHex = bnToHex(saferGasLimitBN); + let simulationFails; try { - estimatedGasHex = await this.estimateTxGas(txMeta) + estimatedGasHex = await this.estimateTxGas(txMeta); } catch (error) { - log.warn(error) + log.warn(error); simulationFails = { reason: error.message, errorKey: error.errorKey, debug: { blockNumber: block.number, blockGasLimit: block.gasLimit }, - } + }; } - return { blockGasLimit: block.gasLimit, estimatedGasHex, simulationFails } + return { blockGasLimit: block.gasLimit, estimatedGasHex, simulationFails }; } /** @@ -57,16 +57,16 @@ export default class TxGasUtil { @returns {string} the estimated gas limit as a hex string */ async estimateTxGas(txMeta) { - const txParams = cloneDeep(txMeta.txParams) + const txParams = cloneDeep(txMeta.txParams); // `eth_estimateGas` can fail if the user has insufficient balance for the // value being sent, or for the gas cost. We don't want to check their // balance here, we just want the gas estimate. The gas price is removed // to skip those balance checks. We check balance elsewhere. - delete txParams.gasPrice + delete txParams.gasPrice; // estimate tx gas requirements - return await this.query.estimateGas(txParams) + return await this.query.estimateGas(txParams); } /** @@ -77,21 +77,21 @@ export default class TxGasUtil { @returns {string} the buffered gas limit as a hex string */ addGasBuffer(initialGasLimitHex, blockGasLimitHex, multiplier = 1.5) { - const initialGasLimitBn = hexToBn(initialGasLimitHex) - const blockGasLimitBn = hexToBn(blockGasLimitHex) - const upperGasLimitBn = blockGasLimitBn.muln(0.9) - const bufferedGasLimitBn = initialGasLimitBn.muln(multiplier) + const initialGasLimitBn = hexToBn(initialGasLimitHex); + const blockGasLimitBn = hexToBn(blockGasLimitHex); + const upperGasLimitBn = blockGasLimitBn.muln(0.9); + const bufferedGasLimitBn = initialGasLimitBn.muln(multiplier); // if initialGasLimit is above blockGasLimit, dont modify it if (initialGasLimitBn.gt(upperGasLimitBn)) { - return bnToHex(initialGasLimitBn) + return bnToHex(initialGasLimitBn); } // if bufferedGasLimit is below blockGasLimit, use bufferedGasLimit if (bufferedGasLimitBn.lt(upperGasLimitBn)) { - return bnToHex(bufferedGasLimitBn) + return bnToHex(bufferedGasLimitBn); } // otherwise use blockGasLimit - return bnToHex(upperGasLimitBn) + return bnToHex(upperGasLimitBn); } async getBufferedGasLimit(txMeta, multiplier) { @@ -99,14 +99,14 @@ export default class TxGasUtil { blockGasLimit, estimatedGasHex, simulationFails, - } = await this.analyzeGasUsage(txMeta) + } = await this.analyzeGasUsage(txMeta); // add additional gas buffer to our estimation for safety const gasLimit = this.addGasBuffer( ethUtil.addHexPrefix(estimatedGasHex), blockGasLimit, multiplier, - ) - return { gasLimit, simulationFails } + ); + return { gasLimit, simulationFails }; } } diff --git a/app/scripts/controllers/transactions/tx-state-manager.js b/app/scripts/controllers/transactions/tx-state-manager.js index 0c94bd270b..492ea4ddef 100644 --- a/app/scripts/controllers/transactions/tx-state-manager.js +++ b/app/scripts/controllers/transactions/tx-state-manager.js @@ -1,14 +1,14 @@ -import EventEmitter from 'safe-event-emitter' -import { ObservableStore } from '@metamask/obs-store' -import log from 'loglevel' -import createId from '../../lib/random-id' -import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction' +import EventEmitter from 'safe-event-emitter'; +import { ObservableStore } from '@metamask/obs-store'; +import log from 'loglevel'; +import createId from '../../lib/random-id'; +import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'; import { generateHistoryEntry, replayHistory, snapshotFromTxMeta, -} from './lib/tx-state-history-helpers' -import { getFinalStates, normalizeTxParams } from './lib/util' +} from './lib/tx-state-history-helpers'; +import { getFinalStates, normalizeTxParams } from './lib/util'; /** * TransactionStatuses reimported from the shared transaction constants file @@ -28,11 +28,11 @@ import { getFinalStates, normalizeTxParams } from './lib/util' */ export default class TransactionStateManager extends EventEmitter { constructor({ initState, txHistoryLimit, getNetwork }) { - super() + super(); - this.store = new ObservableStore({ transactions: [], ...initState }) - this.txHistoryLimit = txHistoryLimit - this.getNetwork = getNetwork + this.store = new ObservableStore({ transactions: [], ...initState }); + this.txHistoryLimit = txHistoryLimit; + this.getNetwork = getNetwork; } /** @@ -40,9 +40,9 @@ export default class TransactionStateManager extends EventEmitter { * @returns {txMeta} the default txMeta object */ generateTxMeta(opts) { - const netId = this.getNetwork() + const netId = this.getNetwork(); if (netId === 'loading') { - throw new Error('MetaMask is having trouble connecting to the network') + throw new Error('MetaMask is having trouble connecting to the network'); } return { id: createId(), @@ -51,7 +51,7 @@ export default class TransactionStateManager extends EventEmitter { metamaskNetworkId: netId, loadingDefaults: true, ...opts, - } + }; } /** @@ -63,38 +63,38 @@ export default class TransactionStateManager extends EventEmitter { * @returns {Object[]} The {@code txMeta}s, filtered to the current network */ getTxList(limit) { - const network = this.getNetwork() - const fullTxList = this.getFullTxList() + const network = this.getNetwork(); + const fullTxList = this.getFullTxList(); - const nonces = new Set() - const txs = [] + const nonces = new Set(); + const txs = []; for (let i = fullTxList.length - 1; i > -1; i--) { - const txMeta = fullTxList[i] + const txMeta = fullTxList[i]; if (txMeta.metamaskNetworkId !== network) { - continue + continue; } if (limit !== undefined) { - const { nonce } = txMeta.txParams + const { nonce } = txMeta.txParams; if (!nonces.has(nonce)) { if (nonces.size < limit) { - nonces.add(nonce) + nonces.add(nonce); } else { - continue + continue; } } } - txs.unshift(txMeta) + txs.unshift(txMeta); } - return txs + return txs; } /** * @returns {Array} of all the txMetas in store */ getFullTxList() { - return this.store.getState().transactions + return this.store.getState().transactions; } /** @@ -104,11 +104,11 @@ export default class TransactionStateManager extends EventEmitter { const txList = this.getTxsByMetaData( 'status', TRANSACTION_STATUSES.UNAPPROVED, - ) + ); return txList.reduce((result, tx) => { - result[tx.id] = tx - return result - }, {}) + result[tx.id] = tx; + return result; + }, {}); } /** @@ -117,11 +117,11 @@ export default class TransactionStateManager extends EventEmitter { * returns all txMetas with approved statuses for the current network */ getApprovedTransactions(address) { - const opts = { status: TRANSACTION_STATUSES.APPROVED } + const opts = { status: TRANSACTION_STATUSES.APPROVED }; if (address) { - opts.from = address + opts.from = address; } - return this.getFilteredTxList(opts) + return this.getFilteredTxList(opts); } /** @@ -130,11 +130,11 @@ export default class TransactionStateManager extends EventEmitter { * returns all txMetas with submitted statuses for the current network */ getPendingTransactions(address) { - const opts = { status: TRANSACTION_STATUSES.SUBMITTED } + const opts = { status: TRANSACTION_STATUSES.SUBMITTED }; if (address) { - opts.from = address + opts.from = address; } - return this.getFilteredTxList(opts) + return this.getFilteredTxList(opts); } /** @@ -143,11 +143,11 @@ export default class TransactionStateManager extends EventEmitter { returns all txMetas who's status is confirmed for the current network */ getConfirmedTransactions(address) { - const opts = { status: TRANSACTION_STATUSES.CONFIRMED } + const opts = { status: TRANSACTION_STATUSES.CONFIRMED }; if (address) { - opts.from = address + opts.from = address; } - return this.getFilteredTxList(opts) + return this.getFilteredTxList(opts); } /** @@ -162,24 +162,24 @@ export default class TransactionStateManager extends EventEmitter { addTx(txMeta) { // normalize and validate txParams if present if (txMeta.txParams) { - txMeta.txParams = this.normalizeAndValidateTxParams(txMeta.txParams) + txMeta.txParams = this.normalizeAndValidateTxParams(txMeta.txParams); } this.once(`${txMeta.id}:signed`, () => { - this.removeAllListeners(`${txMeta.id}:rejected`) - }) + this.removeAllListeners(`${txMeta.id}:rejected`); + }); this.once(`${txMeta.id}:rejected`, () => { - this.removeAllListeners(`${txMeta.id}:signed`) - }) + this.removeAllListeners(`${txMeta.id}:signed`); + }); // initialize history - txMeta.history = [] + txMeta.history = []; // capture initial snapshot of txMeta for history - const snapshot = snapshotFromTxMeta(txMeta) - txMeta.history.push(snapshot) + const snapshot = snapshotFromTxMeta(txMeta); + txMeta.history.push(snapshot); - const transactions = this.getFullTxList() - const txCount = transactions.length - const { txHistoryLimit } = this + const transactions = this.getFullTxList(); + const txCount = transactions.length; + const { txHistoryLimit } = this; // checks if the length of the tx history is // longer then desired persistence limit @@ -188,21 +188,21 @@ export default class TransactionStateManager extends EventEmitter { // not tx's that are pending or unapproved if (txCount > txHistoryLimit - 1) { const index = transactions.findIndex((metaTx) => { - return getFinalStates().includes(metaTx.status) - }) + return getFinalStates().includes(metaTx.status); + }); if (index !== -1) { - transactions.splice(index, 1) + transactions.splice(index, 1); } } const newTxIndex = transactions.findIndex( (currentTxMeta) => currentTxMeta.time > txMeta.time, - ) + ); newTxIndex === -1 ? transactions.push(txMeta) - : transactions.splice(newTxIndex, 0, txMeta) - this._saveTxList(transactions) - return txMeta + : transactions.splice(newTxIndex, 0, txMeta); + this._saveTxList(transactions); + return txMeta; } /** @@ -211,8 +211,8 @@ export default class TransactionStateManager extends EventEmitter { * for the network returns undefined */ getTx(txId) { - const txMeta = this.getTxsByMetaData('id', txId)[0] - return txMeta + const txMeta = this.getTxsByMetaData('id', txId)[0]; + return txMeta; } /** @@ -223,25 +223,25 @@ export default class TransactionStateManager extends EventEmitter { updateTx(txMeta, note) { // normalize and validate txParams if present if (txMeta.txParams) { - txMeta.txParams = this.normalizeAndValidateTxParams(txMeta.txParams) + txMeta.txParams = this.normalizeAndValidateTxParams(txMeta.txParams); } // create txMeta snapshot for history - const currentState = snapshotFromTxMeta(txMeta) + const currentState = snapshotFromTxMeta(txMeta); // recover previous tx state obj - const previousState = replayHistory(txMeta.history) + const previousState = replayHistory(txMeta.history); // generate history entry and add to history - const entry = generateHistoryEntry(previousState, currentState, note) + const entry = generateHistoryEntry(previousState, currentState, note); if (entry.length) { - txMeta.history.push(entry) + txMeta.history.push(entry); } // commit txMeta to state - const txId = txMeta.id - const txList = this.getFullTxList() - const index = txList.findIndex((txData) => txData.id === txId) - txList[index] = txMeta - this._saveTxList(txList) + const txId = txMeta.id; + const txList = this.getFullTxList(); + const index = txList.findIndex((txData) => txData.id === txId); + txList[index] = txMeta; + this._saveTxList(txList); } /** @@ -251,9 +251,9 @@ export default class TransactionStateManager extends EventEmitter { * @param {Object} txParams - the updated txParams */ updateTxParams(txId, txParams) { - const txMeta = this.getTx(txId) - txMeta.txParams = { ...txMeta.txParams, ...txParams } - this.updateTx(txMeta, `txStateManager#updateTxParams`) + const txMeta = this.getTx(txId); + txMeta.txParams = { ...txMeta.txParams, ...txParams }; + this.updateTx(txMeta, `txStateManager#updateTxParams`); } /** @@ -262,12 +262,12 @@ export default class TransactionStateManager extends EventEmitter { */ normalizeAndValidateTxParams(txParams) { if (typeof txParams.data === 'undefined') { - delete txParams.data + delete txParams.data; } // eslint-disable-next-line no-param-reassign - txParams = normalizeTxParams(txParams, false) - this.validateTxParams(txParams) - return txParams + txParams = normalizeTxParams(txParams, false); + this.validateTxParams(txParams); + return txParams; } /** @@ -276,25 +276,25 @@ export default class TransactionStateManager extends EventEmitter { */ validateTxParams(txParams) { Object.keys(txParams).forEach((key) => { - const value = txParams[key] + const value = txParams[key]; // validate types switch (key) { case 'chainId': if (typeof value !== 'number' && typeof value !== 'string') { throw new Error( `${key} in txParams is not a Number or hex string. got: (${value})`, - ) + ); } - break + break; default: if (typeof value !== 'string') { throw new Error( `${key} in txParams is not a string. got: (${value})`, - ) + ); } - break + break; } - }) + }); } /** @@ -326,11 +326,11 @@ export default class TransactionStateManager extends EventEmitter { and that have been 'confirmed' */ getFilteredTxList(opts, initialList) { - let filteredTxList = initialList + let filteredTxList = initialList; Object.keys(opts).forEach((key) => { - filteredTxList = this.getTxsByMetaData(key, opts[key], filteredTxList) - }) - return filteredTxList + filteredTxList = this.getTxsByMetaData(key, opts[key], filteredTxList); + }); + return filteredTxList; } /** @@ -341,14 +341,14 @@ export default class TransactionStateManager extends EventEmitter { * @returns {Array} a list of txMetas who matches the search params */ getTxsByMetaData(key, value, txList = this.getTxList()) { - const filter = typeof value === 'function' ? value : (v) => v === value + const filter = typeof value === 'function' ? value : (v) => v === value; return txList.filter((txMeta) => { if (key in txMeta.txParams) { - return filter(txMeta.txParams[key]) + return filter(txMeta.txParams[key]); } - return filter(txMeta[key]) - }) + return filter(txMeta[key]); + }); } // get::set status @@ -358,8 +358,8 @@ export default class TransactionStateManager extends EventEmitter { * @returns {string} the status of the tx. */ getTxStatus(txId) { - const txMeta = this.getTx(txId) - return txMeta.status + const txMeta = this.getTx(txId); + return txMeta.status; } /** @@ -367,8 +367,8 @@ export default class TransactionStateManager extends EventEmitter { * @param {number} txId - the txMeta Id */ setTxStatusRejected(txId) { - this._setTxStatus(txId, 'rejected') - this._removeTx(txId) + this._setTxStatus(txId, 'rejected'); + this._removeTx(txId); } /** @@ -376,7 +376,7 @@ export default class TransactionStateManager extends EventEmitter { * @param {number} txId - the txMeta Id */ setTxStatusUnapproved(txId) { - this._setTxStatus(txId, TRANSACTION_STATUSES.UNAPPROVED) + this._setTxStatus(txId, TRANSACTION_STATUSES.UNAPPROVED); } /** @@ -384,7 +384,7 @@ export default class TransactionStateManager extends EventEmitter { * @param {number} txId - the txMeta Id */ setTxStatusApproved(txId) { - this._setTxStatus(txId, TRANSACTION_STATUSES.APPROVED) + this._setTxStatus(txId, TRANSACTION_STATUSES.APPROVED); } /** @@ -392,7 +392,7 @@ export default class TransactionStateManager extends EventEmitter { * @param {number} txId - the txMeta Id */ setTxStatusSigned(txId) { - this._setTxStatus(txId, TRANSACTION_STATUSES.SIGNED) + this._setTxStatus(txId, TRANSACTION_STATUSES.SIGNED); } /** @@ -401,10 +401,10 @@ export default class TransactionStateManager extends EventEmitter { * @param {number} txId - the txMeta Id */ setTxStatusSubmitted(txId) { - const txMeta = this.getTx(txId) - txMeta.submittedTime = new Date().getTime() - this.updateTx(txMeta, 'txStateManager - add submitted time stamp') - this._setTxStatus(txId, TRANSACTION_STATUSES.SUBMITTED) + const txMeta = this.getTx(txId); + txMeta.submittedTime = new Date().getTime(); + this.updateTx(txMeta, 'txStateManager - add submitted time stamp'); + this._setTxStatus(txId, TRANSACTION_STATUSES.SUBMITTED); } /** @@ -412,7 +412,7 @@ export default class TransactionStateManager extends EventEmitter { * @param {number} txId - the txMeta Id */ setTxStatusConfirmed(txId) { - this._setTxStatus(txId, TRANSACTION_STATUSES.CONFIRMED) + this._setTxStatus(txId, TRANSACTION_STATUSES.CONFIRMED); } /** @@ -420,7 +420,7 @@ export default class TransactionStateManager extends EventEmitter { * @param {number} txId - the txMeta Id */ setTxStatusDropped(txId) { - this._setTxStatus(txId, TRANSACTION_STATUSES.DROPPED) + this._setTxStatus(txId, TRANSACTION_STATUSES.DROPPED); } /** @@ -429,16 +429,16 @@ export default class TransactionStateManager extends EventEmitter { * @param {erroObject} err - error object */ setTxStatusFailed(txId, err) { - const error = err || new Error('Internal metamask failure') + const error = err || new Error('Internal metamask failure'); - const txMeta = this.getTx(txId) + const txMeta = this.getTx(txId); txMeta.err = { message: error.toString(), rpc: error.value, stack: error.stack, - } - this.updateTx(txMeta, 'transactions:tx-state-manager#fail - add error') - this._setTxStatus(txId, TRANSACTION_STATUSES.FAILED) + }; + this.updateTx(txMeta, 'transactions:tx-state-manager#fail - add error'); + this._setTxStatus(txId, TRANSACTION_STATUSES.FAILED); } /** @@ -449,8 +449,8 @@ export default class TransactionStateManager extends EventEmitter { */ wipeTransactions(address) { // network only tx - const txs = this.getFullTxList() - const network = this.getNetwork() + const txs = this.getFullTxList(); + const network = this.getNetwork(); // Filter out the ones from the current account and network const otherAccountTxs = txs.filter( @@ -459,10 +459,10 @@ export default class TransactionStateManager extends EventEmitter { txMeta.txParams.from === address && txMeta.metamaskNetworkId === network ), - ) + ); // Update state - this._saveTxList(otherAccountTxs) + this._saveTxList(otherAccountTxs); } // @@ -477,17 +477,17 @@ export default class TransactionStateManager extends EventEmitter { * @emits update:badge */ _setTxStatus(txId, status) { - const txMeta = this.getTx(txId) + const txMeta = this.getTx(txId); if (!txMeta) { - return + return; } - txMeta.status = status + txMeta.status = status; try { - this.updateTx(txMeta, `txStateManager: setting status to ${status}`) - this.emit(`${txMeta.id}:${status}`, txId) - this.emit(`tx:status-update`, txId, status) + this.updateTx(txMeta, `txStateManager: setting status to ${status}`); + this.emit(`${txMeta.id}:${status}`, txId); + this.emit(`tx:status-update`, txId, status); if ( [ TRANSACTION_STATUSES.SUBMITTED, @@ -495,11 +495,11 @@ export default class TransactionStateManager extends EventEmitter { TRANSACTION_STATUSES.FAILED, ].includes(status) ) { - this.emit(`${txMeta.id}:finished`, txMeta) + this.emit(`${txMeta.id}:finished`, txMeta); } - this.emit('update:badge') + this.emit('update:badge'); } catch (error) { - log.error(error) + log.error(error); } } @@ -508,22 +508,22 @@ export default class TransactionStateManager extends EventEmitter { * @param {Array} transactions - the list of transactions to save */ _saveTxList(transactions) { - this.store.updateState({ transactions }) + this.store.updateState({ transactions }); } _removeTx(txId) { - const transactionList = this.getFullTxList() - this._saveTxList(transactionList.filter((txMeta) => txMeta.id !== txId)) + const transactionList = this.getFullTxList(); + this._saveTxList(transactionList.filter((txMeta) => txMeta.id !== txId)); } /** * Filters out the unapproved transactions */ clearUnapprovedTxs() { - const transactions = this.getFullTxList() + const transactions = this.getFullTxList(); const nonUnapprovedTxs = transactions.filter( (tx) => tx.status !== TRANSACTION_STATUSES.UNAPPROVED, - ) - this._saveTxList(nonUnapprovedTxs) + ); + this._saveTxList(nonUnapprovedTxs); } } diff --git a/app/scripts/disable-console.js b/app/scripts/disable-console.js index 7416b36f59..d1ba36d574 100644 --- a/app/scripts/disable-console.js +++ b/app/scripts/disable-console.js @@ -4,10 +4,10 @@ if ( !(typeof process !== 'undefined' && process.env.METAMASK_DEBUG) && typeof console !== undefined ) { - console.log = noop - console.info = noop + console.log = noop; + console.info = noop; } function noop() { - return undefined + return undefined; } diff --git a/app/scripts/first-time-state.js b/app/scripts/first-time-state.js index b5b498694c..8579218896 100644 --- a/app/scripts/first-time-state.js +++ b/app/scripts/first-time-state.js @@ -20,6 +20,6 @@ const initialState = { }, ], }, -} +}; -export default initialState +export default initialState; diff --git a/app/scripts/initSentry.js b/app/scripts/initSentry.js index 70ea7b936a..d959997e08 100644 --- a/app/scripts/initSentry.js +++ b/app/scripts/initSentry.js @@ -1,7 +1,7 @@ -import setupSentry from './lib/setupSentry' +import setupSentry from './lib/setupSentry'; // setup sentry error reporting global.sentry = setupSentry({ release: process.env.METAMASK_VERSION, getState: () => global.getSentryState?.() || {}, -}) +}); diff --git a/app/scripts/inpage.js b/app/scripts/inpage.js index c7619f77ee..72bbf7901a 100644 --- a/app/scripts/inpage.js +++ b/app/scripts/inpage.js @@ -1,7 +1,7 @@ // need to make sure we aren't affected by overlapping namespaces // and that we dont affect the app with our namespace // mostly a fix for web3's BigNumber if AMD's "define" is defined... -let __define +let __define; /** * Caches reference to global define object and deletes it to @@ -9,35 +9,35 @@ let __define * AMD's define function */ const cleanContextForImports = () => { - __define = global.define + __define = global.define; try { - global.define = undefined + global.define = undefined; } catch (_) { - console.warn('MetaMask - global.define could not be deleted.') + console.warn('MetaMask - global.define could not be deleted.'); } -} +}; /** * Restores global define object from cached reference */ const restoreContextAfterImports = () => { try { - global.define = __define + global.define = __define; } catch (_) { - console.warn('MetaMask - global.define could not be overwritten.') + console.warn('MetaMask - global.define could not be overwritten.'); } -} +}; -cleanContextForImports() +cleanContextForImports(); /* eslint-disable import/first */ -import log from 'loglevel' -import LocalMessageDuplexStream from 'post-message-stream' -import { initializeProvider } from '@metamask/inpage-provider' +import log from 'loglevel'; +import LocalMessageDuplexStream from 'post-message-stream'; +import { initializeProvider } from '@metamask/inpage-provider'; -restoreContextAfterImports() +restoreContextAfterImports(); -log.setDefaultLevel(process.env.METAMASK_DEBUG ? 'debug' : 'warn') +log.setDefaultLevel(process.env.METAMASK_DEBUG ? 'debug' : 'warn'); // // setup plugin communication @@ -47,10 +47,10 @@ log.setDefaultLevel(process.env.METAMASK_DEBUG ? 'debug' : 'warn') const metamaskStream = new LocalMessageDuplexStream({ name: 'metamask-inpage', target: 'metamask-contentscript', -}) +}); initializeProvider({ connectionStream: metamaskStream, logger: log, shouldShimWeb3: true, -}) +}); diff --git a/app/scripts/lib/ComposableObservableStore.js b/app/scripts/lib/ComposableObservableStore.js index 3661259bdd..68ce42d085 100644 --- a/app/scripts/lib/ComposableObservableStore.js +++ b/app/scripts/lib/ComposableObservableStore.js @@ -1,4 +1,4 @@ -import { ObservableStore } from '@metamask/obs-store' +import { ObservableStore } from '@metamask/obs-store'; /** * An ObservableStore that can composes a flat @@ -12,8 +12,8 @@ export default class ComposableObservableStore extends ObservableStore { * @param {Object} [config] - Map of internal state keys to child stores */ constructor(initState, config) { - super(initState) - this.updateStructure(config) + super(initState); + this.updateStructure(config); } /** @@ -22,13 +22,13 @@ export default class ComposableObservableStore extends ObservableStore { * @param {Object} [config] - Map of internal state keys to child stores */ updateStructure(config) { - this.config = config - this.removeAllListeners() + this.config = config; + this.removeAllListeners(); for (const key in config) { if (Object.prototype.hasOwnProperty.call(config, key)) { config[key].subscribe((state) => { - this.updateState({ [key]: state }) - }) + this.updateState({ [key]: state }); + }); } } } @@ -40,16 +40,16 @@ export default class ComposableObservableStore extends ObservableStore { * @returns {Object} Object containing merged child store state */ getFlatState() { - let flatState = {} + let flatState = {}; for (const key in this.config) { if (Object.prototype.hasOwnProperty.call(this.config, key)) { - const controller = this.config[key] + const controller = this.config[key]; const state = controller.getState ? controller.getState() - : controller.state - flatState = { ...flatState, ...state } + : controller.state; + flatState = { ...flatState, ...state }; } } - return flatState + return flatState; } } diff --git a/app/scripts/lib/account-tracker.js b/app/scripts/lib/account-tracker.js index 6b78081f07..53c6a5c8d1 100644 --- a/app/scripts/lib/account-tracker.js +++ b/app/scripts/lib/account-tracker.js @@ -7,27 +7,27 @@ * on each new block. */ -import EthQuery from 'eth-query' +import EthQuery from 'eth-query'; -import { ObservableStore } from '@metamask/obs-store' -import log from 'loglevel' -import pify from 'pify' -import Web3 from 'web3' -import SINGLE_CALL_BALANCES_ABI from 'single-call-balance-checker-abi' +import { ObservableStore } from '@metamask/obs-store'; +import log from 'loglevel'; +import pify from 'pify'; +import Web3 from 'web3'; +import SINGLE_CALL_BALANCES_ABI from 'single-call-balance-checker-abi'; import { MAINNET_CHAIN_ID, RINKEBY_CHAIN_ID, ROPSTEN_CHAIN_ID, KOVAN_CHAIN_ID, -} from '../../../shared/constants/network' +} from '../../../shared/constants/network'; import { SINGLE_CALL_BALANCES_ADDRESS, SINGLE_CALL_BALANCES_ADDRESS_RINKEBY, SINGLE_CALL_BALANCES_ADDRESS_ROPSTEN, SINGLE_CALL_BALANCES_ADDRESS_KOVAN, -} from '../constants/contracts' -import { bnToHex } from './util' +} from '../constants/contracts'; +import { bnToHex } from './util'; /** * This module is responsible for tracking any number of accounts and caching their current balances & transaction @@ -57,36 +57,36 @@ export default class AccountTracker { const initState = { accounts: {}, currentBlockGasLimit: '', - } - this.store = new ObservableStore(initState) + }; + this.store = new ObservableStore(initState); - this._provider = opts.provider - this._query = pify(new EthQuery(this._provider)) - this._blockTracker = opts.blockTracker + this._provider = opts.provider; + this._query = pify(new EthQuery(this._provider)); + this._blockTracker = opts.blockTracker; // blockTracker.currentBlock may be null - this._currentBlockNumber = this._blockTracker.getCurrentBlock() + this._currentBlockNumber = this._blockTracker.getCurrentBlock(); this._blockTracker.once('latest', (blockNumber) => { - this._currentBlockNumber = blockNumber - }) + this._currentBlockNumber = blockNumber; + }); // bind function for easier listener syntax - this._updateForBlock = this._updateForBlock.bind(this) - this.getCurrentChainId = opts.getCurrentChainId + this._updateForBlock = this._updateForBlock.bind(this); + this.getCurrentChainId = opts.getCurrentChainId; - this.web3 = new Web3(this._provider) + this.web3 = new Web3(this._provider); } start() { // remove first to avoid double add - this._blockTracker.removeListener('latest', this._updateForBlock) + this._blockTracker.removeListener('latest', this._updateForBlock); // add listener - this._blockTracker.addListener('latest', this._updateForBlock) + this._blockTracker.addListener('latest', this._updateForBlock); // fetch account balances - this._updateAccounts() + this._updateAccounts(); } stop() { // remove listener - this._blockTracker.removeListener('latest', this._updateForBlock) + this._blockTracker.removeListener('latest', this._updateForBlock); } /** @@ -101,25 +101,25 @@ export default class AccountTracker { * */ syncWithAddresses(addresses) { - const { accounts } = this.store.getState() - const locals = Object.keys(accounts) + const { accounts } = this.store.getState(); + const locals = Object.keys(accounts); - const accountsToAdd = [] + const accountsToAdd = []; addresses.forEach((upstream) => { if (!locals.includes(upstream)) { - accountsToAdd.push(upstream) + accountsToAdd.push(upstream); } - }) + }); - const accountsToRemove = [] + const accountsToRemove = []; locals.forEach((local) => { if (!addresses.includes(local)) { - accountsToRemove.push(local) + accountsToRemove.push(local); } - }) + }); - this.addAccounts(accountsToAdd) - this.removeAccount(accountsToRemove) + this.addAccounts(accountsToAdd); + this.removeAccount(accountsToRemove); } /** @@ -130,18 +130,18 @@ export default class AccountTracker { * */ addAccounts(addresses) { - const { accounts } = this.store.getState() + const { accounts } = this.store.getState(); // add initial state for addresses addresses.forEach((address) => { - accounts[address] = {} - }) + accounts[address] = {}; + }); // save accounts state - this.store.updateState({ accounts }) + this.store.updateState({ accounts }); // fetch balances for the accounts if there is block number ready if (!this._currentBlockNumber) { - return + return; } - this._updateAccounts() + this._updateAccounts(); } /** @@ -151,13 +151,13 @@ export default class AccountTracker { * */ removeAccount(addresses) { - const { accounts } = this.store.getState() + const { accounts } = this.store.getState(); // remove each state object addresses.forEach((address) => { - delete accounts[address] - }) + delete accounts[address]; + }); // save accounts state - this.store.updateState({ accounts }) + this.store.updateState({ accounts }); } /** @@ -165,7 +165,7 @@ export default class AccountTracker { */ clearAccounts() { - this.store.updateState({ accounts: {} }) + this.store.updateState({ accounts: {} }); } /** @@ -178,20 +178,20 @@ export default class AccountTracker { * */ async _updateForBlock(blockNumber) { - this._currentBlockNumber = blockNumber + this._currentBlockNumber = blockNumber; // block gasLimit polling shouldn't be in account-tracker shouldn't be here... - const currentBlock = await this._query.getBlockByNumber(blockNumber, false) + const currentBlock = await this._query.getBlockByNumber(blockNumber, false); if (!currentBlock) { - return + return; } - const currentBlockGasLimit = currentBlock.gasLimit - this.store.updateState({ currentBlockGasLimit }) + const currentBlockGasLimit = currentBlock.gasLimit; + this.store.updateState({ currentBlockGasLimit }); try { - await this._updateAccounts() + await this._updateAccounts(); } catch (err) { - log.error(err) + log.error(err); } } @@ -203,41 +203,41 @@ export default class AccountTracker { * */ async _updateAccounts() { - const { accounts } = this.store.getState() - const addresses = Object.keys(accounts) - const chainId = this.getCurrentChainId() + const { accounts } = this.store.getState(); + const addresses = Object.keys(accounts); + const chainId = this.getCurrentChainId(); switch (chainId) { case MAINNET_CHAIN_ID: await this._updateAccountsViaBalanceChecker( addresses, SINGLE_CALL_BALANCES_ADDRESS, - ) - break + ); + break; case RINKEBY_CHAIN_ID: await this._updateAccountsViaBalanceChecker( addresses, SINGLE_CALL_BALANCES_ADDRESS_RINKEBY, - ) - break + ); + break; case ROPSTEN_CHAIN_ID: await this._updateAccountsViaBalanceChecker( addresses, SINGLE_CALL_BALANCES_ADDRESS_ROPSTEN, - ) - break + ); + break; case KOVAN_CHAIN_ID: await this._updateAccountsViaBalanceChecker( addresses, SINGLE_CALL_BALANCES_ADDRESS_KOVAN, - ) - break + ); + break; default: - await Promise.all(addresses.map(this._updateAccount.bind(this))) + await Promise.all(addresses.map(this._updateAccount.bind(this))); } } @@ -251,16 +251,16 @@ export default class AccountTracker { */ async _updateAccount(address) { // query balance - const balance = await this._query.getBalance(address) - const result = { address, balance } + const balance = await this._query.getBalance(address); + const result = { address, balance }; // update accounts state - const { accounts } = this.store.getState() + const { accounts } = this.store.getState(); // only populate if the entry is still present if (!accounts[address]) { - return + return; } - accounts[address] = result - this.store.updateState({ accounts }) + accounts[address] = result; + this.store.updateState({ accounts }); } /** @@ -269,27 +269,27 @@ export default class AccountTracker { * @param {*} deployedContractAddress */ async _updateAccountsViaBalanceChecker(addresses, deployedContractAddress) { - const { accounts } = this.store.getState() - this.web3.setProvider(this._provider) + const { accounts } = this.store.getState(); + this.web3.setProvider(this._provider); const ethContract = this.web3.eth .contract(SINGLE_CALL_BALANCES_ABI) - .at(deployedContractAddress) - const ethBalance = ['0x0'] + .at(deployedContractAddress); + const ethBalance = ['0x0']; ethContract.balances(addresses, ethBalance, (error, result) => { if (error) { log.warn( `MetaMask - Account Tracker single call balance fetch failed`, error, - ) - Promise.all(addresses.map(this._updateAccount.bind(this))) - return + ); + Promise.all(addresses.map(this._updateAccount.bind(this))); + return; } addresses.forEach((address, index) => { - const balance = bnToHex(result[index]) - accounts[address] = { address, balance } - }) - this.store.updateState({ accounts }) - }) + const balance = bnToHex(result[index]); + accounts[address] = { address, balance }; + }); + this.store.updateState({ accounts }); + }); } } diff --git a/app/scripts/lib/buy-eth-url.js b/app/scripts/lib/buy-eth-url.js index 9c2e1c5221..bf1b131f0d 100644 --- a/app/scripts/lib/buy-eth-url.js +++ b/app/scripts/lib/buy-eth-url.js @@ -12,40 +12,42 @@ export default function getBuyEthUrl({ network, address, service }) { // default service by network if not specified if (!service) { // eslint-disable-next-line no-param-reassign - service = getDefaultServiceForNetwork(network) + service = getDefaultServiceForNetwork(network); } switch (service) { case 'wyre': - return `https://pay.sendwyre.com/purchase?dest=ethereum:${address}&destCurrency=ETH&accountId=AC-7AG3W4XH4N2&paymentMethod=debit-card` + return `https://pay.sendwyre.com/purchase?dest=ethereum:${address}&destCurrency=ETH&accountId=AC-7AG3W4XH4N2&paymentMethod=debit-card`; case 'metamask-faucet': - return 'https://faucet.metamask.io/' + return 'https://faucet.metamask.io/'; case 'rinkeby-faucet': - return 'https://www.rinkeby.io/' + return 'https://www.rinkeby.io/'; case 'kovan-faucet': - return 'https://github.com/kovan-testnet/faucet' + return 'https://github.com/kovan-testnet/faucet'; case 'goerli-faucet': - return 'https://goerli-faucet.slock.it/' + return 'https://goerli-faucet.slock.it/'; default: - throw new Error(`Unknown cryptocurrency exchange or faucet: "${service}"`) + throw new Error( + `Unknown cryptocurrency exchange or faucet: "${service}"`, + ); } } function getDefaultServiceForNetwork(network) { switch (network) { case '1': - return 'wyre' + return 'wyre'; case '3': - return 'metamask-faucet' + return 'metamask-faucet'; case '4': - return 'rinkeby-faucet' + return 'rinkeby-faucet'; case '42': - return 'kovan-faucet' + return 'kovan-faucet'; case '5': - return 'goerli-faucet' + return 'goerli-faucet'; default: throw new Error( `No default cryptocurrency exchange or faucet for networkId: "${network}"`, - ) + ); } } diff --git a/app/scripts/lib/cleanErrorStack.js b/app/scripts/lib/cleanErrorStack.js index a7bf607ad0..16fb961094 100644 --- a/app/scripts/lib/cleanErrorStack.js +++ b/app/scripts/lib/cleanErrorStack.js @@ -4,19 +4,19 @@ * @returns {Error} Error with clean stack trace. */ export default function cleanErrorStack(err) { - let { name } = err - name = name === undefined ? 'Error' : String(name) + let { name } = err; + name = name === undefined ? 'Error' : String(name); - let msg = err.message - msg = msg === undefined ? '' : String(msg) + let msg = err.message; + msg = msg === undefined ? '' : String(msg); if (name === '') { - err.stack = err.message + err.stack = err.message; } else if (msg === '') { - err.stack = err.name + err.stack = err.name; } else { - err.stack = `${err.name}: ${err.message}` + err.stack = `${err.name}: ${err.message}`; } - return err + return err; } diff --git a/app/scripts/lib/createLoggerMiddleware.js b/app/scripts/lib/createLoggerMiddleware.js index 18a128cbad..89a7696dd7 100644 --- a/app/scripts/lib/createLoggerMiddleware.js +++ b/app/scripts/lib/createLoggerMiddleware.js @@ -1,4 +1,4 @@ -import log from 'loglevel' +import log from 'loglevel'; /** * Returns a middleware that logs RPC activity @@ -13,13 +13,13 @@ export default function createLoggerMiddleware(opts) { ) { next((/** @type {Function} */ cb) => { if (res.error) { - log.error('Error in RPC response:\n', res) + log.error('Error in RPC response:\n', res); } if (req.isMetamaskInternal) { - return + return; } - log.info(`RPC (${opts.origin}):`, req, '->', res) - cb() - }) - } + log.info(`RPC (${opts.origin}):`, req, '->', res); + cb(); + }); + }; } diff --git a/app/scripts/lib/createOnboardingMiddleware.js b/app/scripts/lib/createOnboardingMiddleware.js index cef41deb6e..7f79da8d6f 100644 --- a/app/scripts/lib/createOnboardingMiddleware.js +++ b/app/scripts/lib/createOnboardingMiddleware.js @@ -1,5 +1,5 @@ -import log from 'loglevel' -import extension from 'extensionizer' +import log from 'loglevel'; +import extension from 'extensionizer'; /** * Returns a middleware that intercepts `wallet_registerOnboarding` messages @@ -13,20 +13,20 @@ export default function createOnboardingMiddleware({ return async function originMiddleware(req, res, next, end) { try { if (req.method !== 'wallet_registerOnboarding') { - next() - return + next(); + return; } if (req.tabId && req.tabId !== extension.tabs.TAB_ID_NONE) { - await registerOnboarding(location, req.tabId) + await registerOnboarding(location, req.tabId); } else { log.debug( `'wallet_registerOnboarding' message from ${location} ignored due to missing tabId`, - ) + ); } - res.result = true - end() + res.result = true; + end(); } catch (error) { - end(error) + end(error); } - } + }; } diff --git a/app/scripts/lib/createOriginMiddleware.js b/app/scripts/lib/createOriginMiddleware.js index 031ba84d52..0e3c14add6 100644 --- a/app/scripts/lib/createOriginMiddleware.js +++ b/app/scripts/lib/createOriginMiddleware.js @@ -9,7 +9,7 @@ export default function createOriginMiddleware(opts) { /** @type {any} */ _, /** @type {Function} */ next, ) { - req.origin = opts.origin - next() - } + req.origin = opts.origin; + next(); + }; } diff --git a/app/scripts/lib/createStreamSink.js b/app/scripts/lib/createStreamSink.js index 648e745ddf..84ad69db18 100644 --- a/app/scripts/lib/createStreamSink.js +++ b/app/scripts/lib/createStreamSink.js @@ -1,19 +1,19 @@ -import { Writable as WritableStream } from 'readable-stream' -import promiseToCallback from 'promise-to-callback' +import { Writable as WritableStream } from 'readable-stream'; +import promiseToCallback from 'promise-to-callback'; class AsyncWritableStream extends WritableStream { constructor(asyncWriteFn, _opts) { - const opts = { objectMode: true, ..._opts } - super(opts) - this._asyncWriteFn = asyncWriteFn + const opts = { objectMode: true, ..._opts }; + super(opts); + this._asyncWriteFn = asyncWriteFn; } // write from incoming stream to state _write(chunk, encoding, callback) { - promiseToCallback(this._asyncWriteFn(chunk, encoding))(callback) + promiseToCallback(this._asyncWriteFn(chunk, encoding))(callback); } } export default function createStreamSink(asyncWriteFn, _opts) { - return new AsyncWritableStream(asyncWriteFn, _opts) + return new AsyncWritableStream(asyncWriteFn, _opts); } diff --git a/app/scripts/lib/createTabIdMiddleware.js b/app/scripts/lib/createTabIdMiddleware.js index 9848b68c92..abce443c9e 100644 --- a/app/scripts/lib/createTabIdMiddleware.js +++ b/app/scripts/lib/createTabIdMiddleware.js @@ -9,7 +9,7 @@ export default function createTabIdMiddleware(opts) { /** @type {any} */ _, /** @type {Function} */ next, ) { - req.tabId = opts.tabId - next() - } + req.tabId = opts.tabId; + next(); + }; } diff --git a/app/scripts/lib/decrypt-message-manager.js b/app/scripts/lib/decrypt-message-manager.js index caa2970f67..39f2a0e424 100644 --- a/app/scripts/lib/decrypt-message-manager.js +++ b/app/scripts/lib/decrypt-message-manager.js @@ -1,13 +1,13 @@ -import EventEmitter from 'events' -import { ObservableStore } from '@metamask/obs-store' -import ethUtil from 'ethereumjs-util' -import { ethErrors } from 'eth-rpc-errors' -import log from 'loglevel' -import { MESSAGE_TYPE } from '../../../shared/constants/app' -import { addHexPrefix } from './util' -import createId from './random-id' +import EventEmitter from 'events'; +import { ObservableStore } from '@metamask/obs-store'; +import ethUtil from 'ethereumjs-util'; +import { ethErrors } from 'eth-rpc-errors'; +import log from 'loglevel'; +import { MESSAGE_TYPE } from '../../../shared/constants/app'; +import { addHexPrefix } from './util'; +import createId from './random-id'; -const hexRe = /^[0-9A-Fa-f]+$/gu +const hexRe = /^[0-9A-Fa-f]+$/gu; /** * Represents, and contains data about, an 'eth_decrypt' type decryption request. These are created when a @@ -38,12 +38,12 @@ export default class DecryptMessageManager extends EventEmitter { * */ constructor() { - super() + super(); this.memStore = new ObservableStore({ unapprovedDecryptMsgs: {}, unapprovedDecryptMsgCount: 0, - }) - this.messages = [] + }); + this.messages = []; } /** @@ -53,7 +53,7 @@ export default class DecryptMessageManager extends EventEmitter { * */ get unapprovedDecryptMsgCount() { - return Object.keys(this.getUnapprovedMsgs()).length + return Object.keys(this.getUnapprovedMsgs()).length; } /** @@ -67,9 +67,9 @@ export default class DecryptMessageManager extends EventEmitter { return this.messages .filter((msg) => msg.status === 'unapproved') .reduce((result, msg) => { - result[msg.id] = msg - return result - }, {}) + result[msg.id] = msg; + return result; + }, {}); } /** @@ -85,25 +85,25 @@ export default class DecryptMessageManager extends EventEmitter { addUnapprovedMessageAsync(msgParams, req) { return new Promise((resolve, reject) => { if (!msgParams.from) { - reject(new Error('MetaMask Decryption: from field is required.')) - return + reject(new Error('MetaMask Decryption: from field is required.')); + return; } - const msgId = this.addUnapprovedMessage(msgParams, req) + const msgId = this.addUnapprovedMessage(msgParams, req); this.once(`${msgId}:finished`, (data) => { switch (data.status) { case 'decrypted': - resolve(data.rawData) - return + resolve(data.rawData); + return; case 'rejected': reject( ethErrors.provider.userRejectedRequest( 'MetaMask Decryption: User denied message decryption.', ), - ) - return + ); + return; case 'errored': - reject(new Error('This message cannot be decrypted')) - return + reject(new Error('This message cannot be decrypted')); + return; default: reject( new Error( @@ -111,10 +111,10 @@ export default class DecryptMessageManager extends EventEmitter { msgParams, )}`, ), - ) + ); } - }) - }) + }); + }); } /** @@ -132,27 +132,27 @@ export default class DecryptMessageManager extends EventEmitter { `DecryptMessageManager addUnapprovedMessage: ${JSON.stringify( msgParams, )}`, - ) + ); // add origin from request if (req) { - msgParams.origin = req.origin + msgParams.origin = req.origin; } - msgParams.data = this.normalizeMsgData(msgParams.data) + msgParams.data = this.normalizeMsgData(msgParams.data); // create txData obj with parameters and meta data - const time = new Date().getTime() - const msgId = createId() + const time = new Date().getTime(); + const msgId = createId(); const msgData = { id: msgId, msgParams, time, status: 'unapproved', type: MESSAGE_TYPE.ETH_DECRYPT, - } - this.addMsg(msgData) + }; + this.addMsg(msgData); // signal update - this.emit('update') - return msgId + this.emit('update'); + return msgId; } /** @@ -163,8 +163,8 @@ export default class DecryptMessageManager extends EventEmitter { * */ addMsg(msg) { - this.messages.push(msg) - this._saveMsgList() + this.messages.push(msg); + this._saveMsgList(); } /** @@ -176,7 +176,7 @@ export default class DecryptMessageManager extends EventEmitter { * */ getMsg(msgId) { - return this.messages.find((msg) => msg.id === msgId) + return this.messages.find((msg) => msg.id === msgId); } /** @@ -189,8 +189,8 @@ export default class DecryptMessageManager extends EventEmitter { * */ approveMessage(msgParams) { - this.setMsgStatusApproved(msgParams.metamaskId) - return this.prepMsgForDecryption(msgParams) + this.setMsgStatusApproved(msgParams.metamaskId); + return this.prepMsgForDecryption(msgParams); } /** @@ -200,7 +200,7 @@ export default class DecryptMessageManager extends EventEmitter { * */ setMsgStatusApproved(msgId) { - this._setMsgStatus(msgId, 'approved') + this._setMsgStatus(msgId, 'approved'); } /** @@ -212,10 +212,10 @@ export default class DecryptMessageManager extends EventEmitter { * */ setMsgStatusDecrypted(msgId, rawData) { - const msg = this.getMsg(msgId) - msg.rawData = rawData - this._updateMsg(msg) - this._setMsgStatus(msgId, 'decrypted') + const msg = this.getMsg(msgId); + msg.rawData = rawData; + this._updateMsg(msg); + this._setMsgStatus(msgId, 'decrypted'); } /** @@ -226,8 +226,8 @@ export default class DecryptMessageManager extends EventEmitter { * */ prepMsgForDecryption(msgParams) { - delete msgParams.metamaskId - return Promise.resolve(msgParams) + delete msgParams.metamaskId; + return Promise.resolve(msgParams); } /** @@ -237,7 +237,7 @@ export default class DecryptMessageManager extends EventEmitter { * */ rejectMsg(msgId) { - this._setMsgStatus(msgId, 'rejected') + this._setMsgStatus(msgId, 'rejected'); } /** @@ -247,10 +247,10 @@ export default class DecryptMessageManager extends EventEmitter { * */ errorMessage(msgId, error) { - const msg = this.getMsg(msgId) - msg.error = error - this._updateMsg(msg) - this._setMsgStatus(msgId, 'errored') + const msg = this.getMsg(msgId); + msg.error = error; + this._updateMsg(msg); + this._setMsgStatus(msgId, 'errored'); } /** @@ -267,21 +267,21 @@ export default class DecryptMessageManager extends EventEmitter { * */ _setMsgStatus(msgId, status) { - const msg = this.getMsg(msgId) + const msg = this.getMsg(msgId); if (!msg) { throw new Error( `DecryptMessageManager - Message not found for id: "${msgId}".`, - ) + ); } - msg.status = status - this._updateMsg(msg) - this.emit(`${msgId}:${status}`, msg) + msg.status = status; + this._updateMsg(msg); + this.emit(`${msgId}:${status}`, msg); if ( status === 'rejected' || status === 'decrypted' || status === 'errored' ) { - this.emit(`${msgId}:finished`, msg) + this.emit(`${msgId}:finished`, msg); } } @@ -295,11 +295,11 @@ export default class DecryptMessageManager extends EventEmitter { * */ _updateMsg(msg) { - const index = this.messages.findIndex((message) => message.id === msg.id) + const index = this.messages.findIndex((message) => message.id === msg.id); if (index !== -1) { - this.messages[index] = msg + this.messages[index] = msg; } - this._saveMsgList() + this._saveMsgList(); } /** @@ -310,13 +310,13 @@ export default class DecryptMessageManager extends EventEmitter { * */ _saveMsgList() { - const unapprovedDecryptMsgs = this.getUnapprovedMsgs() - const unapprovedDecryptMsgCount = Object.keys(unapprovedDecryptMsgs).length + const unapprovedDecryptMsgs = this.getUnapprovedMsgs(); + const unapprovedDecryptMsgCount = Object.keys(unapprovedDecryptMsgs).length; this.memStore.updateState({ unapprovedDecryptMsgs, unapprovedDecryptMsgCount, - }) - this.emit('updateBadge') + }); + this.emit('updateBadge'); } /** @@ -328,14 +328,14 @@ export default class DecryptMessageManager extends EventEmitter { */ normalizeMsgData(data) { try { - const stripped = ethUtil.stripHexPrefix(data) + const stripped = ethUtil.stripHexPrefix(data); if (stripped.match(hexRe)) { - return addHexPrefix(stripped) + return addHexPrefix(stripped); } } catch (e) { - log.debug(`Message was not hex encoded, interpreting as utf8.`) + log.debug(`Message was not hex encoded, interpreting as utf8.`); } - return ethUtil.bufferToHex(Buffer.from(data, 'utf8')) + return ethUtil.bufferToHex(Buffer.from(data, 'utf8')); } } diff --git a/app/scripts/lib/encryption-public-key-manager.js b/app/scripts/lib/encryption-public-key-manager.js index 54504fd62f..6fc213b194 100644 --- a/app/scripts/lib/encryption-public-key-manager.js +++ b/app/scripts/lib/encryption-public-key-manager.js @@ -1,9 +1,9 @@ -import EventEmitter from 'events' -import { ObservableStore } from '@metamask/obs-store' -import { ethErrors } from 'eth-rpc-errors' -import log from 'loglevel' -import { MESSAGE_TYPE } from '../../../shared/constants/app' -import createId from './random-id' +import EventEmitter from 'events'; +import { ObservableStore } from '@metamask/obs-store'; +import { ethErrors } from 'eth-rpc-errors'; +import log from 'loglevel'; +import { MESSAGE_TYPE } from '../../../shared/constants/app'; +import createId from './random-id'; /** * Represents, and contains data about, an 'eth_getEncryptionPublicKey' type request. These are created when @@ -34,12 +34,12 @@ export default class EncryptionPublicKeyManager extends EventEmitter { * */ constructor() { - super() + super(); this.memStore = new ObservableStore({ unapprovedEncryptionPublicKeyMsgs: {}, unapprovedEncryptionPublicKeyMsgCount: 0, - }) - this.messages = [] + }); + this.messages = []; } /** @@ -49,7 +49,7 @@ export default class EncryptionPublicKeyManager extends EventEmitter { * */ get unapprovedEncryptionPublicKeyMsgCount() { - return Object.keys(this.getUnapprovedMsgs()).length + return Object.keys(this.getUnapprovedMsgs()).length; } /** @@ -63,9 +63,9 @@ export default class EncryptionPublicKeyManager extends EventEmitter { return this.messages .filter((msg) => msg.status === 'unapproved') .reduce((result, msg) => { - result[msg.id] = msg - return result - }, {}) + result[msg.id] = msg; + return result; + }, {}); } /** @@ -81,22 +81,22 @@ export default class EncryptionPublicKeyManager extends EventEmitter { addUnapprovedMessageAsync(address, req) { return new Promise((resolve, reject) => { if (!address) { - reject(new Error('MetaMask Message: address field is required.')) - return + reject(new Error('MetaMask Message: address field is required.')); + return; } - const msgId = this.addUnapprovedMessage(address, req) + const msgId = this.addUnapprovedMessage(address, req); this.once(`${msgId}:finished`, (data) => { switch (data.status) { case 'received': - resolve(data.rawData) - return + resolve(data.rawData); + return; case 'rejected': reject( ethErrors.provider.userRejectedRequest( 'MetaMask EncryptionPublicKey: User denied message EncryptionPublicKey.', ), - ) - return + ); + return; default: reject( new Error( @@ -104,10 +104,10 @@ export default class EncryptionPublicKeyManager extends EventEmitter { address, )}`, ), - ) + ); } - }) - }) + }); + }); } /** @@ -121,27 +121,27 @@ export default class EncryptionPublicKeyManager extends EventEmitter { * */ addUnapprovedMessage(address, req) { - log.debug(`EncryptionPublicKeyManager addUnapprovedMessage: address`) + log.debug(`EncryptionPublicKeyManager addUnapprovedMessage: address`); // create txData obj with parameters and meta data - const time = new Date().getTime() - const msgId = createId() + const time = new Date().getTime(); + const msgId = createId(); const msgData = { id: msgId, msgParams: address, time, status: 'unapproved', type: MESSAGE_TYPE.ETH_GET_ENCRYPTION_PUBLIC_KEY, - } + }; if (req) { - msgData.origin = req.origin + msgData.origin = req.origin; } - this.addMsg(msgData) + this.addMsg(msgData); // signal update - this.emit('update') - return msgId + this.emit('update'); + return msgId; } /** @@ -152,8 +152,8 @@ export default class EncryptionPublicKeyManager extends EventEmitter { * */ addMsg(msg) { - this.messages.push(msg) - this._saveMsgList() + this.messages.push(msg); + this._saveMsgList(); } /** @@ -165,7 +165,7 @@ export default class EncryptionPublicKeyManager extends EventEmitter { * */ getMsg(msgId) { - return this.messages.find((msg) => msg.id === msgId) + return this.messages.find((msg) => msg.id === msgId); } /** @@ -178,8 +178,8 @@ export default class EncryptionPublicKeyManager extends EventEmitter { * */ approveMessage(msgParams) { - this.setMsgStatusApproved(msgParams.metamaskId) - return this.prepMsgForEncryptionPublicKey(msgParams) + this.setMsgStatusApproved(msgParams.metamaskId); + return this.prepMsgForEncryptionPublicKey(msgParams); } /** @@ -189,7 +189,7 @@ export default class EncryptionPublicKeyManager extends EventEmitter { * */ setMsgStatusApproved(msgId) { - this._setMsgStatus(msgId, 'approved') + this._setMsgStatus(msgId, 'approved'); } /** @@ -201,10 +201,10 @@ export default class EncryptionPublicKeyManager extends EventEmitter { * */ setMsgStatusReceived(msgId, rawData) { - const msg = this.getMsg(msgId) - msg.rawData = rawData - this._updateMsg(msg) - this._setMsgStatus(msgId, 'received') + const msg = this.getMsg(msgId); + msg.rawData = rawData; + this._updateMsg(msg); + this._setMsgStatus(msgId, 'received'); } /** @@ -215,8 +215,8 @@ export default class EncryptionPublicKeyManager extends EventEmitter { * */ prepMsgForEncryptionPublicKey(msgParams) { - delete msgParams.metamaskId - return Promise.resolve(msgParams) + delete msgParams.metamaskId; + return Promise.resolve(msgParams); } /** @@ -226,7 +226,7 @@ export default class EncryptionPublicKeyManager extends EventEmitter { * */ rejectMsg(msgId) { - this._setMsgStatus(msgId, 'rejected') + this._setMsgStatus(msgId, 'rejected'); } /** @@ -236,10 +236,10 @@ export default class EncryptionPublicKeyManager extends EventEmitter { * */ errorMessage(msgId, error) { - const msg = this.getMsg(msgId) - msg.error = error - this._updateMsg(msg) - this._setMsgStatus(msgId, 'errored') + const msg = this.getMsg(msgId); + msg.error = error; + this._updateMsg(msg); + this._setMsgStatus(msgId, 'errored'); } /** @@ -256,17 +256,17 @@ export default class EncryptionPublicKeyManager extends EventEmitter { * */ _setMsgStatus(msgId, status) { - const msg = this.getMsg(msgId) + const msg = this.getMsg(msgId); if (!msg) { throw new Error( `EncryptionPublicKeyManager - Message not found for id: "${msgId}".`, - ) + ); } - msg.status = status - this._updateMsg(msg) - this.emit(`${msgId}:${status}`, msg) + msg.status = status; + this._updateMsg(msg); + this.emit(`${msgId}:${status}`, msg); if (status === 'rejected' || status === 'received') { - this.emit(`${msgId}:finished`, msg) + this.emit(`${msgId}:finished`, msg); } } @@ -280,11 +280,11 @@ export default class EncryptionPublicKeyManager extends EventEmitter { * */ _updateMsg(msg) { - const index = this.messages.findIndex((message) => message.id === msg.id) + const index = this.messages.findIndex((message) => message.id === msg.id); if (index !== -1) { - this.messages[index] = msg + this.messages[index] = msg; } - this._saveMsgList() + this._saveMsgList(); } /** @@ -295,14 +295,14 @@ export default class EncryptionPublicKeyManager extends EventEmitter { * */ _saveMsgList() { - const unapprovedEncryptionPublicKeyMsgs = this.getUnapprovedMsgs() + const unapprovedEncryptionPublicKeyMsgs = this.getUnapprovedMsgs(); const unapprovedEncryptionPublicKeyMsgCount = Object.keys( unapprovedEncryptionPublicKeyMsgs, - ).length + ).length; this.memStore.updateState({ unapprovedEncryptionPublicKeyMsgs, unapprovedEncryptionPublicKeyMsgCount, - }) - this.emit('updateBadge') + }); + this.emit('updateBadge'); } } diff --git a/app/scripts/lib/ens-ipfs/contracts/registry.js b/app/scripts/lib/ens-ipfs/contracts/registry.js index 4eab802872..07342ac37f 100644 --- a/app/scripts/lib/ens-ipfs/contracts/registry.js +++ b/app/scripts/lib/ens-ipfs/contracts/registry.js @@ -105,5 +105,5 @@ const abi = [ name: 'NewTTL', type: 'event', }, -] -export default abi +]; +export default abi; diff --git a/app/scripts/lib/ens-ipfs/contracts/resolver.js b/app/scripts/lib/ens-ipfs/contracts/resolver.js index a392bcfe8d..af1f0e544e 100644 --- a/app/scripts/lib/ens-ipfs/contracts/resolver.js +++ b/app/scripts/lib/ens-ipfs/contracts/resolver.js @@ -232,5 +232,5 @@ const abi = [ name: 'ContenthashChanged', type: 'event', }, -] -export default abi +]; +export default abi; diff --git a/app/scripts/lib/ens-ipfs/resolver.js b/app/scripts/lib/ens-ipfs/resolver.js index 5a4b290434..ff61f00e60 100644 --- a/app/scripts/lib/ens-ipfs/resolver.js +++ b/app/scripts/lib/ens-ipfs/resolver.js @@ -1,61 +1,61 @@ -import namehash from 'eth-ens-namehash' -import Eth from 'ethjs-query' -import EthContract from 'ethjs-contract' -import contentHash from 'content-hash' -import registryAbi from './contracts/registry' -import resolverAbi from './contracts/resolver' +import namehash from 'eth-ens-namehash'; +import Eth from 'ethjs-query'; +import EthContract from 'ethjs-contract'; +import contentHash from 'content-hash'; +import registryAbi from './contracts/registry'; +import resolverAbi from './contracts/resolver'; export default async function resolveEnsToIpfsContentId({ provider, name }) { - const eth = new Eth(provider) - const hash = namehash.hash(name) - const contract = new EthContract(eth) + const eth = new Eth(provider); + const hash = namehash.hash(name); + const contract = new EthContract(eth); // lookup registry - const chainId = Number.parseInt(await eth.net_version(), 10) - const registryAddress = getRegistryForChainId(chainId) + const chainId = Number.parseInt(await eth.net_version(), 10); + const registryAddress = getRegistryForChainId(chainId); if (!registryAddress) { throw new Error( `EnsIpfsResolver - no known ens-ipfs registry for chainId "${chainId}"`, - ) + ); } - const Registry = contract(registryAbi).at(registryAddress) + const Registry = contract(registryAbi).at(registryAddress); // lookup resolver - const resolverLookupResult = await Registry.resolver(hash) - const resolverAddress = resolverLookupResult[0] + const resolverLookupResult = await Registry.resolver(hash); + const resolverAddress = resolverLookupResult[0]; if (hexValueIsEmpty(resolverAddress)) { - throw new Error(`EnsIpfsResolver - no resolver found for name "${name}"`) + throw new Error(`EnsIpfsResolver - no resolver found for name "${name}"`); } - const Resolver = contract(resolverAbi).at(resolverAddress) + const Resolver = contract(resolverAbi).at(resolverAddress); - const isEIP1577Compliant = await Resolver.supportsInterface('0xbc1c58d1') - const isLegacyResolver = await Resolver.supportsInterface('0xd8389dc5') + const isEIP1577Compliant = await Resolver.supportsInterface('0xbc1c58d1'); + const isLegacyResolver = await Resolver.supportsInterface('0xd8389dc5'); if (isEIP1577Compliant[0]) { - const contentLookupResult = await Resolver.contenthash(hash) - const rawContentHash = contentLookupResult[0] - let decodedContentHash = contentHash.decode(rawContentHash) - const type = contentHash.getCodec(rawContentHash) + const contentLookupResult = await Resolver.contenthash(hash); + const rawContentHash = contentLookupResult[0]; + let decodedContentHash = contentHash.decode(rawContentHash); + const type = contentHash.getCodec(rawContentHash); if (type === 'ipfs-ns' || type === 'ipns-ns') { decodedContentHash = contentHash.helpers.cidV0ToV1Base32( decodedContentHash, - ) + ); } - return { type, hash: decodedContentHash } + return { type, hash: decodedContentHash }; } if (isLegacyResolver[0]) { // lookup content id - const contentLookupResult = await Resolver.content(hash) - const content = contentLookupResult[0] + const contentLookupResult = await Resolver.content(hash); + const content = contentLookupResult[0]; if (hexValueIsEmpty(content)) { throw new Error( `EnsIpfsResolver - no content ID found for name "${name}"`, - ) + ); } - return { type: 'swarm-ns', hash: content.slice(2) } + return { type: 'swarm-ns', hash: content.slice(2) }; } throw new Error( `EnsIpfsResolver - the resolver for name "${name}" is not standard, it should either supports contenthash() or content()`, - ) + ); } function hexValueIsEmpty(value) { @@ -65,7 +65,7 @@ function hexValueIsEmpty(value) { '0x', '0x0', '0x0000000000000000000000000000000000000000000000000000000000000000', - ].includes(value) + ].includes(value); } /** @@ -80,8 +80,8 @@ function getRegistryForChainId(chainId) { case 4: case 5: // Mainnet, Ropsten, Rinkeby, and Goerli, respectively, use the same address - return '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e' + return '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e'; default: - return null + return null; } } diff --git a/app/scripts/lib/ens-ipfs/setup.js b/app/scripts/lib/ens-ipfs/setup.js index 9ec6e14921..51b7403017 100644 --- a/app/scripts/lib/ens-ipfs/setup.js +++ b/app/scripts/lib/ens-ipfs/setup.js @@ -1,10 +1,10 @@ -import extension from 'extensionizer' -import getFetchWithTimeout from '../../../../shared/modules/fetch-with-timeout' -import resolveEnsToIpfsContentId from './resolver' +import extension from 'extensionizer'; +import getFetchWithTimeout from '../../../../shared/modules/fetch-with-timeout'; +import resolveEnsToIpfsContentId from './resolver'; -const fetchWithTimeout = getFetchWithTimeout(30000) +const fetchWithTimeout = getFetchWithTimeout(30000); -const supportedTopLevelDomains = ['eth'] +const supportedTopLevelDomains = ['eth']; export default function setupEnsIpfsResolver({ provider, @@ -12,76 +12,79 @@ export default function setupEnsIpfsResolver({ getIpfsGateway, }) { // install listener - const urlPatterns = supportedTopLevelDomains.map((tld) => `*://*.${tld}/*`) + const urlPatterns = supportedTopLevelDomains.map((tld) => `*://*.${tld}/*`); extension.webRequest.onErrorOccurred.addListener(webRequestDidFail, { urls: urlPatterns, types: ['main_frame'], - }) + }); // return api object return { // uninstall listener remove() { - extension.webRequest.onErrorOccurred.removeListener(webRequestDidFail) + extension.webRequest.onErrorOccurred.removeListener(webRequestDidFail); }, - } + }; async function webRequestDidFail(details) { - const { tabId, url } = details + const { tabId, url } = details; // ignore requests that are not associated with tabs // only attempt ENS resolution on mainnet if (tabId === -1 || getCurrentNetwork() !== '1') { - return + return; } // parse ens name - const { hostname: name, pathname, search, hash: fragment } = new URL(url) - const domainParts = name.split('.') - const topLevelDomain = domainParts[domainParts.length - 1] + const { hostname: name, pathname, search, hash: fragment } = new URL(url); + const domainParts = name.split('.'); + const topLevelDomain = domainParts[domainParts.length - 1]; // if unsupported TLD, abort if (!supportedTopLevelDomains.includes(topLevelDomain)) { - return + return; } // otherwise attempt resolve - attemptResolve({ tabId, name, pathname, search, fragment }) + attemptResolve({ tabId, name, pathname, search, fragment }); } async function attemptResolve({ tabId, name, pathname, search, fragment }) { - const ipfsGateway = getIpfsGateway() - extension.tabs.update(tabId, { url: `loading.html` }) - let url = `https://app.ens.domains/name/${name}` + const ipfsGateway = getIpfsGateway(); + extension.tabs.update(tabId, { url: `loading.html` }); + let url = `https://app.ens.domains/name/${name}`; try { - const { type, hash } = await resolveEnsToIpfsContentId({ provider, name }) + const { type, hash } = await resolveEnsToIpfsContentId({ + provider, + name, + }); if (type === 'ipfs-ns' || type === 'ipns-ns') { const resolvedUrl = `https://${hash}.${type.slice( 0, 4, - )}.${ipfsGateway}${pathname}${search || ''}${fragment || ''}` + )}.${ipfsGateway}${pathname}${search || ''}${fragment || ''}`; try { // check if ipfs gateway has result const response = await fetchWithTimeout(resolvedUrl, { method: 'HEAD', - }) + }); if (response.status === 200) { - url = resolvedUrl + url = resolvedUrl; } } catch (err) { - console.warn(err) + console.warn(err); } } else if (type === 'swarm-ns') { url = `https://swarm-gateways.net/bzz:/${hash}${pathname}${ search || '' - }${fragment || ''}` + }${fragment || ''}`; } else if (type === 'onion' || type === 'onion3') { - url = `http://${hash}.onion${pathname}${search || ''}${fragment || ''}` + url = `http://${hash}.onion${pathname}${search || ''}${fragment || ''}`; } else if (type === 'zeronet') { url = `http://127.0.0.1:43110/${hash}${pathname}${search || ''}${ fragment || '' - }` + }`; } } catch (err) { - console.warn(err) + console.warn(err); } finally { - extension.tabs.update(tabId, { url }) + extension.tabs.update(tabId, { url }); } } } diff --git a/app/scripts/lib/extractEthjsErrorMessage.js b/app/scripts/lib/extractEthjsErrorMessage.js index 621e221954..d17d581a08 100644 --- a/app/scripts/lib/extractEthjsErrorMessage.js +++ b/app/scripts/lib/extractEthjsErrorMessage.js @@ -1,5 +1,5 @@ -const ethJsRpcSlug = 'Error: [ethjs-rpc] rpc error with payload ' -const errorLabelPrefix = 'Error: ' +const ethJsRpcSlug = 'Error: [ethjs-rpc] rpc error with payload '; +const errorLabelPrefix = 'Error: '; /** * Extracts the important part of an ethjs-rpc error message. If the passed error is not an isEthjsRpcError, the error @@ -14,13 +14,13 @@ const errorLabelPrefix = 'Error: ' * */ export default function extractEthjsErrorMessage(errorMessage) { - const isEthjsRpcError = errorMessage.includes(ethJsRpcSlug) + const isEthjsRpcError = errorMessage.includes(ethJsRpcSlug); if (isEthjsRpcError) { - const payloadAndError = errorMessage.slice(ethJsRpcSlug.length) + const payloadAndError = errorMessage.slice(ethJsRpcSlug.length); const originalError = payloadAndError.slice( payloadAndError.indexOf(errorLabelPrefix) + errorLabelPrefix.length, - ) - return originalError + ); + return originalError; } - return errorMessage + return errorMessage; } diff --git a/app/scripts/lib/get-first-preferred-lang-code.js b/app/scripts/lib/get-first-preferred-lang-code.js index d37ac6d0d9..4639d6dc92 100644 --- a/app/scripts/lib/get-first-preferred-lang-code.js +++ b/app/scripts/lib/get-first-preferred-lang-code.js @@ -1,19 +1,19 @@ -import extension from 'extensionizer' -import promisify from 'pify' -import allLocales from '../../_locales/index.json' +import extension from 'extensionizer'; +import promisify from 'pify'; +import allLocales from '../../_locales/index.json'; const getPreferredLocales = extension.i18n ? promisify(extension.i18n.getAcceptLanguages, { errorFirst: false }) - : async () => [] + : async () => []; // mapping some browsers return hyphen instead underscore in locale codes (e.g. zh_TW -> zh-tw) -const existingLocaleCodes = {} +const existingLocaleCodes = {}; allLocales.forEach((locale) => { if (locale && locale.code) { existingLocaleCodes[locale.code.toLowerCase().replace('_', '-')] = - locale.code + locale.code; } -}) +}); /** * Returns a preferred language code, based on settings within the user's browser. If we have no translations for the @@ -23,26 +23,26 @@ allLocales.forEach((locale) => { * */ export default async function getFirstPreferredLangCode() { - let userPreferredLocaleCodes + let userPreferredLocaleCodes; try { - userPreferredLocaleCodes = await getPreferredLocales() + userPreferredLocaleCodes = await getPreferredLocales(); } catch (e) { // Brave currently throws when calling getAcceptLanguages, so this handles that. - userPreferredLocaleCodes = [] + userPreferredLocaleCodes = []; } // safeguard for Brave Browser until they implement chrome.i18n.getAcceptLanguages // https://github.com/MetaMask/metamask-extension/issues/4270 if (!userPreferredLocaleCodes) { - userPreferredLocaleCodes = [] + userPreferredLocaleCodes = []; } const firstPreferredLangCode = userPreferredLocaleCodes .map((code) => code.toLowerCase().replace('_', '-')) .find((code) => Object.prototype.hasOwnProperty.call(existingLocaleCodes, code), - ) + ); - return existingLocaleCodes[firstPreferredLangCode] || 'en' + return existingLocaleCodes[firstPreferredLangCode] || 'en'; } diff --git a/app/scripts/lib/getObjStructure.js b/app/scripts/lib/getObjStructure.js index b963519122..8ac90f9fe0 100644 --- a/app/scripts/lib/getObjStructure.js +++ b/app/scripts/lib/getObjStructure.js @@ -1,4 +1,4 @@ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; // This will create an object that represents the structure of the given object // it replaces all values with the result of their type @@ -22,10 +22,10 @@ import { cloneDeep } from 'lodash' * */ export default function getObjStructure(obj) { - const structure = cloneDeep(obj) + const structure = cloneDeep(obj); return deepMap(structure, (value) => { - return value === null ? 'null' : typeof value - }) + return value === null ? 'null' : typeof value; + }); } /** @@ -39,10 +39,10 @@ export default function getObjStructure(obj) { function deepMap(target = {}, visit) { Object.entries(target).forEach(([key, value]) => { if (typeof value === 'object' && value !== null) { - target[key] = deepMap(value, visit) + target[key] = deepMap(value, visit); } else { - target[key] = visit(value) + target[key] = visit(value); } - }) - return target + }); + return target; } diff --git a/app/scripts/lib/local-store.js b/app/scripts/lib/local-store.js index aa12b50f84..4157a39902 100644 --- a/app/scripts/lib/local-store.js +++ b/app/scripts/lib/local-store.js @@ -1,6 +1,6 @@ -import extension from 'extensionizer' -import log from 'loglevel' -import { checkForError } from './util' +import extension from 'extensionizer'; +import log from 'loglevel'; +import { checkForError } from './util'; /** * A wrapper around the extension's storage local API @@ -10,9 +10,9 @@ export default class ExtensionStore { * @constructor */ constructor() { - this.isSupported = Boolean(extension.storage.local) + this.isSupported = Boolean(extension.storage.local); if (!this.isSupported) { - log.error('Storage local API not available.') + log.error('Storage local API not available.'); } } @@ -22,15 +22,15 @@ export default class ExtensionStore { */ async get() { if (!this.isSupported) { - return undefined + return undefined; } - const result = await this._get() + const result = await this._get(); // extension.storage.local always returns an obj // if the object is empty, treat it as undefined if (isEmpty(result)) { - return undefined + return undefined; } - return result + return result; } /** @@ -39,7 +39,7 @@ export default class ExtensionStore { * @returns {Promise} */ async set(state) { - return this._set(state) + return this._set(state); } /** @@ -48,17 +48,17 @@ export default class ExtensionStore { * @returns {Object} the key-value map from local storage */ _get() { - const { local } = extension.storage + const { local } = extension.storage; return new Promise((resolve, reject) => { local.get(null, (/** @type {any} */ result) => { - const err = checkForError() + const err = checkForError(); if (err) { - reject(err) + reject(err); } else { - resolve(result) + resolve(result); } - }) - }) + }); + }); } /** @@ -68,17 +68,17 @@ export default class ExtensionStore { * @private */ _set(obj) { - const { local } = extension.storage + const { local } = extension.storage; return new Promise((resolve, reject) => { local.set(obj, () => { - const err = checkForError() + const err = checkForError(); if (err) { - reject(err) + reject(err); } else { - resolve() + resolve(); } - }) - }) + }); + }); } } @@ -88,5 +88,5 @@ export default class ExtensionStore { * @returns {boolean} */ function isEmpty(obj) { - return Object.keys(obj).length === 0 + return Object.keys(obj).length === 0; } diff --git a/app/scripts/lib/message-manager.js b/app/scripts/lib/message-manager.js index 0e19c35607..796971208a 100644 --- a/app/scripts/lib/message-manager.js +++ b/app/scripts/lib/message-manager.js @@ -1,9 +1,9 @@ -import EventEmitter from 'events' -import { ObservableStore } from '@metamask/obs-store' -import ethUtil from 'ethereumjs-util' -import { ethErrors } from 'eth-rpc-errors' -import { MESSAGE_TYPE } from '../../../shared/constants/app' -import createId from './random-id' +import EventEmitter from 'events'; +import { ObservableStore } from '@metamask/obs-store'; +import ethUtil from 'ethereumjs-util'; +import { ethErrors } from 'eth-rpc-errors'; +import { MESSAGE_TYPE } from '../../../shared/constants/app'; +import createId from './random-id'; /** * Represents, and contains data about, an 'eth_sign' type signature request. These are created when a signature for @@ -35,12 +35,12 @@ export default class MessageManager extends EventEmitter { * */ constructor() { - super() + super(); this.memStore = new ObservableStore({ unapprovedMsgs: {}, unapprovedMsgCount: 0, - }) - this.messages = [] + }); + this.messages = []; } /** @@ -50,7 +50,7 @@ export default class MessageManager extends EventEmitter { * */ get unapprovedMsgCount() { - return Object.keys(this.getUnapprovedMsgs()).length + return Object.keys(this.getUnapprovedMsgs()).length; } /** @@ -63,9 +63,9 @@ export default class MessageManager extends EventEmitter { return this.messages .filter((msg) => msg.status === 'unapproved') .reduce((result, msg) => { - result[msg.id] = msg - return result - }, {}) + result[msg.id] = msg; + return result; + }, {}); } /** @@ -79,18 +79,18 @@ export default class MessageManager extends EventEmitter { */ addUnapprovedMessageAsync(msgParams, req) { return new Promise((resolve, reject) => { - const msgId = this.addUnapprovedMessage(msgParams, req) + const msgId = this.addUnapprovedMessage(msgParams, req); // await finished this.once(`${msgId}:finished`, (data) => { switch (data.status) { case 'signed': - return resolve(data.rawSig) + return resolve(data.rawSig); case 'rejected': return reject( ethErrors.provider.userRejectedRequest( 'MetaMask Message Signature: User denied message signature.', ), - ) + ); default: return reject( new Error( @@ -98,10 +98,10 @@ export default class MessageManager extends EventEmitter { msgParams, )}`, ), - ) + ); } - }) - }) + }); + }); } /** @@ -116,24 +116,24 @@ export default class MessageManager extends EventEmitter { addUnapprovedMessage(msgParams, req) { // add origin from request if (req) { - msgParams.origin = req.origin + msgParams.origin = req.origin; } - msgParams.data = normalizeMsgData(msgParams.data) + msgParams.data = normalizeMsgData(msgParams.data); // create txData obj with parameters and meta data - const time = new Date().getTime() - const msgId = createId() + const time = new Date().getTime(); + const msgId = createId(); const msgData = { id: msgId, msgParams, time, status: 'unapproved', type: MESSAGE_TYPE.ETH_SIGN, - } - this.addMsg(msgData) + }; + this.addMsg(msgData); // signal update - this.emit('update') - return msgId + this.emit('update'); + return msgId; } /** @@ -144,8 +144,8 @@ export default class MessageManager extends EventEmitter { * */ addMsg(msg) { - this.messages.push(msg) - this._saveMsgList() + this.messages.push(msg); + this._saveMsgList(); } /** @@ -156,7 +156,7 @@ export default class MessageManager extends EventEmitter { * */ getMsg(msgId) { - return this.messages.find((msg) => msg.id === msgId) + return this.messages.find((msg) => msg.id === msgId); } /** @@ -169,8 +169,8 @@ export default class MessageManager extends EventEmitter { * */ approveMessage(msgParams) { - this.setMsgStatusApproved(msgParams.metamaskId) - return this.prepMsgForSigning(msgParams) + this.setMsgStatusApproved(msgParams.metamaskId); + return this.prepMsgForSigning(msgParams); } /** @@ -180,7 +180,7 @@ export default class MessageManager extends EventEmitter { * */ setMsgStatusApproved(msgId) { - this._setMsgStatus(msgId, 'approved') + this._setMsgStatus(msgId, 'approved'); } /** @@ -192,10 +192,10 @@ export default class MessageManager extends EventEmitter { * */ setMsgStatusSigned(msgId, rawSig) { - const msg = this.getMsg(msgId) - msg.rawSig = rawSig - this._updateMsg(msg) - this._setMsgStatus(msgId, 'signed') + const msg = this.getMsg(msgId); + msg.rawSig = rawSig; + this._updateMsg(msg); + this._setMsgStatus(msgId, 'signed'); } /** @@ -206,8 +206,8 @@ export default class MessageManager extends EventEmitter { * */ prepMsgForSigning(msgParams) { - delete msgParams.metamaskId - return Promise.resolve(msgParams) + delete msgParams.metamaskId; + return Promise.resolve(msgParams); } /** @@ -217,7 +217,7 @@ export default class MessageManager extends EventEmitter { * */ rejectMsg(msgId) { - this._setMsgStatus(msgId, 'rejected') + this._setMsgStatus(msgId, 'rejected'); } /** @@ -233,15 +233,15 @@ export default class MessageManager extends EventEmitter { * */ _setMsgStatus(msgId, status) { - const msg = this.getMsg(msgId) + const msg = this.getMsg(msgId); if (!msg) { - throw new Error(`MessageManager - Message not found for id: "${msgId}".`) + throw new Error(`MessageManager - Message not found for id: "${msgId}".`); } - msg.status = status - this._updateMsg(msg) - this.emit(`${msgId}:${status}`, msg) + msg.status = status; + this._updateMsg(msg); + this.emit(`${msgId}:${status}`, msg); if (status === 'rejected' || status === 'signed') { - this.emit(`${msgId}:finished`, msg) + this.emit(`${msgId}:finished`, msg); } } @@ -254,11 +254,11 @@ export default class MessageManager extends EventEmitter { * */ _updateMsg(msg) { - const index = this.messages.findIndex((message) => message.id === msg.id) + const index = this.messages.findIndex((message) => message.id === msg.id); if (index !== -1) { - this.messages[index] = msg + this.messages[index] = msg; } - this._saveMsgList() + this._saveMsgList(); } /** @@ -269,10 +269,10 @@ export default class MessageManager extends EventEmitter { * */ _saveMsgList() { - const unapprovedMsgs = this.getUnapprovedMsgs() - const unapprovedMsgCount = Object.keys(unapprovedMsgs).length - this.memStore.updateState({ unapprovedMsgs, unapprovedMsgCount }) - this.emit('updateBadge') + const unapprovedMsgs = this.getUnapprovedMsgs(); + const unapprovedMsgCount = Object.keys(unapprovedMsgs).length; + this.memStore.updateState({ unapprovedMsgs, unapprovedMsgCount }); + this.emit('updateBadge'); } } @@ -286,8 +286,8 @@ export default class MessageManager extends EventEmitter { function normalizeMsgData(data) { if (data.slice(0, 2) === '0x') { // data is already hex - return data + return data; } // data is unicode, convert to hex - return ethUtil.bufferToHex(Buffer.from(data, 'utf8')) + return ethUtil.bufferToHex(Buffer.from(data, 'utf8')); } diff --git a/app/scripts/lib/migrator/index.js b/app/scripts/lib/migrator/index.js index 711acb7c59..258632747e 100644 --- a/app/scripts/lib/migrator/index.js +++ b/app/scripts/lib/migrator/index.js @@ -1,4 +1,4 @@ -import EventEmitter from 'events' +import EventEmitter from 'events'; /** * @typedef {Object} Migration @@ -18,29 +18,29 @@ export default class Migrator extends EventEmitter { * @param {MigratorOptions} opts */ constructor(opts = {}) { - super() - const migrations = opts.migrations || [] + super(); + const migrations = opts.migrations || []; // sort migrations by version - this.migrations = migrations.sort((a, b) => a.version - b.version) + this.migrations = migrations.sort((a, b) => a.version - b.version); // grab migration with highest version - const lastMigration = this.migrations.slice(-1)[0] + const lastMigration = this.migrations.slice(-1)[0]; // use specified defaultVersion or highest migration version this.defaultVersion = - opts.defaultVersion || (lastMigration && lastMigration.version) || 0 + opts.defaultVersion || (lastMigration && lastMigration.version) || 0; } // run all pending migrations on meta in place async migrateData(versionedData = this.generateInitialState()) { // get all migrations that have not yet been run - const pendingMigrations = this.migrations.filter(migrationIsPending) + const pendingMigrations = this.migrations.filter(migrationIsPending); // perform each migration for (const migration of pendingMigrations) { try { // attempt migration and validate - const migratedData = await migration.migrate(versionedData) + const migratedData = await migration.migrate(versionedData); if (!migratedData.data) { - throw new Error('Migrator - migration returned empty data') + throw new Error('Migrator - migration returned empty data'); } if ( migratedData.version !== undefined && @@ -48,23 +48,23 @@ export default class Migrator extends EventEmitter { ) { throw new Error( 'Migrator - Migration did not update version number correctly', - ) + ); } // accept the migration as good // eslint-disable-next-line no-param-reassign - versionedData = migratedData + versionedData = migratedData; } catch (err) { // rewrite error message to add context without clobbering stack - const originalErrorMessage = err.message - err.message = `MetaMask Migration Error #${migration.version}: ${originalErrorMessage}` + const originalErrorMessage = err.message; + err.message = `MetaMask Migration Error #${migration.version}: ${originalErrorMessage}`; // emit error instead of throw so as to not break the run (gracefully fail) - this.emit('error', err) + this.emit('error', err); // stop migrating and use state as is - return versionedData + return versionedData; } } - return versionedData + return versionedData; /** * Returns whether or not the migration is pending @@ -75,7 +75,7 @@ export default class Migrator extends EventEmitter { * @returns {boolean} */ function migrationIsPending(migration) { - return migration.version > versionedData.meta.version + return migration.version > versionedData.meta.version; } } @@ -90,6 +90,6 @@ export default class Migrator extends EventEmitter { version: this.defaultVersion, }, data, - } + }; } } diff --git a/app/scripts/lib/network-store.js b/app/scripts/lib/network-store.js index bfa7a8ba4b..eddba5fa22 100644 --- a/app/scripts/lib/network-store.js +++ b/app/scripts/lib/network-store.js @@ -1,40 +1,40 @@ -import log from 'loglevel' -import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout' +import log from 'loglevel'; +import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout'; -const fetchWithTimeout = getFetchWithTimeout(30000) +const fetchWithTimeout = getFetchWithTimeout(30000); -const FIXTURE_SERVER_HOST = 'localhost' -const FIXTURE_SERVER_PORT = 12345 -const FIXTURE_SERVER_URL = `http://${FIXTURE_SERVER_HOST}:${FIXTURE_SERVER_PORT}/state.json` +const FIXTURE_SERVER_HOST = 'localhost'; +const FIXTURE_SERVER_PORT = 12345; +const FIXTURE_SERVER_URL = `http://${FIXTURE_SERVER_HOST}:${FIXTURE_SERVER_PORT}/state.json`; /** * A read-only network-based storage wrapper */ export default class ReadOnlyNetworkStore { constructor() { - this._initialized = false - this._initializing = this._init() - this._state = undefined + this._initialized = false; + this._initializing = this._init(); + this._state = undefined; } /** * Declares this store as compatible with the current browser */ - isSupported = true + isSupported = true; /** * Initializes by loading state from the network */ async _init() { try { - const response = await fetchWithTimeout(FIXTURE_SERVER_URL) + const response = await fetchWithTimeout(FIXTURE_SERVER_URL); if (response.ok) { - this._state = await response.json() + this._state = await response.json(); } } catch (error) { - log.debug(`Error loading network state: '${error.message}'`) + log.debug(`Error loading network state: '${error.message}'`); } finally { - this._initialized = true + this._initialized = true; } } @@ -44,9 +44,9 @@ export default class ReadOnlyNetworkStore { */ async get() { if (!this._initialized) { - await this._initializing + await this._initializing; } - return this._state + return this._state; } /** @@ -56,8 +56,8 @@ export default class ReadOnlyNetworkStore { */ async set(state) { if (!this._initialized) { - await this._initializing + await this._initializing; } - this._state = state + this._state = state; } } diff --git a/app/scripts/lib/nodeify.js b/app/scripts/lib/nodeify.js index 5e6f463095..ab222e4376 100644 --- a/app/scripts/lib/nodeify.js +++ b/app/scripts/lib/nodeify.js @@ -1,10 +1,10 @@ -import promiseToCallback from 'promise-to-callback' +import promiseToCallback from 'promise-to-callback'; const callbackNoop = function (err) { if (err) { - throw err + throw err; } -} +}; /** * A generator that returns a function which, when passed a promise, can treat that promise as a node style callback. @@ -16,23 +16,23 @@ const callbackNoop = function (err) { */ export default function nodeify(fn, context) { return function (...args) { - const lastArg = args[args.length - 1] - const lastArgIsCallback = typeof lastArg === 'function' - let callback + const lastArg = args[args.length - 1]; + const lastArgIsCallback = typeof lastArg === 'function'; + let callback; if (lastArgIsCallback) { - callback = lastArg - args.pop() + callback = lastArg; + args.pop(); } else { - callback = callbackNoop + callback = callbackNoop; } // call the provided function and ensure result is a promise - let result + let result; try { - result = Promise.resolve(fn.apply(context, args)) + result = Promise.resolve(fn.apply(context, args)); } catch (err) { - result = Promise.reject(err) + result = Promise.reject(err); } // wire up promise resolution to callback - promiseToCallback(result)(callback) - } + promiseToCallback(result)(callback); + }; } diff --git a/app/scripts/lib/notification-manager.js b/app/scripts/lib/notification-manager.js index eab2170833..d7a7a89e02 100644 --- a/app/scripts/lib/notification-manager.js +++ b/app/scripts/lib/notification-manager.js @@ -1,7 +1,7 @@ -import ExtensionPlatform from '../platforms/extension' +import ExtensionPlatform from '../platforms/extension'; -const NOTIFICATION_HEIGHT = 620 -const NOTIFICATION_WIDTH = 360 +const NOTIFICATION_HEIGHT = 620; +const NOTIFICATION_WIDTH = 360; export default class NotificationManager { /** @@ -12,7 +12,7 @@ export default class NotificationManager { */ constructor() { - this.platform = new ExtensionPlatform() + this.platform = new ExtensionPlatform(); } /** @@ -21,27 +21,27 @@ export default class NotificationManager { * */ async showPopup() { - const popup = await this._getPopup() + const popup = await this._getPopup(); // Bring focus to chrome popup if (popup) { // bring focus to existing chrome popup - await this.platform.focusWindow(popup.id) + await this.platform.focusWindow(popup.id); } else { - let left = 0 - let top = 0 + let left = 0; + let top = 0; try { - const lastFocused = await this.platform.getLastFocusedWindow() + const lastFocused = await this.platform.getLastFocusedWindow(); // Position window in top right corner of lastFocused window. - top = lastFocused.top - left = lastFocused.left + (lastFocused.width - NOTIFICATION_WIDTH) + top = lastFocused.top; + left = lastFocused.left + (lastFocused.width - NOTIFICATION_WIDTH); } catch (_) { // The following properties are more than likely 0, due to being // opened from the background chrome process for the extension that // has no physical dimensions - const { screenX, screenY, outerWidth } = window - top = Math.max(screenY, 0) - left = Math.max(screenX + (outerWidth - NOTIFICATION_WIDTH), 0) + const { screenX, screenY, outerWidth } = window; + top = Math.max(screenY, 0); + left = Math.max(screenX + (outerWidth - NOTIFICATION_WIDTH), 0); } // create new notification popup @@ -52,13 +52,13 @@ export default class NotificationManager { height: NOTIFICATION_HEIGHT, left, top, - }) + }); // Firefox currently ignores left/top for create, but it works for update if (popupWindow.left !== left && popupWindow.state !== 'fullscreen') { - await this.platform.updateWindowPosition(popupWindow.id, left, top) + await this.platform.updateWindowPosition(popupWindow.id, left, top); } - this._popupId = popupWindow.id + this._popupId = popupWindow.id; } } @@ -71,8 +71,8 @@ export default class NotificationManager { * */ async _getPopup() { - const windows = await this.platform.getAllWindows() - return this._getPopupIn(windows) + const windows = await this.platform.getAllWindows(); + return this._getPopupIn(windows); } /** @@ -86,8 +86,8 @@ export default class NotificationManager { return windows ? windows.find((win) => { // Returns notification popup - return win && win.type === 'popup' && win.id === this._popupId + return win && win.type === 'popup' && win.id === this._popupId; }) - : null + : null; } } diff --git a/app/scripts/lib/personal-message-manager.js b/app/scripts/lib/personal-message-manager.js index c0a7fe4bfc..66474c8c47 100644 --- a/app/scripts/lib/personal-message-manager.js +++ b/app/scripts/lib/personal-message-manager.js @@ -1,13 +1,13 @@ -import EventEmitter from 'events' -import { ObservableStore } from '@metamask/obs-store' -import ethUtil from 'ethereumjs-util' -import { ethErrors } from 'eth-rpc-errors' -import log from 'loglevel' -import { MESSAGE_TYPE } from '../../../shared/constants/app' -import { addHexPrefix } from './util' -import createId from './random-id' +import EventEmitter from 'events'; +import { ObservableStore } from '@metamask/obs-store'; +import ethUtil from 'ethereumjs-util'; +import { ethErrors } from 'eth-rpc-errors'; +import log from 'loglevel'; +import { MESSAGE_TYPE } from '../../../shared/constants/app'; +import { addHexPrefix } from './util'; +import createId from './random-id'; -const hexRe = /^[0-9A-Fa-f]+$/gu +const hexRe = /^[0-9A-Fa-f]+$/gu; /** * Represents, and contains data about, an 'personal_sign' type signature request. These are created when a @@ -40,12 +40,12 @@ export default class PersonalMessageManager extends EventEmitter { * */ constructor() { - super() + super(); this.memStore = new ObservableStore({ unapprovedPersonalMsgs: {}, unapprovedPersonalMsgCount: 0, - }) - this.messages = [] + }); + this.messages = []; } /** @@ -55,7 +55,7 @@ export default class PersonalMessageManager extends EventEmitter { * */ get unapprovedPersonalMsgCount() { - return Object.keys(this.getUnapprovedMsgs()).length + return Object.keys(this.getUnapprovedMsgs()).length; } /** @@ -69,9 +69,9 @@ export default class PersonalMessageManager extends EventEmitter { return this.messages .filter((msg) => msg.status === 'unapproved') .reduce((result, msg) => { - result[msg.id] = msg - return result - }, {}) + result[msg.id] = msg; + return result; + }, {}); } /** @@ -87,22 +87,24 @@ export default class PersonalMessageManager extends EventEmitter { addUnapprovedMessageAsync(msgParams, req) { return new Promise((resolve, reject) => { if (!msgParams.from) { - reject(new Error('MetaMask Message Signature: from field is required.')) - return + reject( + new Error('MetaMask Message Signature: from field is required.'), + ); + return; } - const msgId = this.addUnapprovedMessage(msgParams, req) + const msgId = this.addUnapprovedMessage(msgParams, req); this.once(`${msgId}:finished`, (data) => { switch (data.status) { case 'signed': - resolve(data.rawSig) - return + resolve(data.rawSig); + return; case 'rejected': reject( ethErrors.provider.userRejectedRequest( 'MetaMask Message Signature: User denied message signature.', ), - ) - return + ); + return; default: reject( new Error( @@ -110,10 +112,10 @@ export default class PersonalMessageManager extends EventEmitter { msgParams, )}`, ), - ) + ); } - }) - }) + }); + }); } /** @@ -131,27 +133,27 @@ export default class PersonalMessageManager extends EventEmitter { `PersonalMessageManager addUnapprovedMessage: ${JSON.stringify( msgParams, )}`, - ) + ); // add origin from request if (req) { - msgParams.origin = req.origin + msgParams.origin = req.origin; } - msgParams.data = this.normalizeMsgData(msgParams.data) + msgParams.data = this.normalizeMsgData(msgParams.data); // create txData obj with parameters and meta data - const time = new Date().getTime() - const msgId = createId() + const time = new Date().getTime(); + const msgId = createId(); const msgData = { id: msgId, msgParams, time, status: 'unapproved', type: MESSAGE_TYPE.PERSONAL_SIGN, - } - this.addMsg(msgData) + }; + this.addMsg(msgData); // signal update - this.emit('update') - return msgId + this.emit('update'); + return msgId; } /** @@ -162,8 +164,8 @@ export default class PersonalMessageManager extends EventEmitter { * */ addMsg(msg) { - this.messages.push(msg) - this._saveMsgList() + this.messages.push(msg); + this._saveMsgList(); } /** @@ -175,7 +177,7 @@ export default class PersonalMessageManager extends EventEmitter { * */ getMsg(msgId) { - return this.messages.find((msg) => msg.id === msgId) + return this.messages.find((msg) => msg.id === msgId); } /** @@ -188,8 +190,8 @@ export default class PersonalMessageManager extends EventEmitter { * */ approveMessage(msgParams) { - this.setMsgStatusApproved(msgParams.metamaskId) - return this.prepMsgForSigning(msgParams) + this.setMsgStatusApproved(msgParams.metamaskId); + return this.prepMsgForSigning(msgParams); } /** @@ -199,7 +201,7 @@ export default class PersonalMessageManager extends EventEmitter { * */ setMsgStatusApproved(msgId) { - this._setMsgStatus(msgId, 'approved') + this._setMsgStatus(msgId, 'approved'); } /** @@ -211,10 +213,10 @@ export default class PersonalMessageManager extends EventEmitter { * */ setMsgStatusSigned(msgId, rawSig) { - const msg = this.getMsg(msgId) - msg.rawSig = rawSig - this._updateMsg(msg) - this._setMsgStatus(msgId, 'signed') + const msg = this.getMsg(msgId); + msg.rawSig = rawSig; + this._updateMsg(msg); + this._setMsgStatus(msgId, 'signed'); } /** @@ -225,8 +227,8 @@ export default class PersonalMessageManager extends EventEmitter { * */ prepMsgForSigning(msgParams) { - delete msgParams.metamaskId - return Promise.resolve(msgParams) + delete msgParams.metamaskId; + return Promise.resolve(msgParams); } /** @@ -236,7 +238,7 @@ export default class PersonalMessageManager extends EventEmitter { * */ rejectMsg(msgId) { - this._setMsgStatus(msgId, 'rejected') + this._setMsgStatus(msgId, 'rejected'); } /** @@ -253,17 +255,17 @@ export default class PersonalMessageManager extends EventEmitter { * */ _setMsgStatus(msgId, status) { - const msg = this.getMsg(msgId) + const msg = this.getMsg(msgId); if (!msg) { throw new Error( `PersonalMessageManager - Message not found for id: "${msgId}".`, - ) + ); } - msg.status = status - this._updateMsg(msg) - this.emit(`${msgId}:${status}`, msg) + msg.status = status; + this._updateMsg(msg); + this.emit(`${msgId}:${status}`, msg); if (status === 'rejected' || status === 'signed') { - this.emit(`${msgId}:finished`, msg) + this.emit(`${msgId}:finished`, msg); } } @@ -277,11 +279,11 @@ export default class PersonalMessageManager extends EventEmitter { * */ _updateMsg(msg) { - const index = this.messages.findIndex((message) => message.id === msg.id) + const index = this.messages.findIndex((message) => message.id === msg.id); if (index !== -1) { - this.messages[index] = msg + this.messages[index] = msg; } - this._saveMsgList() + this._saveMsgList(); } /** @@ -292,14 +294,14 @@ export default class PersonalMessageManager extends EventEmitter { * */ _saveMsgList() { - const unapprovedPersonalMsgs = this.getUnapprovedMsgs() + const unapprovedPersonalMsgs = this.getUnapprovedMsgs(); const unapprovedPersonalMsgCount = Object.keys(unapprovedPersonalMsgs) - .length + .length; this.memStore.updateState({ unapprovedPersonalMsgs, unapprovedPersonalMsgCount, - }) - this.emit('updateBadge') + }); + this.emit('updateBadge'); } /** @@ -311,14 +313,14 @@ export default class PersonalMessageManager extends EventEmitter { */ normalizeMsgData(data) { try { - const stripped = ethUtil.stripHexPrefix(data) + const stripped = ethUtil.stripHexPrefix(data); if (stripped.match(hexRe)) { - return addHexPrefix(stripped) + return addHexPrefix(stripped); } } catch (e) { - log.debug(`Message was not hex encoded, interpreting as utf8.`) + log.debug(`Message was not hex encoded, interpreting as utf8.`); } - return ethUtil.bufferToHex(Buffer.from(data, 'utf8')) + return ethUtil.bufferToHex(Buffer.from(data, 'utf8')); } } diff --git a/app/scripts/lib/random-id.js b/app/scripts/lib/random-id.js index a21717a2be..7bc70b0e9d 100644 --- a/app/scripts/lib/random-id.js +++ b/app/scripts/lib/random-id.js @@ -1,8 +1,8 @@ -const MAX = Number.MAX_SAFE_INTEGER +const MAX = Number.MAX_SAFE_INTEGER; -let idCounter = Math.round(Math.random() * MAX) +let idCounter = Math.round(Math.random() * MAX); export default function createRandomId() { - idCounter %= MAX + idCounter %= MAX; // eslint-disable-next-line no-plusplus - return idCounter++ + return idCounter++; } diff --git a/app/scripts/lib/rpc-method-middleware/createMethodMiddleware.js b/app/scripts/lib/rpc-method-middleware/createMethodMiddleware.js index fdbc265e9e..ea23702178 100644 --- a/app/scripts/lib/rpc-method-middleware/createMethodMiddleware.js +++ b/app/scripts/lib/rpc-method-middleware/createMethodMiddleware.js @@ -1,11 +1,11 @@ -import handlers from './handlers' +import handlers from './handlers'; const handlerMap = handlers.reduce((map, handler) => { for (const methodName of handler.methodNames) { - map.set(methodName, handler.implementation) + map.set(methodName, handler.implementation); } - return map -}, new Map()) + return map; +}, new Map()); /** * Returns a middleware that implements the RPC methods defined in the handlers @@ -27,8 +27,8 @@ const handlerMap = handlers.reduce((map, handler) => { export default function createMethodMiddleware(opts) { return function methodMiddleware(req, res, next, end) { if (handlerMap.has(req.method)) { - return handlerMap.get(req.method)(req, res, next, end, opts) + return handlerMap.get(req.method)(req, res, next, end, opts); } - return next() - } + return next(); + }; } diff --git a/app/scripts/lib/rpc-method-middleware/handlers/get-provider-state.js b/app/scripts/lib/rpc-method-middleware/handlers/get-provider-state.js index 760517e100..c38933b0d3 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/get-provider-state.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/get-provider-state.js @@ -1,4 +1,4 @@ -import { MESSAGE_TYPE } from '../../../../../shared/constants/app' +import { MESSAGE_TYPE } from '../../../../../shared/constants/app'; /** * This RPC method gets background state relevant to the provider. @@ -9,8 +9,8 @@ import { MESSAGE_TYPE } from '../../../../../shared/constants/app' const getProviderState = { methodNames: [MESSAGE_TYPE.GET_PROVIDER_STATE], implementation: getProviderStateHandler, -} -export default getProviderState +}; +export default getProviderState; /** * @typedef {Object} ProviderStateHandlerResult @@ -41,6 +41,6 @@ async function getProviderStateHandler( ) { res.result = { ...(await _getProviderState(req.origin)), - } - return end() + }; + return end(); } diff --git a/app/scripts/lib/rpc-method-middleware/handlers/index.js b/app/scripts/lib/rpc-method-middleware/handlers/index.js index 41011778af..e292e0cdd9 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/index.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/index.js @@ -1,6 +1,6 @@ -import getProviderState from './get-provider-state' -import logWeb3ShimUsage from './log-web3-shim-usage' -import watchAsset from './watch-asset' +import getProviderState from './get-provider-state'; +import logWeb3ShimUsage from './log-web3-shim-usage'; +import watchAsset from './watch-asset'; -const handlers = [getProviderState, logWeb3ShimUsage, watchAsset] -export default handlers +const handlers = [getProviderState, logWeb3ShimUsage, watchAsset]; +export default handlers; diff --git a/app/scripts/lib/rpc-method-middleware/handlers/log-web3-shim-usage.js b/app/scripts/lib/rpc-method-middleware/handlers/log-web3-shim-usage.js index 8dd1551fdb..973d03f61e 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/log-web3-shim-usage.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/log-web3-shim-usage.js @@ -1,4 +1,4 @@ -import { MESSAGE_TYPE } from '../../../../../shared/constants/app' +import { MESSAGE_TYPE } from '../../../../../shared/constants/app'; /** * This RPC method is called by the inpage provider whenever it detects the @@ -10,8 +10,8 @@ import { MESSAGE_TYPE } from '../../../../../shared/constants/app' const logWeb3ShimUsage = { methodNames: [MESSAGE_TYPE.LOG_WEB3_SHIM_USAGE], implementation: logWeb3ShimUsageHandler, -} -export default logWeb3ShimUsage +}; +export default logWeb3ShimUsage; /** * @typedef {Object} LogWeb3ShimUsageOptions @@ -36,9 +36,9 @@ function logWeb3ShimUsageHandler( end, { sendMetrics, getWeb3ShimUsageState, setWeb3ShimUsageRecorded }, ) { - const { origin } = req + const { origin } = req; if (getWeb3ShimUsageState(origin) === undefined) { - setWeb3ShimUsageRecorded(origin) + setWeb3ShimUsageRecorded(origin); sendMetrics( { @@ -51,9 +51,9 @@ function logWeb3ShimUsageHandler( { excludeMetaMetricsId: true, }, - ) + ); } - res.result = true - return end() + res.result = true; + return end(); } diff --git a/app/scripts/lib/rpc-method-middleware/handlers/watch-asset.js b/app/scripts/lib/rpc-method-middleware/handlers/watch-asset.js index 60c8ad6dab..aebcae8916 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/watch-asset.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/watch-asset.js @@ -1,10 +1,10 @@ -import { MESSAGE_TYPE } from '../../../../../shared/constants/app' +import { MESSAGE_TYPE } from '../../../../../shared/constants/app'; const watchAsset = { methodNames: [MESSAGE_TYPE.WATCH_ASSET, MESSAGE_TYPE.WATCH_ASSET_LEGACY], implementation: watchAssetHandler, -} -export default watchAsset +}; +export default watchAsset; /** * @typedef {Object} WatchAssetOptions @@ -32,9 +32,9 @@ async function watchAssetHandler( { handleWatchAssetRequest }, ) { try { - res.result = await handleWatchAssetRequest(req) - return end() + res.result = await handleWatchAssetRequest(req); + return end(); } catch (error) { - return end(error) + return end(error); } } diff --git a/app/scripts/lib/rpc-method-middleware/index.js b/app/scripts/lib/rpc-method-middleware/index.js index 224e060bd4..b0f813570c 100644 --- a/app/scripts/lib/rpc-method-middleware/index.js +++ b/app/scripts/lib/rpc-method-middleware/index.js @@ -1 +1 @@ -export { default } from './createMethodMiddleware' +export { default } from './createMethodMiddleware'; diff --git a/app/scripts/lib/seed-phrase-verifier.js b/app/scripts/lib/seed-phrase-verifier.js index 8c3e778a07..35b6980a5d 100644 --- a/app/scripts/lib/seed-phrase-verifier.js +++ b/app/scripts/lib/seed-phrase-verifier.js @@ -1,5 +1,5 @@ -import KeyringController from 'eth-keyring-controller' -import log from 'loglevel' +import KeyringController from 'eth-keyring-controller'; +import log from 'loglevel'; const seedPhraseVerifier = { /** @@ -17,24 +17,24 @@ const seedPhraseVerifier = { */ async verifyAccounts(createdAccounts, seedWords) { if (!createdAccounts || createdAccounts.length < 1) { - throw new Error('No created accounts defined.') + throw new Error('No created accounts defined.'); } - const keyringController = new KeyringController({}) - const Keyring = keyringController.getKeyringClassForType('HD Key Tree') + const keyringController = new KeyringController({}); + const Keyring = keyringController.getKeyringClassForType('HD Key Tree'); const opts = { mnemonic: seedWords, numberOfAccounts: createdAccounts.length, - } + }; - const keyring = new Keyring(opts) - const restoredAccounts = await keyring.getAccounts() - log.debug(`Created accounts: ${JSON.stringify(createdAccounts)}`) - log.debug(`Restored accounts: ${JSON.stringify(restoredAccounts)}`) + const keyring = new Keyring(opts); + const restoredAccounts = await keyring.getAccounts(); + log.debug(`Created accounts: ${JSON.stringify(createdAccounts)}`); + log.debug(`Restored accounts: ${JSON.stringify(restoredAccounts)}`); if (restoredAccounts.length !== createdAccounts.length) { // this should not happen... - throw new Error('Wrong number of accounts') + throw new Error('Wrong number of accounts'); } for (let i = 0; i < restoredAccounts.length; i++) { @@ -43,10 +43,10 @@ const seedPhraseVerifier = { ) { throw new Error( `Not identical accounts! Original: ${createdAccounts[i]}, Restored: ${restoredAccounts[i]}`, - ) + ); } } }, -} +}; -export default seedPhraseVerifier +export default seedPhraseVerifier; diff --git a/app/scripts/lib/segment.js b/app/scripts/lib/segment.js index e5b67ab189..fa88128c8a 100644 --- a/app/scripts/lib/segment.js +++ b/app/scripts/lib/segment.js @@ -1,11 +1,11 @@ -import Analytics from 'analytics-node' +import Analytics from 'analytics-node'; const isDevOrTestEnvironment = Boolean( process.env.METAMASK_DEBUG || process.env.IN_TEST, -) -const SEGMENT_WRITE_KEY = process.env.SEGMENT_WRITE_KEY ?? null -const SEGMENT_LEGACY_WRITE_KEY = process.env.SEGMENT_LEGACY_WRITE_KEY ?? null -const SEGMENT_HOST = process.env.SEGMENT_HOST ?? null +); +const SEGMENT_WRITE_KEY = process.env.SEGMENT_WRITE_KEY ?? null; +const SEGMENT_LEGACY_WRITE_KEY = process.env.SEGMENT_LEGACY_WRITE_KEY ?? null; +const SEGMENT_HOST = process.env.SEGMENT_HOST ?? null; // flushAt controls how many events are sent to segment at once. Segment will // hold onto a queue of events until it hits this number, then it sends them as @@ -13,7 +13,7 @@ const SEGMENT_HOST = process.env.SEGMENT_HOST ?? null // see events in real time for debugging, so this is set to 1 to disable the // queueing mechanism. const SEGMENT_FLUSH_AT = - process.env.METAMASK_ENVIRONMENT === 'production' ? undefined : 1 + process.env.METAMASK_ENVIRONMENT === 'production' ? undefined : 1; // flushInterval controls how frequently the queue is flushed to segment. // This happens regardless of the size of the queue. The default setting is @@ -22,7 +22,7 @@ const SEGMENT_FLUSH_AT = // deal with short lived sessions that happen faster than the interval // e.g confirmations. This is set to 5,000ms (5 seconds) arbitrarily with the // intent of having a value less than 10 seconds. -const SEGMENT_FLUSH_INTERVAL = 5000 +const SEGMENT_FLUSH_INTERVAL = 5000; /** * Creates a mock segment module for usage in test environments. This is used @@ -49,9 +49,9 @@ export const createSegmentMock = ( */ flush() { segmentMock.queue.forEach(([_, callback]) => { - callback() - }) - segmentMock.queue = [] + callback(); + }); + segmentMock.queue = []; }, /** @@ -59,10 +59,10 @@ export const createSegmentMock = ( * flushAt threshold, flush the queue. */ track(payload, callback = () => undefined) { - segmentMock.queue.push([payload, callback]) + segmentMock.queue.push([payload, callback]); if (segmentMock.queue.length >= flushAt) { - segmentMock.flush() + segmentMock.flush(); } }, @@ -76,11 +76,11 @@ export const createSegmentMock = ( identify() { // noop }, - } + }; // Mimic the flushInterval behavior with an interval - setInterval(segmentMock.flush, flushInterval) - return segmentMock -} + setInterval(segmentMock.flush, flushInterval); + return segmentMock; +}; export const segment = !SEGMENT_WRITE_KEY || (isDevOrTestEnvironment && !SEGMENT_HOST) @@ -89,7 +89,7 @@ export const segment = host: SEGMENT_HOST, flushAt: SEGMENT_FLUSH_AT, flushInterval: SEGMENT_FLUSH_INTERVAL, - }) + }); export const segmentLegacy = !SEGMENT_LEGACY_WRITE_KEY || (isDevOrTestEnvironment && !SEGMENT_HOST) @@ -98,4 +98,4 @@ export const segmentLegacy = host: SEGMENT_HOST, flushAt: SEGMENT_FLUSH_AT, flushInterval: SEGMENT_FLUSH_INTERVAL, - }) + }); diff --git a/app/scripts/lib/setupFetchDebugging.js b/app/scripts/lib/setupFetchDebugging.js index 8b566c31d4..724500b9b5 100644 --- a/app/scripts/lib/setupFetchDebugging.js +++ b/app/scripts/lib/setupFetchDebugging.js @@ -6,36 +6,36 @@ export default function setupFetchDebugging() { if (!window.fetch) { - return + return; } - const originalFetch = window.fetch + const originalFetch = window.fetch; - window.fetch = wrappedFetch + window.fetch = wrappedFetch; async function wrappedFetch(...args) { - const initialStack = getCurrentStack() + const initialStack = getCurrentStack(); try { - return await originalFetch.call(window, ...args) + return await originalFetch.call(window, ...args); } catch (err) { if (!err.stack) { console.warn( 'FetchDebugger - fetch encountered an Error without a stack', err, - ) + ); console.warn( 'FetchDebugger - overriding stack to point of original call', - ) - err.stack = initialStack + ); + err.stack = initialStack; } - throw err + throw err; } } } function getCurrentStack() { try { - throw new Error('Fake error for generating stack trace') + throw new Error('Fake error for generating stack trace'); } catch (err) { - return err.stack + return err.stack; } } diff --git a/app/scripts/lib/setupSentry.js b/app/scripts/lib/setupSentry.js index 1deb4c94b3..eace3f9186 100644 --- a/app/scripts/lib/setupSentry.js +++ b/app/scripts/lib/setupSentry.js @@ -1,15 +1,15 @@ -import * as Sentry from '@sentry/browser' -import { Dedupe, ExtraErrorData } from '@sentry/integrations' +import * as Sentry from '@sentry/browser'; +import { Dedupe, ExtraErrorData } from '@sentry/integrations'; -import extractEthjsErrorMessage from './extractEthjsErrorMessage' +import extractEthjsErrorMessage from './extractEthjsErrorMessage'; /* eslint-disable prefer-destructuring */ // Destructuring breaks the inlining of the environment variables -const METAMASK_DEBUG = process.env.METAMASK_DEBUG -const METAMASK_ENVIRONMENT = process.env.METAMASK_ENVIRONMENT +const METAMASK_DEBUG = process.env.METAMASK_DEBUG; +const METAMASK_ENVIRONMENT = process.env.METAMASK_ENVIRONMENT; /* eslint-enable prefer-destructuring */ const SENTRY_DSN_DEV = - 'https://f59f3dd640d2429d9d0e2445a87ea8e1@sentry.io/273496' + 'https://f59f3dd640d2429d9d0e2445a87ea8e1@sentry.io/273496'; // This describes the subset of Redux state attached to errors sent to Sentry // These properties have some potential to be useful for debugging, and they do @@ -65,28 +65,28 @@ export const SENTRY_STATE = { welcomeScreenSeen: true, }, unconnectedAccount: true, -} +}; export default function setupSentry({ release, getState }) { - let sentryTarget + let sentryTarget; if (METAMASK_DEBUG) { - return undefined + return undefined; } else if (METAMASK_ENVIRONMENT === 'production') { if (!process.env.SENTRY_DSN) { throw new Error( `Missing SENTRY_DSN environment variable in production environment`, - ) + ); } console.log( `Setting up Sentry Remote Error Reporting for '${METAMASK_ENVIRONMENT}': SENTRY_DSN`, - ) - sentryTarget = process.env.SENTRY_DSN + ); + sentryTarget = process.env.SENTRY_DSN; } else { console.log( `Setting up Sentry Remote Error Reporting for '${METAMASK_ENVIRONMENT}': SENTRY_DSN_DEV`, - ) - sentryTarget = SENTRY_DSN_DEV + ); + sentryTarget = SENTRY_DSN_DEV; } Sentry.init({ @@ -96,35 +96,35 @@ export default function setupSentry({ release, getState }) { integrations: [new Dedupe(), new ExtraErrorData()], release, beforeSend: (report) => rewriteReport(report), - }) + }); function rewriteReport(report) { try { // simplify certain complex error messages (e.g. Ethjs) - simplifyErrorMessages(report) + simplifyErrorMessages(report); // modify report urls - rewriteReportUrls(report) + rewriteReportUrls(report); // append app state if (getState) { - const appState = getState() + const appState = getState(); if (!report.extra) { - report.extra = {} + report.extra = {}; } - report.extra.appState = appState + report.extra.appState = appState; } } catch (err) { - console.warn(err) + console.warn(err); } - return report + return report; } - return Sentry + return Sentry; } function simplifyErrorMessages(report) { rewriteErrorMessages(report, (errorMessage) => { // simplify ethjs error messages - let simplifiedErrorMessage = extractEthjsErrorMessage(errorMessage) + let simplifiedErrorMessage = extractEthjsErrorMessage(errorMessage); // simplify 'Transaction Failed: known transaction' if ( simplifiedErrorMessage.indexOf( @@ -132,47 +132,47 @@ function simplifyErrorMessages(report) { ) === 0 ) { // cut the hash from the error message - simplifiedErrorMessage = 'Transaction Failed: known transaction' + simplifiedErrorMessage = 'Transaction Failed: known transaction'; } - return simplifiedErrorMessage - }) + return simplifiedErrorMessage; + }); } function rewriteErrorMessages(report, rewriteFn) { // rewrite top level message if (typeof report.message === 'string') { - report.message = rewriteFn(report.message) + report.message = rewriteFn(report.message); } // rewrite each exception message if (report.exception && report.exception.values) { report.exception.values.forEach((item) => { if (typeof item.value === 'string') { - item.value = rewriteFn(item.value) + item.value = rewriteFn(item.value); } - }) + }); } } function rewriteReportUrls(report) { // update request url - report.request.url = toMetamaskUrl(report.request.url) + report.request.url = toMetamaskUrl(report.request.url); // update exception stack trace if (report.exception && report.exception.values) { report.exception.values.forEach((item) => { if (item.stacktrace) { item.stacktrace.frames.forEach((frame) => { - frame.filename = toMetamaskUrl(frame.filename) - }) + frame.filename = toMetamaskUrl(frame.filename); + }); } - }) + }); } } function toMetamaskUrl(origUrl) { - const filePath = origUrl.split(window.location.origin)[1] + const filePath = origUrl.split(window.location.origin)[1]; if (!filePath) { - return origUrl + return origUrl; } - const metamaskUrl = `metamask${filePath}` - return metamaskUrl + const metamaskUrl = `metamask${filePath}`; + return metamaskUrl; } diff --git a/app/scripts/lib/stream-utils.js b/app/scripts/lib/stream-utils.js index a34245ae41..80b228e175 100644 --- a/app/scripts/lib/stream-utils.js +++ b/app/scripts/lib/stream-utils.js @@ -1,5 +1,5 @@ -import ObjectMultiplex from 'obj-multiplex' -import pump from 'pump' +import ObjectMultiplex from 'obj-multiplex'; +import pump from 'pump'; /** * Sets up stream multiplexing for the given stream @@ -7,11 +7,11 @@ import pump from 'pump' * @returns {stream.Stream} the multiplexed stream */ export function setupMultiplex(connectionStream) { - const mux = new ObjectMultiplex() + const mux = new ObjectMultiplex(); pump(connectionStream, mux, connectionStream, (err) => { if (err) { - console.error(err) + console.error(err); } - }) - return mux + }); + return mux; } diff --git a/app/scripts/lib/typed-message-manager.js b/app/scripts/lib/typed-message-manager.js index 858c945b0f..630e6029c9 100644 --- a/app/scripts/lib/typed-message-manager.js +++ b/app/scripts/lib/typed-message-manager.js @@ -1,13 +1,13 @@ -import EventEmitter from 'events' -import assert from 'assert' -import { ObservableStore } from '@metamask/obs-store' -import { ethErrors } from 'eth-rpc-errors' -import { typedSignatureHash, TYPED_MESSAGE_SCHEMA } from 'eth-sig-util' -import { isValidAddress } from 'ethereumjs-util' -import log from 'loglevel' -import jsonschema from 'jsonschema' -import { MESSAGE_TYPE } from '../../../shared/constants/app' -import createId from './random-id' +import EventEmitter from 'events'; +import assert from 'assert'; +import { ObservableStore } from '@metamask/obs-store'; +import { ethErrors } from 'eth-rpc-errors'; +import { typedSignatureHash, TYPED_MESSAGE_SCHEMA } from 'eth-sig-util'; +import { isValidAddress } from 'ethereumjs-util'; +import log from 'loglevel'; +import jsonschema from 'jsonschema'; +import { MESSAGE_TYPE } from '../../../shared/constants/app'; +import createId from './random-id'; /** * Represents, and contains data about, an 'eth_signTypedData' type signature request. These are created when a @@ -32,13 +32,13 @@ export default class TypedMessageManager extends EventEmitter { * Controller in charge of managing - storing, adding, removing, updating - TypedMessage. */ constructor({ getCurrentChainId }) { - super() - this._getCurrentChainId = getCurrentChainId + super(); + this._getCurrentChainId = getCurrentChainId; this.memStore = new ObservableStore({ unapprovedTypedMessages: {}, unapprovedTypedMessagesCount: 0, - }) - this.messages = [] + }); + this.messages = []; } /** @@ -48,7 +48,7 @@ export default class TypedMessageManager extends EventEmitter { * */ get unapprovedTypedMessagesCount() { - return Object.keys(this.getUnapprovedMsgs()).length + return Object.keys(this.getUnapprovedMsgs()).length; } /** @@ -62,9 +62,9 @@ export default class TypedMessageManager extends EventEmitter { return this.messages .filter((msg) => msg.status === 'unapproved') .reduce((result, msg) => { - result[msg.id] = msg - return result - }, {}) + result[msg.id] = msg; + return result; + }, {}); } /** @@ -79,21 +79,21 @@ export default class TypedMessageManager extends EventEmitter { */ addUnapprovedMessageAsync(msgParams, req, version) { return new Promise((resolve, reject) => { - const msgId = this.addUnapprovedMessage(msgParams, req, version) + const msgId = this.addUnapprovedMessage(msgParams, req, version); this.once(`${msgId}:finished`, (data) => { switch (data.status) { case 'signed': - return resolve(data.rawSig) + return resolve(data.rawSig); case 'rejected': return reject( ethErrors.provider.userRejectedRequest( 'MetaMask Message Signature: User denied message signature.', ), - ) + ); case 'errored': return reject( new Error(`MetaMask Message Signature: ${data.error}`), - ) + ); default: return reject( new Error( @@ -101,10 +101,10 @@ export default class TypedMessageManager extends EventEmitter { msgParams, )}`, ), - ) + ); } - }) - }) + }); + }); } /** @@ -118,31 +118,31 @@ export default class TypedMessageManager extends EventEmitter { * */ addUnapprovedMessage(msgParams, req, version) { - msgParams.version = version + msgParams.version = version; if (req) { - msgParams.origin = req.origin + msgParams.origin = req.origin; } - this.validateParams(msgParams) + this.validateParams(msgParams); log.debug( `TypedMessageManager addUnapprovedMessage: ${JSON.stringify(msgParams)}`, - ) + ); // create txData obj with parameters and meta data - const time = new Date().getTime() - const msgId = createId() + const time = new Date().getTime(); + const msgId = createId(); const msgData = { id: msgId, msgParams, time, status: 'unapproved', type: MESSAGE_TYPE.ETH_SIGN_TYPED_DATA, - } - this.addMsg(msgData) + }; + this.addMsg(msgData); // signal update - this.emit('update') - return msgId + this.emit('update'); + return msgId; } /** @@ -152,59 +152,65 @@ export default class TypedMessageManager extends EventEmitter { * */ validateParams(params) { - assert.ok(params && typeof params === 'object', 'Params must be an object.') - assert.ok('data' in params, 'Params must include a "data" field.') - assert.ok('from' in params, 'Params must include a "from" field.') + assert.ok( + params && typeof params === 'object', + 'Params must be an object.', + ); + assert.ok('data' in params, 'Params must include a "data" field.'); + assert.ok('from' in params, 'Params must include a "from" field.'); assert.ok( typeof params.from === 'string' && isValidAddress(params.from), '"from" field must be a valid, lowercase, hexadecimal Ethereum address string.', - ) + ); switch (params.version) { case 'V1': - assert.ok(Array.isArray(params.data), '"params.data" must be an array.') + assert.ok( + Array.isArray(params.data), + '"params.data" must be an array.', + ); assert.doesNotThrow(() => { - typedSignatureHash(params.data) - }, 'Signing data must be valid EIP-712 typed data.') - break + typedSignatureHash(params.data); + }, 'Signing data must be valid EIP-712 typed data.'); + break; case 'V3': case 'V4': { assert.equal( typeof params.data, 'string', '"params.data" must be a string.', - ) - let data + ); + let data; assert.doesNotThrow(() => { - data = JSON.parse(params.data) - }, '"data" must be a valid JSON string.') - const validation = jsonschema.validate(data, TYPED_MESSAGE_SCHEMA) + data = JSON.parse(params.data); + }, '"data" must be a valid JSON string.'); + const validation = jsonschema.validate(data, TYPED_MESSAGE_SCHEMA); assert.ok( data.primaryType in data.types, `Primary type of "${data.primaryType}" has no type definition.`, - ) + ); assert.equal( validation.errors.length, 0, 'Signing data must conform to EIP-712 schema. See https://git.io/fNtcx.', - ) - const { chainId } = data.domain + ); + const { chainId } = data.domain; if (chainId) { - const activeChainId = parseInt(this._getCurrentChainId(), 16) + const activeChainId = parseInt(this._getCurrentChainId(), 16); assert.ok( !Number.isNaN(activeChainId), `Cannot sign messages for chainId "${chainId}", because MetaMask is switching networks.`, - ) + ); assert.equal( chainId, activeChainId, `Provided chainId "${chainId}" must match the active chainId "${activeChainId}"`, - ) + ); } - break + break; } default: - assert.fail(`Unknown typed data version "${params.version}"`) + assert.fail(`Unknown typed data version "${params.version}"`); } } @@ -216,8 +222,8 @@ export default class TypedMessageManager extends EventEmitter { * */ addMsg(msg) { - this.messages.push(msg) - this._saveMsgList() + this.messages.push(msg); + this._saveMsgList(); } /** @@ -229,7 +235,7 @@ export default class TypedMessageManager extends EventEmitter { * */ getMsg(msgId) { - return this.messages.find((msg) => msg.id === msgId) + return this.messages.find((msg) => msg.id === msgId); } /** @@ -242,8 +248,8 @@ export default class TypedMessageManager extends EventEmitter { * */ approveMessage(msgParams) { - this.setMsgStatusApproved(msgParams.metamaskId) - return this.prepMsgForSigning(msgParams) + this.setMsgStatusApproved(msgParams.metamaskId); + return this.prepMsgForSigning(msgParams); } /** @@ -253,7 +259,7 @@ export default class TypedMessageManager extends EventEmitter { * */ setMsgStatusApproved(msgId) { - this._setMsgStatus(msgId, 'approved') + this._setMsgStatus(msgId, 'approved'); } /** @@ -265,10 +271,10 @@ export default class TypedMessageManager extends EventEmitter { * */ setMsgStatusSigned(msgId, rawSig) { - const msg = this.getMsg(msgId) - msg.rawSig = rawSig - this._updateMsg(msg) - this._setMsgStatus(msgId, 'signed') + const msg = this.getMsg(msgId); + msg.rawSig = rawSig; + this._updateMsg(msg); + this._setMsgStatus(msgId, 'signed'); } /** @@ -279,9 +285,9 @@ export default class TypedMessageManager extends EventEmitter { * */ prepMsgForSigning(msgParams) { - delete msgParams.metamaskId - delete msgParams.version - return Promise.resolve(msgParams) + delete msgParams.metamaskId; + delete msgParams.version; + return Promise.resolve(msgParams); } /** @@ -291,7 +297,7 @@ export default class TypedMessageManager extends EventEmitter { * */ rejectMsg(msgId) { - this._setMsgStatus(msgId, 'rejected') + this._setMsgStatus(msgId, 'rejected'); } /** @@ -301,10 +307,10 @@ export default class TypedMessageManager extends EventEmitter { * */ errorMessage(msgId, error) { - const msg = this.getMsg(msgId) - msg.error = error - this._updateMsg(msg) - this._setMsgStatus(msgId, 'errored') + const msg = this.getMsg(msgId); + msg.error = error; + this._updateMsg(msg); + this._setMsgStatus(msgId, 'errored'); } // @@ -325,17 +331,17 @@ export default class TypedMessageManager extends EventEmitter { * */ _setMsgStatus(msgId, status) { - const msg = this.getMsg(msgId) + const msg = this.getMsg(msgId); if (!msg) { throw new Error( `TypedMessageManager - Message not found for id: "${msgId}".`, - ) + ); } - msg.status = status - this._updateMsg(msg) - this.emit(`${msgId}:${status}`, msg) + msg.status = status; + this._updateMsg(msg); + this.emit(`${msgId}:${status}`, msg); if (status === 'rejected' || status === 'signed' || status === 'errored') { - this.emit(`${msgId}:finished`, msg) + this.emit(`${msgId}:finished`, msg); } } @@ -349,11 +355,11 @@ export default class TypedMessageManager extends EventEmitter { * */ _updateMsg(msg) { - const index = this.messages.findIndex((message) => message.id === msg.id) + const index = this.messages.findIndex((message) => message.id === msg.id); if (index !== -1) { - this.messages[index] = msg + this.messages[index] = msg; } - this._saveMsgList() + this._saveMsgList(); } /** @@ -364,13 +370,13 @@ export default class TypedMessageManager extends EventEmitter { * */ _saveMsgList() { - const unapprovedTypedMessages = this.getUnapprovedMsgs() + const unapprovedTypedMessages = this.getUnapprovedMsgs(); const unapprovedTypedMessagesCount = Object.keys(unapprovedTypedMessages) - .length + .length; this.memStore.updateState({ unapprovedTypedMessages, unapprovedTypedMessagesCount, - }) - this.emit('updateBadge') + }); + this.emit('updateBadge'); } } diff --git a/app/scripts/lib/util.js b/app/scripts/lib/util.js index 04d83aabd3..ccf8d11930 100644 --- a/app/scripts/lib/util.js +++ b/app/scripts/lib/util.js @@ -1,8 +1,8 @@ -import assert from 'assert' -import extension from 'extensionizer' -import ethUtil from 'ethereumjs-util' -import BN from 'bn.js' -import { memoize } from 'lodash' +import assert from 'assert'; +import extension from 'extensionizer'; +import ethUtil from 'ethereumjs-util'; +import BN from 'bn.js'; +import { memoize } from 'lodash'; import { ENVIRONMENT_TYPE_POPUP, @@ -14,22 +14,22 @@ import { PLATFORM_CHROME, PLATFORM_EDGE, PLATFORM_BRAVE, -} from '../../../shared/constants/app' +} from '../../../shared/constants/app'; /** * @see {@link getEnvironmentType} */ const getEnvironmentTypeMemo = memoize((url) => { - const parsedUrl = new URL(url) + const parsedUrl = new URL(url); if (parsedUrl.pathname === '/popup.html') { - return ENVIRONMENT_TYPE_POPUP + return ENVIRONMENT_TYPE_POPUP; } else if (['/home.html', '/phishing.html'].includes(parsedUrl.pathname)) { - return ENVIRONMENT_TYPE_FULLSCREEN + return ENVIRONMENT_TYPE_FULLSCREEN; } else if (parsedUrl.pathname === '/notification.html') { - return ENVIRONMENT_TYPE_NOTIFICATION + return ENVIRONMENT_TYPE_NOTIFICATION; } - return ENVIRONMENT_TYPE_BACKGROUND -}) + return ENVIRONMENT_TYPE_BACKGROUND; +}); /** * Returns the window type for the application @@ -45,7 +45,7 @@ const getEnvironmentTypeMemo = memoize((url) => { * @returns {string} the environment ENUM */ const getEnvironmentType = (url = window.location.href) => - getEnvironmentTypeMemo(url) + getEnvironmentTypeMemo(url); /** * Returns the platform (browser) where the extension is running. @@ -54,21 +54,21 @@ const getEnvironmentType = (url = window.location.href) => * */ const getPlatform = (_) => { - const ua = window.navigator.userAgent + const ua = window.navigator.userAgent; if (ua.search('Firefox') === -1) { if (window && window.chrome && window.chrome.ipcRenderer) { - return PLATFORM_BRAVE + return PLATFORM_BRAVE; } if (ua.search('Edge') !== -1) { - return PLATFORM_EDGE + return PLATFORM_EDGE; } if (ua.search('OPR') !== -1) { - return PLATFORM_OPERA + return PLATFORM_OPERA; } - return PLATFORM_CHROME + return PLATFORM_CHROME; } - return PLATFORM_FIREFOX -} + return PLATFORM_FIREFOX; +}; /** * Checks whether a given balance of ETH, represented as a hex string, is sufficient to pay a value plus a gas fee @@ -87,20 +87,20 @@ function sufficientBalance(txParams, hexBalance) { typeof hexBalance, 'string', 'sufficientBalance - hexBalance is not a hex string', - ) + ); assert.equal( hexBalance.slice(0, 2), '0x', 'sufficientBalance - hexBalance is not a hex string', - ) + ); - const balance = hexToBn(hexBalance) - const value = hexToBn(txParams.value) - const gasLimit = hexToBn(txParams.gas) - const gasPrice = hexToBn(txParams.gasPrice) + const balance = hexToBn(hexBalance); + const value = hexToBn(txParams.value); + const gasLimit = hexToBn(txParams.gas); + const gasPrice = hexToBn(txParams.gasPrice); - const maxCost = value.add(gasLimit.mul(gasPrice)) - return balance.gte(maxCost) + const maxCost = value.add(gasLimit.mul(gasPrice)); + return balance.gte(maxCost); } /** @@ -111,7 +111,7 @@ function sufficientBalance(txParams, hexBalance) { * */ function hexToBn(inputHex) { - return new BN(ethUtil.stripHexPrefix(inputHex), 16) + return new BN(ethUtil.stripHexPrefix(inputHex), 16); } /** @@ -124,9 +124,9 @@ function hexToBn(inputHex) { * */ function BnMultiplyByFraction(targetBN, numerator, denominator) { - const numBN = new BN(numerator) - const denomBN = new BN(denominator) - return targetBN.mul(numBN).div(denomBN) + const numBN = new BN(numerator); + const denomBN = new BN(denominator); + return targetBN.mul(numBN).div(denomBN); } /** @@ -135,16 +135,16 @@ function BnMultiplyByFraction(targetBN, numerator, denominator) { * @returns {Error|undefined} */ function checkForError() { - const { lastError } = extension.runtime + const { lastError } = extension.runtime; if (!lastError) { - return undefined + return undefined; } // if it quacks like an Error, its an Error if (lastError.stack && lastError.message) { - return lastError + return lastError; } // repair incomplete error object (eg chromium v77) - return new Error(lastError.message) + return new Error(lastError.message); } /** @@ -155,19 +155,19 @@ function checkForError() { */ const addHexPrefix = (str) => { if (typeof str !== 'string' || str.match(/^-?0x/u)) { - return str + return str; } if (str.match(/^-?0X/u)) { - return str.replace('0X', '0x') + return str.replace('0X', '0x'); } if (str.startsWith('-')) { - return str.replace('-', '-0x') + return str.replace('-', '-0x'); } - return `0x${str}` -} + return `0x${str}`; +}; /** * Converts a BN object to a hex string with a '0x' prefix @@ -177,7 +177,7 @@ const addHexPrefix = (str) => { * */ function bnToHex(inputBn) { - return addHexPrefix(inputBn.toString(16)) + return addHexPrefix(inputBn.toString(16)); } export { @@ -189,4 +189,4 @@ export { checkForError, addHexPrefix, bnToHex, -} +}; diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index b9d6c598f9..2eff303550 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1,65 +1,65 @@ -import EventEmitter from 'events' -import pump from 'pump' -import Dnode from 'dnode' -import { ObservableStore } from '@metamask/obs-store' -import { storeAsStream } from '@metamask/obs-store/dist/asStream' -import { JsonRpcEngine } from 'json-rpc-engine' -import { debounce } from 'lodash' -import createEngineStream from 'json-rpc-middleware-stream/engineStream' -import createFilterMiddleware from 'eth-json-rpc-filters' -import createSubscriptionManager from 'eth-json-rpc-filters/subscriptionManager' -import providerAsMiddleware from 'eth-json-rpc-middleware/providerAsMiddleware' -import KeyringController from 'eth-keyring-controller' -import { Mutex } from 'await-semaphore' -import ethUtil from 'ethereumjs-util' -import log from 'loglevel' -import TrezorKeyring from 'eth-trezor-keyring' -import LedgerBridgeKeyring from '@metamask/eth-ledger-bridge-keyring' -import EthQuery from 'eth-query' -import nanoid from 'nanoid' -import contractMap from '@metamask/contract-metadata' +import EventEmitter from 'events'; +import pump from 'pump'; +import Dnode from 'dnode'; +import { ObservableStore } from '@metamask/obs-store'; +import { storeAsStream } from '@metamask/obs-store/dist/asStream'; +import { JsonRpcEngine } from 'json-rpc-engine'; +import { debounce } from 'lodash'; +import createEngineStream from 'json-rpc-middleware-stream/engineStream'; +import createFilterMiddleware from 'eth-json-rpc-filters'; +import createSubscriptionManager from 'eth-json-rpc-filters/subscriptionManager'; +import providerAsMiddleware from 'eth-json-rpc-middleware/providerAsMiddleware'; +import KeyringController from 'eth-keyring-controller'; +import { Mutex } from 'await-semaphore'; +import ethUtil from 'ethereumjs-util'; +import log from 'loglevel'; +import TrezorKeyring from 'eth-trezor-keyring'; +import LedgerBridgeKeyring from '@metamask/eth-ledger-bridge-keyring'; +import EthQuery from 'eth-query'; +import nanoid from 'nanoid'; +import contractMap from '@metamask/contract-metadata'; import { AddressBookController, ApprovalController, CurrencyRateController, PhishingController, -} from '@metamask/controllers' -import { getBackgroundMetaMetricState } from '../../ui/app/selectors' -import { TRANSACTION_STATUSES } from '../../shared/constants/transaction' -import ComposableObservableStore from './lib/ComposableObservableStore' -import AccountTracker from './lib/account-tracker' -import createLoggerMiddleware from './lib/createLoggerMiddleware' -import createMethodMiddleware from './lib/rpc-method-middleware' -import createOriginMiddleware from './lib/createOriginMiddleware' -import createTabIdMiddleware from './lib/createTabIdMiddleware' -import createOnboardingMiddleware from './lib/createOnboardingMiddleware' -import { setupMultiplex } from './lib/stream-utils' -import EnsController from './controllers/ens' -import NetworkController from './controllers/network' -import PreferencesController from './controllers/preferences' -import AppStateController from './controllers/app-state' -import CachedBalancesController from './controllers/cached-balances' -import AlertController from './controllers/alert' -import OnboardingController from './controllers/onboarding' -import ThreeBoxController from './controllers/threebox' -import IncomingTransactionsController from './controllers/incoming-transactions' -import MessageManager from './lib/message-manager' -import DecryptMessageManager from './lib/decrypt-message-manager' -import EncryptionPublicKeyManager from './lib/encryption-public-key-manager' -import PersonalMessageManager from './lib/personal-message-manager' -import TypedMessageManager from './lib/typed-message-manager' -import TransactionController from './controllers/transactions' -import TokenRatesController from './controllers/token-rates' -import DetectTokensController from './controllers/detect-tokens' -import SwapsController from './controllers/swaps' -import { PermissionsController } from './controllers/permissions' -import { NOTIFICATION_NAMES } from './controllers/permissions/enums' -import getRestrictedMethods from './controllers/permissions/restrictedMethods' -import nodeify from './lib/nodeify' -import accountImporter from './account-import-strategies' -import seedPhraseVerifier from './lib/seed-phrase-verifier' -import MetaMetricsController from './controllers/metametrics' -import { segment, segmentLegacy } from './lib/segment' +} from '@metamask/controllers'; +import { getBackgroundMetaMetricState } from '../../ui/app/selectors'; +import { TRANSACTION_STATUSES } from '../../shared/constants/transaction'; +import ComposableObservableStore from './lib/ComposableObservableStore'; +import AccountTracker from './lib/account-tracker'; +import createLoggerMiddleware from './lib/createLoggerMiddleware'; +import createMethodMiddleware from './lib/rpc-method-middleware'; +import createOriginMiddleware from './lib/createOriginMiddleware'; +import createTabIdMiddleware from './lib/createTabIdMiddleware'; +import createOnboardingMiddleware from './lib/createOnboardingMiddleware'; +import { setupMultiplex } from './lib/stream-utils'; +import EnsController from './controllers/ens'; +import NetworkController from './controllers/network'; +import PreferencesController from './controllers/preferences'; +import AppStateController from './controllers/app-state'; +import CachedBalancesController from './controllers/cached-balances'; +import AlertController from './controllers/alert'; +import OnboardingController from './controllers/onboarding'; +import ThreeBoxController from './controllers/threebox'; +import IncomingTransactionsController from './controllers/incoming-transactions'; +import MessageManager from './lib/message-manager'; +import DecryptMessageManager from './lib/decrypt-message-manager'; +import EncryptionPublicKeyManager from './lib/encryption-public-key-manager'; +import PersonalMessageManager from './lib/personal-message-manager'; +import TypedMessageManager from './lib/typed-message-manager'; +import TransactionController from './controllers/transactions'; +import TokenRatesController from './controllers/token-rates'; +import DetectTokensController from './controllers/detect-tokens'; +import SwapsController from './controllers/swaps'; +import { PermissionsController } from './controllers/permissions'; +import { NOTIFICATION_NAMES } from './controllers/permissions/enums'; +import getRestrictedMethods from './controllers/permissions/restrictedMethods'; +import nodeify from './lib/nodeify'; +import accountImporter from './account-import-strategies'; +import seedPhraseVerifier from './lib/seed-phrase-verifier'; +import MetaMetricsController from './controllers/metametrics'; +import { segment, segmentLegacy } from './lib/segment'; export default class MetamaskController extends EventEmitter { /** @@ -67,40 +67,40 @@ export default class MetamaskController extends EventEmitter { * @param {Object} opts */ constructor(opts) { - super() + super(); - this.defaultMaxListeners = 20 + this.defaultMaxListeners = 20; - this.sendUpdate = debounce(this.privateSendUpdate.bind(this), 200) - this.opts = opts - this.extension = opts.extension - this.platform = opts.platform - const initState = opts.initState || {} - const version = this.platform.getVersion() - this.recordFirstTimeInfo(initState) + this.sendUpdate = debounce(this.privateSendUpdate.bind(this), 200); + this.opts = opts; + this.extension = opts.extension; + this.platform = opts.platform; + const initState = opts.initState || {}; + const version = this.platform.getVersion(); + this.recordFirstTimeInfo(initState); // this keeps track of how many "controllerStream" connections are open // the only thing that uses controller connections are open metamask UI instances - this.activeControllerConnections = 0 + this.activeControllerConnections = 0; - this.getRequestAccountTabIds = opts.getRequestAccountTabIds - this.getOpenMetamaskTabsIds = opts.getOpenMetamaskTabsIds + this.getRequestAccountTabIds = opts.getRequestAccountTabIds; + this.getOpenMetamaskTabsIds = opts.getOpenMetamaskTabsIds; // observable state store - this.store = new ComposableObservableStore(initState) + this.store = new ComposableObservableStore(initState); // external connections by origin // Do not modify directly. Use the associated methods. - this.connections = {} + this.connections = {}; // lock to ensure only one vault created at once - this.createVaultMutex = new Mutex() + this.createVaultMutex = new Mutex(); this.extension.runtime.onInstalled.addListener((details) => { if (details.reason === 'update' && version === '8.1.0') { - this.platform.openExtensionInBrowser() + this.platform.openExtensionInBrowser(); } - }) + }); // next, we will initialize the controllers // controller initialization order matters @@ -108,10 +108,10 @@ export default class MetamaskController extends EventEmitter { this.approvalController = new ApprovalController({ showApprovalRequest: opts.showUserConfirmation, defaultApprovalType: 'NO_TYPE', - }) + }); - this.networkController = new NetworkController(initState.NetworkController) - this.networkController.setInfuraProjectId(opts.infuraProjectId) + this.networkController = new NetworkController(initState.NetworkController); + this.networkController.setInfuraProjectId(opts.infuraProjectId); this.preferencesController = new PreferencesController({ initState: initState.PreferencesController, @@ -119,7 +119,7 @@ export default class MetamaskController extends EventEmitter { openPopup: opts.openPopup, network: this.networkController, migrateAddressBookState: this.migrateAddressBookState.bind(this), - }) + }); this.metaMetricsController = new MetaMetricsController({ segment, @@ -138,7 +138,7 @@ export default class MetamaskController extends EventEmitter { version: this.platform.getVersion(), environment: process.env.METAMASK_ENVIRONMENT, initState: initState.MetaMetricsController, - }) + }); this.appStateController = new AppStateController({ addUnlockListener: this.on.bind(this, 'unlock'), @@ -147,37 +147,37 @@ export default class MetamaskController extends EventEmitter { onInactiveTimeout: () => this.setLocked(), showUnlockRequest: opts.showUserConfirmation, preferencesStore: this.preferencesController.store, - }) + }); this.currencyRateController = new CurrencyRateController( { includeUSDRate: true }, initState.CurrencyController, - ) + ); - this.phishingController = new PhishingController() + this.phishingController = new PhishingController(); // now we can initialize the RPC provider, which other controllers require - this.initializeProvider() - this.provider = this.networkController.getProviderAndBlockTracker().provider - this.blockTracker = this.networkController.getProviderAndBlockTracker().blockTracker + this.initializeProvider(); + this.provider = this.networkController.getProviderAndBlockTracker().provider; + this.blockTracker = this.networkController.getProviderAndBlockTracker().blockTracker; // token exchange rate tracker this.tokenRatesController = new TokenRatesController({ currency: this.currencyRateController, preferences: this.preferencesController.store, - }) + }); this.ensController = new EnsController({ provider: this.provider, networkStore: this.networkController.networkStore, - }) + }); this.incomingTransactionsController = new IncomingTransactionsController({ blockTracker: this.blockTracker, networkController: this.networkController, preferencesController: this.preferencesController, initState: initState.IncomingTransactionsController, - }) + }); // account tracker watches balances, nonces, and any code at their address this.accountTracker = new AccountTracker({ @@ -186,20 +186,20 @@ export default class MetamaskController extends EventEmitter { getCurrentChainId: this.networkController.getCurrentChainId.bind( this.networkController, ), - }) + }); // start and stop polling for balances based on activeControllerConnections this.on('controllerConnectionChanged', (activeControllerConnections) => { if (activeControllerConnections > 0) { - this.accountTracker.start() - this.incomingTransactionsController.start() - this.tokenRatesController.start() + this.accountTracker.start(); + this.incomingTransactionsController.start(); + this.tokenRatesController.start(); } else { - this.accountTracker.stop() - this.incomingTransactionsController.stop() - this.tokenRatesController.stop() + this.accountTracker.stop(); + this.incomingTransactionsController.stop(); + this.tokenRatesController.stop(); } - }) + }); this.cachedBalancesController = new CachedBalancesController({ accountTracker: this.accountTracker, @@ -207,29 +207,29 @@ export default class MetamaskController extends EventEmitter { this.networkController, ), initState: initState.CachedBalancesController, - }) + }); this.onboardingController = new OnboardingController({ initState: initState.OnboardingController, preferencesController: this.preferencesController, - }) + }); // ensure accountTracker updates balances after network change this.networkController.on('networkDidChange', () => { - this.accountTracker._updateAccounts() - }) + this.accountTracker._updateAccounts(); + }); - const additionalKeyrings = [TrezorKeyring, LedgerBridgeKeyring] + const additionalKeyrings = [TrezorKeyring, LedgerBridgeKeyring]; this.keyringController = new KeyringController({ keyringTypes: additionalKeyrings, initState: initState.KeyringController, encryptor: opts.encryptor || undefined, - }) + }); this.keyringController.memStore.subscribe((state) => this._onKeyringControllerUpdate(state), - ) - this.keyringController.on('unlock', () => this.emit('unlock')) - this.keyringController.on('lock', () => this._onLock()) + ); + this.keyringController.on('unlock', () => this.emit('unlock')); + this.keyringController.on('lock', () => this._onLock()); this.permissionsController = new PermissionsController( { @@ -249,23 +249,23 @@ export default class MetamaskController extends EventEmitter { }, initState.PermissionsController, initState.PermissionsMetadata, - ) + ); this.detectTokensController = new DetectTokensController({ preferences: this.preferencesController, network: this.networkController, keyringMemStore: this.keyringController.memStore, - }) + }); this.addressBookController = new AddressBookController( undefined, initState.AddressBookController, - ) + ); this.alertController = new AlertController({ initState: initState.AlertController, preferencesStore: this.preferencesController.store, - }) + }); this.threeBoxController = new ThreeBoxController({ preferencesController: this.preferencesController, @@ -276,7 +276,7 @@ export default class MetamaskController extends EventEmitter { this.keyringController.memStore, ), version, - }) + }); this.txController = new TransactionController({ initState: @@ -301,49 +301,49 @@ export default class MetamaskController extends EventEmitter { ), getParticipateInMetrics: () => this.metaMetricsController.state.participateInMetaMetrics, - }) - this.txController.on('newUnapprovedTx', () => opts.showUserConfirmation()) + }); + this.txController.on('newUnapprovedTx', () => opts.showUserConfirmation()); this.txController.on(`tx:status-update`, async (txId, status) => { if ( status === TRANSACTION_STATUSES.CONFIRMED || status === TRANSACTION_STATUSES.FAILED ) { - const txMeta = this.txController.txStateManager.getTx(txId) - this.platform.showTransactionNotification(txMeta) + const txMeta = this.txController.txStateManager.getTx(txId); + this.platform.showTransactionNotification(txMeta); - const { txReceipt } = txMeta + const { txReceipt } = txMeta; if (txReceipt && txReceipt.status === '0x0') { this.sendBackgroundMetaMetrics({ action: 'Transactions', name: 'On Chain Failure', customVariables: { errorMessage: txMeta.simulationFails?.reason }, - }) + }); } } - }) + }); this.networkController.on('networkDidChange', () => { this.setCurrentCurrency( this.currencyRateController.state.currentCurrency, (error) => { if (error) { - throw error + throw error; } }, - ) - }) - - this.networkController.lookupNetwork() - this.messageManager = new MessageManager() - this.personalMessageManager = new PersonalMessageManager() - this.decryptMessageManager = new DecryptMessageManager() - this.encryptionPublicKeyManager = new EncryptionPublicKeyManager() + ); + }); + + this.networkController.lookupNetwork(); + this.messageManager = new MessageManager(); + this.personalMessageManager = new PersonalMessageManager(); + this.decryptMessageManager = new DecryptMessageManager(); + this.encryptionPublicKeyManager = new EncryptionPublicKeyManager(); this.typedMessageManager = new TypedMessageManager({ getCurrentChainId: this.networkController.getCurrentChainId.bind( this.networkController, ), - }) + }); this.swapsController = new SwapsController({ getBufferedGasLimit: this.txController.txGasUtil.getBufferedGasLimit.bind( @@ -355,10 +355,10 @@ export default class MetamaskController extends EventEmitter { this.networkController, ), tokenRatesStore: this.tokenRatesController.store, - }) + }); // ensure isClientOpenAndUnlocked is updated when memState updates - this.on('update', (memState) => this._onStateUpdate(memState)) + this.on('update', (memState) => this._onStateUpdate(memState)); this.store.updateStructure({ AppStateController: this.appStateController.store, @@ -376,7 +376,7 @@ export default class MetamaskController extends EventEmitter { PermissionsController: this.permissionsController.permissions, PermissionsMetadata: this.permissionsController.store, ThreeBoxController: this.threeBoxController.store, - }) + }); this.memStore = new ComposableObservableStore(null, { AppStateController: this.appStateController.store, @@ -404,27 +404,27 @@ export default class MetamaskController extends EventEmitter { SwapsController: this.swapsController.store, EnsController: this.ensController.store, ApprovalController: this.approvalController, - }) - this.memStore.subscribe(this.sendUpdate.bind(this)) + }); + this.memStore.subscribe(this.sendUpdate.bind(this)); - const password = process.env.CONF?.password + const password = process.env.CONF?.password; if ( password && !this.isUnlocked() && this.onboardingController.completedOnboarding ) { - this.submitPassword(password) + this.submitPassword(password); } // TODO:LegacyProvider: Delete - this.publicConfigStore = this.createPublicConfigStore() + this.publicConfigStore = this.createPublicConfigStore(); } /** * Constructor helper: initialize a provider. */ initializeProvider() { - const version = this.platform.getVersion() + const version = this.platform.getVersion(); const providerOpts = { static: { eth_syncing: false, @@ -434,12 +434,12 @@ export default class MetamaskController extends EventEmitter { // account mgmt getAccounts: async ({ origin }) => { if (origin === 'metamask') { - const selectedAddress = this.preferencesController.getSelectedAddress() - return selectedAddress ? [selectedAddress] : [] + const selectedAddress = this.preferencesController.getSelectedAddress(); + return selectedAddress ? [selectedAddress] : []; } else if (this.isUnlocked()) { - return await this.permissionsController.getAccounts(origin) + return await this.permissionsController.getAccounts(origin); } - return [] // changing this is a breaking change + return []; // changing this is a breaking change }, // tx signing processTransaction: this.newUnapprovedTransaction.bind(this), @@ -457,11 +457,11 @@ export default class MetamaskController extends EventEmitter { hash, status: TRANSACTION_STATUSES.SUBMITTED, })[0], - } + }; const providerProxy = this.networkController.initializeProvider( providerOpts, - ) - return providerProxy + ); + return providerProxy; } /** @@ -471,17 +471,17 @@ export default class MetamaskController extends EventEmitter { */ createPublicConfigStore() { // subset of state for metamask inpage provider - const publicConfigStore = new ObservableStore() - const { networkController } = this + const publicConfigStore = new ObservableStore(); + const { networkController } = this; // setup memStore subscription hooks - this.on('update', updatePublicConfigStore) - updatePublicConfigStore(this.getState()) + this.on('update', updatePublicConfigStore); + updatePublicConfigStore(this.getState()); function updatePublicConfigStore(memState) { - const chainId = networkController.getCurrentChainId() + const chainId = networkController.getCurrentChainId(); if (memState.network !== 'loading') { - publicConfigStore.putState(selectPublicState(chainId, memState)) + publicConfigStore.putState(selectPublicState(chainId, memState)); } } @@ -490,10 +490,10 @@ export default class MetamaskController extends EventEmitter { isUnlocked, chainId, networkVersion: network, - } + }; } - return publicConfigStore + return publicConfigStore; } /** @@ -512,7 +512,7 @@ export default class MetamaskController extends EventEmitter { isUnlocked: this.isUnlocked(), ...this.getProviderNetworkState(), accounts: await this.permissionsController.getAccounts(origin), - } + }; } /** @@ -523,11 +523,11 @@ export default class MetamaskController extends EventEmitter { * @returns {Object} An object with relevant network state properties. */ getProviderNetworkState(memState) { - const { network } = memState || this.getState() + const { network } = memState || this.getState(); return { chainId: this.networkController.getCurrentChainId(), networkVersion: network, - } + }; } //============================================================================= @@ -540,13 +540,13 @@ export default class MetamaskController extends EventEmitter { * @returns {Object} status */ getState() { - const { vault } = this.keyringController.store.getState() - const isInitialized = Boolean(vault) + const { vault } = this.keyringController.store.getState(); + const isInitialized = Boolean(vault); return { ...{ isInitialized }, ...this.memStore.getFlatState(), - } + }; } /** @@ -568,7 +568,7 @@ export default class MetamaskController extends EventEmitter { swapsController, threeBoxController, txController, - } = this + } = this; return { // etc @@ -883,7 +883,7 @@ export default class MetamaskController extends EventEmitter { metaMetricsController.trackPage, metaMetricsController, ), - } + }; } //============================================================================= @@ -904,21 +904,23 @@ export default class MetamaskController extends EventEmitter { * @returns {Object} vault */ async createNewVaultAndKeychain(password) { - const releaseLock = await this.createVaultMutex.acquire() + const releaseLock = await this.createVaultMutex.acquire(); try { - let vault - const accounts = await this.keyringController.getAccounts() + let vault; + const accounts = await this.keyringController.getAccounts(); if (accounts.length > 0) { - vault = await this.keyringController.fullUpdate() + vault = await this.keyringController.fullUpdate(); } else { - vault = await this.keyringController.createNewVaultAndKeychain(password) - const addresses = await this.keyringController.getAccounts() - this.preferencesController.setAddresses(addresses) - this.selectFirstIdentity() + vault = await this.keyringController.createNewVaultAndKeychain( + password, + ); + const addresses = await this.keyringController.getAccounts(); + this.preferencesController.setAddresses(addresses); + this.selectFirstIdentity(); } - return vault + return vault; } finally { - releaseLock() + releaseLock(); } } @@ -928,63 +930,63 @@ export default class MetamaskController extends EventEmitter { * @param {string} seed */ async createNewVaultAndRestore(password, seed) { - const releaseLock = await this.createVaultMutex.acquire() + const releaseLock = await this.createVaultMutex.acquire(); try { - let accounts, lastBalance + let accounts, lastBalance; - const { keyringController } = this + const { keyringController } = this; // clear known identities - this.preferencesController.setAddresses([]) + this.preferencesController.setAddresses([]); // clear permissions - this.permissionsController.clearPermissions() + this.permissionsController.clearPermissions(); // clear accounts in accountTracker - this.accountTracker.clearAccounts() + this.accountTracker.clearAccounts(); // clear cachedBalances - this.cachedBalancesController.clearCachedBalances() + this.cachedBalancesController.clearCachedBalances(); // clear unapproved transactions - this.txController.txStateManager.clearUnapprovedTxs() + this.txController.txStateManager.clearUnapprovedTxs(); // create new vault const vault = await keyringController.createNewVaultAndRestore( password, seed, - ) + ); - const ethQuery = new EthQuery(this.provider) - accounts = await keyringController.getAccounts() + const ethQuery = new EthQuery(this.provider); + accounts = await keyringController.getAccounts(); lastBalance = await this.getBalance( accounts[accounts.length - 1], ethQuery, - ) + ); const primaryKeyring = keyringController.getKeyringsByType( 'HD Key Tree', - )[0] + )[0]; if (!primaryKeyring) { - throw new Error('MetamaskController - No HD Key Tree found') + throw new Error('MetamaskController - No HD Key Tree found'); } // seek out the first zero balance while (lastBalance !== '0x0') { - await keyringController.addNewAccount(primaryKeyring) - accounts = await keyringController.getAccounts() + await keyringController.addNewAccount(primaryKeyring); + accounts = await keyringController.getAccounts(); lastBalance = await this.getBalance( accounts[accounts.length - 1], ethQuery, - ) + ); } // set new identities - this.preferencesController.setAddresses(accounts) - this.selectFirstIdentity() - return vault + this.preferencesController.setAddresses(accounts); + this.selectFirstIdentity(); + return vault; } finally { - releaseLock() + releaseLock(); } } @@ -995,26 +997,26 @@ export default class MetamaskController extends EventEmitter { */ getBalance(address, ethQuery) { return new Promise((resolve, reject) => { - const cached = this.accountTracker.store.getState().accounts[address] + const cached = this.accountTracker.store.getState().accounts[address]; if (cached && cached.balance) { - resolve(cached.balance) + resolve(cached.balance); } else { ethQuery.getBalance(address, (error, balance) => { if (error) { - reject(error) - log.error(error) + reject(error); + log.error(error); } else { - resolve(balance || '0x0') + resolve(balance || '0x0'); } - }) + }); } - }) + }); } getCurrentNetwork = () => { - return this.networkController.store.getState().network - } + return this.networkController.store.getState().network; + }; /** * Collects all the information that we want to share @@ -1030,13 +1032,13 @@ export default class MetamaskController extends EventEmitter { identities, selectedAddress, tokens, - } = this.preferencesController.store.getState() + } = this.preferencesController.store.getState(); // Filter ERC20 tokens - const filteredAccountTokens = {} + const filteredAccountTokens = {}; Object.keys(accountTokens).forEach((address) => { - const checksummedAddress = ethUtil.toChecksumAddress(address) - filteredAccountTokens[checksummedAddress] = {} + const checksummedAddress = ethUtil.toChecksumAddress(address); + filteredAccountTokens[checksummedAddress] = {}; Object.keys(accountTokens[address]).forEach((networkType) => { filteredAccountTokens[checksummedAddress][networkType] = networkType === 'mainnet' @@ -1044,15 +1046,15 @@ export default class MetamaskController extends EventEmitter { ({ address: tokenAddress }) => { const checksumAddress = ethUtil.toChecksumAddress( tokenAddress, - ) + ); return contractMap[checksumAddress] ? contractMap[checksumAddress].erc20 - : true + : true; }, ) - : accountTokens[address][networkType] - }) - }) + : accountTokens[address][networkType]; + }); + }); const preferences = { accountTokens: filteredAccountTokens, @@ -1061,21 +1063,23 @@ export default class MetamaskController extends EventEmitter { identities, selectedAddress, tokens, - } + }; // Accounts - const hdKeyring = this.keyringController.getKeyringsByType('HD Key Tree')[0] + const hdKeyring = this.keyringController.getKeyringsByType( + 'HD Key Tree', + )[0]; const simpleKeyPairKeyrings = this.keyringController.getKeyringsByType( 'Simple Key Pair', - ) - const hdAccounts = await hdKeyring.getAccounts() + ); + const hdAccounts = await hdKeyring.getAccounts(); const simpleKeyPairKeyringAccounts = await Promise.all( simpleKeyPairKeyrings.map((keyring) => keyring.getAccounts()), - ) + ); const simpleKeyPairAccounts = simpleKeyPairKeyringAccounts.reduce( (acc, accounts) => [...acc, ...accounts], [], - ) + ); const accounts = { hd: hdAccounts .filter((item, pos) => hdAccounts.indexOf(item) === pos) @@ -1085,23 +1089,23 @@ export default class MetamaskController extends EventEmitter { .map((address) => ethUtil.toChecksumAddress(address)), ledger: [], trezor: [], - } + }; // transactions - let { transactions } = this.txController.store.getState() + let { transactions } = this.txController.store.getState(); // delete tx for other accounts that we're not importing transactions = transactions.filter((tx) => { - const checksummedTxFrom = ethUtil.toChecksumAddress(tx.txParams.from) - return accounts.hd.includes(checksummedTxFrom) - }) + const checksummedTxFrom = ethUtil.toChecksumAddress(tx.txParams.from); + return accounts.hd.includes(checksummedTxFrom); + }); return { accounts, preferences, transactions, network: this.networkController.store.getState(), - } + }; } /* @@ -1113,28 +1117,28 @@ export default class MetamaskController extends EventEmitter { * @returns {Promise} The keyringController update. */ async submitPassword(password) { - await this.keyringController.submitPassword(password) + await this.keyringController.submitPassword(password); try { - await this.blockTracker.checkForLatestBlock() + await this.blockTracker.checkForLatestBlock(); } catch (error) { - log.error('Error while unlocking extension.', error) + log.error('Error while unlocking extension.', error); } try { - const threeBoxSyncingAllowed = this.threeBoxController.getThreeBoxSyncingState() + const threeBoxSyncingAllowed = this.threeBoxController.getThreeBoxSyncingState(); if (threeBoxSyncingAllowed && !this.threeBoxController.box) { // 'await' intentionally omitted to avoid waiting for initialization - this.threeBoxController.init() - this.threeBoxController.turnThreeBoxSyncingOn() + this.threeBoxController.init(); + this.threeBoxController.turnThreeBoxSyncingOn(); } else if (threeBoxSyncingAllowed && this.threeBoxController.box) { - this.threeBoxController.turnThreeBoxSyncingOn() + this.threeBoxController.turnThreeBoxSyncingOn(); } } catch (error) { - log.error('Error while unlocking extension.', error) + log.error('Error while unlocking extension.', error); } - return this.keyringController.fullUpdate() + return this.keyringController.fullUpdate(); } /** @@ -1143,7 +1147,7 @@ export default class MetamaskController extends EventEmitter { * @param {string} password The user's password */ async verifyPassword(password) { - await this.keyringController.verifyPassword(password) + await this.keyringController.verifyPassword(password); } /** @@ -1158,9 +1162,9 @@ export default class MetamaskController extends EventEmitter { * Sets the first address in the state to the selected address */ selectFirstIdentity() { - const { identities } = this.preferencesController.store.getState() - const address = Object.keys(identities)[0] - this.preferencesController.setSelectedAddress(address) + const { identities } = this.preferencesController.store.getState(); + const address = Object.keys(identities)[0]; + this.preferencesController.setSelectedAddress(address); } // @@ -1168,30 +1172,32 @@ export default class MetamaskController extends EventEmitter { // async getKeyringForDevice(deviceName, hdPath = null) { - let keyringName = null + let keyringName = null; switch (deviceName) { case 'trezor': - keyringName = TrezorKeyring.type - break + keyringName = TrezorKeyring.type; + break; case 'ledger': - keyringName = LedgerBridgeKeyring.type - break + keyringName = LedgerBridgeKeyring.type; + break; default: throw new Error( 'MetamaskController:getKeyringForDevice - Unknown device', - ) + ); } - let keyring = await this.keyringController.getKeyringsByType(keyringName)[0] + let keyring = await this.keyringController.getKeyringsByType( + keyringName, + )[0]; if (!keyring) { - keyring = await this.keyringController.addNewKeyring(keyringName) + keyring = await this.keyringController.addNewKeyring(keyringName); } if (hdPath && keyring.setHdPath) { - keyring.setHdPath(hdPath) + keyring.setHdPath(hdPath); } - keyring.network = this.networkController.getProviderConfig().type + keyring.network = this.networkController.getProviderConfig().type; - return keyring + return keyring; } /** @@ -1200,29 +1206,29 @@ export default class MetamaskController extends EventEmitter { * @returns [] accounts */ async connectHardware(deviceName, page, hdPath) { - const keyring = await this.getKeyringForDevice(deviceName, hdPath) - let accounts = [] + const keyring = await this.getKeyringForDevice(deviceName, hdPath); + let accounts = []; switch (page) { case -1: - accounts = await keyring.getPreviousPage() - break + accounts = await keyring.getPreviousPage(); + break; case 1: - accounts = await keyring.getNextPage() - break + accounts = await keyring.getNextPage(); + break; default: - accounts = await keyring.getFirstPage() + accounts = await keyring.getFirstPage(); } // Merge with existing accounts // and make sure addresses are not repeated - const oldAccounts = await this.keyringController.getAccounts() + const oldAccounts = await this.keyringController.getAccounts(); const accountsToTrack = [ ...new Set( oldAccounts.concat(accounts.map((a) => a.address.toLowerCase())), ), - ] - this.accountTracker.syncWithAddresses(accountsToTrack) - return accounts + ]; + this.accountTracker.syncWithAddresses(accountsToTrack); + return accounts; } /** @@ -1231,8 +1237,8 @@ export default class MetamaskController extends EventEmitter { * @returns {Promise} */ async checkHardwareStatus(deviceName, hdPath) { - const keyring = await this.getKeyringForDevice(deviceName, hdPath) - return keyring.isUnlocked() + const keyring = await this.getKeyringForDevice(deviceName, hdPath); + return keyring.isUnlocked(); } /** @@ -1241,9 +1247,9 @@ export default class MetamaskController extends EventEmitter { * @returns {Promise} */ async forgetDevice(deviceName) { - const keyring = await this.getKeyringForDevice(deviceName) - keyring.forgetDevice() - return true + const keyring = await this.getKeyringForDevice(deviceName); + keyring.forgetDevice(); + return true; } /** @@ -1252,13 +1258,13 @@ export default class MetamaskController extends EventEmitter { * @returns {} keyState */ async unlockHardwareWalletAccount(index, deviceName, hdPath) { - const keyring = await this.getKeyringForDevice(deviceName, hdPath) + const keyring = await this.getKeyringForDevice(deviceName, hdPath); - keyring.setAccountToUnlock(index) - const oldAccounts = await this.keyringController.getAccounts() - const keyState = await this.keyringController.addNewAccount(keyring) - const newAccounts = await this.keyringController.getAccounts() - this.preferencesController.setAddresses(newAccounts) + keyring.setAccountToUnlock(index); + const oldAccounts = await this.keyringController.getAccounts(); + const keyState = await this.keyringController.addNewAccount(keyring); + const newAccounts = await this.keyringController.getAccounts(); + this.preferencesController.setAddresses(newAccounts); newAccounts.forEach((address) => { if (!oldAccounts.includes(address)) { // Set the account label to Trezor 1 / Ledger 1, etc @@ -1267,14 +1273,14 @@ export default class MetamaskController extends EventEmitter { `${deviceName[0].toUpperCase()}${deviceName.slice(1)} ${ parseInt(index, 10) + 1 }`, - ) + ); // Select the account - this.preferencesController.setSelectedAddress(address) + this.preferencesController.setSelectedAddress(address); } - }) + }); - const { identities } = this.preferencesController.store.getState() - return { ...keyState, identities } + const { identities } = this.preferencesController.store.getState(); + return { ...keyState, identities }; } // @@ -1289,26 +1295,26 @@ export default class MetamaskController extends EventEmitter { async addNewAccount() { const primaryKeyring = this.keyringController.getKeyringsByType( 'HD Key Tree', - )[0] + )[0]; if (!primaryKeyring) { - throw new Error('MetamaskController - No HD Key Tree found') + throw new Error('MetamaskController - No HD Key Tree found'); } - const { keyringController } = this - const oldAccounts = await keyringController.getAccounts() - const keyState = await keyringController.addNewAccount(primaryKeyring) - const newAccounts = await keyringController.getAccounts() + const { keyringController } = this; + const oldAccounts = await keyringController.getAccounts(); + const keyState = await keyringController.addNewAccount(primaryKeyring); + const newAccounts = await keyringController.getAccounts(); - await this.verifySeedPhrase() + await this.verifySeedPhrase(); - this.preferencesController.setAddresses(newAccounts) + this.preferencesController.setAddresses(newAccounts); newAccounts.forEach((address) => { if (!oldAccounts.includes(address)) { - this.preferencesController.setSelectedAddress(address) + this.preferencesController.setSelectedAddress(address); } - }) + }); - const { identities } = this.preferencesController.store.getState() - return { ...keyState, identities } + const { identities } = this.preferencesController.store.getState(); + return { ...keyState, identities }; } /** @@ -1323,25 +1329,25 @@ export default class MetamaskController extends EventEmitter { async verifySeedPhrase() { const primaryKeyring = this.keyringController.getKeyringsByType( 'HD Key Tree', - )[0] + )[0]; if (!primaryKeyring) { - throw new Error('MetamaskController - No HD Key Tree found') + throw new Error('MetamaskController - No HD Key Tree found'); } - const serialized = await primaryKeyring.serialize() - const seedWords = serialized.mnemonic + const serialized = await primaryKeyring.serialize(); + const seedWords = serialized.mnemonic; - const accounts = await primaryKeyring.getAccounts() + const accounts = await primaryKeyring.getAccounts(); if (accounts.length < 1) { - throw new Error('MetamaskController - No accounts found') + throw new Error('MetamaskController - No accounts found'); } try { - await seedPhraseVerifier.verifyAccounts(accounts, seedWords) - return seedWords + await seedPhraseVerifier.verifyAccounts(accounts, seedWords); + return seedWords; } catch (err) { - log.error(err.message) - throw err + log.error(err.message); + throw err; } } @@ -1353,11 +1359,11 @@ export default class MetamaskController extends EventEmitter { * @returns {Promise} The current selected address. */ async resetAccount() { - const selectedAddress = this.preferencesController.getSelectedAddress() - this.txController.wipeTransactions(selectedAddress) - this.networkController.resetConnection() + const selectedAddress = this.preferencesController.getSelectedAddress(); + this.txController.wipeTransactions(selectedAddress); + this.networkController.resetConnection(); - return selectedAddress + return selectedAddress; } /** @@ -1368,15 +1374,15 @@ export default class MetamaskController extends EventEmitter { */ async removeAccount(address) { // Remove all associated permissions - await this.permissionsController.removeAllAccountPermissions(address) + await this.permissionsController.removeAllAccountPermissions(address); // Remove account from the preferences controller - this.preferencesController.removeAddress(address) + this.preferencesController.removeAddress(address); // Remove account from the account tracker controller - this.accountTracker.removeAccount([address]) + this.accountTracker.removeAccount([address]); // Remove account from the keyring - await this.keyringController.removeAccount(address) - return address + await this.keyringController.removeAccount(address); + return address; } /** @@ -1389,17 +1395,17 @@ export default class MetamaskController extends EventEmitter { * @param {Function} cb - A callback function called with a state update on success. */ async importAccountWithStrategy(strategy, args) { - const privateKey = await accountImporter.importAccount(strategy, args) + const privateKey = await accountImporter.importAccount(strategy, args); const keyring = await this.keyringController.addNewKeyring( 'Simple Key Pair', [privateKey], - ) - const accounts = await keyring.getAccounts() + ); + const accounts = await keyring.getAccounts(); // update accounts in preferences controller - const allAccounts = await this.keyringController.getAccounts() - this.preferencesController.setAddresses(allAccounts) + const allAccounts = await this.keyringController.getAccounts(); + this.preferencesController.setAddresses(allAccounts); // set new account as selected - await this.preferencesController.setSelectedAddress(accounts[0]) + await this.preferencesController.setSelectedAddress(accounts[0]); } // --------------------------------------------------------------------------- @@ -1414,7 +1420,7 @@ export default class MetamaskController extends EventEmitter { * @param {Object} req - (optional) the original request, containing the origin */ async newUnapprovedTransaction(txParams, req) { - return await this.txController.newUnapprovedTransaction(txParams, req) + return await this.txController.newUnapprovedTransaction(txParams, req); } // eth_sign methods: @@ -1432,10 +1438,10 @@ export default class MetamaskController extends EventEmitter { const promise = this.messageManager.addUnapprovedMessageAsync( msgParams, req, - ) - this.sendUpdate() - this.opts.showUserConfirmation() - return promise + ); + this.sendUpdate(); + this.opts.showUserConfirmation(); + return promise; } /** @@ -1445,8 +1451,8 @@ export default class MetamaskController extends EventEmitter { * @returns {Promise} Full state update. */ signMessage(msgParams) { - log.info('MetaMaskController - signMessage') - const msgId = msgParams.metamaskId + log.info('MetaMaskController - signMessage'); + const msgId = msgParams.metamaskId; // sets the status op the message to 'approved' // and removes the metamaskId for signing @@ -1454,14 +1460,14 @@ export default class MetamaskController extends EventEmitter { .approveMessage(msgParams) .then((cleanMsgParams) => { // signs the message - return this.keyringController.signMessage(cleanMsgParams) + return this.keyringController.signMessage(cleanMsgParams); }) .then((rawSig) => { // tells the listener that the message has been signed // and can be returned to the dapp - this.messageManager.setMsgStatusSigned(msgId, rawSig) - return this.getState() - }) + this.messageManager.setMsgStatusSigned(msgId, rawSig); + return this.getState(); + }); } /** @@ -1470,12 +1476,12 @@ export default class MetamaskController extends EventEmitter { * @param {string} msgId - The id of the message to cancel. */ cancelMessage(msgId, cb) { - const { messageManager } = this - messageManager.rejectMsg(msgId) + const { messageManager } = this; + messageManager.rejectMsg(msgId); if (!cb || typeof cb !== 'function') { - return + return; } - cb(null, this.getState()) + cb(null, this.getState()); } // personal_sign methods: @@ -1495,10 +1501,10 @@ export default class MetamaskController extends EventEmitter { const promise = this.personalMessageManager.addUnapprovedMessageAsync( msgParams, req, - ) - this.sendUpdate() - this.opts.showUserConfirmation() - return promise + ); + this.sendUpdate(); + this.opts.showUserConfirmation(); + return promise; } /** @@ -1509,22 +1515,22 @@ export default class MetamaskController extends EventEmitter { * @returns {Promise} A full state update. */ signPersonalMessage(msgParams) { - log.info('MetaMaskController - signPersonalMessage') - const msgId = msgParams.metamaskId + log.info('MetaMaskController - signPersonalMessage'); + const msgId = msgParams.metamaskId; // sets the status op the message to 'approved' // and removes the metamaskId for signing return this.personalMessageManager .approveMessage(msgParams) .then((cleanMsgParams) => { // signs the message - return this.keyringController.signPersonalMessage(cleanMsgParams) + return this.keyringController.signPersonalMessage(cleanMsgParams); }) .then((rawSig) => { // tells the listener that the message has been signed // and can be returned to the dapp - this.personalMessageManager.setMsgStatusSigned(msgId, rawSig) - return this.getState() - }) + this.personalMessageManager.setMsgStatusSigned(msgId, rawSig); + return this.getState(); + }); } /** @@ -1533,12 +1539,12 @@ export default class MetamaskController extends EventEmitter { * @param {Function} cb - The callback function called with a full state update. */ cancelPersonalMessage(msgId, cb) { - const messageManager = this.personalMessageManager - messageManager.rejectMsg(msgId) + const messageManager = this.personalMessageManager; + messageManager.rejectMsg(msgId); if (!cb || typeof cb !== 'function') { - return + return; } - cb(null, this.getState()) + cb(null, this.getState()); } // eth_decrypt methods @@ -1554,10 +1560,10 @@ export default class MetamaskController extends EventEmitter { const promise = this.decryptMessageManager.addUnapprovedMessageAsync( msgParams, req, - ) - this.sendUpdate() - this.opts.showUserConfirmation() - return promise + ); + this.sendUpdate(); + this.opts.showUserConfirmation(); + return promise; } /** @@ -1567,22 +1573,22 @@ export default class MetamaskController extends EventEmitter { * @returns {Promise} A full state update. */ async decryptMessageInline(msgParams) { - log.info('MetaMaskController - decryptMessageInline') + log.info('MetaMaskController - decryptMessageInline'); // decrypt the message inline - const msgId = msgParams.metamaskId - const msg = this.decryptMessageManager.getMsg(msgId) + const msgId = msgParams.metamaskId; + const msg = this.decryptMessageManager.getMsg(msgId); try { - const stripped = ethUtil.stripHexPrefix(msgParams.data) - const buff = Buffer.from(stripped, 'hex') - msgParams.data = JSON.parse(buff.toString('utf8')) + const stripped = ethUtil.stripHexPrefix(msgParams.data); + const buff = Buffer.from(stripped, 'hex'); + msgParams.data = JSON.parse(buff.toString('utf8')); - msg.rawData = await this.keyringController.decryptMessage(msgParams) + msg.rawData = await this.keyringController.decryptMessage(msgParams); } catch (e) { - msg.error = e.message + msg.error = e.message; } - this.decryptMessageManager._updateMsg(msg) + this.decryptMessageManager._updateMsg(msg); - return this.getState() + return this.getState(); } /** @@ -1593,30 +1599,30 @@ export default class MetamaskController extends EventEmitter { * @returns {Promise} A full state update. */ async decryptMessage(msgParams) { - log.info('MetaMaskController - decryptMessage') - const msgId = msgParams.metamaskId + log.info('MetaMaskController - decryptMessage'); + const msgId = msgParams.metamaskId; // sets the status op the message to 'approved' // and removes the metamaskId for decryption try { const cleanMsgParams = await this.decryptMessageManager.approveMessage( msgParams, - ) + ); - const stripped = ethUtil.stripHexPrefix(cleanMsgParams.data) - const buff = Buffer.from(stripped, 'hex') - cleanMsgParams.data = JSON.parse(buff.toString('utf8')) + const stripped = ethUtil.stripHexPrefix(cleanMsgParams.data); + const buff = Buffer.from(stripped, 'hex'); + cleanMsgParams.data = JSON.parse(buff.toString('utf8')); // decrypt the message const rawMess = await this.keyringController.decryptMessage( cleanMsgParams, - ) + ); // tells the listener that the message has been decrypted and can be returned to the dapp - this.decryptMessageManager.setMsgStatusDecrypted(msgId, rawMess) + this.decryptMessageManager.setMsgStatusDecrypted(msgId, rawMess); } catch (error) { - log.info('MetaMaskController - eth_decrypt failed.', error) - this.decryptMessageManager.errorMessage(msgId, error) + log.info('MetaMaskController - eth_decrypt failed.', error); + this.decryptMessageManager.errorMessage(msgId, error); } - return this.getState() + return this.getState(); } /** @@ -1625,12 +1631,12 @@ export default class MetamaskController extends EventEmitter { * @param {Function} cb - The callback function called with a full state update. */ cancelDecryptMessage(msgId, cb) { - const messageManager = this.decryptMessageManager - messageManager.rejectMsg(msgId) + const messageManager = this.decryptMessageManager; + messageManager.rejectMsg(msgId); if (!cb || typeof cb !== 'function') { - return + return; } - cb(null, this.getState()) + cb(null, this.getState()); } // eth_getEncryptionPublicKey methods @@ -1643,34 +1649,34 @@ export default class MetamaskController extends EventEmitter { * Passed back to the requesting Dapp. */ async newRequestEncryptionPublicKey(msgParams, req) { - const address = msgParams - const keyring = await this.keyringController.getKeyringForAccount(address) + const address = msgParams; + const keyring = await this.keyringController.getKeyringForAccount(address); switch (keyring.type) { case 'Ledger Hardware': { return new Promise((_, reject) => { reject( new Error('Ledger does not support eth_getEncryptionPublicKey.'), - ) - }) + ); + }); } case 'Trezor Hardware': { return new Promise((_, reject) => { reject( new Error('Trezor does not support eth_getEncryptionPublicKey.'), - ) - }) + ); + }); } default: { const promise = this.encryptionPublicKeyManager.addUnapprovedMessageAsync( msgParams, req, - ) - this.sendUpdate() - this.opts.showUserConfirmation() - return promise + ); + this.sendUpdate(); + this.opts.showUserConfirmation(); + return promise; } } } @@ -1683,28 +1689,31 @@ export default class MetamaskController extends EventEmitter { * @returns {Promise} A full state update. */ async encryptionPublicKey(msgParams) { - log.info('MetaMaskController - encryptionPublicKey') - const msgId = msgParams.metamaskId + log.info('MetaMaskController - encryptionPublicKey'); + const msgId = msgParams.metamaskId; // sets the status op the message to 'approved' // and removes the metamaskId for decryption try { const params = await this.encryptionPublicKeyManager.approveMessage( msgParams, - ) + ); // EncryptionPublicKey message const publicKey = await this.keyringController.getEncryptionPublicKey( params.data, - ) + ); // tells the listener that the message has been processed // and can be returned to the dapp - this.encryptionPublicKeyManager.setMsgStatusReceived(msgId, publicKey) + this.encryptionPublicKeyManager.setMsgStatusReceived(msgId, publicKey); } catch (error) { - log.info('MetaMaskController - eth_getEncryptionPublicKey failed.', error) - this.encryptionPublicKeyManager.errorMessage(msgId, error) + log.info( + 'MetaMaskController - eth_getEncryptionPublicKey failed.', + error, + ); + this.encryptionPublicKeyManager.errorMessage(msgId, error); } - return this.getState() + return this.getState(); } /** @@ -1713,12 +1722,12 @@ export default class MetamaskController extends EventEmitter { * @param {Function} cb - The callback function called with a full state update. */ cancelEncryptionPublicKey(msgId, cb) { - const messageManager = this.encryptionPublicKeyManager - messageManager.rejectMsg(msgId) + const messageManager = this.encryptionPublicKeyManager; + messageManager.rejectMsg(msgId); if (!cb || typeof cb !== 'function') { - return + return; } - cb(null, this.getState()) + cb(null, this.getState()); } // eth_signTypedData methods @@ -1734,10 +1743,10 @@ export default class MetamaskController extends EventEmitter { msgParams, req, version, - ) - this.sendUpdate() - this.opts.showUserConfirmation() - return promise + ); + this.sendUpdate(); + this.opts.showUserConfirmation(); + return promise; } /** @@ -1748,32 +1757,32 @@ export default class MetamaskController extends EventEmitter { * @returns {Object} Full state update. */ async signTypedMessage(msgParams) { - log.info('MetaMaskController - eth_signTypedData') - const msgId = msgParams.metamaskId - const { version } = msgParams + log.info('MetaMaskController - eth_signTypedData'); + const msgId = msgParams.metamaskId; + const { version } = msgParams; try { const cleanMsgParams = await this.typedMessageManager.approveMessage( msgParams, - ) + ); // For some reason every version after V1 used stringified params. if (version !== 'V1') { // But we don't have to require that. We can stop suggesting it now: if (typeof cleanMsgParams.data === 'string') { - cleanMsgParams.data = JSON.parse(cleanMsgParams.data) + cleanMsgParams.data = JSON.parse(cleanMsgParams.data); } } const signature = await this.keyringController.signTypedMessage( cleanMsgParams, { version }, - ) - this.typedMessageManager.setMsgStatusSigned(msgId, signature) - return this.getState() + ); + this.typedMessageManager.setMsgStatusSigned(msgId, signature); + return this.getState(); } catch (error) { - log.info('MetaMaskController - eth_signTypedData failed.', error) - this.typedMessageManager.errorMessage(msgId, error) - throw error + log.info('MetaMaskController - eth_signTypedData failed.', error); + this.typedMessageManager.errorMessage(msgId, error); + throw error; } } @@ -1783,12 +1792,12 @@ export default class MetamaskController extends EventEmitter { * @param {Function} cb - The callback function called with a full state update. */ cancelTypedMessage(msgId, cb) { - const messageManager = this.typedMessageManager - messageManager.rejectMsg(msgId) + const messageManager = this.typedMessageManager; + messageManager.rejectMsg(msgId); if (!cb || typeof cb !== 'function') { - return + return; } - cb(null, this.getState()) + cb(null, this.getState()); } //============================================================================= @@ -1806,9 +1815,9 @@ export default class MetamaskController extends EventEmitter { await this.txController.createCancelTransaction( originalTxId, customGasPrice, - ) - const state = await this.getState() - return state + ); + const state = await this.getState(); + return state; } async createSpeedUpTransaction(originalTxId, customGasPrice, customGasLimit) { @@ -1816,9 +1825,9 @@ export default class MetamaskController extends EventEmitter { originalTxId, customGasPrice, customGasLimit, - ) - const state = await this.getState() - return state + ); + const state = await this.getState(); + return state; } estimateGas(estimateGasParams) { @@ -1827,13 +1836,13 @@ export default class MetamaskController extends EventEmitter { estimateGasParams, (err, res) => { if (err) { - return reject(err) + return reject(err); } - return resolve(res) + return resolve(res); }, - ) - }) + ); + }); } //============================================================================= @@ -1845,9 +1854,9 @@ export default class MetamaskController extends EventEmitter { * @param {Function} cb - A callback function called when complete. */ markPasswordForgotten(cb) { - this.preferencesController.setPasswordForgotten(true) - this.sendUpdate() - cb() + this.preferencesController.setPasswordForgotten(true); + this.sendUpdate(); + cb(); } /** @@ -1855,9 +1864,9 @@ export default class MetamaskController extends EventEmitter { * @param {Function} cb - A callback function called when complete. */ unMarkPasswordForgotten(cb) { - this.preferencesController.setPasswordForgotten(false) - this.sendUpdate() - cb() + this.preferencesController.setPasswordForgotten(false); + this.sendUpdate(); + cb(); } //============================================================================= @@ -1877,24 +1886,24 @@ export default class MetamaskController extends EventEmitter { * @param {MessageSender} sender - The sender of the messages on this stream */ setupUntrustedCommunication(connectionStream, sender) { - const { usePhishDetect } = this.preferencesController.store.getState() - const { hostname } = new URL(sender.url) + const { usePhishDetect } = this.preferencesController.store.getState(); + const { hostname } = new URL(sender.url); // Check if new connection is blocked if phishing detection is on if (usePhishDetect && this.phishingController.test(hostname)) { - log.debug('MetaMask - sending phishing warning for', hostname) - this.sendPhishingWarning(connectionStream, hostname) - return + log.debug('MetaMask - sending phishing warning for', hostname); + this.sendPhishingWarning(connectionStream, hostname); + return; } // setup multiplexing - const mux = setupMultiplex(connectionStream) + const mux = setupMultiplex(connectionStream); // messages between inpage and background - this.setupProviderConnection(mux.createStream('metamask-provider'), sender) + this.setupProviderConnection(mux.createStream('metamask-provider'), sender); // TODO:LegacyProvider: Delete // legacy streams - this.setupPublicConfig(mux.createStream('publicConfig')) + this.setupPublicConfig(mux.createStream('publicConfig')); } /** @@ -1908,10 +1917,10 @@ export default class MetamaskController extends EventEmitter { */ setupTrustedCommunication(connectionStream, sender) { // setup multiplexing - const mux = setupMultiplex(connectionStream) + const mux = setupMultiplex(connectionStream); // connect features - this.setupControllerConnection(mux.createStream('controller')) - this.setupProviderConnection(mux.createStream('provider'), sender, true) + this.setupControllerConnection(mux.createStream('controller')); + this.setupProviderConnection(mux.createStream('provider'), sender, true); } /** @@ -1924,9 +1933,9 @@ export default class MetamaskController extends EventEmitter { * @param {string} hostname - The hostname that triggered the suspicion. */ sendPhishingWarning(connectionStream, hostname) { - const mux = setupMultiplex(connectionStream) - const phishingStream = mux.createStream('phishing') - phishingStream.write({ hostname }) + const mux = setupMultiplex(connectionStream); + const phishingStream = mux.createStream('phishing'); + phishingStream.write({ hostname }); } /** @@ -1934,30 +1943,33 @@ export default class MetamaskController extends EventEmitter { * @param {*} outStream - The stream to provide our API over. */ setupControllerConnection(outStream) { - const api = this.getApi() + const api = this.getApi(); // the "weak: false" option is for nodejs only (eg unit tests) // it is a workaround for node v12 support - const dnode = Dnode(api, { weak: false }) + const dnode = Dnode(api, { weak: false }); // report new active controller connection - this.activeControllerConnections += 1 - this.emit('controllerConnectionChanged', this.activeControllerConnections) + this.activeControllerConnections += 1; + this.emit('controllerConnectionChanged', this.activeControllerConnections); // connect dnode api to remote connection pump(outStream, dnode, outStream, (err) => { // report new active controller connection - this.activeControllerConnections -= 1 - this.emit('controllerConnectionChanged', this.activeControllerConnections) + this.activeControllerConnections -= 1; + this.emit( + 'controllerConnectionChanged', + this.activeControllerConnections, + ); // report any error if (err) { - log.error(err) + log.error(err); } - }) + }); dnode.on('remote', (remote) => { // push updates to popup - const sendUpdate = (update) => remote.sendUpdate(update) - this.on('update', sendUpdate) + const sendUpdate = (update) => remote.sendUpdate(update); + this.on('update', sendUpdate); // remove update listener once the connection ends - dnode.on('end', () => this.removeListener('update', sendUpdate)) - }) + dnode.on('end', () => this.removeListener('update', sendUpdate)); + }); } /** @@ -1967,14 +1979,14 @@ export default class MetamaskController extends EventEmitter { * @param {boolean} isInternal - True if this is a connection with an internal process */ setupProviderConnection(outStream, sender, isInternal) { - const origin = isInternal ? 'metamask' : new URL(sender.url).origin - let extensionId + const origin = isInternal ? 'metamask' : new URL(sender.url).origin; + let extensionId; if (sender.id !== this.extension.runtime.id) { - extensionId = sender.id + extensionId = sender.id; } - let tabId + let tabId; if (sender.tab && sender.tab.id) { - tabId = sender.tab.id + tabId = sender.tab.id; } const engine = this.setupProviderEngine({ @@ -1983,25 +1995,25 @@ export default class MetamaskController extends EventEmitter { extensionId, tabId, isInternal, - }) + }); // setup connection - const providerStream = createEngineStream({ engine }) + const providerStream = createEngineStream({ engine }); - const connectionId = this.addConnection(origin, { engine }) + const connectionId = this.addConnection(origin, { engine }); pump(outStream, providerStream, outStream, (err) => { // handle any middleware cleanup engine._middleware.forEach((mid) => { if (mid.destroy && typeof mid.destroy === 'function') { - mid.destroy() + mid.destroy(); } - }) - connectionId && this.removeConnection(origin, connectionId) + }); + connectionId && this.removeConnection(origin, connectionId); if (err) { - log.error(err) + log.error(err); } - }) + }); } /** @@ -2021,35 +2033,35 @@ export default class MetamaskController extends EventEmitter { isInternal = false, }) { // setup json rpc engine stack - const engine = new JsonRpcEngine() - const { provider, blockTracker } = this + const engine = new JsonRpcEngine(); + const { provider, blockTracker } = this; // create filter polyfill middleware - const filterMiddleware = createFilterMiddleware({ provider, blockTracker }) + const filterMiddleware = createFilterMiddleware({ provider, blockTracker }); // create subscription polyfill middleware const subscriptionManager = createSubscriptionManager({ provider, blockTracker, - }) + }); subscriptionManager.events.on('notification', (message) => engine.emit('notification', message), - ) + ); // append origin to each request - engine.push(createOriginMiddleware({ origin })) + engine.push(createOriginMiddleware({ origin })); // append tabId to each request if it exists if (tabId) { - engine.push(createTabIdMiddleware({ tabId })) + engine.push(createTabIdMiddleware({ tabId })); } // logging - engine.push(createLoggerMiddleware({ origin })) + engine.push(createLoggerMiddleware({ origin })); engine.push( createOnboardingMiddleware({ location, registerOnboarding: this.onboardingController.registerOnboarding, }), - ) + ); engine.push( createMethodMiddleware({ origin, @@ -2067,19 +2079,19 @@ export default class MetamaskController extends EventEmitter { this.alertController, ), }), - ) + ); // filter and subscription polyfills - engine.push(filterMiddleware) - engine.push(subscriptionManager.middleware) + engine.push(filterMiddleware); + engine.push(subscriptionManager.middleware); if (!isInternal) { // permissions engine.push( this.permissionsController.createMiddleware({ origin, extensionId }), - ) + ); } // forward to metamask primary provider - engine.push(providerAsMiddleware(provider)) - return engine + engine.push(providerAsMiddleware(provider)); + return engine; } /** @@ -2094,14 +2106,14 @@ export default class MetamaskController extends EventEmitter { * @param {*} outStream - The stream to provide public config over. */ setupPublicConfig(outStream) { - const configStream = storeAsStream(this.publicConfigStore) + const configStream = storeAsStream(this.publicConfigStore); pump(configStream, outStream, (err) => { - configStream.destroy() + configStream.destroy(); if (err) { - log.error(err) + log.error(err); } - }) + }); } /** @@ -2116,19 +2128,19 @@ export default class MetamaskController extends EventEmitter { */ addConnection(origin, { engine }) { if (origin === 'metamask') { - return null + return null; } if (!this.connections[origin]) { - this.connections[origin] = {} + this.connections[origin] = {}; } - const id = nanoid() + const id = nanoid(); this.connections[origin][id] = { engine, - } + }; - return id + return id; } /** @@ -2139,15 +2151,15 @@ export default class MetamaskController extends EventEmitter { * @param {string} id - The connection's id, as returned from addConnection. */ removeConnection(origin, id) { - const connections = this.connections[origin] + const connections = this.connections[origin]; if (!connections) { - return + return; } - delete connections[id] + delete connections[id]; if (Object.keys(connections).length === 0) { - delete this.connections[origin] + delete this.connections[origin]; } } @@ -2164,14 +2176,14 @@ export default class MetamaskController extends EventEmitter { * @param {any} payload - The event payload. */ notifyConnections(origin, payload) { - const connections = this.connections[origin] + const connections = this.connections[origin]; if (connections) { Object.values(connections).forEach((conn) => { if (conn.engine) { - conn.engine.emit('notification', payload) + conn.engine.emit('notification', payload); } - }) + }); } } @@ -2192,15 +2204,15 @@ export default class MetamaskController extends EventEmitter { const getPayload = typeof payload === 'function' ? (origin) => payload(origin) - : () => payload + : () => payload; Object.values(this.connections).forEach((origin) => { Object.values(origin).forEach((conn) => { if (conn.engine) { - conn.engine.emit('notification', getPayload(origin)) + conn.engine.emit('notification', getPayload(origin)); } - }) - }) + }); + }); } // handlers @@ -2212,19 +2224,19 @@ export default class MetamaskController extends EventEmitter { * @private */ async _onKeyringControllerUpdate(state) { - const { keyrings } = state + const { keyrings } = state; const addresses = keyrings.reduce( (acc, { accounts }) => acc.concat(accounts), [], - ) + ); if (!addresses.length) { - return + return; } // Ensure preferences + identities controller know about all addresses - this.preferencesController.syncAddresses(addresses) - this.accountTracker.syncWithAddresses(addresses) + this.preferencesController.syncAddresses(addresses); + this.accountTracker.syncWithAddresses(addresses); } /** @@ -2239,9 +2251,9 @@ export default class MetamaskController extends EventEmitter { isUnlocked: true, accounts: this.permissionsController.getAccounts(origin), }, - } - }) - this.emit('unlock') + }; + }); + this.emit('unlock'); } /** @@ -2254,8 +2266,8 @@ export default class MetamaskController extends EventEmitter { params: { isUnlocked: false, }, - }) - this.emit('lock') + }); + this.emit('lock'); } /** @@ -2265,11 +2277,11 @@ export default class MetamaskController extends EventEmitter { * - The external providers handle diffing the state */ _onStateUpdate(newState) { - this.isClientOpenAndUnlocked = newState.isUnlocked && this._isClientOpen + this.isClientOpenAndUnlocked = newState.isUnlocked && this._isClientOpen; this.notifyAllConnections({ method: NOTIFICATION_NAMES.chainChanged, params: this.getProviderNetworkState(newState), - }) + }); } // misc @@ -2279,14 +2291,14 @@ export default class MetamaskController extends EventEmitter { * @private */ privateSendUpdate() { - this.emit('update', this.getState()) + this.emit('update', this.getState()); } /** * @returns {boolean} Whether the extension is unlocked. */ isUnlocked() { - return this.keyringController.memStore.getState().isUnlocked + return this.keyringController.memStore.getState().isUnlocked; } //============================================================================= @@ -2302,11 +2314,11 @@ export default class MetamaskController extends EventEmitter { const { nonceDetails, releaseLock, - } = await this.txController.nonceTracker.getNonceLock(address) - const pendingNonce = nonceDetails.params.highestSuggested + } = await this.txController.nonceTracker.getNonceLock(address); + const pendingNonce = nonceDetails.params.highestSuggested; - releaseLock() - return pendingNonce + releaseLock(); + return pendingNonce; } /** @@ -2315,20 +2327,22 @@ export default class MetamaskController extends EventEmitter { * @returns {Promise} */ async getNextNonce(address) { - const nonceLock = await this.txController.nonceTracker.getNonceLock(address) - nonceLock.releaseLock() - return nonceLock.nextNonce + const nonceLock = await this.txController.nonceTracker.getNonceLock( + address, + ); + nonceLock.releaseLock(); + return nonceLock.nextNonce; } async sendBackgroundMetaMetrics({ action, name, customVariables } = {}) { if (!action || !name) { - throw new Error('Must provide action and name.') + throw new Error('Must provide action and name.'); } - const metamaskState = await this.getState() + const metamaskState = await this.getState(); const additionalProperties = getBackgroundMetaMetricState({ metamask: metamaskState, - }) + }); this.metaMetricsController.trackEvent( { @@ -2343,7 +2357,7 @@ export default class MetamaskController extends EventEmitter { { matomoEvent: true, }, - ) + ); } /** @@ -2363,22 +2377,22 @@ export default class MetamaskController extends EventEmitter { * @param {boolean} [duplicate] - Whether to duplicate the addresses on both chainIds (default: false) */ async migrateAddressBookState(oldChainId, newChainId, duplicate = false) { - const { addressBook } = this.addressBookController.state + const { addressBook } = this.addressBookController.state; if (!addressBook[oldChainId]) { - return + return; } for (const address of Object.keys(addressBook[oldChainId])) { - const entry = addressBook[oldChainId][address] + const entry = addressBook[oldChainId][address]; this.addressBookController.set( address, entry.name, newChainId, entry.memo, - ) + ); if (!duplicate) { - this.addressBookController.delete(oldChainId, address) + this.addressBookController.delete(oldChainId, address); } } } @@ -2395,20 +2409,20 @@ export default class MetamaskController extends EventEmitter { * @param {Function} cb - A callback function returning currency info. */ setCurrentCurrency(currencyCode, cb) { - const { ticker } = this.networkController.getProviderConfig() + const { ticker } = this.networkController.getProviderConfig(); try { const currencyState = { nativeCurrency: ticker, currentCurrency: currencyCode, - } - this.currencyRateController.update(currencyState) - this.currencyRateController.configure(currencyState) - cb(null, this.currencyRateController.state) - return + }; + this.currencyRateController.update(currencyState); + this.currencyRateController.configure(currencyState); + cb(null, this.currencyRateController.state); + return; } catch (err) { - cb(err) + cb(err); // eslint-disable-next-line no-useless-return - return + return; } } @@ -2433,15 +2447,15 @@ export default class MetamaskController extends EventEmitter { ticker, nickname, rpcPrefs, - ) + ); await this.preferencesController.updateRpc({ rpcUrl, chainId, ticker, nickname, rpcPrefs, - }) - return rpcUrl + }); + return rpcUrl; } /** @@ -2459,10 +2473,10 @@ export default class MetamaskController extends EventEmitter { nickname = '', rpcPrefs = {}, ) { - const frequentRpcListDetail = this.preferencesController.getFrequentRpcListDetail() + const frequentRpcListDetail = this.preferencesController.getFrequentRpcListDetail(); const rpcSettings = frequentRpcListDetail.find( (rpc) => rpcUrl === rpc.rpcUrl, - ) + ); if (rpcSettings) { this.networkController.setRpcTarget( @@ -2471,7 +2485,7 @@ export default class MetamaskController extends EventEmitter { rpcSettings.ticker, rpcSettings.nickname, rpcPrefs, - ) + ); } else { this.networkController.setRpcTarget( rpcUrl, @@ -2479,16 +2493,16 @@ export default class MetamaskController extends EventEmitter { ticker, nickname, rpcPrefs, - ) + ); await this.preferencesController.addToFrequentRpcList( rpcUrl, chainId, ticker, nickname, rpcPrefs, - ) + ); } - return rpcUrl + return rpcUrl; } /** @@ -2496,11 +2510,11 @@ export default class MetamaskController extends EventEmitter { * @param {string} rpcUrl - A RPC URL to delete. */ async delCustomRpc(rpcUrl) { - await this.preferencesController.removeFromFrequentRpcList(rpcUrl) + await this.preferencesController.removeFromFrequentRpcList(rpcUrl); } async initializeThreeBox() { - await this.threeBoxController.init() + await this.threeBoxController.init(); } /** @@ -2510,13 +2524,13 @@ export default class MetamaskController extends EventEmitter { */ setUseBlockie(val, cb) { try { - this.preferencesController.setUseBlockie(val) - cb(null) - return + this.preferencesController.setUseBlockie(val); + cb(null); + return; } catch (err) { - cb(err) + cb(err); // eslint-disable-next-line no-useless-return - return + return; } } @@ -2527,13 +2541,13 @@ export default class MetamaskController extends EventEmitter { */ setUseNonceField(val, cb) { try { - this.preferencesController.setUseNonceField(val) - cb(null) - return + this.preferencesController.setUseNonceField(val); + cb(null); + return; } catch (err) { - cb(err) + cb(err); // eslint-disable-next-line no-useless-return - return + return; } } @@ -2544,13 +2558,13 @@ export default class MetamaskController extends EventEmitter { */ setUsePhishDetect(val, cb) { try { - this.preferencesController.setUsePhishDetect(val) - cb(null) - return + this.preferencesController.setUsePhishDetect(val); + cb(null); + return; } catch (err) { - cb(err) + cb(err); // eslint-disable-next-line no-useless-return - return + return; } } @@ -2561,13 +2575,13 @@ export default class MetamaskController extends EventEmitter { */ setIpfsGateway(val, cb) { try { - this.preferencesController.setIpfsGateway(val) - cb(null) - return + this.preferencesController.setIpfsGateway(val); + cb(null); + return; } catch (err) { - cb(err) + cb(err); // eslint-disable-next-line no-useless-return - return + return; } } @@ -2580,25 +2594,25 @@ export default class MetamaskController extends EventEmitter { try { const metaMetricsId = this.metaMetricsController.setParticipateInMetaMetrics( bool, - ) - cb(null, metaMetricsId) - return + ); + cb(null, metaMetricsId); + return; } catch (err) { - cb(err) + cb(err); // eslint-disable-next-line no-useless-return - return + return; } } setMetaMetricsSendCount(val, cb) { try { - this.metaMetricsController.setMetaMetricsSendCount(val) - cb(null) - return + this.metaMetricsController.setMetaMetricsSendCount(val); + cb(null); + return; } catch (err) { - cb(err) + cb(err); // eslint-disable-next-line no-useless-return - return + return; } } @@ -2609,13 +2623,13 @@ export default class MetamaskController extends EventEmitter { */ setFirstTimeFlowType(type, cb) { try { - this.preferencesController.setFirstTimeFlowType(type) - cb(null) - return + this.preferencesController.setFirstTimeFlowType(type); + cb(null); + return; } catch (err) { - cb(err) + cb(err); // eslint-disable-next-line no-useless-return - return + return; } } @@ -2626,13 +2640,13 @@ export default class MetamaskController extends EventEmitter { */ setCurrentLocale(key, cb) { try { - const direction = this.preferencesController.setCurrentLocale(key) - cb(null, direction) - return + const direction = this.preferencesController.setCurrentLocale(key); + cb(null, direction); + return; } catch (err) { - cb(err) + cb(err); // eslint-disable-next-line no-useless-return - return + return; } } @@ -2643,11 +2657,11 @@ export default class MetamaskController extends EventEmitter { */ recordFirstTimeInfo(initState) { if (!('firstTimeInfo' in initState)) { - const version = this.platform.getVersion() + const version = this.platform.getVersion(); initState.firstTimeInfo = { version, date: Date.now(), - } + }; } } @@ -2659,8 +2673,8 @@ export default class MetamaskController extends EventEmitter { * @param {boolean} open */ set isClientOpen(open) { - this._isClientOpen = open - this.detectTokensController.isOpen = open + this._isClientOpen = open; + this.detectTokensController.isOpen = open; } /* eslint-enable accessor-pairs */ @@ -2669,13 +2683,13 @@ export default class MetamaskController extends EventEmitter { * @param {string} hostname - the domain to safelist */ safelistPhishingDomain(hostname) { - return this.phishingController.bypass(hostname) + return this.phishingController.bypass(hostname); } /** * Locks MetaMask */ setLocked() { - return this.keyringController.setLocked() + return this.keyringController.setLocked(); } } diff --git a/app/scripts/migrations/002.js b/app/scripts/migrations/002.js index 9de898f832..5c8543eff0 100644 --- a/app/scripts/migrations/002.js +++ b/app/scripts/migrations/002.js @@ -1,22 +1,22 @@ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 2 +const version = 2; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { if (versionedData.data.config.provider.type === 'etherscan') { - versionedData.data.config.provider.type = 'rpc' + versionedData.data.config.provider.type = 'rpc'; versionedData.data.config.provider.rpcTarget = - 'https://rpc.metamask.io/' + 'https://rpc.metamask.io/'; } } catch (_) { // empty } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; diff --git a/app/scripts/migrations/003.js b/app/scripts/migrations/003.js index 8859f2a0fe..3b6b76e12a 100644 --- a/app/scripts/migrations/003.js +++ b/app/scripts/migrations/003.js @@ -1,22 +1,22 @@ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 3 -const oldTestRpc = 'https://rawtestrpc.metamask.io/' -const newTestRpc = 'https://testrpc.metamask.io/' +const version = 3; +const oldTestRpc = 'https://rawtestrpc.metamask.io/'; +const newTestRpc = 'https://testrpc.metamask.io/'; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { if (versionedData.data.config.provider.rpcTarget === oldTestRpc) { - versionedData.data.config.provider.rpcTarget = newTestRpc + versionedData.data.config.provider.rpcTarget = newTestRpc; } } catch (_) { // empty } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; diff --git a/app/scripts/migrations/004.js b/app/scripts/migrations/004.js index c571e8fd15..49dc444ca0 100644 --- a/app/scripts/migrations/004.js +++ b/app/scripts/migrations/004.js @@ -1,33 +1,33 @@ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 4 +const version = 4; export default { version, migrate(versionedData) { - const safeVersionedData = cloneDeep(versionedData) - safeVersionedData.meta.version = version + const safeVersionedData = cloneDeep(versionedData); + safeVersionedData.meta.version = version; try { if (safeVersionedData.data.config.provider.type !== 'rpc') { - return Promise.resolve(safeVersionedData) + return Promise.resolve(safeVersionedData); } switch (safeVersionedData.data.config.provider.rpcTarget) { case 'https://testrpc.metamask.io/': safeVersionedData.data.config.provider = { type: 'testnet', - } - break + }; + break; case 'https://rpc.metamask.io/': safeVersionedData.data.config.provider = { type: 'mainnet', - } - break + }; + break; // No default } } catch (_) { // empty } - return Promise.resolve(safeVersionedData) + return Promise.resolve(safeVersionedData); }, -} +}; diff --git a/app/scripts/migrations/005.js b/app/scripts/migrations/005.js index 757462353a..c455946460 100644 --- a/app/scripts/migrations/005.js +++ b/app/scripts/migrations/005.js @@ -4,29 +4,29 @@ This migration moves state from the flat state trie into KeyringController subst */ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 5 +const version = 5; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { - const state = versionedData.data - const newState = selectSubstateForKeyringController(state) - versionedData.data = newState + const state = versionedData.data; + const newState = selectSubstateForKeyringController(state); + versionedData.data = newState; } catch (err) { - console.warn(`MetaMask Migration #5${err.stack}`) + console.warn(`MetaMask Migration #5${err.stack}`); } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; function selectSubstateForKeyringController(state) { - const { config } = state + const { config } = state; const newState = { ...state, KeyringController: { @@ -34,10 +34,10 @@ function selectSubstateForKeyringController(state) { selectedAccount: config.selectedAccount, walletNicknames: state.walletNicknames, }, - } - delete newState.vault - delete newState.walletNicknames - delete newState.config.selectedAccount + }; + delete newState.vault; + delete newState.walletNicknames; + delete newState.config.selectedAccount; - return newState + return newState; } diff --git a/app/scripts/migrations/006.js b/app/scripts/migrations/006.js index 90ff3f2cbe..d8c2b48fd8 100644 --- a/app/scripts/migrations/006.js +++ b/app/scripts/migrations/006.js @@ -4,29 +4,29 @@ This migration moves KeyringController.selectedAddress to PreferencesController. */ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 6 +const version = 6; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { - const state = versionedData.data - const newState = migrateState(state) - versionedData.data = newState + const state = versionedData.data; + const newState = migrateState(state); + versionedData.data = newState; } catch (err) { - console.warn(`MetaMask Migration #${version}${err.stack}`) + console.warn(`MetaMask Migration #${version}${err.stack}`); } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; function migrateState(state) { - const keyringSubstate = state.KeyringController + const keyringSubstate = state.KeyringController; // add new state const newState = { @@ -34,10 +34,10 @@ function migrateState(state) { PreferencesController: { selectedAddress: keyringSubstate.selectedAccount, }, - } + }; // rm old state - delete newState.KeyringController.selectedAccount + delete newState.KeyringController.selectedAccount; - return newState + return newState; } diff --git a/app/scripts/migrations/007.js b/app/scripts/migrations/007.js index cea831b7ef..73ed80df36 100644 --- a/app/scripts/migrations/007.js +++ b/app/scripts/migrations/007.js @@ -4,26 +4,26 @@ This migration breaks out the TransactionManager substate */ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 7 +const version = 7; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; } catch (err) { - console.warn(`MetaMask Migration #${version}${err.stack}`) + console.warn(`MetaMask Migration #${version}${err.stack}`); } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; function transformState(state) { const newState = { @@ -32,9 +32,9 @@ function transformState(state) { transactions: state.transactions || [], gasMultiplier: state.gasMultiplier || 1, }, - } - delete newState.transactions - delete newState.gasMultiplier + }; + delete newState.transactions; + delete newState.gasMultiplier; - return newState + return newState; } diff --git a/app/scripts/migrations/008.js b/app/scripts/migrations/008.js index ce8ab37ce4..d27d368825 100644 --- a/app/scripts/migrations/008.js +++ b/app/scripts/migrations/008.js @@ -4,26 +4,26 @@ This migration breaks out the NoticeController substate */ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 8 +const version = 8; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; } catch (err) { - console.warn(`MetaMask Migration #${version}${err.stack}`) + console.warn(`MetaMask Migration #${version}${err.stack}`); } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; function transformState(state) { const newState = { @@ -31,8 +31,8 @@ function transformState(state) { NoticeController: { noticesList: state.noticesList || [], }, - } - delete newState.noticesList + }; + delete newState.noticesList; - return newState + return newState; } diff --git a/app/scripts/migrations/009.js b/app/scripts/migrations/009.js index 2d1370bfcd..5d8e094ab5 100644 --- a/app/scripts/migrations/009.js +++ b/app/scripts/migrations/009.js @@ -4,26 +4,26 @@ This migration breaks out the CurrencyController substate */ -import { cloneDeep, merge } from 'lodash' +import { cloneDeep, merge } from 'lodash'; -const version = 9 +const version = 9; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; } catch (err) { - console.warn(`MetaMask Migration #${version}${err.stack}`) + console.warn(`MetaMask Migration #${version}${err.stack}`); } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; function transformState(state) { const newState = merge({}, state, { @@ -32,11 +32,11 @@ function transformState(state) { conversionRate: state.conversionRate, conversionDate: state.conversionDate, }, - }) - delete newState.currentFiat - delete newState.fiatCurrency - delete newState.conversionRate - delete newState.conversionDate + }); + delete newState.currentFiat; + delete newState.fiatCurrency; + delete newState.conversionRate; + delete newState.conversionDate; - return newState + return newState; } diff --git a/app/scripts/migrations/010.js b/app/scripts/migrations/010.js index 053af2562a..2d28691a53 100644 --- a/app/scripts/migrations/010.js +++ b/app/scripts/migrations/010.js @@ -4,34 +4,34 @@ This migration breaks out the ShapeShiftController substate */ -import { cloneDeep, merge } from 'lodash' +import { cloneDeep, merge } from 'lodash'; -const version = 10 +const version = 10; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; } catch (err) { - console.warn(`MetaMask Migration #${version}${err.stack}`) + console.warn(`MetaMask Migration #${version}${err.stack}`); } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; function transformState(state) { const newState = merge({}, state, { ShapeShiftController: { shapeShiftTxList: state.shapeShiftTxList || [], }, - }) - delete newState.shapeShiftTxList + }); + delete newState.shapeShiftTxList; - return newState + return newState; } diff --git a/app/scripts/migrations/011.js b/app/scripts/migrations/011.js index 1e1884825e..feae3d1006 100644 --- a/app/scripts/migrations/011.js +++ b/app/scripts/migrations/011.js @@ -4,30 +4,30 @@ This migration removes the discaimer state from our app, which was integrated in */ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 11 +const version = 11; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; } catch (err) { - console.warn(`MetaMask Migration #${version}${err.stack}`) + console.warn(`MetaMask Migration #${version}${err.stack}`); } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; function transformState(state) { - const newState = state - delete newState.TOSHash - delete newState.isDisclaimerConfirmed - return newState + const newState = state; + delete newState.TOSHash; + delete newState.isDisclaimerConfirmed; + return newState; } diff --git a/app/scripts/migrations/012.js b/app/scripts/migrations/012.js index 3a42992ee6..57e339107c 100644 --- a/app/scripts/migrations/012.js +++ b/app/scripts/migrations/012.js @@ -4,33 +4,33 @@ This migration modifies our notices to delete their body after being read. */ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 12 +const version = 12; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; } catch (err) { - console.warn(`MetaMask Migration #${version}${err.stack}`) + console.warn(`MetaMask Migration #${version}${err.stack}`); } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; function transformState(state) { - const newState = state + const newState = state; newState.NoticeController.noticesList.forEach((notice) => { if (notice.read) { - notice.body = '' + notice.body = ''; } - }) - return newState + }); + return newState; } diff --git a/app/scripts/migrations/013.js b/app/scripts/migrations/013.js index 5c27496dce..f36fa0f1ca 100644 --- a/app/scripts/migrations/013.js +++ b/app/scripts/migrations/013.js @@ -4,34 +4,34 @@ This migration modifies the network config from ambiguous 'testnet' to explicit */ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 13 +const version = 13; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; } catch (err) { - console.warn(`MetaMask Migration #${version}${err.stack}`) + console.warn(`MetaMask Migration #${version}${err.stack}`); } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; function transformState(state) { - const newState = state - const { config } = newState + const newState = state; + const { config } = newState; if (config && config.provider) { if (config.provider.type === 'testnet') { - newState.config.provider.type = 'ropsten' + newState.config.provider.type = 'ropsten'; } } - return newState + return newState; } diff --git a/app/scripts/migrations/014.js b/app/scripts/migrations/014.js index 0a26fcea4b..22eeccdb8b 100644 --- a/app/scripts/migrations/014.js +++ b/app/scripts/migrations/014.js @@ -4,31 +4,31 @@ This migration removes provider from config and moves it too NetworkController. */ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 14 +const version = 14; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; } catch (err) { - console.warn(`MetaMask Migration #${version}${err.stack}`) + console.warn(`MetaMask Migration #${version}${err.stack}`); } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; function transformState(state) { - const newState = state - newState.NetworkController = {} - newState.NetworkController.provider = newState.config.provider - delete newState.config.provider - return newState + const newState = state; + newState.NetworkController = {}; + newState.NetworkController.provider = newState.config.provider; + delete newState.config.provider; + return newState; } diff --git a/app/scripts/migrations/015.js b/app/scripts/migrations/015.js index f10ee9fd9f..f2783cebb8 100644 --- a/app/scripts/migrations/015.js +++ b/app/scripts/migrations/015.js @@ -5,41 +5,41 @@ to a 'failed' stated */ -import { cloneDeep } from 'lodash' -import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' +import { cloneDeep } from 'lodash'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; -const version = 15 +const version = 15; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; } catch (err) { - console.warn(`MetaMask Migration #${version}${err.stack}`) + console.warn(`MetaMask Migration #${version}${err.stack}`); } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; function transformState(state) { - const newState = state - const { TransactionController } = newState + const newState = state; + const { TransactionController } = newState; if (TransactionController && TransactionController.transactions) { - const { transactions } = TransactionController + const { transactions } = TransactionController; newState.TransactionController.transactions = transactions.map((txMeta) => { if (!txMeta.err) { - return txMeta + return txMeta; } else if (txMeta.err.message === 'Gave up submitting tx.') { - txMeta.status = TRANSACTION_STATUSES.FAILED + txMeta.status = TRANSACTION_STATUSES.FAILED; } - return txMeta - }) + return txMeta; + }); } - return newState + return newState; } diff --git a/app/scripts/migrations/016.js b/app/scripts/migrations/016.js index 3f3d3973c9..542ebe81ac 100644 --- a/app/scripts/migrations/016.js +++ b/app/scripts/migrations/016.js @@ -5,46 +5,46 @@ to a 'failed' stated */ -import { cloneDeep } from 'lodash' -import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' +import { cloneDeep } from 'lodash'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; -const version = 16 +const version = 16; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; } catch (err) { - console.warn(`MetaMask Migration #${version}${err.stack}`) + console.warn(`MetaMask Migration #${version}${err.stack}`); } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; function transformState(state) { - const newState = state - const { TransactionController } = newState + const newState = state; + const { TransactionController } = newState; if (TransactionController && TransactionController.transactions) { - const { transactions } = newState.TransactionController + const { transactions } = newState.TransactionController; newState.TransactionController.transactions = transactions.map((txMeta) => { if (!txMeta.err) { - return txMeta + return txMeta; } if ( txMeta.err === 'transaction with the same hash was already imported.' ) { - txMeta.status = TRANSACTION_STATUSES.SUBMITTED - delete txMeta.err + txMeta.status = TRANSACTION_STATUSES.SUBMITTED; + delete txMeta.err; } - return txMeta - }) + return txMeta; + }); } - return newState + return newState; } diff --git a/app/scripts/migrations/017.js b/app/scripts/migrations/017.js index d6814dd8c4..8d510b8577 100644 --- a/app/scripts/migrations/017.js +++ b/app/scripts/migrations/017.js @@ -4,43 +4,43 @@ This migration sets transactions who were retried and marked as failed to submit */ -import { cloneDeep } from 'lodash' -import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' +import { cloneDeep } from 'lodash'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; -const version = 17 +const version = 17; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; } catch (err) { - console.warn(`MetaMask Migration #${version}${err.stack}`) + console.warn(`MetaMask Migration #${version}${err.stack}`); } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; function transformState(state) { - const newState = state - const { TransactionController } = newState + const newState = state; + const { TransactionController } = newState; if (TransactionController && TransactionController.transactions) { - const { transactions } = newState.TransactionController + const { transactions } = newState.TransactionController; newState.TransactionController.transactions = transactions.map((txMeta) => { if (!txMeta.status === TRANSACTION_STATUSES.FAILED) { - return txMeta + return txMeta; } if (txMeta.retryCount > 0 && txMeta.retryCount < 2) { - txMeta.status = TRANSACTION_STATUSES.SUBMITTED - delete txMeta.err + txMeta.status = TRANSACTION_STATUSES.SUBMITTED; + delete txMeta.err; } - return txMeta - }) + return txMeta; + }); } - return newState + return newState; } diff --git a/app/scripts/migrations/018.js b/app/scripts/migrations/018.js index 5a616514ce..10bc9fa698 100644 --- a/app/scripts/migrations/018.js +++ b/app/scripts/migrations/018.js @@ -4,52 +4,52 @@ This migration updates "transaction state history" to diffs style */ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; import { snapshotFromTxMeta, migrateFromSnapshotsToDiffs, -} from '../controllers/transactions/lib/tx-state-history-helpers' +} from '../controllers/transactions/lib/tx-state-history-helpers'; -const version = 18 +const version = 18; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; } catch (err) { - console.warn(`MetaMask Migration #${version}${err.stack}`) + console.warn(`MetaMask Migration #${version}${err.stack}`); } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; function transformState(state) { - const newState = state - const { TransactionController } = newState + const newState = state; + const { TransactionController } = newState; if (TransactionController && TransactionController.transactions) { - const { transactions } = newState.TransactionController + const { transactions } = newState.TransactionController; newState.TransactionController.transactions = transactions.map((txMeta) => { // no history: initialize if (!txMeta.history || txMeta.history.length === 0) { - const snapshot = snapshotFromTxMeta(txMeta) - txMeta.history = [snapshot] - return txMeta + const snapshot = snapshotFromTxMeta(txMeta); + txMeta.history = [snapshot]; + return txMeta; } // has history: migrate const newHistory = migrateFromSnapshotsToDiffs(txMeta.history) // remove empty diffs .filter((entry) => { - return !Array.isArray(entry) || entry.length > 0 - }) - txMeta.history = newHistory - return txMeta - }) + return !Array.isArray(entry) || entry.length > 0; + }); + txMeta.history = newHistory; + return txMeta; + }); } - return newState + return newState; } diff --git a/app/scripts/migrations/019.js b/app/scripts/migrations/019.js index d8cb5f73e3..828795e6fc 100644 --- a/app/scripts/migrations/019.js +++ b/app/scripts/migrations/019.js @@ -5,38 +5,38 @@ whos nonce is too high */ -import { cloneDeep } from 'lodash' -import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' +import { cloneDeep } from 'lodash'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; -const version = 19 +const version = 19; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; } catch (err) { - console.warn(`MetaMask Migration #${version}${err.stack}`) + console.warn(`MetaMask Migration #${version}${err.stack}`); } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; function transformState(state) { - const newState = state - const { TransactionController } = newState + const newState = state; + const { TransactionController } = newState; if (TransactionController && TransactionController.transactions) { - const { transactions } = newState.TransactionController + const { transactions } = newState.TransactionController; newState.TransactionController.transactions = transactions.map( (txMeta, _, txList) => { if (txMeta.status !== TRANSACTION_STATUSES.SUBMITTED) { - return txMeta + return txMeta; } const confirmedTxs = txList @@ -44,55 +44,58 @@ function transformState(state) { .filter((tx) => tx.txParams.from === txMeta.txParams.from) .filter( (tx) => tx.metamaskNetworkId.from === txMeta.metamaskNetworkId.from, - ) - const highestConfirmedNonce = getHighestNonce(confirmedTxs) + ); + const highestConfirmedNonce = getHighestNonce(confirmedTxs); const pendingTxs = txList .filter((tx) => tx.status === TRANSACTION_STATUSES.SUBMITTED) .filter((tx) => tx.txParams.from === txMeta.txParams.from) .filter( (tx) => tx.metamaskNetworkId.from === txMeta.metamaskNetworkId.from, - ) + ); const highestContinuousNonce = getHighestContinuousFrom( pendingTxs, highestConfirmedNonce, - ) + ); - const maxNonce = Math.max(highestContinuousNonce, highestConfirmedNonce) + const maxNonce = Math.max( + highestContinuousNonce, + highestConfirmedNonce, + ); if (parseInt(txMeta.txParams.nonce, 16) > maxNonce + 1) { - txMeta.status = TRANSACTION_STATUSES.FAILED + txMeta.status = TRANSACTION_STATUSES.FAILED; txMeta.err = { message: 'nonce too high', note: 'migration 019 custom error', - } + }; } - return txMeta + return txMeta; }, - ) + ); } - return newState + return newState; } function getHighestContinuousFrom(txList, startPoint) { const nonces = txList.map((txMeta) => { - const { nonce } = txMeta.txParams - return parseInt(nonce, 16) - }) + const { nonce } = txMeta.txParams; + return parseInt(nonce, 16); + }); - let highest = startPoint + let highest = startPoint; while (nonces.includes(highest)) { - highest += 1 + highest += 1; } - return highest + return highest; } function getHighestNonce(txList) { const nonces = txList.map((txMeta) => { - const { nonce } = txMeta.txParams - return parseInt(nonce || '0x0', 16) - }) - const highestNonce = Math.max.apply(null, nonces) - return highestNonce + const { nonce } = txMeta.txParams; + return parseInt(nonce || '0x0', 16); + }); + const highestNonce = Math.max.apply(null, nonces); + return highestNonce; } diff --git a/app/scripts/migrations/020.js b/app/scripts/migrations/020.js index b2a28cb7ac..04884eb41e 100644 --- a/app/scripts/migrations/020.js +++ b/app/scripts/migrations/020.js @@ -6,34 +6,34 @@ so that we can version notices in the future. */ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 20 +const version = 20; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; } catch (err) { - console.warn(`MetaMask Migration #${version}${err.stack}`) + console.warn(`MetaMask Migration #${version}${err.stack}`); } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; function transformState(state) { - const newState = state + const newState = state; if ('metamask' in newState && !('firstTimeInfo' in newState.metamask)) { newState.metamask.firstTimeInfo = { version: '3.12.0', date: Date.now(), - } + }; } - return newState + return newState; } diff --git a/app/scripts/migrations/021.js b/app/scripts/migrations/021.js index 4783d6ed90..2ae40183c8 100644 --- a/app/scripts/migrations/021.js +++ b/app/scripts/migrations/021.js @@ -4,30 +4,30 @@ This migration removes the BlackListController from disk state */ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 21 +const version = 21; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; } catch (err) { - console.warn(`MetaMask Migration #${version}${err.stack}`) + console.warn(`MetaMask Migration #${version}${err.stack}`); } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; function transformState(state) { - const newState = state - delete newState.BlacklistController - delete newState.RecentBlocks - return newState + const newState = state; + delete newState.BlacklistController; + delete newState.RecentBlocks; + return newState; } diff --git a/app/scripts/migrations/022.js b/app/scripts/migrations/022.js index cb1b4335f1..d0477b0d16 100644 --- a/app/scripts/migrations/022.js +++ b/app/scripts/migrations/022.js @@ -4,44 +4,44 @@ This migration adds submittedTime to the txMeta if it is not their */ -import { cloneDeep } from 'lodash' -import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' +import { cloneDeep } from 'lodash'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; -const version = 22 +const version = 22; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; } catch (err) { - console.warn(`MetaMask Migration #${version}${err.stack}`) + console.warn(`MetaMask Migration #${version}${err.stack}`); } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; function transformState(state) { - const newState = state - const { TransactionController } = newState + const newState = state; + const { TransactionController } = newState; if (TransactionController && TransactionController.transactions) { - const { transactions } = newState.TransactionController + const { transactions } = newState.TransactionController; newState.TransactionController.transactions = transactions.map((txMeta) => { if ( txMeta.status !== TRANSACTION_STATUSES.SUBMITTED || txMeta.submittedTime ) { - return txMeta + return txMeta; } - txMeta.submittedTime = new Date().getTime() - return txMeta - }) + txMeta.submittedTime = new Date().getTime(); + return txMeta; + }); } - return newState + return newState; } diff --git a/app/scripts/migrations/023.js b/app/scripts/migrations/023.js index 531a73e13a..4ec54b1388 100644 --- a/app/scripts/migrations/023.js +++ b/app/scripts/migrations/023.js @@ -4,41 +4,41 @@ This migration removes transactions that are no longer usefull down to 40 total */ -import { cloneDeep } from 'lodash' -import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' +import { cloneDeep } from 'lodash'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; -const version = 23 +const version = 23; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; } catch (err) { - console.warn(`MetaMask Migration #${version}${err.stack}`) + console.warn(`MetaMask Migration #${version}${err.stack}`); } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; function transformState(state) { - const newState = state + const newState = state; - const { TransactionController } = newState + const { TransactionController } = newState; if (TransactionController && TransactionController.transactions) { - const { transactions } = newState.TransactionController + const { transactions } = newState.TransactionController; if (transactions.length <= 40) { - return newState + return newState; } - const reverseTxList = transactions.reverse() - let stripping = true + const reverseTxList = transactions.reverse(); + let stripping = true; while (reverseTxList.length > 40 && stripping) { const txIndex = reverseTxList.findIndex((txMeta) => { return ( @@ -46,16 +46,16 @@ function transformState(state) { txMeta.status === TRANSACTION_STATUSES.REJECTED || txMeta.status === TRANSACTION_STATUSES.CONFIRMED || txMeta.status === TRANSACTION_STATUSES.DROPPED - ) - }) + ); + }); if (txIndex < 0) { - stripping = false + stripping = false; } else { - reverseTxList.splice(txIndex, 1) + reverseTxList.splice(txIndex, 1); } } - newState.TransactionController.transactions = reverseTxList.reverse() + newState.TransactionController.transactions = reverseTxList.reverse(); } - return newState + return newState; } diff --git a/app/scripts/migrations/024.js b/app/scripts/migrations/024.js index b4189a4e09..1eb2100290 100644 --- a/app/scripts/migrations/024.js +++ b/app/scripts/migrations/024.js @@ -5,30 +5,30 @@ all unapproved transactions */ -import { cloneDeep } from 'lodash' -import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' +import { cloneDeep } from 'lodash'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; -const version = 24 +const version = 24; export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; + return versionedData; }, -} +}; function transformState(state) { - const newState = state + const newState = state; if (!newState.TransactionController) { - return newState + return newState; } - const { transactions } = newState.TransactionController + const { transactions } = newState.TransactionController; newState.TransactionController.transactions = transactions.map( (txMeta, _) => { if ( @@ -36,10 +36,10 @@ function transformState(state) { txMeta.txParams && txMeta.txParams.from ) { - txMeta.txParams.from = txMeta.txParams.from.toLowerCase() + txMeta.txParams.from = txMeta.txParams.from.toLowerCase(); } - return txMeta + return txMeta; }, - ) - return newState + ); + return newState; } diff --git a/app/scripts/migrations/025.js b/app/scripts/migrations/025.js index 3338ec9cf7..7ea7a00cb4 100644 --- a/app/scripts/migrations/025.js +++ b/app/scripts/migrations/025.js @@ -4,44 +4,44 @@ normalizes txParams on unconfirmed txs */ -import { cloneDeep } from 'lodash' -import { addHexPrefix } from '../lib/util' -import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' +import { cloneDeep } from 'lodash'; +import { addHexPrefix } from '../lib/util'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; -const version = 25 +const version = 25; export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; + return versionedData; }, -} +}; function transformState(state) { - const newState = state + const newState = state; if (newState.TransactionController) { if (newState.TransactionController.transactions) { - const { transactions } = newState.TransactionController + const { transactions } = newState.TransactionController; newState.TransactionController.transactions = transactions.map( (txMeta) => { if (txMeta.status !== TRANSACTION_STATUSES.UNAPPROVED) { - return txMeta + return txMeta; } - txMeta.txParams = normalizeTxParams(txMeta.txParams) - return txMeta + txMeta.txParams = normalizeTxParams(txMeta.txParams); + return txMeta; }, - ) + ); } } - return newState + return newState; } function normalizeTxParams(txParams) { @@ -54,15 +54,15 @@ function normalizeTxParams(txParams) { data: (data) => addHexPrefix(data), gas: (gas) => addHexPrefix(gas), gasPrice: (gasPrice) => addHexPrefix(gasPrice), - } + }; // apply only keys in the whiteList - const normalizedTxParams = {} + const normalizedTxParams = {}; Object.keys(whiteList).forEach((key) => { if (txParams[key]) { - normalizedTxParams[key] = whiteList[key](txParams[key]) + normalizedTxParams[key] = whiteList[key](txParams[key]); } - }) + }); - return normalizedTxParams + return normalizedTxParams; } diff --git a/app/scripts/migrations/026.js b/app/scripts/migrations/026.js index c237cce1c6..a141343d08 100644 --- a/app/scripts/migrations/026.js +++ b/app/scripts/migrations/026.js @@ -5,33 +5,33 @@ This migration moves the identities stored in the KeyringController */ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 26 +const version = 26; export default { version, migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { - const state = versionedData.data - versionedData.data = transformState(state) + const state = versionedData.data; + versionedData.data = transformState(state); } catch (err) { - console.warn(`MetaMask Migration #${version}${err.stack}`) - return Promise.reject(err) + console.warn(`MetaMask Migration #${version}${err.stack}`); + return Promise.reject(err); } - return Promise.resolve(versionedData) + return Promise.resolve(versionedData); }, -} +}; function transformState(state) { if (!state.KeyringController || !state.PreferencesController) { - return state + return state; } if (!state.KeyringController.walletNicknames) { - return state + return state; } state.PreferencesController.identities = Object.keys( @@ -40,9 +40,9 @@ function transformState(state) { identities[address] = { name: state.KeyringController.walletNicknames[address], address, - } - return identities - }, {}) - delete state.KeyringController.walletNicknames - return state + }; + return identities; + }, {}); + delete state.KeyringController.walletNicknames; + return state; } diff --git a/app/scripts/migrations/027.js b/app/scripts/migrations/027.js index 09d5a00e83..a067e00848 100644 --- a/app/scripts/migrations/027.js +++ b/app/scripts/migrations/027.js @@ -4,35 +4,35 @@ normalizes txParams on unconfirmed txs */ -import { cloneDeep } from 'lodash' -import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' +import { cloneDeep } from 'lodash'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; -const version = 27 +const version = 27; export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; + return versionedData; }, -} +}; function transformState(state) { - const newState = state + const newState = state; if (newState.TransactionController) { if (newState.TransactionController.transactions) { - const { transactions } = newState.TransactionController + const { transactions } = newState.TransactionController; newState.TransactionController.transactions = transactions.filter( (txMeta) => txMeta.status !== TRANSACTION_STATUSES.REJECTED, - ) + ); } } - return newState + return newState; } diff --git a/app/scripts/migrations/028.js b/app/scripts/migrations/028.js index 8f83bda042..8ee590e22c 100644 --- a/app/scripts/migrations/028.js +++ b/app/scripts/migrations/028.js @@ -4,41 +4,41 @@ normalizes txParams on unconfirmed txs */ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 28 +const version = 28; export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; + return versionedData; }, -} +}; function transformState(state) { - const newState = state + const newState = state; if (newState.PreferencesController) { if ( newState.PreferencesController.tokens && newState.PreferencesController.identities ) { - const { identities, tokens } = newState.PreferencesController - newState.PreferencesController.accountTokens = {} + const { identities, tokens } = newState.PreferencesController; + newState.PreferencesController.accountTokens = {}; Object.keys(identities).forEach((identity) => { newState.PreferencesController.accountTokens[identity] = { mainnet: tokens, - } - }) - newState.PreferencesController.tokens = [] + }; + }); + newState.PreferencesController.tokens = []; } } - return newState + return newState; } diff --git a/app/scripts/migrations/029.js b/app/scripts/migrations/029.js index 242cc995bc..af70ee899e 100644 --- a/app/scripts/migrations/029.js +++ b/app/scripts/migrations/029.js @@ -1,14 +1,14 @@ // next version number -import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' -import failTxsThat from './fail-tx' +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; +import failTxsThat from './fail-tx'; -const version = 29 +const version = 29; // time -const seconds = 1000 -const minutes = 60 * seconds -const hours = 60 * minutes -const unacceptableDelay = 12 * hours +const seconds = 1000; +const minutes = 60 * seconds; +const hours = 60 * minutes; +const unacceptableDelay = 12 * hours; /* @@ -23,10 +23,10 @@ export default { version, 'Stuck in approved state for too long.', (txMeta) => { - const isApproved = txMeta.status === TRANSACTION_STATUSES.APPROVED - const createdTime = txMeta.submittedTime - const now = Date.now() - return isApproved && now - createdTime > unacceptableDelay + const isApproved = txMeta.status === TRANSACTION_STATUSES.APPROVED; + const createdTime = txMeta.submittedTime; + const now = Date.now(); + return isApproved && now - createdTime > unacceptableDelay; }, ), -} +}; diff --git a/app/scripts/migrations/030.js b/app/scripts/migrations/030.js index 1062cbaf22..31dc1cf6ed 100644 --- a/app/scripts/migrations/030.js +++ b/app/scripts/migrations/030.js @@ -5,35 +5,35 @@ removes invalid chaids from preferences and networkController for custom rpcs */ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 30 +const version = 30; export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; + return versionedData; }, -} +}; function transformState(state) { - const newState = state + const newState = state; if (state.PreferencesController) { - const { frequentRpcListDetail } = newState.PreferencesController + const { frequentRpcListDetail } = newState.PreferencesController; if (frequentRpcListDetail) { frequentRpcListDetail.forEach((rpc, index) => { // eslint-disable-next-line radix if (Boolean(rpc.chainId) && Number.isNaN(parseInt(rpc.chainId))) { - delete frequentRpcListDetail[index].chainId + delete frequentRpcListDetail[index].chainId; } - }) - newState.PreferencesController.frequentRpcListDetail = frequentRpcListDetail + }); + newState.PreferencesController.frequentRpcListDetail = frequentRpcListDetail; } } if (state.NetworkController) { @@ -42,7 +42,7 @@ function transformState(state) { // eslint-disable-next-line radix Number.isNaN(parseInt(newState.NetworkController.network)) ) { - delete newState.NetworkController.network + delete newState.NetworkController.network; } if ( @@ -51,9 +51,9 @@ function transformState(state) { // eslint-disable-next-line radix Number.isNaN(parseInt(newState.NetworkController.provider.chainId)) ) { - delete newState.NetworkController.provider.chainId + delete newState.NetworkController.provider.chainId; } } - return newState + return newState; } diff --git a/app/scripts/migrations/031.js b/app/scripts/migrations/031.js index 87eea11fa9..904e2da4f8 100644 --- a/app/scripts/migrations/031.js +++ b/app/scripts/migrations/031.js @@ -1,7 +1,7 @@ // next version number -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 31 +const version = 31; /* * The purpose of this migration is to properly set the completedOnboarding flag based on the state @@ -11,22 +11,22 @@ export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; + return versionedData; }, -} +}; function transformState(state) { - const { KeyringController, PreferencesController } = state + const { KeyringController, PreferencesController } = state; if (KeyringController && PreferencesController) { - const { vault } = KeyringController - PreferencesController.completedOnboarding = Boolean(vault) + const { vault } = KeyringController; + PreferencesController.completedOnboarding = Boolean(vault); } - return state + return state; } diff --git a/app/scripts/migrations/032.js b/app/scripts/migrations/032.js index facdf10722..0f3ceab393 100644 --- a/app/scripts/migrations/032.js +++ b/app/scripts/migrations/032.js @@ -1,6 +1,6 @@ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 32 +const version = 32; /** * The purpose of this migration is to set the {@code completedUiMigration} flag based on the user's UI preferences @@ -8,23 +8,23 @@ const version = 32 export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - versionedData.data = transformState(state) - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + versionedData.data = transformState(state); + return versionedData; }, -} +}; function transformState(state) { - const { PreferencesController } = state + const { PreferencesController } = state; if (PreferencesController) { - const { betaUI } = PreferencesController.featureFlags || {} + const { betaUI } = PreferencesController.featureFlags || {}; // Users who have been using the "beta" UI are considered to have completed the migration // as they'll see no difference in this version - PreferencesController.completedUiMigration = betaUI + PreferencesController.completedUiMigration = betaUI; } - return state + return state; } diff --git a/app/scripts/migrations/033.js b/app/scripts/migrations/033.js index 8f88ba4e1a..b815dae66c 100644 --- a/app/scripts/migrations/033.js +++ b/app/scripts/migrations/033.js @@ -5,28 +5,28 @@ Cleans up notices and assocated notice controller code */ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 33 +const version = 33; export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; + return versionedData; }, -} +}; function transformState(state) { - const newState = state + const newState = state; // transform state here if (state.NoticeController) { - delete newState.NoticeController + delete newState.NoticeController; } - return newState + return newState; } diff --git a/app/scripts/migrations/034.js b/app/scripts/migrations/034.js index 4bb2f94911..59369b1490 100644 --- a/app/scripts/migrations/034.js +++ b/app/scripts/migrations/034.js @@ -1,6 +1,6 @@ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 34 +const version = 34; /** * The purpose of this migration is to enable the {@code privacyMode} feature flag and set the user as being migrated @@ -9,29 +9,29 @@ const version = 34 export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - versionedData.data = transformState(state) - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + versionedData.data = transformState(state); + return versionedData; }, -} +}; function transformState(state) { - const { PreferencesController } = state + const { PreferencesController } = state; if (PreferencesController) { - const featureFlags = PreferencesController.featureFlags || {} + const featureFlags = PreferencesController.featureFlags || {}; if ( !featureFlags.privacyMode && typeof PreferencesController.migratedPrivacyMode === 'undefined' ) { // Mark the state has being migrated and enable Privacy Mode - PreferencesController.migratedPrivacyMode = true - featureFlags.privacyMode = true + PreferencesController.migratedPrivacyMode = true; + featureFlags.privacyMode = true; } } - return state + return state; } diff --git a/app/scripts/migrations/035.js b/app/scripts/migrations/035.js index d98f8562a1..0fa498823f 100644 --- a/app/scripts/migrations/035.js +++ b/app/scripts/migrations/035.js @@ -5,27 +5,27 @@ Removes the deprecated 'seedWords' state */ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 35 +const version = 35; export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - versionedData.data = transformState(versionedData.data) - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + versionedData.data = transformState(versionedData.data); + return versionedData; }, -} +}; function transformState(state) { if ( state.PreferencesController && state.PreferencesController.seedWords !== undefined ) { - delete state.PreferencesController.seedWords + delete state.PreferencesController.seedWords; } - return state + return state; } diff --git a/app/scripts/migrations/036.js b/app/scripts/migrations/036.js index 056f96f018..3fc055bfab 100644 --- a/app/scripts/migrations/036.js +++ b/app/scripts/migrations/036.js @@ -1,6 +1,6 @@ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 36 +const version = 36; /** * The purpose of this migration is to remove the {@code privacyMode} feature flag. @@ -8,24 +8,24 @@ const version = 36 export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - versionedData.data = transformState(state) - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + versionedData.data = transformState(state); + return versionedData; }, -} +}; function transformState(state) { - const { PreferencesController } = state + const { PreferencesController } = state; if (PreferencesController) { - const featureFlags = PreferencesController.featureFlags || {} + const featureFlags = PreferencesController.featureFlags || {}; if (typeof featureFlags.privacyMode !== 'undefined') { - delete featureFlags.privacyMode + delete featureFlags.privacyMode; } } - return state + return state; } diff --git a/app/scripts/migrations/037.js b/app/scripts/migrations/037.js index 80a166e61d..4552de1da9 100644 --- a/app/scripts/migrations/037.js +++ b/app/scripts/migrations/037.js @@ -1,7 +1,7 @@ -import { cloneDeep } from 'lodash' -import { util } from '@metamask/controllers' +import { cloneDeep } from 'lodash'; +import { util } from '@metamask/controllers'; -const version = 37 +const version = 37; /** * The purpose of this migration is to update the address book state @@ -11,43 +11,43 @@ const version = 37 export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - versionedData.data = transformState(state) - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + versionedData.data = transformState(state); + return versionedData; }, -} +}; function transformState(state) { if (state.AddressBookController) { - const ab = state.AddressBookController.addressBook + const ab = state.AddressBookController.addressBook; - const chainIds = new Set() - const newAddressBook = {} + const chainIds = new Set(); + const newAddressBook = {}; // add all of the chainIds to a set Object.values(ab).forEach((v) => { - chainIds.add(v.chainId) - }) + chainIds.add(v.chainId); + }); // fill the chainId object with the entries with the matching chainId for (const id of chainIds.values()) { // make an empty object entry for each chainId - newAddressBook[id] = {} + newAddressBook[id] = {}; for (const address in ab) { if (ab[address].chainId === id) { - ab[address].isEns = false + ab[address].isEns = false; if (util.normalizeEnsName(ab[address].name)) { - ab[address].isEns = true + ab[address].isEns = true; } - newAddressBook[id][address] = ab[address] + newAddressBook[id][address] = ab[address]; } } } - state.AddressBookController.addressBook = newAddressBook + state.AddressBookController.addressBook = newAddressBook; } - return state + return state; } diff --git a/app/scripts/migrations/038.js b/app/scripts/migrations/038.js index 9c179735b0..c533f338a7 100644 --- a/app/scripts/migrations/038.js +++ b/app/scripts/migrations/038.js @@ -1,6 +1,6 @@ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 38 +const version = 38; /** * The purpose of this migration is to assign all users to a test group for the fullScreenVsPopup a/b test @@ -8,20 +8,20 @@ const version = 38 export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - versionedData.data = transformState(state) - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + versionedData.data = transformState(state); + return versionedData; }, -} +}; function transformState(state) { - const { ABTestController: ABTestControllerState = {} } = state - const { abTests = {} } = ABTestControllerState + const { ABTestController: ABTestControllerState = {} } = state; + const { abTests = {} } = ABTestControllerState; if (abTests.fullScreenVsPopup) { - return state + return state; } return { @@ -33,5 +33,5 @@ function transformState(state) { fullScreenVsPopup: 'control', }, }, - } + }; } diff --git a/app/scripts/migrations/039.js b/app/scripts/migrations/039.js index d8bec42e48..adc8390db4 100644 --- a/app/scripts/migrations/039.js +++ b/app/scripts/migrations/039.js @@ -1,11 +1,11 @@ -import { cloneDeep } from 'lodash' -import ethUtil from 'ethereumjs-util' +import { cloneDeep } from 'lodash'; +import ethUtil from 'ethereumjs-util'; -const version = 39 +const version = 39; -const DAI_V1_CONTRACT_ADDRESS = '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359' -const DAI_V1_TOKEN_SYMBOL = 'DAI' -const SAI_TOKEN_SYMBOL = 'SAI' +const DAI_V1_CONTRACT_ADDRESS = '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359'; +const DAI_V1_TOKEN_SYMBOL = 'DAI'; +const SAI_TOKEN_SYMBOL = 'SAI'; function isOldDai(token = {}) { return ( @@ -13,7 +13,7 @@ function isOldDai(token = {}) { typeof token === 'object' && token.symbol === DAI_V1_TOKEN_SYMBOL && ethUtil.toChecksumAddress(token.address) === DAI_V1_CONTRACT_ADDRESS - ) + ); } /** @@ -26,38 +26,38 @@ function isOldDai(token = {}) { export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - versionedData.data = transformState(state) - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + versionedData.data = transformState(state); + return versionedData; }, -} +}; function transformState(state) { - const { PreferencesController } = state + const { PreferencesController } = state; if (PreferencesController) { - const tokens = PreferencesController.tokens || [] + const tokens = PreferencesController.tokens || []; if (Array.isArray(tokens)) { for (const token of tokens) { if (isOldDai(token)) { - token.symbol = SAI_TOKEN_SYMBOL + token.symbol = SAI_TOKEN_SYMBOL; } } } - const accountTokens = PreferencesController.accountTokens || {} + const accountTokens = PreferencesController.accountTokens || {}; if (accountTokens && typeof accountTokens === 'object') { for (const address of Object.keys(accountTokens)) { - const networkTokens = accountTokens[address] + const networkTokens = accountTokens[address]; if (networkTokens && typeof networkTokens === 'object') { for (const network of Object.keys(networkTokens)) { - const tokensOnNetwork = networkTokens[network] + const tokensOnNetwork = networkTokens[network]; if (Array.isArray(tokensOnNetwork)) { for (const token of tokensOnNetwork) { if (isOldDai(token)) { - token.symbol = SAI_TOKEN_SYMBOL + token.symbol = SAI_TOKEN_SYMBOL; } } } @@ -67,5 +67,5 @@ function transformState(state) { } } - return state + return state; } diff --git a/app/scripts/migrations/040.js b/app/scripts/migrations/040.js index 49f91fecda..6c91693b6d 100644 --- a/app/scripts/migrations/040.js +++ b/app/scripts/migrations/040.js @@ -1,6 +1,6 @@ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 40 +const version = 40; /** * Site connections are now managed by the PermissionsController, and the @@ -10,15 +10,15 @@ const version = 40 export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - versionedData.data = transformState(state) - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + versionedData.data = transformState(state); + return versionedData; }, -} +}; function transformState(state) { - delete state.ProviderApprovalController - return state + delete state.ProviderApprovalController; + return state; } diff --git a/app/scripts/migrations/041.js b/app/scripts/migrations/041.js index eb0964e4cd..a93c5a1155 100644 --- a/app/scripts/migrations/041.js +++ b/app/scripts/migrations/041.js @@ -1,6 +1,6 @@ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 41 +const version = 41; /** * PreferencesController.autoLogoutTimeLimit -> autoLockTimeLimit @@ -8,19 +8,19 @@ const version = 41 export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - versionedData.data = transformState(state) - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + versionedData.data = transformState(state); + return versionedData; }, -} +}; function transformState(state) { if (state.PreferencesController && state.PreferencesController.preferences) { state.PreferencesController.preferences.autoLockTimeLimit = - state.PreferencesController.preferences.autoLogoutTimeLimit - delete state.PreferencesController.preferences.autoLogoutTimeLimit + state.PreferencesController.preferences.autoLogoutTimeLimit; + delete state.PreferencesController.preferences.autoLogoutTimeLimit; } - return state + return state; } diff --git a/app/scripts/migrations/042.js b/app/scripts/migrations/042.js index ca52cada7a..5320ecf533 100644 --- a/app/scripts/migrations/042.js +++ b/app/scripts/migrations/042.js @@ -1,6 +1,6 @@ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 42 +const version = 42; /** * Initialize `connectedStatusPopoverHasBeenShown` to `false` if it hasn't yet been set, @@ -9,21 +9,21 @@ const version = 42 export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - versionedData.data = transformState(state) - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + versionedData.data = transformState(state); + return versionedData; }, -} +}; function transformState(state) { if (state.AppStateController) { - state.AppStateController.connectedStatusPopoverHasBeenShown = false + state.AppStateController.connectedStatusPopoverHasBeenShown = false; } else { state.AppStateController = { connectedStatusPopoverHasBeenShown: false, - } + }; } - return state + return state; } diff --git a/app/scripts/migrations/043.js b/app/scripts/migrations/043.js index afee378f8f..963a87549b 100644 --- a/app/scripts/migrations/043.js +++ b/app/scripts/migrations/043.js @@ -1,6 +1,6 @@ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 43 +const version = 43; /** * Remove unused 'currentAccountTab' state @@ -8,17 +8,17 @@ const version = 43 export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - versionedData.data = transformState(state) - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + versionedData.data = transformState(state); + return versionedData; }, -} +}; function transformState(state) { if (state?.PreferencesController?.currentAccountTab) { - delete state.PreferencesController.currentAccountTab + delete state.PreferencesController.currentAccountTab; } - return state + return state; } diff --git a/app/scripts/migrations/044.js b/app/scripts/migrations/044.js index a3fcf5036d..8bb3be8578 100644 --- a/app/scripts/migrations/044.js +++ b/app/scripts/migrations/044.js @@ -1,6 +1,6 @@ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 44 +const version = 44; /** * Remove unused 'mkrMigrationReminderTimestamp' state from the `AppStateController` @@ -8,20 +8,20 @@ const version = 44 export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - versionedData.data = transformState(state) - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + versionedData.data = transformState(state); + return versionedData; }, -} +}; function transformState(state) { if ( typeof state?.AppStateController?.mkrMigrationReminderTimestamp !== 'undefined' ) { - delete state.AppStateController.mkrMigrationReminderTimestamp + delete state.AppStateController.mkrMigrationReminderTimestamp; } - return state + return state; } diff --git a/app/scripts/migrations/045.js b/app/scripts/migrations/045.js index 69965845ae..50d99f3074 100644 --- a/app/scripts/migrations/045.js +++ b/app/scripts/migrations/045.js @@ -1,6 +1,6 @@ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 45 +const version = 45; /** * Replaces {@code PreferencesController.ipfsGateway} with 'dweb.link' if set @@ -8,19 +8,19 @@ const version = 45 export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - versionedData.data = transformState(state) - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + versionedData.data = transformState(state); + return versionedData; }, -} +}; -const outdatedGateways = ['ipfs.io', 'ipfs.dweb.link'] +const outdatedGateways = ['ipfs.io', 'ipfs.dweb.link']; function transformState(state) { if (outdatedGateways.includes(state?.PreferencesController?.ipfsGateway)) { - state.PreferencesController.ipfsGateway = 'dweb.link' + state.PreferencesController.ipfsGateway = 'dweb.link'; } - return state + return state; } diff --git a/app/scripts/migrations/046.js b/app/scripts/migrations/046.js index d7e2fbcec7..9aaefdaecb 100644 --- a/app/scripts/migrations/046.js +++ b/app/scripts/migrations/046.js @@ -1,6 +1,6 @@ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 46 +const version = 46; /** * Delete {@code ABTestController} state @@ -8,17 +8,17 @@ const version = 46 export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - versionedData.data = transformState(state) - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + versionedData.data = transformState(state); + return versionedData; }, -} +}; function transformState(state) { if (typeof state?.ABTestController !== 'undefined') { - delete state.ABTestController + delete state.ABTestController; } - return state + return state; } diff --git a/app/scripts/migrations/047.js b/app/scripts/migrations/047.js index 2e3fffe84e..b3d2a6fd7e 100644 --- a/app/scripts/migrations/047.js +++ b/app/scripts/migrations/047.js @@ -1,6 +1,6 @@ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 47 +const version = 47; /** * Stringify the `metamaskNetworkId` property of all transactions @@ -8,22 +8,22 @@ const version = 47 export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - versionedData.data = transformState(state) - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + versionedData.data = transformState(state); + return versionedData; }, -} +}; function transformState(state) { - const transactions = state?.TransactionController?.transactions + const transactions = state?.TransactionController?.transactions; if (Array.isArray(transactions)) { transactions.forEach((transaction) => { if (typeof transaction.metamaskNetworkId === 'number') { - transaction.metamaskNetworkId = transaction.metamaskNetworkId.toString() + transaction.metamaskNetworkId = transaction.metamaskNetworkId.toString(); } - }) + }); } - return state + return state; } diff --git a/app/scripts/migrations/048.js b/app/scripts/migrations/048.js index 4a7c1fecf0..75d80f6334 100644 --- a/app/scripts/migrations/048.js +++ b/app/scripts/migrations/048.js @@ -1,6 +1,6 @@ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 48 +const version = 48; /** * 1. Delete NetworkController.settings @@ -17,27 +17,27 @@ const version = 48 export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - versionedData.data = transformState(state) - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + versionedData.data = transformState(state); + return versionedData; }, -} +}; -const hexRegEx = /^0x[0-9a-f]+$/iu -const chainIdRegEx = /^0x[1-9a-f]+[0-9a-f]*$/iu +const hexRegEx = /^0x[0-9a-f]+$/iu; +const chainIdRegEx = /^0x[1-9a-f]+[0-9a-f]*$/iu; function transformState(state = {}) { // 1. Delete NetworkController.settings - delete state.NetworkController?.settings + delete state.NetworkController?.settings; // 2. Migrate NetworkController.provider to Rinkeby or rename rpcTarget key - const provider = state.NetworkController?.provider || {} + const provider = state.NetworkController?.provider || {}; const isCustomRpcWithInvalidChainId = provider.type === 'rpc' && (typeof provider.chainId !== 'string' || - !chainIdRegEx.test(provider.chainId)) + !chainIdRegEx.test(provider.chainId)); if (isCustomRpcWithInvalidChainId || provider.type === 'localhost') { state.NetworkController.provider = { type: 'rinkeby', @@ -46,21 +46,21 @@ function transformState(state = {}) { nickname: '', rpcPrefs: {}, ticker: 'ETH', - } + }; } else if (state.NetworkController?.provider) { if ('rpcTarget' in state.NetworkController.provider) { - const rpcUrl = state.NetworkController.provider.rpcTarget - state.NetworkController.provider.rpcUrl = rpcUrl + const rpcUrl = state.NetworkController.provider.rpcTarget; + state.NetworkController.provider.rpcUrl = rpcUrl; } - delete state.NetworkController?.provider?.rpcTarget + delete state.NetworkController?.provider?.rpcTarget; } // 3. Add localhost network to frequentRpcListDetail. if (!state.PreferencesController) { - state.PreferencesController = {} + state.PreferencesController = {}; } if (!state.PreferencesController.frequentRpcListDetail) { - state.PreferencesController.frequentRpcListDetail = [] + state.PreferencesController.frequentRpcListDetail = []; } state.PreferencesController.frequentRpcListDetail.unshift({ rpcUrl: 'http://localhost:8545', @@ -68,16 +68,16 @@ function transformState(state = {}) { ticker: 'ETH', nickname: 'Localhost 8545', rpcPrefs: {}, - }) + }); // 4. Delete CachedBalancesController.cachedBalances - delete state.CachedBalancesController?.cachedBalances + delete state.CachedBalancesController?.cachedBalances; // 5. Convert transactions metamaskNetworkId to decimal if they are hex - const transactions = state.TransactionController?.transactions + const transactions = state.TransactionController?.transactions; if (Array.isArray(transactions)) { transactions.forEach((transaction) => { - const metamaskNetworkId = transaction?.metamaskNetworkId + const metamaskNetworkId = transaction?.metamaskNetworkId; if ( typeof metamaskNetworkId === 'string' && hexRegEx.test(metamaskNetworkId) @@ -85,54 +85,54 @@ function transformState(state = {}) { transaction.metamaskNetworkId = parseInt( metamaskNetworkId, 16, - ).toString(10) + ).toString(10); } - }) + }); } // 6. Convert address book keys from decimal to hex - const addressBook = state.AddressBookController?.addressBook || {} + const addressBook = state.AddressBookController?.addressBook || {}; Object.keys(addressBook).forEach((networkKey) => { if (/^\d+$/iu.test(networkKey)) { - const chainId = `0x${parseInt(networkKey, 10).toString(16)}` - updateChainIds(addressBook[networkKey], chainId) + const chainId = `0x${parseInt(networkKey, 10).toString(16)}`; + updateChainIds(addressBook[networkKey], chainId); if (addressBook[chainId]) { - mergeAddressBookKeys(addressBook, networkKey, chainId) + mergeAddressBookKeys(addressBook, networkKey, chainId); } else { - addressBook[chainId] = addressBook[networkKey] + addressBook[chainId] = addressBook[networkKey]; } - delete addressBook[networkKey] + delete addressBook[networkKey]; } - }) + }); // 7. Delete localhost key in IncomingTransactionsController delete state.IncomingTransactionsController - ?.incomingTxLastFetchedBlocksByNetwork?.localhost + ?.incomingTxLastFetchedBlocksByNetwork?.localhost; // 8. Merge 'localhost' tokens into 'rpc' tokens - const accountTokens = state.PreferencesController?.accountTokens + const accountTokens = state.PreferencesController?.accountTokens; if (accountTokens) { Object.keys(accountTokens).forEach((account) => { - const localhostTokens = accountTokens[account]?.localhost || [] + const localhostTokens = accountTokens[account]?.localhost || []; if (localhostTokens.length > 0) { - const rpcTokens = accountTokens[account].rpc || [] + const rpcTokens = accountTokens[account].rpc || []; if (rpcTokens.length > 0) { accountTokens[account].rpc = mergeTokenArrays( localhostTokens, rpcTokens, - ) + ); } else { - accountTokens[account].rpc = localhostTokens + accountTokens[account].rpc = localhostTokens; } } - delete accountTokens[account]?.localhost - }) + delete accountTokens[account]?.localhost; + }); } - return state + return state; } /** @@ -141,14 +141,14 @@ function transformState(state = {}) { * @returns {void} */ function mergeAddressBookKeys(addressBook, networkKey, chainIdKey) { - const networkKeyEntries = addressBook[networkKey] || {} + const networkKeyEntries = addressBook[networkKey] || {}; // For the new entries, start by copying the existing entries for the chainId - const newEntries = { ...addressBook[chainIdKey] } + const newEntries = { ...addressBook[chainIdKey] }; // For each address of the old/networkId key entries Object.keys(networkKeyEntries).forEach((address) => { if (newEntries[address] && typeof newEntries[address] === 'object') { - const mergedEntry = {} + const mergedEntry = {}; // Collect all keys from both entries and merge the corresponding chainId // entry with the networkId entry @@ -158,21 +158,21 @@ function mergeAddressBookKeys(addressBook, networkKey, chainIdKey) { ]).forEach((key) => { // Use non-empty value for the current key, if any mergedEntry[key] = - newEntries[address][key] || networkKeyEntries[address]?.[key] || '' - }) + newEntries[address][key] || networkKeyEntries[address]?.[key] || ''; + }); - newEntries[address] = mergedEntry + newEntries[address] = mergedEntry; } else if ( networkKeyEntries[address] && typeof networkKeyEntries[address] === 'object' ) { // If there is no corresponding chainId entry, just use the networkId entry // directly - newEntries[address] = networkKeyEntries[address] + newEntries[address] = networkKeyEntries[address]; } - }) + }); - addressBook[chainIdKey] = newEntries + addressBook[chainIdKey] = newEntries; } /** @@ -184,9 +184,9 @@ function mergeAddressBookKeys(addressBook, networkKey, chainIdKey) { function updateChainIds(networkEntries, chainId) { Object.values(networkEntries).forEach((entry) => { if (entry && typeof entry === 'object') { - entry.chainId = chainId + entry.chainId = chainId; } - }) + }); } /** @@ -196,10 +196,10 @@ function updateChainIds(networkEntries, chainId) { * @returns {Array} */ function mergeTokenArrays(localhostTokens, rpcTokens) { - const localhostTokensMap = tokenArrayToMap(localhostTokens) - const rpcTokensMap = tokenArrayToMap(rpcTokens) + const localhostTokensMap = tokenArrayToMap(localhostTokens); + const rpcTokensMap = tokenArrayToMap(rpcTokens); - const mergedTokens = [] + const mergedTokens = []; new Set([ ...Object.keys(localhostTokensMap), ...Object.keys(rpcTokensMap), @@ -207,17 +207,17 @@ function mergeTokenArrays(localhostTokens, rpcTokens) { mergedTokens.push({ ...localhostTokensMap[tokenAddress], ...rpcTokensMap[tokenAddress], - }) - }) + }); + }); - return mergedTokens + return mergedTokens; function tokenArrayToMap(array) { return array.reduce((map, token) => { if (token?.address && typeof token?.address === 'string') { - map[token.address] = token + map[token.address] = token; } - return map - }, {}) + return map; + }, {}); } } diff --git a/app/scripts/migrations/049.js b/app/scripts/migrations/049.js index 6a9b6ea433..6b3013d829 100644 --- a/app/scripts/migrations/049.js +++ b/app/scripts/migrations/049.js @@ -1,6 +1,6 @@ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 49 +const version = 49; /** * Migrate metaMetrics state to the new MetaMetrics controller @@ -8,13 +8,13 @@ const version = 49 export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - versionedData.data = transformState(state) - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + versionedData.data = transformState(state); + return versionedData; }, -} +}; function transformState(state = {}) { if (state.PreferencesController) { @@ -22,23 +22,23 @@ function transformState(state = {}) { metaMetricsId, participateInMetaMetrics, metaMetricsSendCount, - } = state.PreferencesController - state.MetaMetricsController = state.MetaMetricsController ?? {} + } = state.PreferencesController; + state.MetaMetricsController = state.MetaMetricsController ?? {}; if (metaMetricsId !== undefined) { - state.MetaMetricsController.metaMetricsId = metaMetricsId - delete state.PreferencesController.metaMetricsId + state.MetaMetricsController.metaMetricsId = metaMetricsId; + delete state.PreferencesController.metaMetricsId; } if (participateInMetaMetrics !== undefined) { - state.MetaMetricsController.participateInMetaMetrics = participateInMetaMetrics - delete state.PreferencesController.participateInMetaMetrics + state.MetaMetricsController.participateInMetaMetrics = participateInMetaMetrics; + delete state.PreferencesController.participateInMetaMetrics; } if (metaMetricsSendCount !== undefined) { - state.MetaMetricsController.metaMetricsSendCount = metaMetricsSendCount - delete state.PreferencesController.metaMetricsSendCount + state.MetaMetricsController.metaMetricsSendCount = metaMetricsSendCount; + delete state.PreferencesController.metaMetricsSendCount; } } - return state + return state; } diff --git a/app/scripts/migrations/050.js b/app/scripts/migrations/050.js index af2873873d..0d7b16296d 100644 --- a/app/scripts/migrations/050.js +++ b/app/scripts/migrations/050.js @@ -1,6 +1,6 @@ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 50 +const version = 50; const LEGACY_LOCAL_STORAGE_KEYS = [ 'METASWAP_GAS_PRICE_ESTIMATES_LAST_RETRIEVED', @@ -12,7 +12,7 @@ const LEGACY_LOCAL_STORAGE_KEYS = [ 'BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED', 'GAS_API_ESTIMATES_LAST_RETRIEVED', 'GAS_API_ESTIMATES', -] +]; /** * Migrate metaMetrics state to the new MetaMetrics controller @@ -20,13 +20,13 @@ const LEGACY_LOCAL_STORAGE_KEYS = [ export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; LEGACY_LOCAL_STORAGE_KEYS.forEach((key) => window.localStorage.removeItem(key), - ) + ); - return versionedData + return versionedData; }, -} +}; diff --git a/app/scripts/migrations/051.js b/app/scripts/migrations/051.js index 4c024458d2..c429fa635e 100644 --- a/app/scripts/migrations/051.js +++ b/app/scripts/migrations/051.js @@ -1,7 +1,7 @@ -import { cloneDeep } from 'lodash' -import { NETWORK_TYPE_TO_ID_MAP } from '../../../shared/constants/network' +import { cloneDeep } from 'lodash'; +import { NETWORK_TYPE_TO_ID_MAP } from '../../../shared/constants/network'; -const version = 51 +const version = 51; /** * Set the chainId in the Network Controller provider data for all infura networks @@ -9,20 +9,20 @@ const version = 51 export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - versionedData.data = transformState(state) - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + versionedData.data = transformState(state); + return versionedData; }, -} +}; function transformState(state) { - const { chainId, type } = state?.NetworkController?.provider || {} - const enumChainId = NETWORK_TYPE_TO_ID_MAP[type]?.chainId + const { chainId, type } = state?.NetworkController?.provider || {}; + const enumChainId = NETWORK_TYPE_TO_ID_MAP[type]?.chainId; if (enumChainId && chainId !== enumChainId) { - state.NetworkController.provider.chainId = enumChainId + state.NetworkController.provider.chainId = enumChainId; } - return state + return state; } diff --git a/app/scripts/migrations/fail-tx.js b/app/scripts/migrations/fail-tx.js index 240d110363..0fedb60524 100644 --- a/app/scripts/migrations/fail-tx.js +++ b/app/scripts/migrations/fail-tx.js @@ -1,40 +1,40 @@ -import { cloneDeep } from 'lodash' -import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' +import { cloneDeep } from 'lodash'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; export default function failTxsThat(version, reason, condition) { return function (originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; try { - const state = versionedData.data - const newState = transformState(state, condition, reason) - versionedData.data = newState + const state = versionedData.data; + const newState = transformState(state, condition, reason); + versionedData.data = newState; } catch (err) { - console.warn(`MetaMask Migration #${version}${err.stack}`) + console.warn(`MetaMask Migration #${version}${err.stack}`); } - return Promise.resolve(versionedData) - } + return Promise.resolve(versionedData); + }; } function transformState(state, condition, reason) { - const newState = state - const { TransactionController } = newState + const newState = state; + const { TransactionController } = newState; if (TransactionController && TransactionController.transactions) { - const { transactions } = TransactionController + const { transactions } = TransactionController; newState.TransactionController.transactions = transactions.map((txMeta) => { if (!condition(txMeta)) { - return txMeta + return txMeta; } - txMeta.status = TRANSACTION_STATUSES.FAILED + txMeta.status = TRANSACTION_STATUSES.FAILED; txMeta.err = { message: reason, note: `Tx automatically failed by migration because ${reason}`, - } + }; - return txMeta - }) + return txMeta; + }); } - return newState + return newState; } diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js index 1701fd19c7..5fe85ae74a 100644 --- a/app/scripts/migrations/index.js +++ b/app/scripts/migrations/index.js @@ -56,6 +56,6 @@ const migrations = [ require('./049').default, require('./050').default, require('./051').default, -] +]; -export default migrations +export default migrations; diff --git a/app/scripts/migrations/template.js b/app/scripts/migrations/template.js index b582c5a002..b3f050dfcd 100644 --- a/app/scripts/migrations/template.js +++ b/app/scripts/migrations/template.js @@ -5,25 +5,25 @@ description of migration and what it does */ -import { cloneDeep } from 'lodash' +import { cloneDeep } from 'lodash'; -const version = 0 +const version = 0; export default { version, async migrate(originalVersionedData) { - const versionedData = cloneDeep(originalVersionedData) - versionedData.meta.version = version - const state = versionedData.data - const newState = transformState(state) - versionedData.data = newState - return versionedData + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + const state = versionedData.data; + const newState = transformState(state); + versionedData.data = newState; + return versionedData; }, -} +}; function transformState(state) { - const newState = state + const newState = state; // transform state here - return newState + return newState; } diff --git a/app/scripts/phishing-detect.js b/app/scripts/phishing-detect.js index 300fe70fa6..9ade869f08 100644 --- a/app/scripts/phishing-detect.js +++ b/app/scripts/phishing-detect.js @@ -1,57 +1,57 @@ -import querystring from 'querystring' -import { EventEmitter } from 'events' -import dnode from 'dnode' -import PortStream from 'extension-port-stream' -import extension from 'extensionizer' -import { setupMultiplex } from './lib/stream-utils' -import { getEnvironmentType } from './lib/util' -import ExtensionPlatform from './platforms/extension' +import querystring from 'querystring'; +import { EventEmitter } from 'events'; +import dnode from 'dnode'; +import PortStream from 'extension-port-stream'; +import extension from 'extensionizer'; +import { setupMultiplex } from './lib/stream-utils'; +import { getEnvironmentType } from './lib/util'; +import ExtensionPlatform from './platforms/extension'; -document.addEventListener('DOMContentLoaded', start) +document.addEventListener('DOMContentLoaded', start); function start() { - const hash = window.location.hash.substring(1) - const suspect = querystring.parse(hash) + const hash = window.location.hash.substring(1); + const suspect = querystring.parse(hash); - document.getElementById('csdbLink').href = `https://cryptoscamdb.org/search` + document.getElementById('csdbLink').href = `https://cryptoscamdb.org/search`; - global.platform = new ExtensionPlatform() + global.platform = new ExtensionPlatform(); const extensionPort = extension.runtime.connect({ name: getEnvironmentType(), - }) - const connectionStream = new PortStream(extensionPort) - const mx = setupMultiplex(connectionStream) + }); + const connectionStream = new PortStream(extensionPort); + const mx = setupMultiplex(connectionStream); setupControllerConnection( mx.createStream('controller'), (err, metaMaskController) => { if (err) { - return + return; } - const continueLink = document.getElementById('unsafe-continue') + const continueLink = document.getElementById('unsafe-continue'); continueLink.addEventListener('click', () => { - metaMaskController.safelistPhishingDomain(suspect.hostname) - window.location.href = suspect.href - }) + metaMaskController.safelistPhishingDomain(suspect.hostname); + window.location.href = suspect.href; + }); }, - ) + ); } function setupControllerConnection(connectionStream, cb) { - const eventEmitter = new EventEmitter() + const eventEmitter = new EventEmitter(); // the "weak: false" option is for nodejs only (eg unit tests) // it is a workaround for node v12 support const metaMaskControllerDnode = dnode( { sendUpdate(state) { - eventEmitter.emit('update', state) + eventEmitter.emit('update', state); }, }, { weak: false }, - ) - connectionStream.pipe(metaMaskControllerDnode).pipe(connectionStream) + ); + connectionStream.pipe(metaMaskControllerDnode).pipe(connectionStream); metaMaskControllerDnode.once('remote', (backgroundConnection) => cb(null, backgroundConnection), - ) + ); } diff --git a/app/scripts/platforms/extension.js b/app/scripts/platforms/extension.js index 88117700da..8c43a343ba 100644 --- a/app/scripts/platforms/extension.js +++ b/app/scripts/platforms/extension.js @@ -1,117 +1,117 @@ -import extension from 'extensionizer' -import { createExplorerLink as explorerLink } from '@metamask/etherscan-link' -import { getEnvironmentType, checkForError } from '../lib/util' -import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../shared/constants/app' -import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' +import extension from 'extensionizer'; +import { createExplorerLink as explorerLink } from '@metamask/etherscan-link'; +import { getEnvironmentType, checkForError } from '../lib/util'; +import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../shared/constants/app'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; export default class ExtensionPlatform { // // Public // reload() { - extension.runtime.reload() + extension.runtime.reload(); } openTab(options) { return new Promise((resolve, reject) => { extension.tabs.create(options, (newTab) => { - const error = checkForError() + const error = checkForError(); if (error) { - return reject(error) + return reject(error); } - return resolve(newTab) - }) - }) + return resolve(newTab); + }); + }); } openWindow(options) { return new Promise((resolve, reject) => { extension.windows.create(options, (newWindow) => { - const error = checkForError() + const error = checkForError(); if (error) { - return reject(error) + return reject(error); } - return resolve(newWindow) - }) - }) + return resolve(newWindow); + }); + }); } focusWindow(windowId) { return new Promise((resolve, reject) => { extension.windows.update(windowId, { focused: true }, () => { - const error = checkForError() + const error = checkForError(); if (error) { - return reject(error) + return reject(error); } - return resolve() - }) - }) + return resolve(); + }); + }); } updateWindowPosition(windowId, left, top) { return new Promise((resolve, reject) => { extension.windows.update(windowId, { left, top }, () => { - const error = checkForError() + const error = checkForError(); if (error) { - return reject(error) + return reject(error); } - return resolve() - }) - }) + return resolve(); + }); + }); } getLastFocusedWindow() { return new Promise((resolve, reject) => { extension.windows.getLastFocused((windowObject) => { - const error = checkForError() + const error = checkForError(); if (error) { - return reject(error) + return reject(error); } - return resolve(windowObject) - }) - }) + return resolve(windowObject); + }); + }); } closeCurrentWindow() { return extension.windows.getCurrent((windowDetails) => { - return extension.windows.remove(windowDetails.id) - }) + return extension.windows.remove(windowDetails.id); + }); } getVersion() { - return extension.runtime.getManifest().version + return extension.runtime.getManifest().version; } openExtensionInBrowser(route = null, queryString = null) { - let extensionURL = extension.runtime.getURL('home.html') + let extensionURL = extension.runtime.getURL('home.html'); if (queryString) { - extensionURL += `?${queryString}` + extensionURL += `?${queryString}`; } if (route) { - extensionURL += `#${route}` + extensionURL += `#${route}`; } - this.openTab({ url: extensionURL }) + this.openTab({ url: extensionURL }); if (getEnvironmentType() !== ENVIRONMENT_TYPE_BACKGROUND) { - window.close() + window.close(); } } getPlatformInfo(cb) { try { extension.runtime.getPlatformInfo((platform) => { - cb(null, platform) - }) + cb(null, platform); + }); } catch (e) { - cb(e) + cb(e); // eslint-disable-next-line no-useless-return - return + return; } } showTransactionNotification(txMeta) { - const { status, txReceipt: { status: receiptStatus } = {} } = txMeta + const { status, txReceipt: { status: receiptStatus } = {} } = txMeta; if (status === TRANSACTION_STATUSES.CONFIRMED) { // There was an on-chain failure @@ -120,93 +120,93 @@ export default class ExtensionPlatform { txMeta, 'Transaction encountered an error.', ) - : this._showConfirmedTransaction(txMeta) + : this._showConfirmedTransaction(txMeta); } else if (status === TRANSACTION_STATUSES.FAILED) { - this._showFailedTransaction(txMeta) + this._showFailedTransaction(txMeta); } } getAllWindows() { return new Promise((resolve, reject) => { extension.windows.getAll((windows) => { - const error = checkForError() + const error = checkForError(); if (error) { - return reject(error) + return reject(error); } - return resolve(windows) - }) - }) + return resolve(windows); + }); + }); } getActiveTabs() { return new Promise((resolve, reject) => { extension.tabs.query({ active: true }, (tabs) => { - const error = checkForError() + const error = checkForError(); if (error) { - return reject(error) + return reject(error); } - return resolve(tabs) - }) - }) + return resolve(tabs); + }); + }); } currentTab() { return new Promise((resolve, reject) => { extension.tabs.getCurrent((tab) => { - const err = checkForError() + const err = checkForError(); if (err) { - reject(err) + reject(err); } else { - resolve(tab) + resolve(tab); } - }) - }) + }); + }); } switchToTab(tabId) { return new Promise((resolve, reject) => { extension.tabs.update(tabId, { highlighted: true }, (tab) => { - const err = checkForError() + const err = checkForError(); if (err) { - reject(err) + reject(err); } else { - resolve(tab) + resolve(tab); } - }) - }) + }); + }); } closeTab(tabId) { return new Promise((resolve, reject) => { extension.tabs.remove(tabId, () => { - const err = checkForError() + const err = checkForError(); if (err) { - reject(err) + reject(err); } else { - resolve() + resolve(); } - }) - }) + }); + }); } _showConfirmedTransaction(txMeta) { - this._subscribeToNotificationClicked() + this._subscribeToNotificationClicked(); - const url = explorerLink(txMeta.hash, txMeta.metamaskNetworkId) - const nonce = parseInt(txMeta.txParams.nonce, 16) + const url = explorerLink(txMeta.hash, txMeta.metamaskNetworkId); + const nonce = parseInt(txMeta.txParams.nonce, 16); - const title = 'Confirmed transaction' - const message = `Transaction ${nonce} confirmed! View on Etherscan` - this._showNotification(title, message, url) + const title = 'Confirmed transaction'; + const message = `Transaction ${nonce} confirmed! View on Etherscan`; + this._showNotification(title, message, url); } _showFailedTransaction(txMeta, errorMessage) { - const nonce = parseInt(txMeta.txParams.nonce, 16) - const title = 'Failed transaction' + const nonce = parseInt(txMeta.txParams.nonce, 16); + const title = 'Failed transaction'; const message = `Transaction ${nonce} failed! ${ errorMessage || txMeta.err.message - }` - this._showNotification(title, message) + }`; + this._showNotification(title, message); } _showNotification(title, message, url) { @@ -215,18 +215,18 @@ export default class ExtensionPlatform { title, iconUrl: extension.extension.getURL('../../images/icon-64.png'), message, - }) + }); } _subscribeToNotificationClicked() { if (!extension.notifications.onClicked.hasListener(this._viewOnEtherscan)) { - extension.notifications.onClicked.addListener(this._viewOnEtherscan) + extension.notifications.onClicked.addListener(this._viewOnEtherscan); } } _viewOnEtherscan(txId) { if (txId.startsWith('https://')) { - extension.tabs.create({ url: txId }) + extension.tabs.create({ url: txId }); } } } diff --git a/app/scripts/runLockdown.js b/app/scripts/runLockdown.js index 2100059676..8dc1b01541 100644 --- a/app/scripts/runLockdown.js +++ b/app/scripts/runLockdown.js @@ -6,14 +6,14 @@ try { errorTaming: 'unsafe', mathTaming: 'unsafe', dateTaming: 'unsafe', - }) + }); } catch (error) { // If the `lockdown` call throws an exception, it interferes with the // contentscript injection on some versions of Firefox. The error is // caught and logged here so that the contentscript still gets injected. // This affects Firefox v56 and Waterfox Classic - console.error('Lockdown failed:', error) + console.error('Lockdown failed:', error); if (window.sentry && window.sentry.captureException) { - window.sentry.captureException(error) + window.sentry.captureException(error); } } diff --git a/app/scripts/ui.js b/app/scripts/ui.js index a67eb3e6a8..0d048191c1 100644 --- a/app/scripts/ui.js +++ b/app/scripts/ui.js @@ -1,64 +1,64 @@ // polyfills -import 'abortcontroller-polyfill/dist/polyfill-patch-fetch' -import '@formatjs/intl-relativetimeformat/polyfill' - -import { EventEmitter } from 'events' -import PortStream from 'extension-port-stream' -import extension from 'extensionizer' - -import Dnode from 'dnode' -import Eth from 'ethjs' -import EthQuery from 'eth-query' -import StreamProvider from 'web3-stream-provider' -import log from 'loglevel' -import launchMetaMaskUi from '../../ui' +import 'abortcontroller-polyfill/dist/polyfill-patch-fetch'; +import '@formatjs/intl-relativetimeformat/polyfill'; + +import { EventEmitter } from 'events'; +import PortStream from 'extension-port-stream'; +import extension from 'extensionizer'; + +import Dnode from 'dnode'; +import Eth from 'ethjs'; +import EthQuery from 'eth-query'; +import StreamProvider from 'web3-stream-provider'; +import log from 'loglevel'; +import launchMetaMaskUi from '../../ui'; import { ENVIRONMENT_TYPE_FULLSCREEN, ENVIRONMENT_TYPE_POPUP, -} from '../../shared/constants/app' -import ExtensionPlatform from './platforms/extension' -import { setupMultiplex } from './lib/stream-utils' -import { getEnvironmentType } from './lib/util' +} from '../../shared/constants/app'; +import ExtensionPlatform from './platforms/extension'; +import { setupMultiplex } from './lib/stream-utils'; +import { getEnvironmentType } from './lib/util'; -start().catch(log.error) +start().catch(log.error); async function start() { // create platform global - global.platform = new ExtensionPlatform() + global.platform = new ExtensionPlatform(); // identify window type (popup, notification) - const windowType = getEnvironmentType() + const windowType = getEnvironmentType(); // setup stream to background - const extensionPort = extension.runtime.connect({ name: windowType }) - const connectionStream = new PortStream(extensionPort) + const extensionPort = extension.runtime.connect({ name: windowType }); + const connectionStream = new PortStream(extensionPort); - const activeTab = await queryCurrentActiveTab(windowType) - initializeUiWithTab(activeTab) + const activeTab = await queryCurrentActiveTab(windowType); + initializeUiWithTab(activeTab); function displayCriticalError(container, err) { container.innerHTML = - '
The MetaMask app failed to load: please open and close MetaMask again to restart.
' - container.style.height = '80px' - log.error(err.stack) - throw err + '
The MetaMask app failed to load: please open and close MetaMask again to restart.
'; + container.style.height = '80px'; + log.error(err.stack); + throw err; } function initializeUiWithTab(tab) { - const container = document.getElementById('app-content') + const container = document.getElementById('app-content'); initializeUi(tab, container, connectionStream, (err, store) => { if (err) { - displayCriticalError(container, err) - return + displayCriticalError(container, err); + return; } - const state = store.getState() - const { metamask: { completedOnboarding } = {} } = state + const state = store.getState(); + const { metamask: { completedOnboarding } = {} } = state; if (!completedOnboarding && windowType !== ENVIRONMENT_TYPE_FULLSCREEN) { - global.platform.openExtensionInBrowser() + global.platform.openExtensionInBrowser(); } - }) + }); } } @@ -67,30 +67,30 @@ async function queryCurrentActiveTab(windowType) { // At the time of writing we only have the `activeTab` permission which means // that this query will only succeed in the popup context (i.e. after a "browserAction") if (windowType !== ENVIRONMENT_TYPE_POPUP) { - resolve({}) - return + resolve({}); + return; } extension.tabs.query({ active: true, currentWindow: true }, (tabs) => { - const [activeTab] = tabs - const { id, title, url } = activeTab - const { origin, protocol } = url ? new URL(url) : {} + const [activeTab] = tabs; + const { id, title, url } = activeTab; + const { origin, protocol } = url ? new URL(url) : {}; if (!origin || origin === 'null') { - resolve({}) - return + resolve({}); + return; } - resolve({ id, title, origin, protocol, url }) - }) - }) + resolve({ id, title, origin, protocol, url }); + }); + }); } function initializeUi(activeTab, container, connectionStream, cb) { connectToAccountManager(connectionStream, (err, backgroundConnection) => { if (err) { - cb(err) - return + cb(err); + return; } launchMetaMaskUi( @@ -100,8 +100,8 @@ function initializeUi(activeTab, container, connectionStream, cb) { backgroundConnection, }, cb, - ) - }) + ); + }); } /** @@ -111,9 +111,9 @@ function initializeUi(activeTab, container, connectionStream, cb) { * @param {Function} cb - Called when controller connection is established */ function connectToAccountManager(connectionStream, cb) { - const mx = setupMultiplex(connectionStream) - setupControllerConnection(mx.createStream('controller'), cb) - setupWeb3Connection(mx.createStream('provider')) + const mx = setupMultiplex(connectionStream); + setupControllerConnection(mx.createStream('controller'), cb); + setupWeb3Connection(mx.createStream('provider')); } /** @@ -122,13 +122,13 @@ function connectToAccountManager(connectionStream, cb) { * @param {PortDuplexStream} connectionStream - PortStream instance establishing a background connection */ function setupWeb3Connection(connectionStream) { - const providerStream = new StreamProvider() - providerStream.pipe(connectionStream).pipe(providerStream) - connectionStream.on('error', console.error.bind(console)) - providerStream.on('error', console.error.bind(console)) - global.ethereumProvider = providerStream - global.ethQuery = new EthQuery(providerStream) - global.eth = new Eth(providerStream) + const providerStream = new StreamProvider(); + providerStream.pipe(connectionStream).pipe(providerStream); + connectionStream.on('error', console.error.bind(console)); + providerStream.on('error', console.error.bind(console)); + global.ethereumProvider = providerStream; + global.ethQuery = new EthQuery(providerStream); + global.eth = new Eth(providerStream); } /** @@ -138,20 +138,20 @@ function setupWeb3Connection(connectionStream) { * @param {Function} cb - Called when the remote account manager connection is established */ function setupControllerConnection(connectionStream, cb) { - const eventEmitter = new EventEmitter() + const eventEmitter = new EventEmitter(); // the "weak: false" option is for nodejs only (eg unit tests) // it is a workaround for node v12 support const backgroundDnode = Dnode( { sendUpdate(state) { - eventEmitter.emit('update', state) + eventEmitter.emit('update', state); }, }, { weak: false }, - ) - connectionStream.pipe(backgroundDnode).pipe(connectionStream) + ); + connectionStream.pipe(backgroundDnode).pipe(connectionStream); backgroundDnode.once('remote', function (backgroundConnection) { - backgroundConnection.on = eventEmitter.on.bind(eventEmitter) - cb(null, backgroundConnection) - }) + backgroundConnection.on = eventEmitter.on.bind(eventEmitter); + cb(null, backgroundConnection); + }); } diff --git a/babel.config.js b/babel.config.js index d95fa7e3f4..6c98e6df41 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,5 +1,5 @@ module.exports = function (api) { - api.cache(false) + api.cache(false); return { presets: [ [ @@ -19,5 +19,5 @@ module.exports = function (api) { '@babel/plugin-proposal-optional-chaining', '@babel/plugin-proposal-nullish-coalescing-operator', ], - } -} + }; +}; diff --git a/development/announcer.js b/development/announcer.js index e6927cb8b4..f0c42c07ad 100644 --- a/development/announcer.js +++ b/development/announcer.js @@ -1,13 +1,13 @@ -const fs = require('fs') -const path = require('path') -const { version } = require('../app/manifest/_base.json') +const fs = require('fs'); +const path = require('path'); +const { version } = require('../app/manifest/_base.json'); const changelog = fs.readFileSync( path.join(__dirname, '..', 'CHANGELOG.md'), 'utf8', -) +); -const log = changelog.split(version)[1].split('##')[0].trim() -const msg = `*MetaMask ${version}* now published! It should auto-update soon!\n${log}` +const log = changelog.split(version)[1].split('##')[0].trim(); +const msg = `*MetaMask ${version}* now published! It should auto-update soon!\n${log}`; -console.log(msg) +console.log(msg); diff --git a/development/build/display.js b/development/build/display.js index 153f471892..6d16cc7e7c 100644 --- a/development/build/display.js +++ b/development/build/display.js @@ -1,7 +1,7 @@ -const randomColor = require('randomcolor') -const chalk = require('chalk') +const randomColor = require('randomcolor'); +const chalk = require('chalk'); -module.exports = { setupTaskDisplay, displayChart } +module.exports = { setupTaskDisplay, displayChart }; const SYMBOLS = { Empty: '', @@ -16,135 +16,145 @@ const SYMBOLS = { Eighth: '▏', RightHalf: '▐', RightEighth: '▕', -} +}; function setupTaskDisplay(taskEvents) { - const taskData = [] + const taskData = []; taskEvents.on('start', ([name]) => { - console.log(`Starting '${name}'...`) - }) + console.log(`Starting '${name}'...`); + }); taskEvents.on('end', ([name, start, end]) => { - taskData.push([name, start, end]) - console.log(`Finished '${name}'`) - }) + taskData.push([name, start, end]); + console.log(`Finished '${name}'`); + }); taskEvents.on('complete', () => { - displayChart(taskData) - }) + displayChart(taskData); + }); } function displayChart(data) { // sort tasks by start time - data.sort((a, b) => a[1] - b[1]) + data.sort((a, b) => a[1] - b[1]); // get bounds - const first = Math.min(...data.map((entry) => entry[1])) - const last = Math.max(...data.map((entry) => entry[2])) + const first = Math.min(...data.map((entry) => entry[1])); + const last = Math.max(...data.map((entry) => entry[2])); // get colors - const colors = randomColor({ count: data.length }) + const colors = randomColor({ count: data.length }); // some heading before the bars - console.log(`\nbuild completed. task timeline:`) + console.log(`\nbuild completed. task timeline:`); // build bars for bounds data.forEach((entry, index) => { - const [label, start, end] = entry + const [label, start, end] = entry; const [start2, end2] = [start, end].map((value) => adjust(value, first, last, 40), - ) - const barString = barBuilder(start2, end2) - const color = colors[index] - const coloredBarString = colorize(color, barString) - const duration = ((end - start) / 1e3).toFixed(1) - console.log(coloredBarString, `${label} ${duration}s`) - }) + ); + const barString = barBuilder(start2, end2); + const color = colors[index]; + const coloredBarString = colorize(color, barString); + const duration = ((end - start) / 1e3).toFixed(1); + console.log(coloredBarString, `${label} ${duration}s`); + }); } function colorize(color, string) { const colorizer = - typeof chalk[color] === 'function' ? chalk[color] : chalk.hex(color) - return colorizer(string) + typeof chalk[color] === 'function' ? chalk[color] : chalk.hex(color); + return colorizer(string); } // scale number within bounds function adjust(value, first, last, size) { - const length = last - first - const result = ((value - first) / length) * size - return result + const length = last - first; + const result = ((value - first) / length) * size; + return result; } // draw bars function barBuilder(start, end) { - const [spaceInt, spaceRest] = splitNumber(start) - const barBodyLength = end - spaceInt - let [barInt, barRest] = splitNumber(barBodyLength) + const [spaceInt, spaceRest] = splitNumber(start); + const barBodyLength = end - spaceInt; + let [barInt, barRest] = splitNumber(barBodyLength); // We are handling zero value as a special case // to print at least something on the screen if (barInt === 0 && barRest === 0) { - barInt = 0 - barRest = 0.001 + barInt = 0; + barRest = 0.001; } - const spaceFull = SYMBOLS.Space.repeat(spaceInt) - const spacePartial = getSymbolNormalRight(spaceRest) - const barFull = SYMBOLS.Full.repeat(barInt) - const barPartial = getSymbolNormal(barRest) + const spaceFull = SYMBOLS.Space.repeat(spaceInt); + const spacePartial = getSymbolNormalRight(spaceRest); + const barFull = SYMBOLS.Full.repeat(barInt); + const barPartial = getSymbolNormal(barRest); - return `${spaceFull}${spacePartial}${barFull}${barPartial}` + return `${spaceFull}${spacePartial}${barFull}${barPartial}`; } // get integer and remainder function splitNumber(value = 0) { - const [int, rest = '0'] = value.toString().split('.') - const int2 = parseInt(int, 10) - const rest2 = parseInt(rest, 10) / Math.pow(10, rest.length) - return [int2, rest2] + const [int, rest = '0'] = value.toString().split('.'); + const int2 = parseInt(int, 10); + const rest2 = parseInt(rest, 10) / Math.pow(10, rest.length); + return [int2, rest2]; } // get partial block char for value (left-adjusted) function getSymbolNormal(value) { // round to closest supported value - const possibleValues = [0, 1 / 8, 1 / 4, 3 / 8, 1 / 2, 5 / 8, 3 / 4, 7 / 8, 1] + const possibleValues = [ + 0, + 1 / 8, + 1 / 4, + 3 / 8, + 1 / 2, + 5 / 8, + 3 / 4, + 7 / 8, + 1, + ]; const rounded = possibleValues.reduce((prev, curr) => { - return Math.abs(curr - value) < Math.abs(prev - value) ? curr : prev - }) + return Math.abs(curr - value) < Math.abs(prev - value) ? curr : prev; + }); if (rounded === 0) { - return SYMBOLS.Empty + return SYMBOLS.Empty; } else if (rounded === 1 / 8) { - return SYMBOLS.Eighth + return SYMBOLS.Eighth; } else if (rounded === 1 / 4) { - return SYMBOLS.Quarter + return SYMBOLS.Quarter; } else if (rounded === 3 / 8) { - return SYMBOLS.ThreeEighths + return SYMBOLS.ThreeEighths; } else if (rounded === 1 / 2) { - return SYMBOLS.Half + return SYMBOLS.Half; } else if (rounded === 5 / 8) { - return SYMBOLS.FiveEighths + return SYMBOLS.FiveEighths; } else if (rounded === 3 / 4) { - return SYMBOLS.ThreeQuarters + return SYMBOLS.ThreeQuarters; } else if (rounded === 7 / 8) { - return SYMBOLS.SevenEighths + return SYMBOLS.SevenEighths; } - return SYMBOLS.Full + return SYMBOLS.Full; } // get partial block char for value (right-adjusted) function getSymbolNormalRight(value) { // round to closest supported value (not much :/) - const possibleValues = [0, 1 / 2, 7 / 8, 1] + const possibleValues = [0, 1 / 2, 7 / 8, 1]; const rounded = possibleValues.reduce((prev, curr) => { - return Math.abs(curr - value) < Math.abs(prev - value) ? curr : prev - }) + return Math.abs(curr - value) < Math.abs(prev - value) ? curr : prev; + }); if (rounded === 0) { - return SYMBOLS.Full + return SYMBOLS.Full; } else if (rounded === 1 / 2) { - return SYMBOLS.RightHalf + return SYMBOLS.RightHalf; } else if (rounded === 7 / 8) { - return SYMBOLS.RightEighth + return SYMBOLS.RightEighth; } else if (rounded === 1) { - return SYMBOLS.Space + return SYMBOLS.Space; } - throw new Error('getSymbolNormalRight got unexpected result') + throw new Error('getSymbolNormalRight got unexpected result'); } diff --git a/development/build/etc.js b/development/build/etc.js index 374b9a6169..49070887fb 100644 --- a/development/build/etc.js +++ b/development/build/etc.js @@ -1,27 +1,27 @@ -const { promises: fs } = require('fs') -const gulp = require('gulp') -const gulpZip = require('gulp-zip') -const del = require('del') -const pify = require('pify') -const pump = pify(require('pump')) -const baseManifest = require('../../app/manifest/_base.json') -const { createTask, composeParallel } = require('./task') +const { promises: fs } = require('fs'); +const gulp = require('gulp'); +const gulpZip = require('gulp-zip'); +const del = require('del'); +const pify = require('pify'); +const pump = pify(require('pump')); +const baseManifest = require('../../app/manifest/_base.json'); +const { createTask, composeParallel } = require('./task'); -module.exports = createEtcTasks +module.exports = createEtcTasks; function createEtcTasks({ browserPlatforms, livereload }) { const clean = createTask('clean', async function clean() { - await del(['./dist/*']) + await del(['./dist/*']); await Promise.all( browserPlatforms.map(async (platform) => { - await fs.mkdir(`./dist/${platform}`, { recursive: true }) + await fs.mkdir(`./dist/${platform}`, { recursive: true }); }), - ) - }) + ); + }); const reload = createTask('reload', function devReload() { - livereload.listen({ port: 35729 }) - }) + livereload.listen({ port: 35729 }); + }); // zip tasks for distribution const zip = createTask( @@ -29,9 +29,9 @@ function createEtcTasks({ browserPlatforms, livereload }) { composeParallel( ...browserPlatforms.map((platform) => createZipTask(platform)), ), - ) + ); - return { clean, reload, zip } + return { clean, reload, zip }; } function createZipTask(target) { @@ -40,6 +40,6 @@ function createZipTask(target) { gulp.src(`dist/${target}/**`), gulpZip(`metamask-${target}-${baseManifest.version}.zip`), gulp.dest('builds'), - ) - } + ); + }; } diff --git a/development/build/index.js b/development/build/index.js index 7c5aeb6a2d..c6ce884f5f 100755 --- a/development/build/index.js +++ b/development/build/index.js @@ -3,33 +3,33 @@ // // run any task with "yarn build ${taskName}" // -const livereload = require('gulp-livereload') +const livereload = require('gulp-livereload'); const { createTask, composeSeries, composeParallel, detectAndRunEntryTask, -} = require('./task') -const createManifestTasks = require('./manifest') -const createScriptTasks = require('./scripts') -const createStyleTasks = require('./styles') -const createStaticAssetTasks = require('./static') -const createEtcTasks = require('./etc') +} = require('./task'); +const createManifestTasks = require('./manifest'); +const createScriptTasks = require('./scripts'); +const createStyleTasks = require('./styles'); +const createStaticAssetTasks = require('./static'); +const createEtcTasks = require('./etc'); -const browserPlatforms = ['firefox', 'chrome', 'brave', 'opera'] +const browserPlatforms = ['firefox', 'chrome', 'brave', 'opera']; -defineAllTasks() -detectAndRunEntryTask() +defineAllTasks(); +detectAndRunEntryTask(); function defineAllTasks() { - const staticTasks = createStaticAssetTasks({ livereload, browserPlatforms }) - const manifestTasks = createManifestTasks({ browserPlatforms }) - const styleTasks = createStyleTasks({ livereload }) - const scriptTasks = createScriptTasks({ livereload, browserPlatforms }) + const staticTasks = createStaticAssetTasks({ livereload, browserPlatforms }); + const manifestTasks = createManifestTasks({ browserPlatforms }); + const styleTasks = createStyleTasks({ livereload }); + const scriptTasks = createScriptTasks({ livereload, browserPlatforms }); const { clean, reload, zip } = createEtcTasks({ livereload, browserPlatforms, - }) + }); // build for development (livereload) createTask( @@ -44,7 +44,7 @@ function defineAllTasks() { reload, ), ), - ) + ); // build for test development (livereload) createTask( @@ -59,7 +59,7 @@ function defineAllTasks() { reload, ), ), - ) + ); // build for prod release createTask( @@ -70,7 +70,7 @@ function defineAllTasks() { composeParallel(scriptTasks.prod, staticTasks.prod, manifestTasks.prod), zip, ), - ) + ); // build for CI testing createTask( @@ -81,8 +81,8 @@ function defineAllTasks() { composeParallel(scriptTasks.test, staticTasks.prod, manifestTasks.test), zip, ), - ) + ); // special build for minimal CI testing - createTask('styles', styleTasks.prod) + createTask('styles', styleTasks.prod); } diff --git a/development/build/manifest.js b/development/build/manifest.js index 7750205b14..0dc8880b18 100644 --- a/development/build/manifest.js +++ b/development/build/manifest.js @@ -1,16 +1,16 @@ -const { promises: fs } = require('fs') -const path = require('path') -const { merge, cloneDeep } = require('lodash') +const { promises: fs } = require('fs'); +const path = require('path'); +const { merge, cloneDeep } = require('lodash'); -const baseManifest = require('../../app/manifest/_base.json') +const baseManifest = require('../../app/manifest/_base.json'); -const { createTask, composeSeries } = require('./task') +const { createTask, composeSeries } = require('./task'); -module.exports = createManifestTasks +module.exports = createManifestTasks; const scriptsToExcludeFromBackgroundDevBuild = { 'bg-libs.js': true, -} +}; function createManifestTasks({ browserPlatforms }) { // merge base manifest with per-platform manifests @@ -26,44 +26,44 @@ function createManifestTasks({ browserPlatforms }) { 'manifest', `${platform}.json`, ), - ) - const result = merge(cloneDeep(baseManifest), platformModifications) - const dir = path.join('.', 'dist', platform) - await fs.mkdir(dir, { recursive: true }) - await writeJson(result, path.join(dir, 'manifest.json')) + ); + const result = merge(cloneDeep(baseManifest), platformModifications); + const dir = path.join('.', 'dist', platform); + await fs.mkdir(dir, { recursive: true }); + await writeJson(result, path.join(dir, 'manifest.json')); }), - ) - } + ); + }; // dev: remove bg-libs, add chromereload, add perms const envDev = createTaskForModifyManifestForEnvironment((manifest) => { const scripts = manifest.background.scripts.filter( (scriptName) => !scriptsToExcludeFromBackgroundDevBuild[scriptName], - ) - scripts.push('chromereload.js') + ); + scripts.push('chromereload.js'); manifest.background = { ...manifest.background, scripts, - } - manifest.permissions = [...manifest.permissions, 'webRequestBlocking'] - }) + }; + manifest.permissions = [...manifest.permissions, 'webRequestBlocking']; + }); // testDev: remove bg-libs, add perms const envTestDev = createTaskForModifyManifestForEnvironment((manifest) => { const scripts = manifest.background.scripts.filter( (scriptName) => !scriptsToExcludeFromBackgroundDevBuild[scriptName], - ) - scripts.push('chromereload.js') + ); + scripts.push('chromereload.js'); manifest.background = { ...manifest.background, scripts, - } + }; manifest.permissions = [ ...manifest.permissions, 'webRequestBlocking', 'http://localhost/*', - ] - }) + ]; + }); // test: add permissions const envTest = createTaskForModifyManifestForEnvironment((manifest) => { @@ -71,47 +71,52 @@ function createManifestTasks({ browserPlatforms }) { ...manifest.permissions, 'webRequestBlocking', 'http://localhost/*', - ] - }) + ]; + }); // high level manifest tasks - const dev = createTask('manifest:dev', composeSeries(prepPlatforms, envDev)) + const dev = createTask('manifest:dev', composeSeries(prepPlatforms, envDev)); const testDev = createTask( 'manifest:testDev', composeSeries(prepPlatforms, envTestDev), - ) + ); const test = createTask( 'manifest:test', composeSeries(prepPlatforms, envTest), - ) + ); - const prod = createTask('manifest:prod', prepPlatforms) + const prod = createTask('manifest:prod', prepPlatforms); - return { prod, dev, testDev, test } + return { prod, dev, testDev, test }; // helper for modifying each platform's manifest.json in place function createTaskForModifyManifestForEnvironment(transformFn) { return () => { return Promise.all( browserPlatforms.map(async (platform) => { - const manifestPath = path.join('.', 'dist', platform, 'manifest.json') - const manifest = await readJson(manifestPath) - transformFn(manifest) - await writeJson(manifest, manifestPath) + const manifestPath = path.join( + '.', + 'dist', + platform, + 'manifest.json', + ); + const manifest = await readJson(manifestPath); + transformFn(manifest); + await writeJson(manifest, manifestPath); }), - ) - } + ); + }; } } // helper for reading and deserializing json from fs async function readJson(file) { - return JSON.parse(await fs.readFile(file, 'utf8')) + return JSON.parse(await fs.readFile(file, 'utf8')); } // helper for serializing and writing json to fs async function writeJson(obj, file) { - return fs.writeFile(file, JSON.stringify(obj, null, 2)) + return fs.writeFile(file, JSON.stringify(obj, null, 2)); } diff --git a/development/build/scripts.js b/development/build/scripts.js index 8a54c9b332..57bbbcc6d3 100644 --- a/development/build/scripts.js +++ b/development/build/scripts.js @@ -1,46 +1,46 @@ -const gulp = require('gulp') -const watch = require('gulp-watch') -const pify = require('pify') -const pump = pify(require('pump')) -const source = require('vinyl-source-stream') -const buffer = require('vinyl-buffer') -const log = require('fancy-log') -const { assign } = require('lodash') -const watchify = require('watchify') -const browserify = require('browserify') -const envify = require('loose-envify/custom') -const sourcemaps = require('gulp-sourcemaps') -const terser = require('gulp-terser-js') +const gulp = require('gulp'); +const watch = require('gulp-watch'); +const pify = require('pify'); +const pump = pify(require('pump')); +const source = require('vinyl-source-stream'); +const buffer = require('vinyl-buffer'); +const log = require('fancy-log'); +const { assign } = require('lodash'); +const watchify = require('watchify'); +const browserify = require('browserify'); +const envify = require('loose-envify/custom'); +const sourcemaps = require('gulp-sourcemaps'); +const terser = require('gulp-terser-js'); const conf = require('rc')('metamask', { INFURA_PROJECT_ID: process.env.INFURA_PROJECT_ID, SEGMENT_HOST: process.env.SEGMENT_HOST, SEGMENT_WRITE_KEY: process.env.SEGMENT_WRITE_KEY, SEGMENT_LEGACY_WRITE_KEY: process.env.SEGMENT_LEGACY_WRITE_KEY, -}) +}); -const baseManifest = require('../../app/manifest/_base.json') +const baseManifest = require('../../app/manifest/_base.json'); -const packageJSON = require('../../package.json') +const packageJSON = require('../../package.json'); const { createTask, composeParallel, composeSeries, runInChildProcess, -} = require('./task') +} = require('./task'); -module.exports = createScriptTasks +module.exports = createScriptTasks; const dependencies = Object.keys( (packageJSON && packageJSON.dependencies) || {}, -) -const materialUIDependencies = ['@material-ui/core'] -const reactDepenendencies = dependencies.filter((dep) => dep.match(/react/u)) +); +const materialUIDependencies = ['@material-ui/core']; +const reactDepenendencies = dependencies.filter((dep) => dep.match(/react/u)); const externalDependenciesMap = { background: ['3box'], ui: [...materialUIDependencies, ...reactDepenendencies], -} +}; function createScriptTasks({ browserPlatforms, livereload }) { // internal tasks @@ -62,24 +62,24 @@ function createScriptTasks({ browserPlatforms, livereload }) { }), // production prod: createTasksForBuildJsExtension({ taskPrefix: 'scripts:core:prod' }), - } + }; const deps = { background: createTasksForBuildJsDeps({ filename: 'bg-libs', key: 'background', }), ui: createTasksForBuildJsDeps({ filename: 'ui-libs', key: 'ui' }), - } + }; // high level tasks - const prod = composeParallel(deps.background, deps.ui, core.prod) + const prod = composeParallel(deps.background, deps.ui, core.prod); - const { dev, testDev } = core + const { dev, testDev } = core; - const test = composeParallel(deps.background, deps.ui, core.test) + const test = composeParallel(deps.background, deps.ui, core.test); - return { prod, dev, testDev, test } + return { prod, dev, testDev, test }; function createTasksForBuildJsDeps({ key, filename }) { return createTask( @@ -91,7 +91,7 @@ function createScriptTasks({ browserPlatforms, livereload }) { dependenciesToBundle: externalDependenciesMap[key], devMode: false, }), - ) + ); } function createTasksForBuildJsExtension({ taskPrefix, devMode, testing }) { @@ -100,7 +100,7 @@ function createScriptTasks({ browserPlatforms, livereload }) { 'ui', 'phishing-detect', 'initSentry', - ] + ]; const standardSubtasks = standardBundles.map((filename) => { return createTask( @@ -110,21 +110,21 @@ function createScriptTasks({ browserPlatforms, livereload }) { devMode, testing, }), - ) - }) + ); + }); // inpage must be built before contentscript // because inpage bundle result is included inside contentscript const contentscriptSubtask = createTask( `${taskPrefix}:contentscript`, createTaskForBuildJsExtensionContentscript({ devMode, testing }), - ) + ); // this can run whenever const disableConsoleSubtask = createTask( `${taskPrefix}:disable-console`, createTaskForBuildJsExtensionDisableConsole({ devMode }), - ) + ); // task for initiating livereload const initiateLiveReload = async () => { @@ -136,21 +136,21 @@ function createScriptTasks({ browserPlatforms, livereload }) { // - build tasks never "complete" when run with livereload + child process setTimeout(() => { watch('./dist/*/*.js', (event) => { - livereload.changed(event.path) - }) - }, 75e3) + livereload.changed(event.path); + }); + }, 75e3); } - } + }; // make each bundle run in a separate process const allSubtasks = [ ...standardSubtasks, contentscriptSubtask, disableConsoleSubtask, - ].map((subtask) => runInChildProcess(subtask)) + ].map((subtask) => runInChildProcess(subtask)); // const allSubtasks = [...standardSubtasks, contentscriptSubtask].map(subtask => (subtask)) // make a parent task that runs each task in a child thread - return composeParallel(initiateLiveReload, ...allSubtasks) + return composeParallel(initiateLiveReload, ...allSubtasks); } function createBundleTaskForBuildJsExtensionNormal({ @@ -167,22 +167,22 @@ function createScriptTasks({ browserPlatforms, livereload }) { : externalDependenciesMap[filename], devMode, testing, - }) + }); } function createTaskForBuildJsExtensionDisableConsole({ devMode }) { - const filename = 'disable-console' + const filename = 'disable-console'; return bundleTask({ label: filename, filename: `${filename}.js`, filepath: `./app/scripts/${filename}.js`, devMode, - }) + }); } function createTaskForBuildJsExtensionContentscript({ devMode, testing }) { - const inpage = 'inpage' - const contentscript = 'contentscript' + const inpage = 'inpage'; + const contentscript = 'contentscript'; return composeSeries( bundleTask({ label: inpage, @@ -204,21 +204,21 @@ function createScriptTasks({ browserPlatforms, livereload }) { devMode, testing, }), - ) + ); } function bundleTask(opts) { - let bundler + let bundler; - return performBundle + return performBundle; async function performBundle() { // initialize bundler if not available yet // dont create bundler until task is actually run if (!bundler) { - bundler = generateBundler(opts, performBundle) + bundler = generateBundler(opts, performBundle); // output build logs to terminal - bundler.on('log', log) + bundler.on('log', log); } const buildPipeline = [ @@ -229,7 +229,7 @@ function createScriptTasks({ browserPlatforms, livereload }) { buffer(), // loads map from browserify file sourcemaps.init({ loadMaps: true }), - ] + ]; // Minification if (!opts.devMode) { @@ -242,7 +242,7 @@ function createScriptTasks({ browserPlatforms, livereload }) { content: true, }, }), - ) + ); } // Finalize Source Maps @@ -250,26 +250,26 @@ function createScriptTasks({ browserPlatforms, livereload }) { // Use inline source maps for development due to Chrome DevTools bug // https://bugs.chromium.org/p/chromium/issues/detail?id=931675 // note: sourcemaps call arity is important - buildPipeline.push(sourcemaps.write()) + buildPipeline.push(sourcemaps.write()); } else { - buildPipeline.push(sourcemaps.write('../sourcemaps')) + buildPipeline.push(sourcemaps.write('../sourcemaps')); } // write completed bundles browserPlatforms.forEach((platform) => { - const dest = `./dist/${platform}` - buildPipeline.push(gulp.dest(dest)) - }) + const dest = `./dist/${platform}`; + buildPipeline.push(gulp.dest(dest)); + }); // process bundles if (opts.devMode) { try { - await pump(buildPipeline) + await pump(buildPipeline); } catch (err) { - gracefulError(err) + gracefulError(err); } } else { - await pump(buildPipeline) + await pump(buildPipeline); } } } @@ -280,37 +280,37 @@ function createScriptTasks({ browserPlatforms, livereload }) { transform: [], debug: true, fullPaths: opts.devMode, - }) + }); if (!opts.buildLib) { if (opts.devMode && opts.filename === 'ui.js') { browserifyOpts.entries = [ './development/require-react-devtools.js', opts.filepath, - ] + ]; } else { - browserifyOpts.entries = [opts.filepath] + browserifyOpts.entries = [opts.filepath]; } } let bundler = browserify(browserifyOpts) .transform('babelify') - .transform('brfs') + .transform('brfs'); if (opts.buildLib) { - bundler = bundler.require(opts.dependenciesToBundle) + bundler = bundler.require(opts.dependenciesToBundle); } if (opts.externalDependencies) { - bundler = bundler.external(opts.externalDependencies) + bundler = bundler.external(opts.externalDependencies); } const environment = getEnvironment({ devMode: opts.devMode, test: opts.testing, - }) + }); if (environment === 'production' && !process.env.SENTRY_DSN) { - throw new Error('Missing SENTRY_DSN environment variable') + throw new Error('Missing SENTRY_DSN environment variable'); } // Inject variables into bundle @@ -346,46 +346,46 @@ function createScriptTasks({ browserPlatforms, livereload }) { { global: true, }, - ) + ); // Live reload - minimal rebundle on change if (opts.devMode) { - bundler = watchify(bundler) + bundler = watchify(bundler); // on any file update, re-runs the bundler bundler.on('update', () => { - performBundle() - }) + performBundle(); + }); } - return bundler + return bundler; } } function getEnvironment({ devMode, test }) { // get environment slug if (devMode) { - return 'development' + return 'development'; } else if (test) { - return 'testing' + return 'testing'; } else if (process.env.CIRCLE_BRANCH === 'master') { - return 'production' + return 'production'; } else if ( /^Version-v(\d+)[.](\d+)[.](\d+)/u.test(process.env.CIRCLE_BRANCH) ) { - return 'release-candidate' + return 'release-candidate'; } else if (process.env.CIRCLE_BRANCH === 'develop') { - return 'staging' + return 'staging'; } else if (process.env.CIRCLE_PULL_REQUEST) { - return 'pull-request' + return 'pull-request'; } - return 'other' + return 'other'; } function beep() { - process.stdout.write('\x07') + process.stdout.write('\x07'); } function gracefulError(err) { - console.warn(err) - beep() + console.warn(err); + beep(); } diff --git a/development/build/static.js b/development/build/static.js index ee33416433..d041d87ae3 100644 --- a/development/build/static.js +++ b/development/build/static.js @@ -1,13 +1,13 @@ -const path = require('path') -const fs = require('fs-extra') -const watch = require('gulp-watch') -const glob = require('fast-glob') +const path = require('path'); +const fs = require('fs-extra'); +const watch = require('gulp-watch'); +const glob = require('fast-glob'); -const locales = require('../../app/_locales/index.json') +const locales = require('../../app/_locales/index.json'); -const { createTask, composeSeries } = require('./task') +const { createTask, composeSeries } = require('./task'); -module.exports = createStaticAssetTasks +module.exports = createStaticAssetTasks; const copyTargets = [ { @@ -57,20 +57,20 @@ const copyTargets = [ pattern: `runLockdown.js`, dest: ``, }, -] +]; -const languageTags = new Set() +const languageTags = new Set(); for (const locale of locales) { - const { code } = locale - const tag = code.split('_')[0] - languageTags.add(tag) + const { code } = locale; + const tag = code.split('_')[0]; + languageTags.add(tag); } for (const tag of languageTags) { copyTargets.push({ src: `./node_modules/@formatjs/intl-relativetimeformat/dist/locale-data/${tag}.json`, dest: `intl/${tag}/relative-time-format-data.json`, - }) + }); } const copyTargetsDev = [ @@ -80,7 +80,7 @@ const copyTargetsDev = [ pattern: '/chromereload.js', dest: ``, }, -] +]; function createStaticAssetTasks({ livereload, browserPlatforms }) { const prod = createTask( @@ -88,31 +88,31 @@ function createStaticAssetTasks({ livereload, browserPlatforms }) { composeSeries( ...copyTargets.map((target) => { return async function copyStaticAssets() { - await performCopy(target) - } + await performCopy(target); + }; }), ), - ) + ); const dev = createTask( 'static:dev', composeSeries( ...copyTargetsDev.map((target) => { return async function copyStaticAssets() { - await setupLiveCopy(target) - } + await setupLiveCopy(target); + }; }), ), - ) + ); - return { dev, prod } + return { dev, prod }; async function setupLiveCopy(target) { - const pattern = target.pattern || '/**/*' + const pattern = target.pattern || '/**/*'; watch(target.src + pattern, (event) => { - livereload.changed(event.path) - performCopy(target) - }) - await performCopy(target) + livereload.changed(event.path); + performCopy(target); + }); + await performCopy(target); } async function performCopy(target) { @@ -123,25 +123,25 @@ function createStaticAssetTasks({ livereload, browserPlatforms }) { target.src, `${target.src}${target.pattern}`, `./dist/${platform}/${target.dest}`, - ) + ); } else { await copyGlob( target.src, `${target.src}`, `./dist/${platform}/${target.dest}`, - ) + ); } }), - ) + ); } async function copyGlob(baseDir, srcGlob, dest) { - const sources = await glob(srcGlob, { onlyFiles: false }) + const sources = await glob(srcGlob, { onlyFiles: false }); await Promise.all( sources.map(async (src) => { - const relativePath = path.relative(baseDir, src) - await fs.copy(src, `${dest}${relativePath}`) + const relativePath = path.relative(baseDir, src); + await fs.copy(src, `${dest}${relativePath}`); }), - ) + ); } } diff --git a/development/build/styles.js b/development/build/styles.js index c8b9e67189..b1b31fbef2 100644 --- a/development/build/styles.js +++ b/development/build/styles.js @@ -1,18 +1,18 @@ -const pify = require('pify') -const gulp = require('gulp') -const sass = require('gulp-sass') -sass.compiler = require('sass') -const autoprefixer = require('gulp-autoprefixer') -const gulpStylelint = require('gulp-stylelint') -const watch = require('gulp-watch') -const sourcemaps = require('gulp-sourcemaps') -const rtlcss = require('gulp-rtlcss') -const rename = require('gulp-rename') -const pump = pify(require('pump')) -const { createTask } = require('./task') +const pify = require('pify'); +const gulp = require('gulp'); +const sass = require('gulp-sass'); +sass.compiler = require('sass'); +const autoprefixer = require('gulp-autoprefixer'); +const gulpStylelint = require('gulp-stylelint'); +const watch = require('gulp-watch'); +const sourcemaps = require('gulp-sourcemaps'); +const rtlcss = require('gulp-rtlcss'); +const rename = require('gulp-rename'); +const pump = pify(require('pump')); +const { createTask } = require('./task'); // scss compilation and autoprefixing tasks -module.exports = createStyleTasks +module.exports = createStyleTasks; function createStyleTasks({ livereload }) { const prod = createTask( @@ -22,7 +22,7 @@ function createStyleTasks({ livereload }) { dest: 'ui/app/css/output', devMode: false, }), - ) + ); const dev = createTask( 'styles:dev', @@ -32,7 +32,7 @@ function createStyleTasks({ livereload }) { devMode: true, pattern: 'ui/app/**/*.scss', }), - ) + ); const lint = createTask('lint-scss', function () { return gulp.src('ui/app/css/itcss/**/*.scss').pipe( @@ -40,27 +40,27 @@ function createStyleTasks({ livereload }) { reporters: [{ formatter: 'string', console: true }], fix: true, }), - ) - }) + ); + }); - return { prod, dev, lint } + return { prod, dev, lint }; function createScssBuildTask({ src, dest, devMode, pattern }) { return async function () { if (devMode) { watch(pattern, async (event) => { - await buildScss() - livereload.changed(event.path) - }) + await buildScss(); + livereload.changed(event.path); + }); } - await buildScss() - } + await buildScss(); + }; async function buildScss() { await Promise.all([ buildScssPipeline(src, dest, devMode, false), buildScssPipeline(src, dest, devMode, true), - ]) + ]); } } } @@ -78,5 +78,5 @@ async function buildScssPipeline(src, dest, devMode, rtl) { devMode && sourcemaps.write(), gulp.dest(dest), ].filter(Boolean), - ) + ); } diff --git a/development/build/task.js b/development/build/task.js index 1ed252413a..e4de01ef65 100644 --- a/development/build/task.js +++ b/development/build/task.js @@ -1,8 +1,8 @@ -const EventEmitter = require('events') -const spawn = require('cross-spawn') +const EventEmitter = require('events'); +const spawn = require('cross-spawn'); -const tasks = {} -const taskEvents = new EventEmitter() +const tasks = {}; +const taskEvents = new EventEmitter(); module.exports = { detectAndRunEntryTask, @@ -13,74 +13,74 @@ module.exports = { composeSeries, composeParallel, runInChildProcess, -} +}; -const { setupTaskDisplay } = require('./display') +const { setupTaskDisplay } = require('./display'); function detectAndRunEntryTask() { // get requested task name and execute - const taskName = process.argv[2] + const taskName = process.argv[2]; if (!taskName) { - throw new Error(`MetaMask build: No task name specified`) + throw new Error(`MetaMask build: No task name specified`); } - const skipStats = process.argv[3] === '--skip-stats' + const skipStats = process.argv[3] === '--skip-stats'; - runTask(taskName, { skipStats }) + runTask(taskName, { skipStats }); } async function runTask(taskName, { skipStats } = {}) { if (!(taskName in tasks)) { - throw new Error(`MetaMask build: Unrecognized task name "${taskName}"`) + throw new Error(`MetaMask build: Unrecognized task name "${taskName}"`); } if (!skipStats) { - setupTaskDisplay(taskEvents) - console.log(`running task "${taskName}"...`) + setupTaskDisplay(taskEvents); + console.log(`running task "${taskName}"...`); } try { - await tasks[taskName]() + await tasks[taskName](); } catch (err) { console.error( `MetaMask build: Encountered an error while running task "${taskName}".`, - ) - console.error(err) - process.exit(1) + ); + console.error(err); + process.exit(1); } - taskEvents.emit('complete') + taskEvents.emit('complete'); } function createTask(taskName, taskFn) { if (taskName in tasks) { throw new Error( `MetaMask build: task "${taskName}" already exists. Refusing to redefine`, - ) + ); } - const task = instrumentForTaskStats(taskName, taskFn) - task.taskName = taskName - tasks[taskName] = task - return task + const task = instrumentForTaskStats(taskName, taskFn); + task.taskName = taskName; + tasks[taskName] = task; + return task; } function runInChildProcess(task) { - const taskName = typeof task === 'string' ? task : task.taskName + const taskName = typeof task === 'string' ? task : task.taskName; if (!taskName) { throw new Error( `MetaMask build: runInChildProcess unable to identify task name`, - ) + ); } return instrumentForTaskStats(taskName, async () => { const childProcess = spawn('yarn', ['build', taskName, '--skip-stats'], { env: process.env, - }) + }); // forward logs to main process // skip the first stdout event (announcing the process command) childProcess.stdout.once('data', () => { childProcess.stdout.on('data', (data) => process.stdout.write(`${taskName}: ${data}`), - ) - }) + ); + }); childProcess.stderr.on('data', (data) => process.stderr.write(`${taskName}: ${data}`), - ) + ); // await end of process await new Promise((resolve, reject) => { childProcess.once('close', (errCode) => { @@ -89,37 +89,37 @@ function runInChildProcess(task) { new Error( `MetaMask build: runInChildProcess for task "${taskName}" encountered an error ${errCode}`, ), - ) - return + ); + return; } - resolve() - }) - }) - }) + resolve(); + }); + }); + }); } function instrumentForTaskStats(taskName, asyncFn) { return async () => { - const start = Date.now() - taskEvents.emit('start', [taskName, start]) - await asyncFn() - const end = Date.now() - taskEvents.emit('end', [taskName, start, end]) - } + const start = Date.now(); + taskEvents.emit('start', [taskName, start]); + await asyncFn(); + const end = Date.now(); + taskEvents.emit('end', [taskName, start, end]); + }; } function composeSeries(...subtasks) { return async () => { - const realTasks = subtasks + const realTasks = subtasks; for (const subtask of realTasks) { - await subtask() + await subtask(); } - } + }; } function composeParallel(...subtasks) { return async () => { - const realTasks = subtasks - await Promise.all(realTasks.map((subtask) => subtask())) - } + const realTasks = subtasks; + await Promise.all(realTasks.map((subtask) => subtask())); + }; } diff --git a/development/create-static-server.js b/development/create-static-server.js index 3312c43e7a..c01a5e16a6 100644 --- a/development/create-static-server.js +++ b/development/create-static-server.js @@ -1,22 +1,22 @@ -const http = require('http') -const path = require('path') +const http = require('http'); +const path = require('path'); -const serveHandler = require('serve-handler') +const serveHandler = require('serve-handler'); const createStaticServer = (rootDirectory) => { return http.createServer((request, response) => { if (request.url.startsWith('/node_modules/')) { - request.url = request.url.substr(14) + request.url = request.url.substr(14); return serveHandler(request, response, { directoryListing: false, public: path.resolve('./node_modules'), - }) + }); } return serveHandler(request, response, { directoryListing: false, public: rootDirectory, - }) - }) -} + }); + }); +}; -module.exports = createStaticServer +module.exports = createStaticServer; diff --git a/development/lib/create-segment-server.js b/development/lib/create-segment-server.js index 2a15a34c91..00f999c9e9 100644 --- a/development/lib/create-segment-server.js +++ b/development/lib/create-segment-server.js @@ -1,4 +1,4 @@ -const http = require('http') +const http = require('http'); /** * This is the default error handler to be used by this mock segment server. @@ -7,8 +7,8 @@ const http = require('http') * @param {Error} error - The server error */ function defaultOnError(error) { - console.log(error) - process.exit(1) + console.log(error); + process.exit(1); } /** @@ -32,62 +32,62 @@ function defaultOnError(error) { */ function createSegmentServer(onRequest, onError = defaultOnError) { const server = http.createServer(async (request, response) => { - const chunks = [] + const chunks = []; request.on('data', (chunk) => { - chunks.push(chunk) - }) + chunks.push(chunk); + }); await new Promise((resolve) => { request.on('end', () => { - resolve() - }) - }) + resolve(); + }); + }); // respond to preflight request if (request.method === 'OPTIONS') { - response.setHeader('Access-Control-Allow-Origin', '*') - response.setHeader('Access-Control-Allow-Methods', '*') - response.setHeader('Access-Control-Allow-Headers', '*') - response.statusCode = 200 - response.end() - return + response.setHeader('Access-Control-Allow-Origin', '*'); + response.setHeader('Access-Control-Allow-Methods', '*'); + response.setHeader('Access-Control-Allow-Headers', '*'); + response.statusCode = 200; + response.end(); + return; } - let metricEvents = [] + let metricEvents = []; if (chunks.length) { - const body = Buffer.concat(chunks).toString() - const segmentPayload = JSON.parse(body) - metricEvents = segmentPayload.batch + const body = Buffer.concat(chunks).toString(); + const segmentPayload = JSON.parse(body); + metricEvents = segmentPayload.batch; } - onRequest(request, response, metricEvents) - }) + onRequest(request, response, metricEvents); + }); - server.on('error', onError) + server.on('error', onError); return { start: async (port) => { await new Promise((resolve, reject) => { server.listen(port, (error) => { if (error) { - return reject(error) + return reject(error); } - return resolve() - }) - }) + return resolve(); + }); + }); }, stop: async () => { await new Promise((resolve, reject) => { server.close((error) => { if (error) { - return reject(error) + return reject(error); } - return resolve() - }) - }) + return resolve(); + }); + }); }, - } + }; } -module.exports = { createSegmentServer } +module.exports = { createSegmentServer }; diff --git a/development/lib/locales.js b/development/lib/locales.js index 86f1e6ec96..0b83d0ac6a 100644 --- a/development/lib/locales.js +++ b/development/lib/locales.js @@ -1,10 +1,10 @@ -const path = require('path') -const fs = require('fs') -const { promisify } = require('util') +const path = require('path'); +const fs = require('fs'); +const { promisify } = require('util'); -const log = require('loglevel') +const log = require('loglevel'); -const readFile = promisify(fs.readFile) +const readFile = promisify(fs.readFile); function getLocalePath(code) { return path.resolve( @@ -15,26 +15,26 @@ function getLocalePath(code) { '_locales', code, 'messages.json', - ) + ); } async function getLocale(code) { try { - const localeFilePath = getLocalePath(code) - const fileContents = await readFile(localeFilePath, 'utf8') - return JSON.parse(fileContents) + const localeFilePath = getLocalePath(code); + const fileContents = await readFile(localeFilePath, 'utf8'); + return JSON.parse(fileContents); } catch (e) { if (e.code === 'ENOENT') { - log.error('Locale file not found') + log.error('Locale file not found'); } else { - log.error(`Error opening your locale ("${code}") file: `, e) + log.error(`Error opening your locale ("${code}") file: `, e); } - process.exit(1) + process.exit(1); } } function compareLocalesForMissingItems({ base, subject }) { - return Object.keys(base).filter((key) => !subject[key]) + return Object.keys(base).filter((key) => !subject[key]); } function compareLocalesForMissingDescriptions({ englishLocale, targetLocale }) { @@ -43,7 +43,7 @@ function compareLocalesForMissingDescriptions({ englishLocale, targetLocale }) { targetLocale[key] !== undefined && englishLocale[key].description !== undefined && englishLocale[key].description !== targetLocale[key].description, - ) + ); } module.exports = { @@ -51,4 +51,4 @@ module.exports = { compareLocalesForMissingItems, getLocale, getLocalePath, -} +}; diff --git a/development/lib/parse-port.js b/development/lib/parse-port.js index 0a53712fb6..4368da79f2 100644 --- a/development/lib/parse-port.js +++ b/development/lib/parse-port.js @@ -6,15 +6,15 @@ * @returns {number} The parsed port number */ function parsePort(portString) { - const port = Number(portString) + const port = Number(portString); if (!Number.isInteger(port)) { - throw new Error(`Port '${portString}' is invalid; must be an integer`) + throw new Error(`Port '${portString}' is invalid; must be an integer`); } else if (port < 0 || port > 65535) { throw new Error( `Port '${portString}' is out of range; must be between 0 and 65535 inclusive`, - ) + ); } - return port + return port; } -module.exports = { parsePort } +module.exports = { parsePort }; diff --git a/development/metamaskbot-build-announce.js b/development/metamaskbot-build-announce.js index 8ea766ed33..f0fd332603 100755 --- a/development/metamaskbot-build-announce.js +++ b/development/metamaskbot-build-announce.js @@ -1,42 +1,42 @@ #!/usr/bin/env node -const { promises: fs } = require('fs') -const path = require('path') -const fetch = require('node-fetch') -const VERSION = require('../dist/chrome/manifest.json').version // eslint-disable-line import/no-unresolved +const { promises: fs } = require('fs'); +const path = require('path'); +const fetch = require('node-fetch'); +const VERSION = require('../dist/chrome/manifest.json').version; // eslint-disable-line import/no-unresolved -start().catch(console.error) +start().catch(console.error); function capitalizeFirstLetter(string) { - return string.charAt(0).toUpperCase() + string.slice(1) + return string.charAt(0).toUpperCase() + string.slice(1); } async function start() { - const { GITHUB_COMMENT_TOKEN, CIRCLE_PULL_REQUEST } = process.env - console.log('CIRCLE_PULL_REQUEST', CIRCLE_PULL_REQUEST) - const { CIRCLE_SHA1 } = process.env - console.log('CIRCLE_SHA1', CIRCLE_SHA1) - const { CIRCLE_BUILD_NUM } = process.env - console.log('CIRCLE_BUILD_NUM', CIRCLE_BUILD_NUM) + const { GITHUB_COMMENT_TOKEN, CIRCLE_PULL_REQUEST } = process.env; + console.log('CIRCLE_PULL_REQUEST', CIRCLE_PULL_REQUEST); + const { CIRCLE_SHA1 } = process.env; + console.log('CIRCLE_SHA1', CIRCLE_SHA1); + const { CIRCLE_BUILD_NUM } = process.env; + console.log('CIRCLE_BUILD_NUM', CIRCLE_BUILD_NUM); if (!CIRCLE_PULL_REQUEST) { - console.warn(`No pull request detected for commit "${CIRCLE_SHA1}"`) - return + console.warn(`No pull request detected for commit "${CIRCLE_SHA1}"`); + return; } - const CIRCLE_PR_NUMBER = CIRCLE_PULL_REQUEST.split('/').pop() - const SHORT_SHA1 = CIRCLE_SHA1.slice(0, 7) - const BUILD_LINK_BASE = `https://${CIRCLE_BUILD_NUM}-42009758-gh.circle-artifacts.com/0` + const CIRCLE_PR_NUMBER = CIRCLE_PULL_REQUEST.split('/').pop(); + const SHORT_SHA1 = CIRCLE_SHA1.slice(0, 7); + const BUILD_LINK_BASE = `https://${CIRCLE_BUILD_NUM}-42009758-gh.circle-artifacts.com/0`; // build the github comment content // links to extension builds - const platforms = ['chrome', 'firefox', 'opera'] + const platforms = ['chrome', 'firefox', 'opera']; const buildLinks = platforms .map((platform) => { - const url = `${BUILD_LINK_BASE}/builds/metamask-${platform}-${VERSION}.zip` - return `${platform}` + const url = `${BUILD_LINK_BASE}/builds/metamask-${platform}-${VERSION}.zip`; + return `${platform}`; }) - .join(', ') + .join(', '); // links to bundle browser builds const bundles = [ @@ -47,22 +47,22 @@ async function start() { 'ui-libs', 'bg-libs', 'phishing-detect', - ] + ]; const bundleLinks = bundles .map((bundle) => { - const url = `${BUILD_LINK_BASE}/build-artifacts/source-map-explorer/${bundle}.html` - return `${bundle}` + const url = `${BUILD_LINK_BASE}/build-artifacts/source-map-explorer/${bundle}.html`; + return `${bundle}`; }) - .join(', ') + .join(', '); - const coverageUrl = `${BUILD_LINK_BASE}/coverage/index.html` - const coverageLink = `Report` + const coverageUrl = `${BUILD_LINK_BASE}/coverage/index.html`; + const coverageLink = `Report`; - const storybookUrl = `${BUILD_LINK_BASE}/storybook/index.html` - const storybookLink = `Storybook` + const storybookUrl = `${BUILD_LINK_BASE}/storybook/index.html`; + const storybookLink = `Storybook`; // link to artifacts - const allArtifactsUrl = `https://circleci.com/gh/MetaMask/metamask-extension/${CIRCLE_BUILD_NUM}#artifacts/containers/0` + const allArtifactsUrl = `https://circleci.com/gh/MetaMask/metamask-extension/${CIRCLE_BUILD_NUM}#artifacts/containers/0`; const contentRows = [ `builds: ${buildLinks}`, @@ -70,124 +70,124 @@ async function start() { `code coverage: ${coverageLink}`, `storybook: ${storybookLink}`, `all artifacts`, - ] + ]; const hiddenContent = `
    ${contentRows .map((row) => `
  • ${row}
  • `) - .join('\n')}
` - const exposedContent = `Builds ready [${SHORT_SHA1}]` - const artifactsBody = `
${exposedContent}${hiddenContent}
` + .join('\n')}`; + const exposedContent = `Builds ready [${SHORT_SHA1}]`; + const artifactsBody = `
${exposedContent}${hiddenContent}
`; - const benchmarkResults = {} + const benchmarkResults = {}; for (const platform of platforms) { const benchmarkPath = path.resolve( __dirname, '..', path.join('test-artifacts', platform, 'benchmark', 'pageload.json'), - ) + ); try { - const data = await fs.readFile(benchmarkPath, 'utf8') - const benchmark = JSON.parse(data) - benchmarkResults[platform] = benchmark + const data = await fs.readFile(benchmarkPath, 'utf8'); + const benchmark = JSON.parse(data); + benchmarkResults[platform] = benchmark; } catch (error) { if (error.code === 'ENOENT') { - console.log(`No benchmark data found for ${platform}; skipping`) + console.log(`No benchmark data found for ${platform}; skipping`); } else { console.error( `Error encountered processing benchmark data for '${platform}': '${error}'`, - ) + ); } } } - const summaryPlatform = 'chrome' - const summaryPage = 'home' - let commentBody + const summaryPlatform = 'chrome'; + const summaryPage = 'home'; + let commentBody; if (benchmarkResults[summaryPlatform]) { try { const summaryPageLoad = Math.round( parseFloat(benchmarkResults[summaryPlatform][summaryPage].average.load), - ) + ); const summaryPageLoadMarginOfError = Math.round( parseFloat( benchmarkResults[summaryPlatform][summaryPage].marginOfError.load, ), - ) - const benchmarkSummary = `Page Load Metrics (${summaryPageLoad} ± ${summaryPageLoadMarginOfError} ms)` + ); + const benchmarkSummary = `Page Load Metrics (${summaryPageLoad} ± ${summaryPageLoadMarginOfError} ms)`; - const allPlatforms = new Set() - const allPages = new Set() - const allMetrics = new Set() - const allMeasures = new Set() + const allPlatforms = new Set(); + const allPages = new Set(); + const allMetrics = new Set(); + const allMeasures = new Set(); for (const platform of Object.keys(benchmarkResults)) { - allPlatforms.add(platform) - const platformBenchmark = benchmarkResults[platform] - const pages = Object.keys(platformBenchmark) + allPlatforms.add(platform); + const platformBenchmark = benchmarkResults[platform]; + const pages = Object.keys(platformBenchmark); for (const page of pages) { - allPages.add(page) - const pageBenchmark = platformBenchmark[page] - const measures = Object.keys(pageBenchmark) + allPages.add(page); + const pageBenchmark = platformBenchmark[page]; + const measures = Object.keys(pageBenchmark); for (const measure of measures) { - allMeasures.add(measure) - const measureBenchmark = pageBenchmark[measure] - const metrics = Object.keys(measureBenchmark) + allMeasures.add(measure); + const measureBenchmark = pageBenchmark[measure]; + const metrics = Object.keys(measureBenchmark); for (const metric of metrics) { - allMetrics.add(metric) + allMetrics.add(metric); } } } } - const tableRows = [] + const tableRows = []; for (const platform of allPlatforms) { - const pageRows = [] + const pageRows = []; for (const page of allPages) { - const metricRows = [] + const metricRows = []; for (const metric of allMetrics) { - let metricData = `${metric}` + let metricData = `${metric}`; for (const measure of allMeasures) { metricData += `${Math.round( parseFloat(benchmarkResults[platform][page][measure][metric]), - )}` + )}`; } - metricRows.push(metricData) + metricRows.push(metricData); } metricRows[0] = `${capitalizeFirstLetter(page)}${metricRows[0]}` - pageRows.push(...metricRows) + }">${capitalizeFirstLetter(page)}${metricRows[0]}`; + pageRows.push(...metricRows); } pageRows[0] = `${capitalizeFirstLetter(platform)}${pageRows[0]}` + }">${capitalizeFirstLetter(platform)}${pageRows[0]}`; for (const row of pageRows) { - tableRows.push(`${row}`) + tableRows.push(`${row}`); } } - const benchmarkTableHeaders = ['Platform', 'Page', 'Metric'] + const benchmarkTableHeaders = ['Platform', 'Page', 'Metric']; for (const measure of allMeasures) { - benchmarkTableHeaders.push(`${capitalizeFirstLetter(measure)} (ms)`) + benchmarkTableHeaders.push(`${capitalizeFirstLetter(measure)} (ms)`); } const benchmarkTableHeader = `${benchmarkTableHeaders .map((header) => `${header}`) - .join('')}` - const benchmarkTableBody = `${tableRows.join('')}` - const benchmarkTable = `${benchmarkTableHeader}${benchmarkTableBody}
` - const benchmarkBody = `
${benchmarkSummary}${benchmarkTable}
` - commentBody = `${artifactsBody}${benchmarkBody}` + .join('')}`; + const benchmarkTableBody = `${tableRows.join('')}`; + const benchmarkTable = `${benchmarkTableHeader}${benchmarkTableBody}
`; + const benchmarkBody = `
${benchmarkSummary}${benchmarkTable}
`; + commentBody = `${artifactsBody}${benchmarkBody}`; } catch (error) { - console.error(`Error constructing benchmark results: '${error}'`) - commentBody = artifactsBody + console.error(`Error constructing benchmark results: '${error}'`); + commentBody = artifactsBody; } } else { - console.log(`No results for ${summaryPlatform} found; skipping benchmark`) - commentBody = artifactsBody + console.log(`No results for ${summaryPlatform} found; skipping benchmark`); + commentBody = artifactsBody; } - const JSON_PAYLOAD = JSON.stringify({ body: commentBody }) - const POST_COMMENT_URI = `https://api.github.com/repos/metamask/metamask-extension/issues/${CIRCLE_PR_NUMBER}/comments` - console.log(`Announcement:\n${commentBody}`) - console.log(`Posting to: ${POST_COMMENT_URI}`) + const JSON_PAYLOAD = JSON.stringify({ body: commentBody }); + const POST_COMMENT_URI = `https://api.github.com/repos/metamask/metamask-extension/issues/${CIRCLE_PR_NUMBER}/comments`; + console.log(`Announcement:\n${commentBody}`); + console.log(`Posting to: ${POST_COMMENT_URI}`); const response = await fetch(POST_COMMENT_URI, { method: 'POST', @@ -196,8 +196,8 @@ async function start() { 'User-Agent': 'metamaskbot', Authorization: `token ${GITHUB_COMMENT_TOKEN}`, }, - }) + }); if (!response.ok) { - throw new Error(`Post comment failed with status '${response.statusText}'`) + throw new Error(`Post comment failed with status '${response.statusText}'`); } } diff --git a/development/missing-locale-strings.js b/development/missing-locale-strings.js index 74f26b8bd0..387e13501d 100644 --- a/development/missing-locale-strings.js +++ b/development/missing-locale-strings.js @@ -15,64 +15,64 @@ // // ////////////////////////////////////////////////////////////////////////////// -const log = require('loglevel') -const localeIndex = require('../app/_locales/index.json') -const { compareLocalesForMissingItems, getLocale } = require('./lib/locales') +const log = require('loglevel'); +const localeIndex = require('../app/_locales/index.json'); +const { compareLocalesForMissingItems, getLocale } = require('./lib/locales'); -log.setDefaultLevel('info') +log.setDefaultLevel('info'); -let verbose = false -let specifiedLocale +let verbose = false; +let specifiedLocale; for (const arg of process.argv.slice(2)) { if (arg === '--verbose') { - verbose = true + verbose = true; } else { - specifiedLocale = arg + specifiedLocale = arg; } } main().catch((error) => { - log.error(error) - process.exit(1) -}) + log.error(error); + process.exit(1); +}); async function main() { if (specifiedLocale === 'en') { throw new Error( `Can't compare 'en' locale to itself to find missing messages`, - ) + ); } else if (specifiedLocale) { - await reportMissingMessages(specifiedLocale) + await reportMissingMessages(specifiedLocale); } else { const localeCodes = localeIndex .filter((localeMeta) => localeMeta.code !== 'en') - .map((localeMeta) => localeMeta.code) + .map((localeMeta) => localeMeta.code); for (const code of localeCodes) { - await reportMissingMessages(code) + await reportMissingMessages(code); } } } async function reportMissingMessages(code) { - const englishLocale = await getLocale('en') - const targetLocale = await getLocale(code) + const englishLocale = await getLocale('en'); + const targetLocale = await getLocale(code); const missingItems = compareLocalesForMissingItems({ base: englishLocale, subject: targetLocale, - }) + }); - const englishEntryCount = Object.keys(englishLocale).length + const englishEntryCount = Object.keys(englishLocale).length; const coveragePercent = - (100 * (englishEntryCount - missingItems.length)) / englishEntryCount + (100 * (englishEntryCount - missingItems.length)) / englishEntryCount; - log.info(`**${code}**: ${coveragePercent.toFixed(2)}% coverage`) + log.info(`**${code}**: ${coveragePercent.toFixed(2)}% coverage`); if (missingItems.length && verbose) { - console.log(`**${code}**: ${missingItems.length} missing messages`) - log.info('Extra items that should not be localized:') + console.log(`**${code}**: ${missingItems.length} missing messages`); + log.info('Extra items that should not be localized:'); missingItems.forEach(function (key) { - log.info(` - [ ] ${key}`) - }) + log.info(` - [ ] ${key}`); + }); } } diff --git a/development/mock-3box.js b/development/mock-3box.js index 14c888f868..ebbbe325d9 100644 --- a/development/mock-3box.js +++ b/development/mock-3box.js @@ -1,11 +1,11 @@ function delay(time) { - return new Promise((resolve) => setTimeout(resolve, time)) + return new Promise((resolve) => setTimeout(resolve, time)); } async function loadFromMock3Box(key) { - const res = await window.fetch(`http://localhost:8889?key=${key}`) - const text = await res.text() - return text.length ? JSON.parse(text) : null + const res = await window.fetch(`http://localhost:8889?key=${key}`); + const text = await res.text(); + return text.length ? JSON.parse(text) : null; } async function saveToMock3Box(key, newDataAtKey) { @@ -15,54 +15,54 @@ async function saveToMock3Box(key, newDataAtKey) { key, data: newDataAtKey, }), - }) + }); - return res.text() + return res.text(); } class Mock3Box { static openBox(address) { - this.address = address + this.address = address; return Promise.resolve({ onSyncDone: (cb) => { - setTimeout(cb, 200) + setTimeout(cb, 200); }, openSpace: async (spaceName, config) => { - const { onSyncDone } = config - this.spaceName = spaceName + const { onSyncDone } = config; + this.spaceName = spaceName; - setTimeout(onSyncDone, 150) + setTimeout(onSyncDone, 150); - await delay(50) + await delay(50); return { private: { get: async (key) => { - await delay(50) + await delay(50); const res = await loadFromMock3Box( `${this.address}-${this.spaceName}-${key}`, - ) - return res + ); + return res; }, set: async (key, data) => { await saveToMock3Box( `${this.address}-${this.spaceName}-${key}`, data, - ) - await delay(50) - return null + ); + await delay(50); + return null; }, }, - } + }; }, logout: () => undefined, - }) + }); } static async getConfig(address) { - const backup = await loadFromMock3Box(`${address}-metamask-metamaskBackup`) - return backup ? { spaces: { metamask: {} } } : {} + const backup = await loadFromMock3Box(`${address}-metamask-metamaskBackup`); + return backup ? { spaces: { metamask: {} } } : {}; } } -module.exports = Mock3Box +module.exports = Mock3Box; diff --git a/development/mock-segment.js b/development/mock-segment.js index f4e2acb580..b05e661d63 100644 --- a/development/mock-segment.js +++ b/development/mock-segment.js @@ -1,28 +1,28 @@ -const { createSegmentServer } = require('./lib/create-segment-server') -const { parsePort } = require('./lib/parse-port') +const { createSegmentServer } = require('./lib/create-segment-server'); +const { parsePort } = require('./lib/parse-port'); -const DEFAULT_PORT = 9090 -const prefix = '[mock-segment]' +const DEFAULT_PORT = 9090; +const prefix = '[mock-segment]'; function onRequest(request, response, events) { - console.log(`${prefix}: ${request.method} ${request.url}`) + console.log(`${prefix}: ${request.method} ${request.url}`); const eventDescriptions = events.map((event) => { if (event.type === 'track') { - return event.event + return event.event; } else if (event.type === 'page') { - return event.name + return event.name; } - return `[Unrecognized event type: ${event.type}]` - }) - console.log(`${prefix}: Events received: ${eventDescriptions.join(', ')}`) + return `[Unrecognized event type: ${event.type}]`; + }); + console.log(`${prefix}: Events received: ${eventDescriptions.join(', ')}`); - response.statusCode = 200 - response.end() + response.statusCode = 200; + response.end(); } function onError(error) { - console.error(error) - process.exit(1) + console.error(error); + process.exit(1); } /** @@ -45,24 +45,24 @@ function onError(error) { * metric events. */ const main = async () => { - const args = process.argv.slice(2) + const args = process.argv.slice(2); - let port = process.env.port || DEFAULT_PORT + let port = process.env.port || DEFAULT_PORT; while (args.length) { if (/^(--port|-p)$/u.test(args[0])) { if (args[1] === undefined) { - throw new Error('Missing port argument') + throw new Error('Missing port argument'); } - port = parsePort(args[1]) - args.splice(0, 2) + port = parsePort(args[1]); + args.splice(0, 2); } } - const server = createSegmentServer(onRequest, onError) + const server = createSegmentServer(onRequest, onError); - await server.start(port) - console.log(`${prefix}: Listening on port ${port}`) -} + await server.start(port); + console.log(`${prefix}: Listening on port ${port}`); +}; -main().catch(onError) +main().catch(onError); diff --git a/development/require-react-devtools.js b/development/require-react-devtools.js index 9d0b1f46da..9af12aa878 100644 --- a/development/require-react-devtools.js +++ b/development/require-react-devtools.js @@ -1 +1 @@ -require('react-devtools') +require('react-devtools'); diff --git a/development/sentry-publish.js b/development/sentry-publish.js index aad6e4ac48..6fee0f9501 100644 --- a/development/sentry-publish.js +++ b/development/sentry-publish.js @@ -1,84 +1,86 @@ #!/usr/bin/env node -const childProcess = require('child_process') -const pify = require('pify') +const childProcess = require('child_process'); +const pify = require('pify'); -const exec = pify(childProcess.exec, { multiArgs: true }) -const VERSION = require('../dist/chrome/manifest.json').version // eslint-disable-line import/no-unresolved +const exec = pify(childProcess.exec, { multiArgs: true }); +const VERSION = require('../dist/chrome/manifest.json').version; // eslint-disable-line import/no-unresolved start().catch((error) => { - console.error(error) - process.exit(1) -}) + console.error(error); + process.exit(1); +}); async function start() { - const authWorked = await checkIfAuthWorks() + const authWorked = await checkIfAuthWorks(); if (!authWorked) { - throw new Error(`Sentry auth failed`) + throw new Error(`Sentry auth failed`); } // check if version exists or not - const versionAlreadyExists = await checkIfVersionExists() + const versionAlreadyExists = await checkIfVersionExists(); // abort if versions exists if (versionAlreadyExists) { console.log( `Version "${VERSION}" already exists on Sentry, skipping version creation`, - ) + ); } else { // create sentry release - console.log(`creating Sentry release for "${VERSION}"...`) + console.log(`creating Sentry release for "${VERSION}"...`); await exec( `sentry-cli releases --org 'metamask' --project 'metamask' new ${VERSION}`, - ) + ); console.log( `removing any existing files from Sentry release "${VERSION}"...`, - ) + ); await exec( `sentry-cli releases --org 'metamask' --project 'metamask' files ${VERSION} delete --all`, - ) + ); } // check if version has artifacts or not const versionHasArtifacts = - versionAlreadyExists && (await checkIfVersionHasArtifacts()) + versionAlreadyExists && (await checkIfVersionHasArtifacts()); if (versionHasArtifacts) { console.log( `Version "${VERSION}" already has artifacts on Sentry, skipping sourcemap upload`, - ) - return + ); + return; } // upload sentry source and sourcemaps - await exec(`./development/sentry-upload-artifacts.sh --release ${VERSION}`) + await exec(`./development/sentry-upload-artifacts.sh --release ${VERSION}`); } async function checkIfAuthWorks() { const itWorked = await doesNotFail(async () => { - await exec(`sentry-cli releases --org 'metamask' --project 'metamask' list`) - }) - return itWorked + await exec( + `sentry-cli releases --org 'metamask' --project 'metamask' list`, + ); + }); + return itWorked; } async function checkIfVersionExists() { const versionAlreadyExists = await doesNotFail(async () => { await exec( `sentry-cli releases --org 'metamask' --project 'metamask' info ${VERSION}`, - ) - }) - return versionAlreadyExists + ); + }); + return versionAlreadyExists; } async function checkIfVersionHasArtifacts() { const artifacts = await exec( `sentry-cli releases --org 'metamask' --project 'metamask' files ${VERSION} list`, - ) + ); // When there's no artifacts, we get a response from the shell like this ['', ''] - return artifacts[0] && artifacts[0].length > 0 + return artifacts[0] && artifacts[0].length > 0; } async function doesNotFail(asyncFn) { try { - await asyncFn() - return true + await asyncFn(); + return true; } catch (err) { - return false + return false; } } diff --git a/development/show-deps-install-scripts.js b/development/show-deps-install-scripts.js index 3421ed3513..dca698b10c 100644 --- a/development/show-deps-install-scripts.js +++ b/development/show-deps-install-scripts.js @@ -1,40 +1,40 @@ // This script lists all dependencies that have package install scripts -const path = require('path') -const readInstalled = require('read-installed') +const path = require('path'); +const readInstalled = require('read-installed'); -const installScripts = ['preinstall', 'install', 'postinstall'] +const installScripts = ['preinstall', 'install', 'postinstall']; readInstalled('./', { dev: true }, function (err, data) { if (err) { - throw err + throw err; } - const deps = data.dependencies + const deps = data.dependencies; Object.entries(deps).forEach(([packageName, packageData]) => { - const packageScripts = packageData.scripts || {} - const scriptKeys = Reflect.ownKeys(packageScripts) + const packageScripts = packageData.scripts || {}; + const scriptKeys = Reflect.ownKeys(packageScripts); const hasInstallScript = installScripts.some((installKey) => scriptKeys.includes(installKey), - ) + ); if (!hasInstallScript) { - return + return; } - const matchingScripts = {} + const matchingScripts = {}; if (packageScripts.preinstall) { - matchingScripts.preinstall = packageScripts.preinstall + matchingScripts.preinstall = packageScripts.preinstall; } if (packageScripts.install) { - matchingScripts.install = packageScripts.install + matchingScripts.install = packageScripts.install; } if (packageScripts.postinstall) { - matchingScripts.postinstall = packageScripts.postinstall + matchingScripts.postinstall = packageScripts.postinstall; } - const scriptNames = Reflect.ownKeys(matchingScripts) + const scriptNames = Reflect.ownKeys(matchingScripts); - const relativePath = path.relative(process.cwd(), packageData.path) + const relativePath = path.relative(process.cwd(), packageData.path); - console.log(`${packageName}: ${relativePath} ${scriptNames}`) - }) -}) + console.log(`${packageName}: ${relativePath} ${scriptNames}`); + }); +}); diff --git a/development/sourcemap-validator.js b/development/sourcemap-validator.js index 6730b87852..15feb56f18 100644 --- a/development/sourcemap-validator.js +++ b/development/sourcemap-validator.js @@ -1,9 +1,9 @@ -const fs = require('fs') -const path = require('path') -const { SourceMapConsumer } = require('source-map') -const pify = require('pify') +const fs = require('fs'); +const path = require('path'); +const { SourceMapConsumer } = require('source-map'); +const pify = require('pify'); -const fsAsync = pify(fs) +const fsAsync = pify(fs); // // Utility to help check if sourcemaps are working @@ -14,9 +14,9 @@ const fsAsync = pify(fs) // start().catch((error) => { - console.error(error) - process.exit(1) -}) + console.error(error); + process.exit(1); +}); async function start() { const targetFiles = [ @@ -27,48 +27,48 @@ async function start() { 'phishing-detect.js', `ui.js`, // `ui-libs.js`, skipped because source maps are invalid due to browserify bug: https://github.com/browserify/browserify/issues/1971 - ] - let valid = true + ]; + let valid = true; for (const buildName of targetFiles) { - const fileIsValid = await validateSourcemapForFile({ buildName }) - valid = valid && fileIsValid + const fileIsValid = await validateSourcemapForFile({ buildName }); + valid = valid && fileIsValid; } if (!valid) { - process.exit(1) + process.exit(1); } } async function validateSourcemapForFile({ buildName }) { - console.log(`build "${buildName}"`) - const platform = `chrome` + console.log(`build "${buildName}"`); + const platform = `chrome`; // load build and sourcemaps - let rawBuild + let rawBuild; try { const filePath = path.join( __dirname, `/../dist/${platform}/`, `${buildName}`, - ) - rawBuild = await fsAsync.readFile(filePath, 'utf8') + ); + rawBuild = await fsAsync.readFile(filePath, 'utf8'); } catch (_) { // empty } if (!rawBuild) { throw new Error( `SourcemapValidator - failed to load source file for "${buildName}"`, - ) + ); } // attempt to load in dist mode - let rawSourceMap + let rawSourceMap; try { const filePath = path.join( __dirname, `/../dist/sourcemaps/`, `${buildName}.map`, - ) - rawSourceMap = await fsAsync.readFile(filePath, 'utf8') + ); + rawSourceMap = await fsAsync.readFile(filePath, 'utf8'); } catch (_) { // empty } @@ -78,94 +78,96 @@ async function validateSourcemapForFile({ buildName }) { __dirname, `/../dist/${platform}/`, `${buildName}.map`, - ) - rawSourceMap = await fsAsync.readFile(filePath, 'utf8') + ); + rawSourceMap = await fsAsync.readFile(filePath, 'utf8'); } catch (_) { // empty } if (!rawSourceMap) { throw new Error( `SourcemapValidator - failed to load sourcemaps for "${buildName}"`, - ) + ); } - const consumer = await new SourceMapConsumer(rawSourceMap) + const consumer = await new SourceMapConsumer(rawSourceMap); - const hasContentsOfAllSources = consumer.hasContentsOfAllSources() + const hasContentsOfAllSources = consumer.hasContentsOfAllSources(); if (!hasContentsOfAllSources) { - console.warn('SourcemapValidator - missing content of some sources...') + console.warn('SourcemapValidator - missing content of some sources...'); } - console.log(` sampling from ${consumer.sources.length} files`) - let sampleCount = 0 - let valid = true + console.log(` sampling from ${consumer.sources.length} files`); + let sampleCount = 0; + let valid = true; - const buildLines = rawBuild.split('\n') - const targetString = 'new Error' + const buildLines = rawBuild.split('\n'); + const targetString = 'new Error'; // const targetString = 'null' - const matchesPerLine = buildLines.map((line) => indicesOf(targetString, line)) + const matchesPerLine = buildLines.map((line) => + indicesOf(targetString, line), + ); matchesPerLine.forEach((matchIndices, lineIndex) => { matchIndices.forEach((matchColumn) => { - sampleCount += 1 - const position = { line: lineIndex + 1, column: matchColumn } - const result = consumer.originalPositionFor(position) + sampleCount += 1; + const position = { line: lineIndex + 1, column: matchColumn }; + const result = consumer.originalPositionFor(position); // warn if source content is missing if (!result.source) { - valid = false + valid = false; console.warn( `!! missing source for position: ${JSON.stringify(position)}`, - ) + ); // const buildLine = buildLines[position.line - 1] - console.warn(` origin in build:`) - console.warn(` ${buildLines[position.line - 2]}`) - console.warn(`-> ${buildLines[position.line - 1]}`) - console.warn(` ${buildLines[position.line - 0]}`) - return + console.warn(` origin in build:`); + console.warn(` ${buildLines[position.line - 2]}`); + console.warn(`-> ${buildLines[position.line - 1]}`); + console.warn(` ${buildLines[position.line - 0]}`); + return; } - const sourceContent = consumer.sourceContentFor(result.source) - const sourceLines = sourceContent.split('\n') - const line = sourceLines[result.line - 1] + const sourceContent = consumer.sourceContentFor(result.source); + const sourceLines = sourceContent.split('\n'); + const line = sourceLines[result.line - 1]; // this sometimes includes the whole line though we tried to match somewhere in the middle - const portion = line.slice(result.column) - const isMaybeValid = portion.includes(targetString) + const portion = line.slice(result.column); + const isMaybeValid = portion.includes(targetString); if (!isMaybeValid) { - valid = false + valid = false; console.error( `Sourcemap seems invalid:\n${getFencedCode(result.source, line)}`, - ) + ); } - }) - }) - console.log(` checked ${sampleCount} samples`) - return valid + }); + }); + console.log(` checked ${sampleCount} samples`); + return valid; } -const CODE_FENCE_LENGTH = 80 -const TITLE_PADDING_LENGTH = 1 +const CODE_FENCE_LENGTH = 80; +const TITLE_PADDING_LENGTH = 1; function getFencedCode(filename, code) { const title = `${' '.repeat(TITLE_PADDING_LENGTH)}${filename}${' '.repeat( TITLE_PADDING_LENGTH, - )}` + )}`; const openingFenceLength = Math.max( CODE_FENCE_LENGTH - (filename.length + TITLE_PADDING_LENGTH * 2), 0, - ) - const startOpeningFenceLength = Math.floor(openingFenceLength / 2) - const endOpeningFenceLength = Math.ceil(openingFenceLength / 2) + ); + const startOpeningFenceLength = Math.floor(openingFenceLength / 2); + const endOpeningFenceLength = Math.ceil(openingFenceLength / 2); const openingFence = `${'='.repeat( startOpeningFenceLength, - )}${title}${'='.repeat(endOpeningFenceLength)}` - const closingFence = '='.repeat(CODE_FENCE_LENGTH) + )}${title}${'='.repeat(endOpeningFenceLength)}`; + const closingFence = '='.repeat(CODE_FENCE_LENGTH); - return `${openingFence}\n${code}\n${closingFence}\n` + return `${openingFence}\n${code}\n${closingFence}\n`; } function indicesOf(substring, string) { - const a = [] - let i = -1 + const a = []; + let i = -1; while ((i = string.indexOf(substring, i + 1)) >= 0) { - a.push(i) + a.push(i); } - return a + return a; } diff --git a/development/static-server.js b/development/static-server.js index 1690fc0e22..de994aec37 100644 --- a/development/static-server.js +++ b/development/static-server.js @@ -1,77 +1,79 @@ -const fs = require('fs') -const path = require('path') +const fs = require('fs'); +const path = require('path'); -const chalk = require('chalk') -const pify = require('pify') +const chalk = require('chalk'); +const pify = require('pify'); -const createStaticServer = require('./create-static-server') -const { parsePort } = require('./lib/parse-port') +const createStaticServer = require('./create-static-server'); +const { parsePort } = require('./lib/parse-port'); -const fsStat = pify(fs.stat) -const DEFAULT_PORT = 9080 +const fsStat = pify(fs.stat); +const DEFAULT_PORT = 9080; const onResponse = (request, response) => { if (response.statusCode >= 400) { - console.log(chalk`{gray '-->'} {red ${response.statusCode}} ${request.url}`) + console.log( + chalk`{gray '-->'} {red ${response.statusCode}} ${request.url}`, + ); } else if (response.statusCode >= 200 && response.statusCode < 300) { console.log( chalk`{gray '-->'} {green ${response.statusCode}} ${request.url}`, - ) + ); } else { console.log( chalk`{gray '-->'} {green.dim ${response.statusCode}} ${request.url}`, - ) + ); } -} +}; const onRequest = (request, response) => { - console.log(chalk`{gray '<--'} {blue [${request.method}]} ${request.url}`) - response.on('finish', () => onResponse(request, response)) -} + console.log(chalk`{gray '<--'} {blue [${request.method}]} ${request.url}`); + response.on('finish', () => onResponse(request, response)); +}; const startServer = ({ port, rootDirectory }) => { - const server = createStaticServer(rootDirectory) + const server = createStaticServer(rootDirectory); - server.on('request', onRequest) + server.on('request', onRequest); server.listen(port, () => { - console.log(`Running at http://localhost:${port}`) - }) -} + console.log(`Running at http://localhost:${port}`); + }); +}; const parseDirectoryArgument = async (pathString) => { - const resolvedPath = path.resolve(pathString) - const directoryStats = await fsStat(resolvedPath) + const resolvedPath = path.resolve(pathString); + const directoryStats = await fsStat(resolvedPath); if (!directoryStats.isDirectory()) { - throw new Error(`Invalid path '${pathString}'; must be a directory`) + throw new Error(`Invalid path '${pathString}'; must be a directory`); } - return resolvedPath -} + return resolvedPath; +}; const main = async () => { - const args = process.argv.slice(2) + const args = process.argv.slice(2); const options = { port: process.env.port || DEFAULT_PORT, rootDirectory: path.resolve('.'), - } + }; while (args.length) { if (/^(--port|-p)$/u.test(args[0])) { if (args[1] === undefined) { - throw new Error('Missing port argument') + throw new Error('Missing port argument'); } - options.port = parsePort(args[1]) - args.splice(0, 2) + options.port = parsePort(args[1]); + args.splice(0, 2); } else { - options.rootDirectory = await parseDirectoryArgument(args[0]) - args.splice(0, 1) + options.rootDirectory = await parseDirectoryArgument(args[0]); + args.splice(0, 1); } } - startServer(options) -} + startServer(options); +}; main().catch((error) => { - console.error(error) - process.exit(1) -}) + console.error(error); + process.exit(1); +}); diff --git a/development/verify-locale-strings.js b/development/verify-locale-strings.js index 7a0aa6281a..d49b60095e 100644 --- a/development/verify-locale-strings.js +++ b/development/verify-locale-strings.js @@ -21,238 +21,239 @@ // // ////////////////////////////////////////////////////////////////////////////// -const fs = require('fs') -const path = require('path') -const { promisify } = require('util') -const log = require('loglevel') -const matchAll = require('string.prototype.matchall').getPolyfill() -const localeIndex = require('../app/_locales/index.json') +const fs = require('fs'); +const path = require('path'); +const { promisify } = require('util'); +const log = require('loglevel'); +const matchAll = require('string.prototype.matchall').getPolyfill(); +const localeIndex = require('../app/_locales/index.json'); const { compareLocalesForMissingDescriptions, compareLocalesForMissingItems, getLocale, getLocalePath, -} = require('./lib/locales') +} = require('./lib/locales'); -const readdir = promisify(fs.readdir) -const readFile = promisify(fs.readFile) -const writeFile = promisify(fs.writeFile) +const readdir = promisify(fs.readdir); +const readFile = promisify(fs.readFile); +const writeFile = promisify(fs.writeFile); -log.setDefaultLevel('info') +log.setDefaultLevel('info'); -let fix = false -let specifiedLocale +let fix = false; +let specifiedLocale; for (const arg of process.argv.slice(2)) { if (arg === '--fix') { - fix = true + fix = true; } else if (arg === '--quiet') { - log.setLevel('error') + log.setLevel('error'); } else { - specifiedLocale = arg + specifiedLocale = arg; } } main().catch((error) => { - log.error(error) - process.exit(1) -}) + log.error(error); + process.exit(1); +}); async function main() { if (specifiedLocale) { - log.info(`Verifying selected locale "${specifiedLocale}":\n`) + log.info(`Verifying selected locale "${specifiedLocale}":\n`); const localeEntry = localeIndex.find( (localeMeta) => localeMeta.code === specifiedLocale, - ) + ); if (!localeEntry) { - throw new Error(`No localize entry found for ${specifiedLocale}`) + throw new Error(`No localize entry found for ${specifiedLocale}`); } const failed = specifiedLocale === 'en' ? await verifyEnglishLocale() - : await verifyLocale(specifiedLocale) + : await verifyLocale(specifiedLocale); if (failed) { - process.exit(1) + process.exit(1); } else { - console.log('No invalid entries!') + console.log('No invalid entries!'); } } else { - log.info('Verifying all locales:\n') - let failed = await verifyEnglishLocale(fix) + log.info('Verifying all locales:\n'); + let failed = await verifyEnglishLocale(fix); const localeCodes = localeIndex .filter((localeMeta) => localeMeta.code !== 'en') - .map((localeMeta) => localeMeta.code) + .map((localeMeta) => localeMeta.code); for (const code of localeCodes) { - const localeFailed = await verifyLocale(code, fix) - failed = failed || localeFailed + const localeFailed = await verifyLocale(code, fix); + failed = failed || localeFailed; } if (failed) { - process.exit(1) + process.exit(1); } else { - console.log('No invalid entries!') + console.log('No invalid entries!'); } } } async function writeLocale(code, locale) { try { - const localeFilePath = getLocalePath(code) + const localeFilePath = getLocalePath(code); return writeFile( localeFilePath, `${JSON.stringify(locale, null, 2)}\n`, 'utf8', - ) + ); } catch (e) { if (e.code === 'ENOENT') { - log.error('Locale file not found') + log.error('Locale file not found'); } else { - log.error(`Error writing your locale ("${code}") file: `, e) + log.error(`Error writing your locale ("${code}") file: `, e); } - process.exit(1) + process.exit(1); } } async function verifyLocale(code) { - const englishLocale = await getLocale('en') - const targetLocale = await getLocale(code) + const englishLocale = await getLocale('en'); + const targetLocale = await getLocale(code); const extraItems = compareLocalesForMissingItems({ base: targetLocale, subject: englishLocale, - }) + }); if (extraItems.length) { - console.log(`**${code}**: ${extraItems.length} unused messages`) - log.info('Extra items that should not be localized:') + console.log(`**${code}**: ${extraItems.length} unused messages`); + log.info('Extra items that should not be localized:'); extraItems.forEach(function (key) { - log.info(` - [ ] ${key}`) - }) + log.info(` - [ ] ${key}`); + }); } const missingDescriptions = compareLocalesForMissingDescriptions({ englishLocale, targetLocale, - }) + }); if (missingDescriptions.length) { console.log( `**${code}**: ${missingDescriptions.length} missing descriptions`, - ) - log.info('Messages with missing descriptions:') + ); + log.info('Messages with missing descriptions:'); missingDescriptions.forEach(function (key) { - log.info(` - [ ] ${key}`) - }) + log.info(` - [ ] ${key}`); + }); } if (extraItems.length > 0 || missingDescriptions.length > 0) { if (fix) { - const newLocale = { ...targetLocale } + const newLocale = { ...targetLocale }; for (const item of extraItems) { - delete newLocale[item] + delete newLocale[item]; } for (const message of Object.keys(englishLocale)) { if (englishLocale[message].description && targetLocale[message]) { - targetLocale[message].description = englishLocale[message].description + targetLocale[message].description = + englishLocale[message].description; } } - await writeLocale(code, newLocale) + await writeLocale(code, newLocale); } - return true + return true; } - return false + return false; } async function verifyEnglishLocale() { - const englishLocale = await getLocale('en') + const englishLocale = await getLocale('en'); const uiJSFiles = await findJavascriptFiles( path.resolve(__dirname, '..', 'ui'), - ) + ); const sharedJSFiles = await findJavascriptFiles( path.resolve(__dirname, '..', 'shared'), - ) + ); - const javascriptFiles = sharedJSFiles.concat(uiJSFiles) + const javascriptFiles = sharedJSFiles.concat(uiJSFiles); // match "t(`...`)" because constructing message keys from template strings // prevents this script from finding the messages, and then inappropriately // deletes them - const templateStringRegex = /\bt\(`.*`\)/gu - const templateUsage = [] + const templateStringRegex = /\bt\(`.*`\)/gu; + const templateUsage = []; // match the keys from the locale file - const keyRegex = /'(\w+)'|"(\w+)"/gu - const usedMessages = new Set() + const keyRegex = /'(\w+)'|"(\w+)"/gu; + const usedMessages = new Set(); for await (const fileContents of getFileContents(javascriptFiles)) { for (const match of matchAll.call(fileContents, keyRegex)) { - usedMessages.add(match[1] || match[2]) + usedMessages.add(match[1] || match[2]); } - const templateMatches = fileContents.match(templateStringRegex) + const templateMatches = fileContents.match(templateStringRegex); if (templateMatches) { // concat doesn't work here for some reason - templateMatches.forEach((match) => templateUsage.push(match)) + templateMatches.forEach((match) => templateUsage.push(match)); } } // never consider these messages as unused - const messageExceptions = ['appName', 'appDescription'] + const messageExceptions = ['appName', 'appDescription']; - const englishMessages = Object.keys(englishLocale) + const englishMessages = Object.keys(englishLocale); const unusedMessages = englishMessages.filter( (message) => !messageExceptions.includes(message) && !usedMessages.has(message), - ) + ); if (unusedMessages.length) { - console.log(`**en**: ${unusedMessages.length} unused messages`) - log.info(`Messages not present in UI:`) + console.log(`**en**: ${unusedMessages.length} unused messages`); + log.info(`Messages not present in UI:`); unusedMessages.forEach(function (key) { - log.info(` - [ ] ${key}`) - }) + log.info(` - [ ] ${key}`); + }); } if (templateUsage.length) { - log.info(`Forbidden use of template strings in 't' function:`) + log.info(`Forbidden use of template strings in 't' function:`); templateUsage.forEach(function (occurrence) { - log.info(` - ${occurrence}`) - }) + log.info(` - ${occurrence}`); + }); } if (!unusedMessages.length && !templateUsage.length) { - return false // failed === false + return false; // failed === false } if (unusedMessages.length > 0 && fix) { - const newLocale = { ...englishLocale } + const newLocale = { ...englishLocale }; for (const key of unusedMessages) { - delete newLocale[key] + delete newLocale[key]; } - await writeLocale('en', newLocale) + await writeLocale('en', newLocale); } - return true // failed === true + return true; // failed === true } async function findJavascriptFiles(rootDir) { - const javascriptFiles = [] - const contents = await readdir(rootDir, { withFileTypes: true }) + const javascriptFiles = []; + const contents = await readdir(rootDir, { withFileTypes: true }); for (const file of contents) { if (file.isDirectory()) { javascriptFiles.push( ...(await findJavascriptFiles(path.join(rootDir, file.name))), - ) + ); } else if (file.isFile() && file.name.endsWith('.js')) { - javascriptFiles.push(path.join(rootDir, file.name)) + javascriptFiles.push(path.join(rootDir, file.name)); } } - return javascriptFiles + return javascriptFiles; } async function* getFileContents(filenames) { for (const filename of filenames) { - yield readFile(filename, 'utf8') + yield readFile(filename, 'utf8'); } } diff --git a/nyc.config.js b/nyc.config.js index 8902e05716..ee1e2055ac 100644 --- a/nyc.config.js +++ b/nyc.config.js @@ -3,4 +3,4 @@ module.exports = { lines: 95, functions: 95, statements: 95, -} +}; diff --git a/package.json b/package.json index cb6ae4c97e..fde50dfbb2 100644 --- a/package.json +++ b/package.json @@ -192,7 +192,7 @@ "@babel/preset-react": "^7.0.0", "@babel/register": "^7.5.5", "@lavamoat/allow-scripts": "^1.0.3", - "@metamask/eslint-config": "^4.1.0", + "@metamask/eslint-config": "^5.0.0", "@metamask/forwarder": "^1.1.0", "@metamask/test-dapp": "^4.0.1", "@sentry/cli": "^1.58.0", diff --git a/shared/constants/alerts.js b/shared/constants/alerts.js index 4b2bed1471..99ef70f4cb 100644 --- a/shared/constants/alerts.js +++ b/shared/constants/alerts.js @@ -2,7 +2,7 @@ export const ALERT_TYPES = { unconnectedAccount: 'unconnectedAccount', web3ShimUsage: 'web3ShimUsage', invalidCustomNetwork: 'invalidCustomNetwork', -} +}; /** * Alerts that can be enabled or disabled by the user. @@ -10,9 +10,9 @@ export const ALERT_TYPES = { export const TOGGLEABLE_ALERT_TYPES = [ ALERT_TYPES.unconnectedAccount, ALERT_TYPES.web3ShimUsage, -] +]; export const WEB3_SHIM_USAGE_ALERT_STATES = { RECORDED: 1, DISMISSED: 2, -} +}; diff --git a/shared/constants/app.js b/shared/constants/app.js index 90e4726b01..d0369cd828 100644 --- a/shared/constants/app.js +++ b/shared/constants/app.js @@ -6,16 +6,16 @@ * background - The background process that powers the extension * @typedef {'popup' | 'notification' | 'fullscreen' | 'background'} EnvironmentType */ -export const ENVIRONMENT_TYPE_POPUP = 'popup' -export const ENVIRONMENT_TYPE_NOTIFICATION = 'notification' -export const ENVIRONMENT_TYPE_FULLSCREEN = 'fullscreen' -export const ENVIRONMENT_TYPE_BACKGROUND = 'background' +export const ENVIRONMENT_TYPE_POPUP = 'popup'; +export const ENVIRONMENT_TYPE_NOTIFICATION = 'notification'; +export const ENVIRONMENT_TYPE_FULLSCREEN = 'fullscreen'; +export const ENVIRONMENT_TYPE_BACKGROUND = 'background'; -export const PLATFORM_BRAVE = 'Brave' -export const PLATFORM_CHROME = 'Chrome' -export const PLATFORM_EDGE = 'Edge' -export const PLATFORM_FIREFOX = 'Firefox' -export const PLATFORM_OPERA = 'Opera' +export const PLATFORM_BRAVE = 'Brave'; +export const PLATFORM_CHROME = 'Chrome'; +export const PLATFORM_EDGE = 'Edge'; +export const PLATFORM_FIREFOX = 'Firefox'; +export const PLATFORM_OPERA = 'Opera'; export const MESSAGE_TYPE = { ETH_DECRYPT: 'eth_decrypt', @@ -27,4 +27,4 @@ export const MESSAGE_TYPE = { PERSONAL_SIGN: 'personal_sign', WATCH_ASSET: 'wallet_watchAsset', WATCH_ASSET_LEGACY: 'metamask_watchAsset', -} +}; diff --git a/shared/constants/metametrics.js b/shared/constants/metametrics.js index edb37a2a13..ab71141bc1 100644 --- a/shared/constants/metametrics.js +++ b/shared/constants/metametrics.js @@ -110,7 +110,7 @@ * the page view */ -export const METAMETRICS_ANONYMOUS_ID = '0x0000000000000000' +export const METAMETRICS_ANONYMOUS_ID = '0x0000000000000000'; /** * This object is used to identify events that are triggered by the background @@ -121,7 +121,7 @@ export const METAMETRICS_BACKGROUND_PAGE_OBJECT = { path: '/background-process', title: 'Background Process', url: '/background-process', -} +}; /** * @typedef {Object} SegmentInterface diff --git a/shared/constants/network.js b/shared/constants/network.js index 7a0f6daf0f..d3a53e5192 100644 --- a/shared/constants/network.js +++ b/shared/constants/network.js @@ -1,35 +1,35 @@ -export const ROPSTEN = 'ropsten' -export const RINKEBY = 'rinkeby' -export const KOVAN = 'kovan' -export const MAINNET = 'mainnet' -export const GOERLI = 'goerli' -export const NETWORK_TYPE_RPC = 'rpc' +export const ROPSTEN = 'ropsten'; +export const RINKEBY = 'rinkeby'; +export const KOVAN = 'kovan'; +export const MAINNET = 'mainnet'; +export const GOERLI = 'goerli'; +export const NETWORK_TYPE_RPC = 'rpc'; -export const MAINNET_NETWORK_ID = '1' -export const ROPSTEN_NETWORK_ID = '3' -export const RINKEBY_NETWORK_ID = '4' -export const GOERLI_NETWORK_ID = '5' -export const KOVAN_NETWORK_ID = '42' +export const MAINNET_NETWORK_ID = '1'; +export const ROPSTEN_NETWORK_ID = '3'; +export const RINKEBY_NETWORK_ID = '4'; +export const GOERLI_NETWORK_ID = '5'; +export const KOVAN_NETWORK_ID = '42'; -export const MAINNET_CHAIN_ID = '0x1' -export const ROPSTEN_CHAIN_ID = '0x3' -export const RINKEBY_CHAIN_ID = '0x4' -export const GOERLI_CHAIN_ID = '0x5' -export const KOVAN_CHAIN_ID = '0x2a' +export const MAINNET_CHAIN_ID = '0x1'; +export const ROPSTEN_CHAIN_ID = '0x3'; +export const RINKEBY_CHAIN_ID = '0x4'; +export const GOERLI_CHAIN_ID = '0x5'; +export const KOVAN_CHAIN_ID = '0x2a'; /** * The largest possible chain ID we can handle. * Explanation: https://gist.github.com/rekmarks/a47bd5f2525936c4b8eee31a16345553 */ -export const MAX_SAFE_CHAIN_ID = 4503599627370476 +export const MAX_SAFE_CHAIN_ID = 4503599627370476; -export const ROPSTEN_DISPLAY_NAME = 'Ropsten' -export const RINKEBY_DISPLAY_NAME = 'Rinkeby' -export const KOVAN_DISPLAY_NAME = 'Kovan' -export const MAINNET_DISPLAY_NAME = 'Ethereum Mainnet' -export const GOERLI_DISPLAY_NAME = 'Goerli' +export const ROPSTEN_DISPLAY_NAME = 'Ropsten'; +export const RINKEBY_DISPLAY_NAME = 'Rinkeby'; +export const KOVAN_DISPLAY_NAME = 'Kovan'; +export const MAINNET_DISPLAY_NAME = 'Ethereum Mainnet'; +export const GOERLI_DISPLAY_NAME = 'Goerli'; -export const INFURA_PROVIDER_TYPES = [ROPSTEN, RINKEBY, KOVAN, MAINNET, GOERLI] +export const INFURA_PROVIDER_TYPES = [ROPSTEN, RINKEBY, KOVAN, MAINNET, GOERLI]; export const NETWORK_TYPE_TO_ID_MAP = { [ROPSTEN]: { networkId: ROPSTEN_NETWORK_ID, chainId: ROPSTEN_CHAIN_ID }, @@ -37,7 +37,7 @@ export const NETWORK_TYPE_TO_ID_MAP = { [KOVAN]: { networkId: KOVAN_NETWORK_ID, chainId: KOVAN_CHAIN_ID }, [GOERLI]: { networkId: GOERLI_NETWORK_ID, chainId: GOERLI_CHAIN_ID }, [MAINNET]: { networkId: MAINNET_NETWORK_ID, chainId: MAINNET_CHAIN_ID }, -} +}; export const NETWORK_TO_NAME_MAP = { [ROPSTEN]: ROPSTEN_DISPLAY_NAME, @@ -57,18 +57,18 @@ export const NETWORK_TO_NAME_MAP = { [KOVAN_CHAIN_ID]: KOVAN_DISPLAY_NAME, [GOERLI_CHAIN_ID]: GOERLI_DISPLAY_NAME, [MAINNET_CHAIN_ID]: MAINNET_DISPLAY_NAME, -} +}; export const CHAIN_ID_TO_TYPE_MAP = Object.entries( NETWORK_TYPE_TO_ID_MAP, ).reduce((chainIdToTypeMap, [networkType, { chainId }]) => { - chainIdToTypeMap[chainId] = networkType - return chainIdToTypeMap -}, {}) + chainIdToTypeMap[chainId] = networkType; + return chainIdToTypeMap; +}, {}); export const CHAIN_ID_TO_NETWORK_ID_MAP = Object.values( NETWORK_TYPE_TO_ID_MAP, ).reduce((chainIdToNetworkIdMap, { chainId, networkId }) => { - chainIdToNetworkIdMap[chainId] = networkId - return chainIdToNetworkIdMap -}, {}) + chainIdToNetworkIdMap[chainId] = networkId; + return chainIdToNetworkIdMap; +}, {}); diff --git a/shared/constants/permissions.js b/shared/constants/permissions.js index f396fbebaf..443ba2c294 100644 --- a/shared/constants/permissions.js +++ b/shared/constants/permissions.js @@ -1,4 +1,4 @@ export const CAVEAT_NAMES = { exposedAccounts: 'exposedAccounts', primaryAccountOnly: 'primaryAccountOnly', -} +}; diff --git a/shared/constants/tokens.js b/shared/constants/tokens.js index 27b240f7b3..1772cbf337 100644 --- a/shared/constants/tokens.js +++ b/shared/constants/tokens.js @@ -1,4 +1,4 @@ -import contractMap from '@metamask/contract-metadata' +import contractMap from '@metamask/contract-metadata'; /** * A normalized list of addresses exported as part of the contractMap in @@ -7,4 +7,4 @@ import contractMap from '@metamask/contract-metadata' */ export const LISTED_CONTRACT_ADDRESSES = Object.keys( contractMap, -).map((address) => address.toLowerCase()) +).map((address) => address.toLowerCase()); diff --git a/shared/constants/transaction.js b/shared/constants/transaction.js index cce09fb8de..833463a604 100644 --- a/shared/constants/transaction.js +++ b/shared/constants/transaction.js @@ -19,7 +19,7 @@ export const TRANSACTION_TYPES = { STANDARD: 'standard', CANCEL: 'cancel', RETRY: 'retry', -} +}; /** * Transaction Status is a mix of Ethereum and MetaMask terminology, used internally @@ -51,7 +51,7 @@ export const TRANSACTION_STATUSES = { FAILED: 'failed', DROPPED: 'dropped', CONFIRMED: 'confirmed', -} +}; /** * @typedef {Object} TransactionCategories @@ -90,7 +90,7 @@ export const TRANSACTION_CATEGORIES = { DEPLOY_CONTRACT: 'contractDeployment', SWAP: 'swap', SWAP_APPROVAL: 'swapApproval', -} +}; /** * Transaction Group Status is a MetaMask construct to track the status of groups @@ -109,7 +109,7 @@ export const TRANSACTION_CATEGORIES = { export const TRANSACTION_GROUP_STATUSES = { CANCELLED: 'cancelled', PENDING: 'pending', -} +}; /** * Transaction Group Category is a MetaMask construct to categorize the intent @@ -144,4 +144,4 @@ export const TRANSACTION_GROUP_CATEGORIES = { APPROVAL: 'approval', SIGNATURE_REQUEST: 'signature-request', SWAP: 'swap', -} +}; diff --git a/shared/modules/fetch-with-timeout.js b/shared/modules/fetch-with-timeout.js index e97ae3402b..b12e8cba56 100644 --- a/shared/modules/fetch-with-timeout.js +++ b/shared/modules/fetch-with-timeout.js @@ -1,29 +1,29 @@ -import { memoize } from 'lodash' +import { memoize } from 'lodash'; const getFetchWithTimeout = memoize((timeout) => { if (!Number.isInteger(timeout) || timeout < 1) { - throw new Error('Must specify positive integer timeout.') + throw new Error('Must specify positive integer timeout.'); } return async function _fetch(url, opts) { - const abortController = new window.AbortController() - const { signal } = abortController + const abortController = new window.AbortController(); + const { signal } = abortController; const f = window.fetch(url, { ...opts, signal, - }) + }); - const timer = setTimeout(() => abortController.abort(), timeout) + const timer = setTimeout(() => abortController.abort(), timeout); try { - const res = await f - clearTimeout(timer) - return res + const res = await f; + clearTimeout(timer); + return res; } catch (e) { - clearTimeout(timer) - throw e + clearTimeout(timer); + throw e; } - } -}) + }; +}); -export default getFetchWithTimeout +export default getFetchWithTimeout; diff --git a/shared/modules/utils.js b/shared/modules/utils.js index b9778b40b8..7d72d18f7c 100644 --- a/shared/modules/utils.js +++ b/shared/modules/utils.js @@ -1,4 +1,4 @@ -import { MAX_SAFE_CHAIN_ID } from '../constants/network' +import { MAX_SAFE_CHAIN_ID } from '../constants/network'; /** * Checks whether the given number primitive chain ID is safe. @@ -11,7 +11,7 @@ import { MAX_SAFE_CHAIN_ID } from '../constants/network' export function isSafeChainId(chainId) { return ( Number.isSafeInteger(chainId) && chainId > 0 && chainId <= MAX_SAFE_CHAIN_ID - ) + ); } /** @@ -24,7 +24,7 @@ export function isSafeChainId(chainId) { */ export function isPrefixedFormattedHexString(value) { if (typeof value !== 'string') { - return false + return false; } - return /^0x[1-9a-f]+[0-9a-f]*$/iu.test(value) + return /^0x[1-9a-f]+[0-9a-f]*$/iu.test(value); } diff --git a/stylelint.config.js b/stylelint.config.js index e732238635..b27e13ec93 100644 --- a/stylelint.config.js +++ b/stylelint.config.js @@ -131,4 +131,4 @@ module.exports = { // 'max-nesting-depth': 3, 'no-unknown-animations': true, }, -} +}; diff --git a/test/e2e/address-book.spec.js b/test/e2e/address-book.spec.js index 3d0e2712b6..4ac0d1722a 100644 --- a/test/e2e/address-book.spec.js +++ b/test/e2e/address-book.spec.js @@ -1,21 +1,21 @@ -const assert = require('assert') -const { By, until } = require('selenium-webdriver') +const assert = require('assert'); +const { By, until } = require('selenium-webdriver'); -const enLocaleMessages = require('../../app/_locales/en/messages.json') -const { tinyDelayMs, regularDelayMs, largeDelayMs } = require('./helpers') -const { buildWebDriver } = require('./webdriver') -const Ganache = require('./ganache') +const enLocaleMessages = require('../../app/_locales/en/messages.json'); +const { tinyDelayMs, regularDelayMs, largeDelayMs } = require('./helpers'); +const { buildWebDriver } = require('./webdriver'); +const Ganache = require('./ganache'); -const ganacheServer = new Ganache() +const ganacheServer = new Ganache(); describe('MetaMask', function () { - let driver + let driver; const testSeedPhrase = - 'forum vessel pink push lonely enact gentle tail admit parrot grunt dress' + 'forum vessel pink push lonely enact gentle tail admit parrot grunt dress'; - this.timeout(0) - this.bail(true) + this.timeout(0); + this.bail(true); before(async function () { await ganacheServer.start({ @@ -26,279 +26,283 @@ describe('MetaMask', function () { balance: 25000000000000000000, }, ], - }) - const result = await buildWebDriver() - driver = result.driver - await driver.navigate() - }) + }); + const result = await buildWebDriver(); + driver = result.driver; + await driver.navigate(); + }); afterEach(async function () { if (process.env.SELENIUM_BROWSER === 'chrome') { - const errors = await driver.checkBrowserForConsoleErrors() + const errors = await driver.checkBrowserForConsoleErrors(); if (errors.length) { - const errorReports = errors.map((err) => err.message) + const errorReports = errors.map((err) => err.message); const errorMessage = `Errors found in browser console:\n${errorReports.join( '\n', - )}` - console.error(new Error(errorMessage)) + )}`; + console.error(new Error(errorMessage)); } } if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest.title) + await driver.verboseReportOnFailure(this.currentTest.title); } - }) + }); after(async function () { - await ganacheServer.quit() - await driver.quit() - }) + await ganacheServer.quit(); + await driver.quit(); + }); describe('Going through the first time flow', function () { it('clicks the continue button on the welcome screen', async function () { - await driver.findElement(By.css('.welcome-page__header')) + await driver.findElement(By.css('.welcome-page__header')); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`, ), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('clicks the "Create New Wallet" option', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Create a Wallet')]`), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('clicks the "No thanks" option on the metametrics opt-in screen', async function () { - await driver.clickElement(By.css('.btn-default')) - await driver.delay(largeDelayMs) - }) + await driver.clickElement(By.css('.btn-default')); + await driver.delay(largeDelayMs); + }); it('accepts a secure password', async function () { const passwordBox = await driver.findElement( By.css('.first-time-flow__form #create-password'), - ) + ); const passwordBoxConfirm = await driver.findElement( By.css('.first-time-flow__form #confirm-password'), - ) + ); - await passwordBox.sendKeys('correct horse battery staple') - await passwordBoxConfirm.sendKeys('correct horse battery staple') + await passwordBox.sendKeys('correct horse battery staple'); + await passwordBoxConfirm.sendKeys('correct horse battery staple'); - await driver.clickElement(By.css('.first-time-flow__checkbox')) - await driver.clickElement(By.css('.first-time-flow__form button')) - await driver.delay(regularDelayMs) - }) + await driver.clickElement(By.css('.first-time-flow__checkbox')); + await driver.clickElement(By.css('.first-time-flow__form button')); + await driver.delay(regularDelayMs); + }); - let seedPhrase + let seedPhrase; it('reveals the seed phrase', async function () { const byRevealButton = By.css( '.reveal-seed-phrase__secret-blocker .reveal-seed-phrase__reveal-button', - ) - await driver.clickElement(byRevealButton) - await driver.delay(regularDelayMs) + ); + await driver.clickElement(byRevealButton); + await driver.delay(regularDelayMs); const revealedSeedPhrase = await driver.findElement( By.css('.reveal-seed-phrase__secret-words'), - ) - seedPhrase = await revealedSeedPhrase.getText() - assert.equal(seedPhrase.split(' ').length, 12) - await driver.delay(regularDelayMs) + ); + seedPhrase = await revealedSeedPhrase.getText(); + assert.equal(seedPhrase.split(' ').length, 12); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.next.message}')]`, ), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); async function clickWordAndWait(word) { await driver.clickElement( By.css( `[data-testid="seed-phrase-sorted"] [data-testid="draggable-seed-${word}"]`, ), - ) - await driver.delay(tinyDelayMs) + ); + await driver.delay(tinyDelayMs); } it('can retype the seed phrase', async function () { - const words = seedPhrase.split(' ') + const words = seedPhrase.split(' '); for (const word of words) { - await clickWordAndWait(word) + await clickWordAndWait(word); } await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('clicks through the success screen', async function () { await driver.findElement( By.xpath(`//div[contains(text(), 'Congratulations')]`), - ) + ); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`, ), - ) - await driver.delay(regularDelayMs) - }) - }) + ); + await driver.delay(regularDelayMs); + }); + }); describe('Import seed phrase', function () { it('logs out of the vault', async function () { - await driver.clickElement(By.css('.account-menu__icon')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.account-menu__icon')); + await driver.delay(regularDelayMs); const lockButton = await driver.findClickableElement( By.css('.account-menu__lock-button'), - ) - assert.equal(await lockButton.getText(), 'Lock') - await lockButton.click() - await driver.delay(regularDelayMs) - }) + ); + assert.equal(await lockButton.getText(), 'Lock'); + await lockButton.click(); + await driver.delay(regularDelayMs); + }); it('imports seed phrase', async function () { const restoreSeedLink = await driver.findClickableElement( By.css('.unlock-page__link--import'), - ) + ); assert.equal( await restoreSeedLink.getText(), 'Import using account seed phrase', - ) - await restoreSeedLink.click() - await driver.delay(regularDelayMs) + ); + await restoreSeedLink.click(); + await driver.delay(regularDelayMs); - await driver.clickElement(By.css('.import-account__checkbox-container')) + await driver.clickElement(By.css('.import-account__checkbox-container')); - const seedTextArea = await driver.findElement(By.css('textarea')) - await seedTextArea.sendKeys(testSeedPhrase) - await driver.delay(regularDelayMs) + const seedTextArea = await driver.findElement(By.css('textarea')); + await seedTextArea.sendKeys(testSeedPhrase); + await driver.delay(regularDelayMs); - const passwordInputs = await driver.findElements(By.css('input')) - await driver.delay(regularDelayMs) + const passwordInputs = await driver.findElements(By.css('input')); + await driver.delay(regularDelayMs); - await passwordInputs[0].sendKeys('correct horse battery staple') - await passwordInputs[1].sendKeys('correct horse battery staple') + await passwordInputs[0].sendKeys('correct horse battery staple'); + await passwordInputs[1].sendKeys('correct horse battery staple'); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.restore.message}')]`, ), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('balance renders', async function () { const balance = await driver.findElement( By.css('[data-testid="wallet-balance"] .list-item__heading'), - ) - await driver.wait(until.elementTextMatches(balance, /25\s*ETH/u)) - await driver.delay(regularDelayMs) - }) - }) + ); + await driver.wait(until.elementTextMatches(balance, /25\s*ETH/u)); + await driver.delay(regularDelayMs); + }); + }); describe('Adds an entry to the address book and sends eth to that address', function () { it('starts a send transaction', async function () { - await driver.clickElement(By.css('[data-testid="eth-overview-send"]')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('[data-testid="eth-overview-send"]')); + await driver.delay(regularDelayMs); const inputAddress = await driver.findElement( By.css('input[placeholder="Search, public address (0x), or ENS"]'), - ) - await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970') - await driver.delay(regularDelayMs) + ); + await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970'); + await driver.delay(regularDelayMs); - await driver.clickElement(By.css('.dialog.send__dialog.dialog--message')) + await driver.clickElement(By.css('.dialog.send__dialog.dialog--message')); const addressBookAddModal = await driver.findElement( By.css('span .modal'), - ) - await driver.findElement(By.css('.add-to-address-book-modal')) + ); + await driver.findElement(By.css('.add-to-address-book-modal')); const addressBookInput = await driver.findElement( By.css('.add-to-address-book-modal__input'), - ) - await addressBookInput.sendKeys('Test Name 1') - await driver.delay(tinyDelayMs) + ); + await addressBookInput.sendKeys('Test Name 1'); + await driver.delay(tinyDelayMs); await driver.clickElement( By.css('.add-to-address-book-modal__footer .btn-primary'), - ) + ); - await driver.wait(until.stalenessOf(addressBookAddModal)) + await driver.wait(until.stalenessOf(addressBookAddModal)); - const inputAmount = await driver.findElement(By.css('.unit-input__input')) - await inputAmount.sendKeys('1') + const inputAmount = await driver.findElement( + By.css('.unit-input__input'), + ); + await inputAmount.sendKeys('1'); - const inputValue = await inputAmount.getAttribute('value') - assert.equal(inputValue, '1') - await driver.delay(regularDelayMs) + const inputValue = await inputAmount.getAttribute('value'); + assert.equal(inputValue, '1'); + await driver.delay(regularDelayMs); // Continue to next screen - await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await driver.delay(regularDelayMs) - }) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)); + await driver.delay(regularDelayMs); + }); it('confirms the transaction', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - await driver.delay(largeDelayMs * 2) - }) + ); + await driver.delay(largeDelayMs * 2); + }); it('finds the transaction in the transactions list', async function () { - await driver.clickElement(By.css('[data-testid="home__activity-tab"]')) + await driver.clickElement(By.css('[data-testid="home__activity-tab"]')); await driver.wait(async () => { const confirmedTxes = await driver.findElements( By.css( '.transaction-list__completed-transactions .transaction-list-item', ), - ) - return confirmedTxes.length === 1 - }, 10000) + ); + return confirmedTxes.length === 1; + }, 10000); const txValues = await driver.findElement( By.css('.transaction-list-item__primary-currency'), - ) - await driver.wait(until.elementTextMatches(txValues, /-1\s*ETH/u), 10000) - }) - }) + ); + await driver.wait(until.elementTextMatches(txValues, /-1\s*ETH/u), 10000); + }); + }); describe('Sends to an address book entry', function () { it('starts a send transaction by clicking address book entry', async function () { - await driver.clickElement(By.css('[data-testid="eth-overview-send"]')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('[data-testid="eth-overview-send"]')); + await driver.delay(regularDelayMs); const recipientRowTitle = await driver.findElement( By.css('.send__select-recipient-wrapper__group-item__title'), - ) - const recipientRowTitleString = await recipientRowTitle.getText() - assert.equal(recipientRowTitleString, 'Test Name 1') + ); + const recipientRowTitleString = await recipientRowTitle.getText(); + assert.equal(recipientRowTitleString, 'Test Name 1'); await driver.clickElement( By.css('.send__select-recipient-wrapper__group-item'), - ) + ); - await driver.delay(regularDelayMs) - const inputAmount = await driver.findElement(By.css('.unit-input__input')) - await inputAmount.sendKeys('2') - await driver.delay(regularDelayMs) + await driver.delay(regularDelayMs); + const inputAmount = await driver.findElement( + By.css('.unit-input__input'), + ); + await inputAmount.sendKeys('2'); + await driver.delay(regularDelayMs); // Continue to next screen - await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await driver.delay(regularDelayMs) - }) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)); + await driver.delay(regularDelayMs); + }); it('confirms the transaction', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - await driver.delay(largeDelayMs * 2) - }) + ); + await driver.delay(largeDelayMs * 2); + }); it('finds the transaction in the transactions list', async function () { await driver.wait(async () => { @@ -306,14 +310,14 @@ describe('MetaMask', function () { By.css( '.transaction-list__completed-transactions .transaction-list-item', ), - ) - return confirmedTxes.length === 2 - }, 10000) + ); + return confirmedTxes.length === 2; + }, 10000); const txValues = await driver.findElement( By.css('.transaction-list-item__primary-currency'), - ) - await driver.wait(until.elementTextMatches(txValues, /-2\s*ETH/u), 10000) - }) - }) -}) + ); + await driver.wait(until.elementTextMatches(txValues, /-2\s*ETH/u), 10000); + }); + }); +}); diff --git a/test/e2e/benchmark.js b/test/e2e/benchmark.js index a364ed62ad..2f02d93cc8 100644 --- a/test/e2e/benchmark.js +++ b/test/e2e/benchmark.js @@ -1,66 +1,66 @@ #!/usr/bin/env node -const path = require('path') -const { promises: fs, constants: fsConstants } = require('fs') -const ttest = require('ttest') -const { By, Key } = require('selenium-webdriver') -const { withFixtures } = require('./helpers') -const { PAGES } = require('./webdriver/driver') +const path = require('path'); +const { promises: fs, constants: fsConstants } = require('fs'); +const ttest = require('ttest'); +const { By, Key } = require('selenium-webdriver'); +const { withFixtures } = require('./helpers'); +const { PAGES } = require('./webdriver/driver'); -const DEFAULT_NUM_SAMPLES = 20 -const ALL_PAGES = Object.values(PAGES) +const DEFAULT_NUM_SAMPLES = 20; +const ALL_PAGES = Object.values(PAGES); async function measurePage(pageName) { - let metrics + let metrics; await withFixtures({ fixtures: 'imported-account' }, async ({ driver }) => { - await driver.navigate() - const passwordField = await driver.findElement(By.css('#password')) - await passwordField.sendKeys('correct horse battery staple') - await passwordField.sendKeys(Key.ENTER) - await driver.findElement(By.css('.selected-account__name')) - await driver.navigate(pageName) - await driver.delay(1000) - metrics = await driver.collectMetrics() - }) - return metrics + await driver.navigate(); + const passwordField = await driver.findElement(By.css('#password')); + await passwordField.sendKeys('correct horse battery staple'); + await passwordField.sendKeys(Key.ENTER); + await driver.findElement(By.css('.selected-account__name')); + await driver.navigate(pageName); + await driver.delay(1000); + metrics = await driver.collectMetrics(); + }); + return metrics; } function calculateResult(calc) { return (result) => { - const calculatedResult = {} + const calculatedResult = {}; for (const key of Object.keys(result)) { - calculatedResult[key] = calc(result[key]) + calculatedResult[key] = calc(result[key]); } - return calculatedResult - } + return calculatedResult; + }; } -const calculateSum = (array) => array.reduce((sum, val) => sum + val) -const calculateAverage = (array) => calculateSum(array) / array.length -const minResult = calculateResult((array) => Math.min(...array)) -const maxResult = calculateResult((array) => Math.max(...array)) -const averageResult = calculateResult((array) => calculateAverage(array)) +const calculateSum = (array) => array.reduce((sum, val) => sum + val); +const calculateAverage = (array) => calculateSum(array) / array.length; +const minResult = calculateResult((array) => Math.min(...array)); +const maxResult = calculateResult((array) => Math.max(...array)); +const averageResult = calculateResult((array) => calculateAverage(array)); const standardDeviationResult = calculateResult((array) => { - const average = calculateAverage(array) - const squareDiffs = array.map((value) => Math.pow(value - average, 2)) - return Math.sqrt(calculateAverage(squareDiffs)) -}) + const average = calculateAverage(array); + const squareDiffs = array.map((value) => Math.pow(value - average, 2)); + return Math.sqrt(calculateAverage(squareDiffs)); +}); // 95% margin of error calculated using Student's t-distribution const calculateMarginOfError = (array) => - ttest(array).confidence()[1] - calculateAverage(array) + ttest(array).confidence()[1] - calculateAverage(array); const marginOfErrorResult = calculateResult((array) => calculateMarginOfError(array), -) +); async function profilePageLoad(pages, numSamples) { - const results = {} + const results = {}; for (const pageName of pages) { - const runResults = [] + const runResults = []; for (let i = 0; i < numSamples; i += 1) { - runResults.push(await measurePage(pageName)) + runResults.push(await measurePage(pageName)); } if (runResults.some((result) => result.navigation.lenth > 1)) { - throw new Error(`Multiple navigations not supported`) + throw new Error(`Multiple navigations not supported`); } else if ( runResults.some((result) => result.navigation[0].type !== 'navigate') ) { @@ -69,7 +69,7 @@ async function profilePageLoad(pages, numSamples) { runResults.find((result) => result.navigation[0].type !== 'navigate') .navigation[0].type } not supported`, - ) + ); } const result = { @@ -85,7 +85,7 @@ async function profilePageLoad(pages, numSamples) { (metrics) => metrics.navigation[0] && metrics.navigation[0].domInteractive, ), - } + }; results[pageName] = { min: minResult(result), @@ -93,101 +93,101 @@ async function profilePageLoad(pages, numSamples) { average: averageResult(result), standardDeviation: standardDeviationResult(result), marginOfError: marginOfErrorResult(result), - } + }; } - return results + return results; } async function isWritable(directory) { try { - await fs.access(directory, fsConstants.W_OK) - return true + await fs.access(directory, fsConstants.W_OK); + return true; } catch (error) { if (error.code !== 'EACCES') { - throw error + throw error; } - return false + return false; } } async function getFirstParentDirectoryThatExists(directory) { - let nextDirectory = directory + let nextDirectory = directory; for (;;) { try { - await fs.access(nextDirectory, fsConstants.F_OK) - return nextDirectory + await fs.access(nextDirectory, fsConstants.F_OK); + return nextDirectory; } catch (error) { if (error.code !== 'ENOENT') { - throw error + throw error; } else if (nextDirectory === path.dirname(nextDirectory)) { - throw new Error('Failed to find parent directory that exists') + throw new Error('Failed to find parent directory that exists'); } - nextDirectory = path.dirname(nextDirectory) + nextDirectory = path.dirname(nextDirectory); } } } async function main() { - const args = process.argv.slice(2) + const args = process.argv.slice(2); - let pages = ['home'] - let numSamples = DEFAULT_NUM_SAMPLES - let outputPath - let outputDirectory - let existingParentDirectory + let pages = ['home']; + let numSamples = DEFAULT_NUM_SAMPLES; + let outputPath; + let outputDirectory; + let existingParentDirectory; while (args.length) { if (/^(--pages|-p)$/u.test(args[0])) { if (args[1] === undefined) { - throw new Error('Missing pages argument') + throw new Error('Missing pages argument'); } - pages = args[1].split(',') + pages = args[1].split(','); for (const page of pages) { if (!ALL_PAGES.includes(page)) { - throw new Error(`Invalid page: '${page}`) + throw new Error(`Invalid page: '${page}`); } } - args.splice(0, 2) + args.splice(0, 2); } else if (/^(--samples|-s)$/u.test(args[0])) { if (args[1] === undefined) { - throw new Error('Missing number of samples') + throw new Error('Missing number of samples'); } - numSamples = parseInt(args[1], 10) + numSamples = parseInt(args[1], 10); if (isNaN(numSamples)) { - throw new Error(`Invalid 'samples' argument given: '${args[1]}'`) + throw new Error(`Invalid 'samples' argument given: '${args[1]}'`); } - args.splice(0, 2) + args.splice(0, 2); } else if (/^(--out|-o)$/u.test(args[0])) { if (args[1] === undefined) { - throw new Error('Missing output filename') + throw new Error('Missing output filename'); } - outputPath = path.resolve(args[1]) - outputDirectory = path.dirname(outputPath) + outputPath = path.resolve(args[1]); + outputDirectory = path.dirname(outputPath); existingParentDirectory = await getFirstParentDirectoryThatExists( outputDirectory, - ) + ); if (!(await isWritable(existingParentDirectory))) { - throw new Error(`Specified directory is not writable: '${args[1]}'`) + throw new Error(`Specified directory is not writable: '${args[1]}'`); } - args.splice(0, 2) + args.splice(0, 2); } else { - throw new Error(`Unrecognized argument: '${args[0]}'`) + throw new Error(`Unrecognized argument: '${args[0]}'`); } } - const results = await profilePageLoad(pages, numSamples) + const results = await profilePageLoad(pages, numSamples); if (outputPath) { if (outputDirectory !== existingParentDirectory) { - await fs.mkdir(outputDirectory, { recursive: true }) + await fs.mkdir(outputDirectory, { recursive: true }); } - await fs.writeFile(outputPath, JSON.stringify(results, null, 2)) + await fs.writeFile(outputPath, JSON.stringify(results, null, 2)); } else { - console.log(JSON.stringify(results, null, 2)) + console.log(JSON.stringify(results, null, 2)); } } main().catch((e) => { - console.error(e) - process.exit(1) -}) + console.error(e); + process.exit(1); +}); diff --git a/test/e2e/ethereum-on.spec.js b/test/e2e/ethereum-on.spec.js index 52485d76a4..dfe1a5d1aa 100644 --- a/test/e2e/ethereum-on.spec.js +++ b/test/e2e/ethereum-on.spec.js @@ -1,20 +1,20 @@ -const assert = require('assert') -const webdriver = require('selenium-webdriver') +const assert = require('assert'); +const webdriver = require('selenium-webdriver'); -const { By, until } = webdriver -const enLocaleMessages = require('../../app/_locales/en/messages.json') -const { regularDelayMs, largeDelayMs } = require('./helpers') -const { buildWebDriver } = require('./webdriver') -const Ganache = require('./ganache') +const { By, until } = webdriver; +const enLocaleMessages = require('../../app/_locales/en/messages.json'); +const { regularDelayMs, largeDelayMs } = require('./helpers'); +const { buildWebDriver } = require('./webdriver'); +const Ganache = require('./ganache'); -const ganacheServer = new Ganache() +const ganacheServer = new Ganache(); describe('MetaMask', function () { - let driver - let publicAddress + let driver; + let publicAddress; - this.timeout(0) - this.bail(true) + this.timeout(0); + this.bail(true); before(async function () { await ganacheServer.start({ @@ -25,175 +25,177 @@ describe('MetaMask', function () { balance: 25000000000000000000, }, ], - }) - const result = await buildWebDriver() - driver = result.driver - await driver.navigate() - }) + }); + const result = await buildWebDriver(); + driver = result.driver; + await driver.navigate(); + }); afterEach(async function () { if (process.env.SELENIUM_BROWSER === 'chrome') { - const errors = await driver.checkBrowserForConsoleErrors(driver) + const errors = await driver.checkBrowserForConsoleErrors(driver); if (errors.length) { - const errorReports = errors.map((err) => err.message) + const errorReports = errors.map((err) => err.message); const errorMessage = `Errors found in browser console:\n${errorReports.join( '\n', - )}` - console.error(new Error(errorMessage)) + )}`; + console.error(new Error(errorMessage)); } } if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest.title) + await driver.verboseReportOnFailure(this.currentTest.title); } - }) + }); after(async function () { - await ganacheServer.quit() - await driver.quit() - }) + await ganacheServer.quit(); + await driver.quit(); + }); describe('Going through the first time flow, but skipping the seed phrase challenge', function () { it('clicks the continue button on the welcome screen', async function () { - await driver.findElement(By.css('.welcome-page__header')) + await driver.findElement(By.css('.welcome-page__header')); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`, ), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('clicks the "Create New Wallet" option', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Create a Wallet')]`), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('clicks the "No thanks" option on the metametrics opt-in screen', async function () { - await driver.clickElement(By.css('.btn-default')) - await driver.delay(largeDelayMs) - }) + await driver.clickElement(By.css('.btn-default')); + await driver.delay(largeDelayMs); + }); it('accepts a secure password', async function () { const passwordBox = await driver.findElement( By.css('.first-time-flow__form #create-password'), - ) + ); const passwordBoxConfirm = await driver.findElement( By.css('.first-time-flow__form #confirm-password'), - ) + ); - await passwordBox.sendKeys('correct horse battery staple') - await passwordBoxConfirm.sendKeys('correct horse battery staple') + await passwordBox.sendKeys('correct horse battery staple'); + await passwordBoxConfirm.sendKeys('correct horse battery staple'); - await driver.clickElement(By.css('.first-time-flow__checkbox')) - await driver.clickElement(By.css('.first-time-flow__form button')) - await driver.delay(largeDelayMs) - }) + await driver.clickElement(By.css('.first-time-flow__checkbox')); + await driver.clickElement(By.css('.first-time-flow__form button')); + await driver.delay(largeDelayMs); + }); it('skips the seed phrase challenge', async function () { await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.remindMeLater.message}')]`, ), - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); await driver.clickElement( By.css('[data-testid="account-options-menu-button"]'), - ) + ); await driver.clickElement( By.css('[data-testid="account-options-menu__account-details"]'), - ) - }) + ); + }); it('gets the current accounts address', async function () { const addressInput = await driver.findElement( By.css('.readonly-input__input'), - ) - publicAddress = await addressInput.getAttribute('value') - const accountModal = await driver.findElement(By.css('span .modal')) + ); + publicAddress = await addressInput.getAttribute('value'); + const accountModal = await driver.findElement(By.css('span .modal')); - await driver.clickElement(By.css('.account-modal__close')) + await driver.clickElement(By.css('.account-modal__close')); - await driver.wait(until.stalenessOf(accountModal)) - await driver.delay(regularDelayMs) - }) - }) + await driver.wait(until.stalenessOf(accountModal)); + await driver.delay(regularDelayMs); + }); + }); describe('provider listening for events', function () { - let extension - let popup - let dapp + let extension; + let popup; + let dapp; it('connects to the dapp', async function () { - await driver.openNewPage('http://127.0.0.1:8080/') - await driver.delay(regularDelayMs) + await driver.openNewPage('http://127.0.0.1:8080/'); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//button[contains(text(), 'Connect')]`), - ) + ); - await driver.delay(regularDelayMs) + await driver.delay(regularDelayMs); - await driver.waitUntilXWindowHandles(3) - const windowHandles = await driver.getAllWindowHandles() + await driver.waitUntilXWindowHandles(3); + const windowHandles = await driver.getAllWindowHandles(); - extension = windowHandles[0] + extension = windowHandles[0]; dapp = await driver.switchToWindowWithTitle( 'E2E Test Dapp', windowHandles, - ) + ); popup = windowHandles.find( (handle) => handle !== extension && handle !== dapp, - ) + ); - await driver.switchToWindow(popup) + await driver.switchToWindow(popup); - await driver.delay(regularDelayMs) + await driver.delay(regularDelayMs); - await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)); await driver.clickElement( By.xpath(`//button[contains(text(), 'Connect')]`), - ) + ); - await driver.waitUntilXWindowHandles(2) - await driver.switchToWindow(dapp) - await driver.delay(regularDelayMs) - }) + await driver.waitUntilXWindowHandles(2); + await driver.switchToWindow(dapp); + await driver.delay(regularDelayMs); + }); it('has the ganache network id within the dapp', async function () { - const networkDiv = await driver.findElement(By.css('#network')) - await driver.delay(regularDelayMs) - assert.equal(await networkDiv.getText(), '1337') - }) + const networkDiv = await driver.findElement(By.css('#network')); + await driver.delay(regularDelayMs); + assert.equal(await networkDiv.getText(), '1337'); + }); it('changes the network', async function () { - await driver.switchToWindow(extension) + await driver.switchToWindow(extension); - await driver.clickElement(By.css('.network-display')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.network-display')); + await driver.delay(regularDelayMs); - await driver.clickElement(By.xpath(`//span[contains(text(), 'Ropsten')]`)) - await driver.delay(largeDelayMs) - }) + await driver.clickElement( + By.xpath(`//span[contains(text(), 'Ropsten')]`), + ); + await driver.delay(largeDelayMs); + }); it('sets the network div within the dapp', async function () { - await driver.switchToWindow(dapp) - const networkDiv = await driver.findElement(By.css('#network')) - assert.equal(await networkDiv.getText(), '3') - }) + await driver.switchToWindow(dapp); + const networkDiv = await driver.findElement(By.css('#network')); + assert.equal(await networkDiv.getText(), '3'); + }); it('sets the chainId div within the dapp', async function () { - await driver.switchToWindow(dapp) - const chainIdDiv = await driver.findElement(By.css('#chainId')) - assert.equal(await chainIdDiv.getText(), '0x3') - }) + await driver.switchToWindow(dapp); + const chainIdDiv = await driver.findElement(By.css('#chainId')); + assert.equal(await chainIdDiv.getText(), '0x3'); + }); it('sets the account div within the dapp', async function () { - await driver.switchToWindow(dapp) - const accountsDiv = await driver.findElement(By.css('#accounts')) - assert.equal(await accountsDiv.getText(), publicAddress.toLowerCase()) - }) - }) -}) + await driver.switchToWindow(dapp); + const accountsDiv = await driver.findElement(By.css('#accounts')); + assert.equal(await accountsDiv.getText(), publicAddress.toLowerCase()); + }); + }); +}); diff --git a/test/e2e/fixture-server.js b/test/e2e/fixture-server.js index 7c0ea5a863..6709b97591 100644 --- a/test/e2e/fixture-server.js +++ b/test/e2e/fixture-server.js @@ -1,26 +1,26 @@ -const { promises: fs } = require('fs') -const path = require('path') -const Koa = require('koa') +const { promises: fs } = require('fs'); +const path = require('path'); +const Koa = require('koa'); -const CURRENT_STATE_KEY = '__CURRENT__' -const DEFAULT_STATE_KEY = '__DEFAULT__' +const CURRENT_STATE_KEY = '__CURRENT__'; +const DEFAULT_STATE_KEY = '__DEFAULT__'; -const FIXTURE_SERVER_HOST = 'localhost' -const FIXTURE_SERVER_PORT = 12345 +const FIXTURE_SERVER_HOST = 'localhost'; +const FIXTURE_SERVER_PORT = 12345; class FixtureServer { constructor() { - this._app = new Koa() - this._stateMap = new Map([[DEFAULT_STATE_KEY, Object.create(null)]]) - this._initialStateCache = new Map() + this._app = new Koa(); + this._stateMap = new Map([[DEFAULT_STATE_KEY, Object.create(null)]]); + this._initialStateCache = new Map(); this._app.use(async (ctx) => { // Firefox is _super_ strict about needing CORS headers - ctx.set('Access-Control-Allow-Origin', '*') + ctx.set('Access-Control-Allow-Origin', '*'); if (this._isStateRequest(ctx)) { - ctx.body = this._stateMap.get(CURRENT_STATE_KEY) + ctx.body = this._stateMap.get(CURRENT_STATE_KEY); } - }) + }); } async start() { @@ -28,45 +28,45 @@ class FixtureServer { host: FIXTURE_SERVER_HOST, port: FIXTURE_SERVER_PORT, exclusive: true, - } + }; return new Promise((resolve, reject) => { - this._server = this._app.listen(options) - this._server.once('error', reject) - this._server.once('listening', resolve) - }) + this._server = this._app.listen(options); + this._server.once('error', reject); + this._server.once('listening', resolve); + }); } async stop() { if (!this._server) { - return + return; } await new Promise((resolve, reject) => { - this._server.close() - this._server.once('error', reject) - this._server.once('close', resolve) - }) + this._server.close(); + this._server.once('error', reject); + this._server.once('close', resolve); + }); } async loadState(directory) { - const statePath = path.resolve(__dirname, directory, 'state.json') + const statePath = path.resolve(__dirname, directory, 'state.json'); - let state + let state; if (this._initialStateCache.has(statePath)) { - state = this._initialStateCache.get(statePath) + state = this._initialStateCache.get(statePath); } else { - const data = await fs.readFile(statePath) - state = JSON.parse(data.toString('utf-8')) - this._initialStateCache.set(statePath, state) + const data = await fs.readFile(statePath); + state = JSON.parse(data.toString('utf-8')); + this._initialStateCache.set(statePath, state); } - this._stateMap.set(CURRENT_STATE_KEY, state) + this._stateMap.set(CURRENT_STATE_KEY, state); } _isStateRequest(ctx) { - return ctx.method === 'GET' && ctx.path === '/state.json' + return ctx.method === 'GET' && ctx.path === '/state.json'; } } -module.exports = FixtureServer +module.exports = FixtureServer; diff --git a/test/e2e/from-import-ui.spec.js b/test/e2e/from-import-ui.spec.js index 8dbabbcac1..fdea86cf89 100644 --- a/test/e2e/from-import-ui.spec.js +++ b/test/e2e/from-import-ui.spec.js @@ -1,27 +1,27 @@ -const assert = require('assert') -const webdriver = require('selenium-webdriver') +const assert = require('assert'); +const webdriver = require('selenium-webdriver'); -const { By, Key, until } = webdriver -const enLocaleMessages = require('../../app/_locales/en/messages.json') -const { regularDelayMs, largeDelayMs } = require('./helpers') -const { buildWebDriver } = require('./webdriver') -const Ganache = require('./ganache') +const { By, Key, until } = webdriver; +const enLocaleMessages = require('../../app/_locales/en/messages.json'); +const { regularDelayMs, largeDelayMs } = require('./helpers'); +const { buildWebDriver } = require('./webdriver'); +const Ganache = require('./ganache'); -const ganacheServer = new Ganache() +const ganacheServer = new Ganache(); describe('Using MetaMask with an existing account', function () { - let driver + let driver; const testSeedPhrase = - 'forum vessel pink push lonely enact gentle tail admit parrot grunt dress' - const testAddress = '0x0Cc5261AB8cE458dc977078A3623E2BaDD27afD3' + 'forum vessel pink push lonely enact gentle tail admit parrot grunt dress'; + const testAddress = '0x0Cc5261AB8cE458dc977078A3623E2BaDD27afD3'; const testPrivateKey2 = - '14abe6f4aab7f9f626fe981c864d0adeb5685f289ac9270c27b8fd790b4235d6' + '14abe6f4aab7f9f626fe981c864d0adeb5685f289ac9270c27b8fd790b4235d6'; const testPrivateKey3 = - 'F4EC2590A0C10DE95FBF4547845178910E40F5035320C516A18C117DE02B5669' + 'F4EC2590A0C10DE95FBF4547845178910E40F5035320C516A18C117DE02B5669'; - this.timeout(0) - this.bail(true) + this.timeout(0); + this.bail(true); before(async function () { await ganacheServer.start({ @@ -32,392 +32,394 @@ describe('Using MetaMask with an existing account', function () { balance: 25000000000000000000, }, ], - }) - const result = await buildWebDriver() - driver = result.driver - await driver.navigate() - }) + }); + const result = await buildWebDriver(); + driver = result.driver; + await driver.navigate(); + }); afterEach(async function () { if (process.env.SELENIUM_BROWSER === 'chrome') { - const errors = await driver.checkBrowserForConsoleErrors(driver) + const errors = await driver.checkBrowserForConsoleErrors(driver); if (errors.length) { - const errorReports = errors.map((err) => err.message) + const errorReports = errors.map((err) => err.message); const errorMessage = `Errors found in browser console:\n${errorReports.join( '\n', - )}` - console.error(new Error(errorMessage)) + )}`; + console.error(new Error(errorMessage)); } } if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest.title) + await driver.verboseReportOnFailure(this.currentTest.title); } - }) + }); after(async function () { - await ganacheServer.quit() - await driver.quit() - }) + await ganacheServer.quit(); + await driver.quit(); + }); describe('First time flow starting from an existing seed phrase', function () { it('clicks the continue button on the welcome screen', async function () { - await driver.findElement(By.css('.welcome-page__header')) + await driver.findElement(By.css('.welcome-page__header')); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`, ), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('clicks the "Import Wallet" option', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Import wallet')]`), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('clicks the "No thanks" option on the metametrics opt-in screen', async function () { - await driver.clickElement(By.css('.btn-default')) - await driver.delay(largeDelayMs) - }) + await driver.clickElement(By.css('.btn-default')); + await driver.delay(largeDelayMs); + }); it('imports a seed phrase', async function () { const [seedTextArea] = await driver.findElements( By.css('input[placeholder="Paste seed phrase from clipboard"]'), - ) - await seedTextArea.sendKeys(testSeedPhrase) - await driver.delay(regularDelayMs) + ); + await seedTextArea.sendKeys(testSeedPhrase); + await driver.delay(regularDelayMs); - const [password] = await driver.findElements(By.id('password')) - await password.sendKeys('correct horse battery staple') + const [password] = await driver.findElements(By.id('password')); + await password.sendKeys('correct horse battery staple'); const [confirmPassword] = await driver.findElements( By.id('confirm-password'), - ) - confirmPassword.sendKeys('correct horse battery staple') + ); + confirmPassword.sendKeys('correct horse battery staple'); - await driver.clickElement(By.css('.first-time-flow__terms')) + await driver.clickElement(By.css('.first-time-flow__terms')); await driver.clickElement( By.xpath(`//button[contains(text(), 'Import')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('clicks through the success screen', async function () { await driver.findElement( By.xpath(`//div[contains(text(), 'Congratulations')]`), - ) + ); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`, ), - ) - await driver.delay(regularDelayMs) - }) - }) + ); + await driver.delay(regularDelayMs); + }); + }); describe('Show account information', function () { it('shows the correct account address', async function () { await driver.clickElement( By.css('[data-testid="account-options-menu-button"]'), - ) + ); await driver.clickElement( By.css('[data-testid="account-options-menu__account-details"]'), - ) - await driver.findVisibleElement(By.css('.qr-code__wrapper')) - await driver.delay(regularDelayMs) + ); + await driver.findVisibleElement(By.css('.qr-code__wrapper')); + await driver.delay(regularDelayMs); const [address] = await driver.findElements( By.css('.readonly-input__input'), - ) - assert.equal(await address.getAttribute('value'), testAddress) + ); + assert.equal(await address.getAttribute('value'), testAddress); - await driver.clickElement(By.css('.account-modal__close')) - await driver.delay(largeDelayMs) - }) + await driver.clickElement(By.css('.account-modal__close')); + await driver.delay(largeDelayMs); + }); it('shows a QR code for the account', async function () { await driver.clickElement( By.css('[data-testid="account-options-menu-button"]'), - ) + ); await driver.clickElement( By.css('[data-testid="account-options-menu__account-details"]'), - ) - await driver.findVisibleElement(By.css('.qr-code__wrapper')) - const detailModal = await driver.findElement(By.css('span .modal')) - await driver.delay(regularDelayMs) + ); + await driver.findVisibleElement(By.css('.qr-code__wrapper')); + const detailModal = await driver.findElement(By.css('span .modal')); + await driver.delay(regularDelayMs); - await driver.clickElement(By.css('.account-modal__close')) - await driver.wait(until.stalenessOf(detailModal)) - await driver.delay(regularDelayMs) - }) - }) + await driver.clickElement(By.css('.account-modal__close')); + await driver.wait(until.stalenessOf(detailModal)); + await driver.delay(regularDelayMs); + }); + }); describe('Lock and unlock', function () { it('logs out of the account', async function () { - await driver.clickElement(By.css('.account-menu__icon .identicon')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.account-menu__icon .identicon')); + await driver.delay(regularDelayMs); const lockButton = await driver.findClickableElement( By.css('.account-menu__lock-button'), - ) - assert.equal(await lockButton.getText(), 'Lock') - await lockButton.click() - await driver.delay(regularDelayMs) - }) + ); + assert.equal(await lockButton.getText(), 'Lock'); + await lockButton.click(); + await driver.delay(regularDelayMs); + }); it('accepts the account password after lock', async function () { - const passwordField = await driver.findElement(By.id('password')) - await passwordField.sendKeys('correct horse battery staple') - await passwordField.sendKeys(Key.ENTER) - await driver.delay(largeDelayMs) - }) - }) + const passwordField = await driver.findElement(By.id('password')); + await passwordField.sendKeys('correct horse battery staple'); + await passwordField.sendKeys(Key.ENTER); + await driver.delay(largeDelayMs); + }); + }); describe('Add an account', function () { it('switches to localhost', async function () { - await driver.clickElement(By.css('.network-display')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.network-display')); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//span[contains(text(), 'Localhost')]`), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('choose Create Account from the account menu', async function () { - await driver.clickElement(By.css('.account-menu__icon')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.account-menu__icon')); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//div[contains(text(), 'Create Account')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('set account name', async function () { const [accountName] = await driver.findElements( By.css('.new-account-create-form input'), - ) - await accountName.sendKeys('2nd account') - await driver.delay(regularDelayMs) + ); + await accountName.sendKeys('2nd account'); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//button[contains(text(), 'Create')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('should show the correct account name', async function () { const accountName = await driver.findElement( By.css('.selected-account__name'), - ) - assert.equal(await accountName.getText(), '2nd account') - await driver.delay(regularDelayMs) - }) - }) + ); + assert.equal(await accountName.getText(), '2nd account'); + await driver.delay(regularDelayMs); + }); + }); describe('Switch back to original account', function () { it('chooses the original account from the account menu', async function () { - await driver.clickElement(By.css('.account-menu__icon')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.account-menu__icon')); + await driver.delay(regularDelayMs); - await driver.clickElement(By.css('.account-menu__name')) - await driver.delay(regularDelayMs) - }) - }) + await driver.clickElement(By.css('.account-menu__name')); + await driver.delay(regularDelayMs); + }); + }); describe('Send ETH from inside MetaMask', function () { it('starts a send transaction', async function () { - await driver.clickElement(By.css('[data-testid="eth-overview-send"]')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('[data-testid="eth-overview-send"]')); + await driver.delay(regularDelayMs); const inputAddress = await driver.findElement( By.css('input[placeholder="Search, public address (0x), or ENS"]'), - ) - await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970') + ); + await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970'); - const inputAmount = await driver.findElement(By.css('.unit-input__input')) - await inputAmount.sendKeys('1') + const inputAmount = await driver.findElement( + By.css('.unit-input__input'), + ); + await inputAmount.sendKeys('1'); // Set the gas limit - await driver.clickElement(By.css('.advanced-gas-options-btn')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.advanced-gas-options-btn')); + await driver.delay(regularDelayMs); - const gasModal = await driver.findElement(By.css('span .modal')) - await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)) - await driver.wait(until.stalenessOf(gasModal)) - await driver.delay(regularDelayMs) + const gasModal = await driver.findElement(By.css('span .modal')); + await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)); + await driver.wait(until.stalenessOf(gasModal)); + await driver.delay(regularDelayMs); // Continue to next screen - await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await driver.delay(regularDelayMs) - }) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)); + await driver.delay(regularDelayMs); + }); it('confirms the transaction', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('finds the transaction in the transactions list', async function () { - await driver.clickElement(By.css('[data-testid="home__activity-tab"]')) + await driver.clickElement(By.css('[data-testid="home__activity-tab"]')); await driver.wait(async () => { const confirmedTxes = await driver.findElements( By.css( '.transaction-list__completed-transactions .transaction-list-item', ), - ) - return confirmedTxes.length === 1 - }, 10000) + ); + return confirmedTxes.length === 1; + }, 10000); const txValues = await driver.findElements( By.css('.transaction-list-item__primary-currency'), - ) - assert.equal(txValues.length, 1) - assert.ok(/-1\s*ETH/u.test(await txValues[0].getText())) - }) - }) + ); + assert.equal(txValues.length, 1); + assert.ok(/-1\s*ETH/u.test(await txValues[0].getText())); + }); + }); describe('Imports an account with private key', function () { it('choose Create Account from the account menu', async function () { - await driver.clickElement(By.css('.account-menu__icon')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.account-menu__icon')); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//div[contains(text(), 'Import Account')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('enter private key', async function () { const privateKeyInput = await driver.findElement( By.css('#private-key-box'), - ) - await privateKeyInput.sendKeys(testPrivateKey2) - await driver.delay(regularDelayMs) + ); + await privateKeyInput.sendKeys(testPrivateKey2); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//button[contains(text(), 'Import')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('should show the correct account name', async function () { const accountName = await driver.findElement( By.css('.selected-account__name'), - ) - assert.equal(await accountName.getText(), 'Account 4') - await driver.delay(regularDelayMs) - }) + ); + assert.equal(await accountName.getText(), 'Account 4'); + await driver.delay(regularDelayMs); + }); it('should show the imported label', async function () { - await driver.clickElement(By.css('.account-menu__icon')) + await driver.clickElement(By.css('.account-menu__icon')); // confirm 4th account is account 4, as expected - const accountMenuItemSelector = '.account-menu__account:nth-child(4)' + const accountMenuItemSelector = '.account-menu__account:nth-child(4)'; const accountName = await driver.findElement( By.css(`${accountMenuItemSelector} .account-menu__name`), - ) - assert.equal(await accountName.getText(), 'Account 4') + ); + assert.equal(await accountName.getText(), 'Account 4'); // confirm label is present on the same menu item const importedLabel = await driver.findElement( By.css(`${accountMenuItemSelector} .keyring-label`), - ) - assert.equal(await importedLabel.getText(), 'IMPORTED') - }) - }) + ); + assert.equal(await importedLabel.getText(), 'IMPORTED'); + }); + }); describe('Imports and removes an account', function () { it('choose Create Account from the account menu', async function () { await driver.clickElement( By.xpath(`//div[contains(text(), 'Import Account')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('enter private key', async function () { const privateKeyInput = await driver.findElement( By.css('#private-key-box'), - ) - await privateKeyInput.sendKeys(testPrivateKey3) - await driver.delay(regularDelayMs) + ); + await privateKeyInput.sendKeys(testPrivateKey3); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//button[contains(text(), 'Import')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('should see new account in account menu', async function () { const accountName = await driver.findElement( By.css('.selected-account__name'), - ) - assert.equal(await accountName.getText(), 'Account 5') - await driver.delay(regularDelayMs) + ); + assert.equal(await accountName.getText(), 'Account 5'); + await driver.delay(regularDelayMs); - await driver.clickElement(By.css('.account-menu__icon')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.account-menu__icon')); + await driver.delay(regularDelayMs); const accountListItems = await driver.findElements( By.css('.account-menu__account'), - ) - assert.equal(accountListItems.length, 5) + ); + assert.equal(accountListItems.length, 5); - await driver.clickPoint(By.css('.account-menu__icon'), 0, 0) - }) + await driver.clickPoint(By.css('.account-menu__icon'), 0, 0); + }); it('should open the remove account modal', async function () { await driver.clickElement( By.css('[data-testid="account-options-menu-button"]'), - ) + ); await driver.clickElement( By.css('[data-testid="account-options-menu__remove-account"]'), - ) + ); - await driver.findElement(By.css('.confirm-remove-account__account')) - }) + await driver.findElement(By.css('.confirm-remove-account__account')); + }); it('should remove the account', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Remove')]`), - ) + ); - await driver.delay(regularDelayMs) + await driver.delay(regularDelayMs); const accountName = await driver.findElement( By.css('.selected-account__name'), - ) - assert.equal(await accountName.getText(), 'Account 1') - await driver.delay(regularDelayMs) + ); + assert.equal(await accountName.getText(), 'Account 1'); + await driver.delay(regularDelayMs); - await driver.clickElement(By.css('.account-menu__icon')) + await driver.clickElement(By.css('.account-menu__icon')); const accountListItems = await driver.findElements( By.css('.account-menu__account'), - ) - assert.equal(accountListItems.length, 4) - }) - }) + ); + assert.equal(accountListItems.length, 4); + }); + }); describe('Connects to a Hardware wallet', function () { it('choose Connect Hardware Wallet from the account menu', async function () { await driver.clickElement( By.xpath(`//div[contains(text(), 'Connect Hardware Wallet')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('should open the TREZOR Connect popup', async function () { - await driver.clickElement(By.css('.hw-connect__btn:nth-of-type(2)')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.hw-connect__btn:nth-of-type(2)')); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//button[contains(text(), 'Connect')]`), - ) - await driver.delay(regularDelayMs) - const allWindows = await driver.getAllWindowHandles() - assert.equal(allWindows.length, 2) - }) - }) -}) + ); + await driver.delay(regularDelayMs); + const allWindows = await driver.getAllWindowHandles(); + assert.equal(allWindows.length, 2); + }); + }); +}); diff --git a/test/e2e/ganache.js b/test/e2e/ganache.js index 2794737662..8f9974da13 100644 --- a/test/e2e/ganache.js +++ b/test/e2e/ganache.js @@ -1,5 +1,5 @@ -const { promisify } = require('util') -const ganache = require('ganache-core') +const { promisify } = require('util'); +const ganache = require('ganache-core'); const defaultOptions = { blockTime: 2, @@ -8,30 +8,30 @@ const defaultOptions = { 'phrase upgrade clock rough situate wedding elder clever doctor stamp excess tent', port: 8545, vmErrorsOnRPCResponse: false, -} +}; class Ganache { async start(opts) { - const options = { ...defaultOptions, ...opts } - const { port } = options - this._server = ganache.server(options) + const options = { ...defaultOptions, ...opts }; + const { port } = options; + this._server = ganache.server(options); - const listen = promisify(this._server.listen).bind(this._server) - const blockchain = await listen(port) + const listen = promisify(this._server.listen).bind(this._server); + const blockchain = await listen(port); return { ...blockchain, port, - } + }; } async quit() { if (!this._server) { - throw new Error('Server not running yet') + throw new Error('Server not running yet'); } - const close = promisify(this._server.close).bind(this._server) - await close() + const close = promisify(this._server.close).bind(this._server); + await close(); } } -module.exports = Ganache +module.exports = Ganache; diff --git a/test/e2e/helpers.js b/test/e2e/helpers.js index 926f671772..5daadbb0d3 100644 --- a/test/e2e/helpers.js +++ b/test/e2e/helpers.js @@ -1,18 +1,18 @@ -const path = require('path') -const sinon = require('sinon') -const createStaticServer = require('../../development/create-static-server') +const path = require('path'); +const sinon = require('sinon'); +const createStaticServer = require('../../development/create-static-server'); const { createSegmentServer, -} = require('../../development/lib/create-segment-server') -const Ganache = require('./ganache') -const FixtureServer = require('./fixture-server') -const { buildWebDriver } = require('./webdriver') +} = require('../../development/lib/create-segment-server'); +const Ganache = require('./ganache'); +const FixtureServer = require('./fixture-server'); +const { buildWebDriver } = require('./webdriver'); -const tinyDelayMs = 200 -const regularDelayMs = tinyDelayMs * 2 -const largeDelayMs = regularDelayMs * 2 +const tinyDelayMs = 200; +const regularDelayMs = tinyDelayMs * 2; +const largeDelayMs = regularDelayMs * 2; -const dappPort = 8080 +const dappPort = 8080; async function withFixtures(options, testSuite) { const { @@ -22,18 +22,18 @@ async function withFixtures(options, testSuite) { driverOptions, mockSegment, title, - } = options - const fixtureServer = new FixtureServer() - const ganacheServer = new Ganache() - let dappServer - let segmentServer - let segmentStub + } = options; + const fixtureServer = new FixtureServer(); + const ganacheServer = new Ganache(); + let dappServer; + let segmentServer; + let segmentStub; - let webDriver + let webDriver; try { - await ganacheServer.start(ganacheOptions) - await fixtureServer.start() - await fixtureServer.loadState(path.join(__dirname, 'fixtures', fixtures)) + await ganacheServer.start(ganacheOptions); + await fixtureServer.start(); + await fixtureServer.loadState(path.join(__dirname, 'fixtures', fixtures)); if (dapp) { const dappDirectory = path.resolve( __dirname, @@ -43,70 +43,70 @@ async function withFixtures(options, testSuite) { '@metamask', 'test-dapp', 'dist', - ) - dappServer = createStaticServer(dappDirectory) - dappServer.listen(dappPort) + ); + dappServer = createStaticServer(dappDirectory); + dappServer.listen(dappPort); await new Promise((resolve, reject) => { - dappServer.on('listening', resolve) - dappServer.on('error', reject) - }) + dappServer.on('listening', resolve); + dappServer.on('error', reject); + }); } if (mockSegment) { - segmentStub = sinon.stub() + segmentStub = sinon.stub(); segmentServer = createSegmentServer((_request, response, events) => { for (const event of events) { - segmentStub(event) + segmentStub(event); } - response.statusCode = 200 - response.end() - }) - await segmentServer.start(9090) + response.statusCode = 200; + response.end(); + }); + await segmentServer.start(9090); } - const { driver } = await buildWebDriver(driverOptions) - webDriver = driver + const { driver } = await buildWebDriver(driverOptions); + webDriver = driver; await testSuite({ driver, segmentStub, - }) + }); if (process.env.SELENIUM_BROWSER === 'chrome') { - const errors = await driver.checkBrowserForConsoleErrors(driver) + const errors = await driver.checkBrowserForConsoleErrors(driver); if (errors.length) { - const errorReports = errors.map((err) => err.message) + const errorReports = errors.map((err) => err.message); const errorMessage = `Errors found in browser console:\n${errorReports.join( '\n', - )}` - throw new Error(errorMessage) + )}`; + throw new Error(errorMessage); } } } catch (error) { if (webDriver) { try { - await webDriver.verboseReportOnFailure(title) + await webDriver.verboseReportOnFailure(title); } catch (verboseReportError) { - console.error(verboseReportError) + console.error(verboseReportError); } } - throw error + throw error; } finally { - await fixtureServer.stop() - await ganacheServer.quit() + await fixtureServer.stop(); + await ganacheServer.quit(); if (webDriver) { - await webDriver.quit() + await webDriver.quit(); } if (dappServer) { await new Promise((resolve, reject) => { dappServer.close((error) => { if (error) { - return reject(error) + return reject(error); } - return resolve() - }) - }) + return resolve(); + }); + }); } if (segmentServer) { - await segmentServer.stop() + await segmentServer.stop(); } } } @@ -116,4 +116,4 @@ module.exports = { regularDelayMs, largeDelayMs, withFixtures, -} +}; diff --git a/test/e2e/incremental-security.spec.js b/test/e2e/incremental-security.spec.js index cb0c67e3c7..7f9b99665d 100644 --- a/test/e2e/incremental-security.spec.js +++ b/test/e2e/incremental-security.spec.js @@ -1,20 +1,20 @@ -const assert = require('assert') -const webdriver = require('selenium-webdriver') +const assert = require('assert'); +const webdriver = require('selenium-webdriver'); -const { By, until } = webdriver -const enLocaleMessages = require('../../app/_locales/en/messages.json') -const { tinyDelayMs, regularDelayMs, largeDelayMs } = require('./helpers') -const { buildWebDriver } = require('./webdriver') -const Ganache = require('./ganache') +const { By, until } = webdriver; +const enLocaleMessages = require('../../app/_locales/en/messages.json'); +const { tinyDelayMs, regularDelayMs, largeDelayMs } = require('./helpers'); +const { buildWebDriver } = require('./webdriver'); +const Ganache = require('./ganache'); -const ganacheServer = new Ganache() +const ganacheServer = new Ganache(); describe('MetaMask', function () { - let driver - let publicAddress + let driver; + let publicAddress; - this.timeout(0) - this.bail(true) + this.timeout(0); + this.bail(true); before(async function () { await ganacheServer.start({ @@ -30,140 +30,140 @@ describe('MetaMask', function () { balance: 25000000000000000000, }, ], - }) - const result = await buildWebDriver() - driver = result.driver - await driver.navigate() - }) + }); + const result = await buildWebDriver(); + driver = result.driver; + await driver.navigate(); + }); afterEach(async function () { if (process.env.SELENIUM_BROWSER === 'chrome') { - const errors = await driver.checkBrowserForConsoleErrors(driver) + const errors = await driver.checkBrowserForConsoleErrors(driver); if (errors.length) { - const errorReports = errors.map((err) => err.message) + const errorReports = errors.map((err) => err.message); const errorMessage = `Errors found in browser console:\n${errorReports.join( '\n', - )}` - console.error(new Error(errorMessage)) + )}`; + console.error(new Error(errorMessage)); } } if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest.title) + await driver.verboseReportOnFailure(this.currentTest.title); } - }) + }); after(async function () { - await ganacheServer.quit() - await driver.quit() - }) + await ganacheServer.quit(); + await driver.quit(); + }); describe('Going through the first time flow, but skipping the seed phrase challenge', function () { it('clicks the continue button on the welcome screen', async function () { - await driver.findElement(By.css('.welcome-page__header')) + await driver.findElement(By.css('.welcome-page__header')); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`, ), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('clicks the "Create New Wallet" option', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Create a Wallet')]`), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('clicks the "No thanks" option on the metametrics opt-in screen', async function () { - await driver.clickElement(By.css('.btn-default')) - await driver.delay(largeDelayMs) - }) + await driver.clickElement(By.css('.btn-default')); + await driver.delay(largeDelayMs); + }); it('accepts a secure password', async function () { const passwordBox = await driver.findElement( By.css('.first-time-flow__form #create-password'), - ) + ); const passwordBoxConfirm = await driver.findElement( By.css('.first-time-flow__form #confirm-password'), - ) + ); - await passwordBox.sendKeys('correct horse battery staple') - await passwordBoxConfirm.sendKeys('correct horse battery staple') + await passwordBox.sendKeys('correct horse battery staple'); + await passwordBoxConfirm.sendKeys('correct horse battery staple'); - await driver.clickElement(By.css('.first-time-flow__checkbox')) + await driver.clickElement(By.css('.first-time-flow__checkbox')); - await driver.clickElement(By.css('.first-time-flow__form button')) - await driver.delay(regularDelayMs) - }) + await driver.clickElement(By.css('.first-time-flow__form button')); + await driver.delay(regularDelayMs); + }); it('skips the seed phrase challenge', async function () { await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.remindMeLater.message}')]`, ), - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); await driver.clickElement( By.css('[data-testid="account-options-menu-button"]'), - ) + ); await driver.clickElement( By.css('[data-testid="account-options-menu__account-details"]'), - ) - }) + ); + }); it('gets the current accounts address', async function () { const addressInput = await driver.findElement( By.css('.readonly-input__input'), - ) - publicAddress = await addressInput.getAttribute('value') + ); + publicAddress = await addressInput.getAttribute('value'); - const accountModal = await driver.findElement(By.css('span .modal')) + const accountModal = await driver.findElement(By.css('span .modal')); - await driver.clickElement(By.css('.account-modal__close')) + await driver.clickElement(By.css('.account-modal__close')); - await driver.wait(until.stalenessOf(accountModal)) - await driver.delay(regularDelayMs) - }) - }) + await driver.wait(until.stalenessOf(accountModal)); + await driver.delay(regularDelayMs); + }); + }); describe('send to current account from dapp with different provider', function () { - let extension + let extension; it('switches to dapp screen', async function () { - const windowHandles = await driver.getAllWindowHandles() - extension = windowHandles[0] + const windowHandles = await driver.getAllWindowHandles(); + extension = windowHandles[0]; - await driver.openNewPage('http://127.0.0.1:8080/') - await driver.delay(regularDelayMs) - }) + await driver.openNewPage('http://127.0.0.1:8080/'); + await driver.delay(regularDelayMs); + }); it('sends eth to the current account', async function () { - const addressInput = await driver.findElement(By.css('#address')) - await addressInput.sendKeys(publicAddress) - await driver.delay(regularDelayMs) + const addressInput = await driver.findElement(By.css('#address')); + await addressInput.sendKeys(publicAddress); + await driver.delay(regularDelayMs); - await driver.clickElement(By.css('#send')) + await driver.clickElement(By.css('#send')); - const txStatus = await driver.findElement(By.css('#success')) - await driver.wait(until.elementTextMatches(txStatus, /Success/u), 15000) - }) + const txStatus = await driver.findElement(By.css('#success')); + await driver.wait(until.elementTextMatches(txStatus, /Success/u), 15000); + }); it('switches back to MetaMask', async function () { - await driver.switchToWindow(extension) - }) + await driver.switchToWindow(extension); + }); it('should have the correct amount of eth', async function () { const balances = await driver.findElements( By.css('.currency-display-component__text'), - ) - await driver.wait(until.elementTextMatches(balances[0], /1/u), 15000) - const balance = await balances[0].getText() + ); + await driver.wait(until.elementTextMatches(balances[0], /1/u), 15000); + const balance = await balances[0].getText(); - assert.equal(balance, '1') - }) - }) + assert.equal(balance, '1'); + }); + }); describe('backs up the seed phrase', function () { it('should show a backup reminder', async function () { @@ -171,80 +171,80 @@ describe('MetaMask', function () { By.xpath( "//div[contains(@class, 'home-notification__text') and contains(text(), 'Backup your Secret Recovery code to keep your wallet and funds secure')]", ), - ) - assert.equal(backupReminder.length, 1) - }) + ); + assert.equal(backupReminder.length, 1); + }); it('should take the user to the seedphrase backup screen', async function () { - await driver.clickElement(By.css('.home-notification__accept-button')) - await driver.delay(regularDelayMs) - }) + await driver.clickElement(By.css('.home-notification__accept-button')); + await driver.delay(regularDelayMs); + }); - let seedPhrase + let seedPhrase; it('reveals the seed phrase', async function () { const byRevealButton = By.css( '.reveal-seed-phrase__secret-blocker .reveal-seed-phrase__reveal-button', - ) - await driver.clickElement(byRevealButton) - await driver.delay(regularDelayMs) + ); + await driver.clickElement(byRevealButton); + await driver.delay(regularDelayMs); const revealedSeedPhrase = await driver.findElement( By.css('.reveal-seed-phrase__secret-words'), - ) - seedPhrase = await revealedSeedPhrase.getText() - assert.equal(seedPhrase.split(' ').length, 12) - await driver.delay(regularDelayMs) + ); + seedPhrase = await revealedSeedPhrase.getText(); + assert.equal(seedPhrase.split(' ').length, 12); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.next.message}')]`, ), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); async function clickWordAndWait(word) { await driver.clickElement( By.css( `[data-testid="seed-phrase-sorted"] [data-testid="draggable-seed-${word}"]`, ), - ) - await driver.delay(tinyDelayMs) + ); + await driver.delay(tinyDelayMs); } it('can retype the seed phrase', async function () { - const words = seedPhrase.split(' ') + const words = seedPhrase.split(' '); for (const word of words) { - await clickWordAndWait(word) + await clickWordAndWait(word); } await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('can click through the success screen', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'All Done')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('should have the correct amount of eth', async function () { const balances = await driver.findElements( By.css('.currency-display-component__text'), - ) - await driver.wait(until.elementTextMatches(balances[0], /1/u), 15000) - const balance = await balances[0].getText() + ); + await driver.wait(until.elementTextMatches(balances[0], /1/u), 15000); + const balance = await balances[0].getText(); - assert.equal(balance, '1') - }) + assert.equal(balance, '1'); + }); it('should not show a backup reminder', async function () { - await driver.assertElementNotPresent(By.css('.backup-notification')) - }) - }) -}) + await driver.assertElementNotPresent(By.css('.backup-notification')); + }); + }); +}); diff --git a/test/e2e/metamask-responsive-ui.spec.js b/test/e2e/metamask-responsive-ui.spec.js index 60fe1c9018..eab3f498e2 100644 --- a/test/e2e/metamask-responsive-ui.spec.js +++ b/test/e2e/metamask-responsive-ui.spec.js @@ -1,287 +1,289 @@ -const assert = require('assert') -const webdriver = require('selenium-webdriver') +const assert = require('assert'); +const webdriver = require('selenium-webdriver'); -const { By, until } = webdriver -const enLocaleMessages = require('../../app/_locales/en/messages.json') -const { tinyDelayMs, regularDelayMs, largeDelayMs } = require('./helpers') -const { buildWebDriver } = require('./webdriver') -const Ganache = require('./ganache') +const { By, until } = webdriver; +const enLocaleMessages = require('../../app/_locales/en/messages.json'); +const { tinyDelayMs, regularDelayMs, largeDelayMs } = require('./helpers'); +const { buildWebDriver } = require('./webdriver'); +const Ganache = require('./ganache'); -const ganacheServer = new Ganache() +const ganacheServer = new Ganache(); describe('MetaMask', function () { - let driver + let driver; const testSeedPhrase = - 'phrase upgrade clock rough situate wedding elder clever doctor stamp excess tent' + 'phrase upgrade clock rough situate wedding elder clever doctor stamp excess tent'; - this.timeout(0) - this.bail(true) + this.timeout(0); + this.bail(true); before(async function () { - await ganacheServer.start() - const result = await buildWebDriver({ responsive: true }) - driver = result.driver - await driver.navigate() - }) + await ganacheServer.start(); + const result = await buildWebDriver({ responsive: true }); + driver = result.driver; + await driver.navigate(); + }); afterEach(async function () { if (process.env.SELENIUM_BROWSER === 'chrome') { - const errors = await driver.checkBrowserForConsoleErrors(driver) + const errors = await driver.checkBrowserForConsoleErrors(driver); if (errors.length) { - const errorReports = errors.map((err) => err.message) + const errorReports = errors.map((err) => err.message); const errorMessage = `Errors found in browser console:\n${errorReports.join( '\n', - )}` - console.error(new Error(errorMessage)) + )}`; + console.error(new Error(errorMessage)); } } if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest.title) + await driver.verboseReportOnFailure(this.currentTest.title); } - }) + }); after(async function () { - await ganacheServer.quit() - await driver.quit() - }) + await ganacheServer.quit(); + await driver.quit(); + }); describe('Going through the first time flow', function () { it('clicks the continue button on the welcome screen', async function () { - await driver.findElement(By.css('.welcome-page__header')) + await driver.findElement(By.css('.welcome-page__header')); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`, ), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('clicks the "Create New Wallet" option', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Create a Wallet')]`), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('clicks the "I Agree" option on the metametrics opt-in screen', async function () { - await driver.clickElement(By.css('.btn-primary')) - await driver.delay(largeDelayMs) - }) + await driver.clickElement(By.css('.btn-primary')); + await driver.delay(largeDelayMs); + }); it('accepts a secure password', async function () { const passwordBox = await driver.findElement( By.css('.first-time-flow__form #create-password'), - ) + ); const passwordBoxConfirm = await driver.findElement( By.css('.first-time-flow__form #confirm-password'), - ) + ); - await passwordBox.sendKeys('correct horse battery staple') - await passwordBoxConfirm.sendKeys('correct horse battery staple') + await passwordBox.sendKeys('correct horse battery staple'); + await passwordBoxConfirm.sendKeys('correct horse battery staple'); - await driver.clickElement(By.css('.first-time-flow__checkbox')) + await driver.clickElement(By.css('.first-time-flow__checkbox')); - await driver.clickElement(By.css('.first-time-flow__form button')) - await driver.delay(regularDelayMs) - }) + await driver.clickElement(By.css('.first-time-flow__form button')); + await driver.delay(regularDelayMs); + }); - let seedPhrase + let seedPhrase; it('reveals the seed phrase', async function () { const byRevealButton = By.css( '.reveal-seed-phrase__secret-blocker .reveal-seed-phrase__reveal-button', - ) - await driver.clickElement(byRevealButton) - await driver.delay(regularDelayMs) + ); + await driver.clickElement(byRevealButton); + await driver.delay(regularDelayMs); const revealedSeedPhrase = await driver.findElement( By.css('.reveal-seed-phrase__secret-words'), - ) - seedPhrase = await revealedSeedPhrase.getText() - assert.equal(seedPhrase.split(' ').length, 12) - await driver.delay(regularDelayMs) + ); + seedPhrase = await revealedSeedPhrase.getText(); + assert.equal(seedPhrase.split(' ').length, 12); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.next.message}')]`, ), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); async function clickWordAndWait(word) { await driver.clickElement( By.css( `[data-testid="seed-phrase-sorted"] [data-testid="draggable-seed-${word}"]`, ), - ) - await driver.delay(tinyDelayMs) + ); + await driver.delay(tinyDelayMs); } it('can retype the seed phrase', async function () { - const words = seedPhrase.split(' ') + const words = seedPhrase.split(' '); for (const word of words) { - await clickWordAndWait(word) + await clickWordAndWait(word); } await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('clicks through the success screen', async function () { await driver.findElement( By.xpath(`//div[contains(text(), 'Congratulations')]`), - ) + ); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`, ), - ) - await driver.delay(regularDelayMs) - }) - }) + ); + await driver.delay(regularDelayMs); + }); + }); describe('Show account information', function () { it('show account details dropdown menu', async function () { await driver.clickElement( By.css('[data-testid="account-options-menu-button"]'), - ) + ); const options = await driver.findElements( By.css('.account-options-menu .menu-item'), - ) - assert.equal(options.length, 3) // HD Wallet type does not have to show the Remove Account option + ); + assert.equal(options.length, 3); // HD Wallet type does not have to show the Remove Account option // click outside of menu to dismiss // account menu button chosen because the menu never covers it. - await driver.clickPoint(By.css('.account-menu__icon'), 0, 0) - await driver.delay(regularDelayMs) - }) - }) + await driver.clickPoint(By.css('.account-menu__icon'), 0, 0); + await driver.delay(regularDelayMs); + }); + }); describe('Import seed phrase', function () { it('logs out of the vault', async function () { - await driver.clickElement(By.css('.account-menu__icon')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.account-menu__icon')); + await driver.delay(regularDelayMs); const lockButton = await driver.findClickableElement( By.css('.account-menu__lock-button'), - ) - assert.equal(await lockButton.getText(), 'Lock') - await lockButton.click() - await driver.delay(regularDelayMs) - }) + ); + assert.equal(await lockButton.getText(), 'Lock'); + await lockButton.click(); + await driver.delay(regularDelayMs); + }); it('imports seed phrase', async function () { const restoreSeedLink = await driver.findClickableElement( By.css('.unlock-page__link--import'), - ) + ); assert.equal( await restoreSeedLink.getText(), 'Import using account seed phrase', - ) - await restoreSeedLink.click() - await driver.delay(regularDelayMs) + ); + await restoreSeedLink.click(); + await driver.delay(regularDelayMs); - await driver.clickElement(By.css('.import-account__checkbox-container')) + await driver.clickElement(By.css('.import-account__checkbox-container')); - const seedTextArea = await driver.findElement(By.css('textarea')) - await seedTextArea.sendKeys(testSeedPhrase) - await driver.delay(regularDelayMs) + const seedTextArea = await driver.findElement(By.css('textarea')); + await seedTextArea.sendKeys(testSeedPhrase); + await driver.delay(regularDelayMs); - const passwordInputs = await driver.findElements(By.css('input')) - await driver.delay(regularDelayMs) + const passwordInputs = await driver.findElements(By.css('input')); + await driver.delay(regularDelayMs); - await passwordInputs[0].sendKeys('correct horse battery staple') - await passwordInputs[1].sendKeys('correct horse battery staple') + await passwordInputs[0].sendKeys('correct horse battery staple'); + await passwordInputs[1].sendKeys('correct horse battery staple'); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.restore.message}')]`, ), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('switches to localhost', async function () { - await driver.clickElement(By.css('.network-display')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.network-display')); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath( `//span[contains(@class, 'network-name-item') and contains(text(), 'Localhost 8545')]`, ), - ) - await driver.delay(largeDelayMs * 2) - }) + ); + await driver.delay(largeDelayMs * 2); + }); it('balance renders', async function () { const balance = await driver.findElement( By.css('[data-testid="eth-overview__primary-currency"]'), - ) - await driver.wait(until.elementTextMatches(balance, /100\s*ETH/u)) - await driver.delay(regularDelayMs) - }) - }) + ); + await driver.wait(until.elementTextMatches(balance, /100\s*ETH/u)); + await driver.delay(regularDelayMs); + }); + }); describe('Send ETH from inside MetaMask', function () { it('starts to send a transaction', async function () { - await driver.clickElement(By.css('[data-testid="eth-overview-send"]')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('[data-testid="eth-overview-send"]')); + await driver.delay(regularDelayMs); const inputAddress = await driver.findElement( By.css('input[placeholder="Search, public address (0x), or ENS"]'), - ) - await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970') + ); + await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970'); - const inputAmount = await driver.findElement(By.css('.unit-input__input')) - await inputAmount.sendKeys('1') + const inputAmount = await driver.findElement( + By.css('.unit-input__input'), + ); + await inputAmount.sendKeys('1'); - const inputValue = await inputAmount.getAttribute('value') - assert.equal(inputValue, '1') - await driver.delay(regularDelayMs) - }) + const inputValue = await inputAmount.getAttribute('value'); + assert.equal(inputValue, '1'); + await driver.delay(regularDelayMs); + }); it('opens and closes the gas modal', async function () { // Set the gas limit - await driver.clickElement(By.css('.advanced-gas-options-btn')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.advanced-gas-options-btn')); + await driver.delay(regularDelayMs); - const gasModal = await driver.findElement(By.css('span .modal')) + const gasModal = await driver.findElement(By.css('span .modal')); - await driver.clickElement(By.css('.page-container__header-close-text')) - await driver.wait(until.stalenessOf(gasModal), 10000) - await driver.delay(regularDelayMs) - }) + await driver.clickElement(By.css('.page-container__header-close-text')); + await driver.wait(until.stalenessOf(gasModal), 10000); + await driver.delay(regularDelayMs); + }); it('clicks through to the confirm screen', async function () { // Continue to next screen - await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await driver.delay(regularDelayMs) - }) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)); + await driver.delay(regularDelayMs); + }); it('confirms the transaction', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - }) + ); + }); it('finds the transaction in the transactions list', async function () { - await driver.clickElement(By.css('[data-testid="home__activity-tab"]')) + await driver.clickElement(By.css('[data-testid="home__activity-tab"]')); await driver.wait(async () => { const confirmedTxes = await driver.findElements( By.css( '.transaction-list__completed-transactions .transaction-list-item', ), - ) - return confirmedTxes.length === 1 - }, 10000) + ); + return confirmedTxes.length === 1; + }, 10000); const txValues = await driver.findElement( By.css('.transaction-list-item__primary-currency'), - ) - await driver.wait(until.elementTextMatches(txValues, /-1\s*ETH/u), 10000) - }) - }) -}) + ); + await driver.wait(until.elementTextMatches(txValues, /-1\s*ETH/u), 10000); + }); + }); +}); diff --git a/test/e2e/metamask-ui.spec.js b/test/e2e/metamask-ui.spec.js index da6d159f6c..4ac2ee14d2 100644 --- a/test/e2e/metamask-ui.spec.js +++ b/test/e2e/metamask-ui.spec.js @@ -1,390 +1,394 @@ -const assert = require('assert') -const webdriver = require('selenium-webdriver') +const assert = require('assert'); +const webdriver = require('selenium-webdriver'); -const { By, Key, until } = webdriver -const enLocaleMessages = require('../../app/_locales/en/messages.json') -const { tinyDelayMs, regularDelayMs, largeDelayMs } = require('./helpers') -const { buildWebDriver } = require('./webdriver') -const Ganache = require('./ganache') +const { By, Key, until } = webdriver; +const enLocaleMessages = require('../../app/_locales/en/messages.json'); +const { tinyDelayMs, regularDelayMs, largeDelayMs } = require('./helpers'); +const { buildWebDriver } = require('./webdriver'); +const Ganache = require('./ganache'); -const ganacheServer = new Ganache() +const ganacheServer = new Ganache(); describe('MetaMask', function () { - let driver - let tokenAddress + let driver; + let tokenAddress; const testSeedPhrase = - 'phrase upgrade clock rough situate wedding elder clever doctor stamp excess tent' + 'phrase upgrade clock rough situate wedding elder clever doctor stamp excess tent'; - this.timeout(0) - this.bail(true) + this.timeout(0); + this.bail(true); before(async function () { - await ganacheServer.start() - const result = await buildWebDriver() - driver = result.driver - await driver.navigate() - }) + await ganacheServer.start(); + const result = await buildWebDriver(); + driver = result.driver; + await driver.navigate(); + }); afterEach(async function () { if (process.env.SELENIUM_BROWSER === 'chrome') { - const errors = await driver.checkBrowserForConsoleErrors(driver) + const errors = await driver.checkBrowserForConsoleErrors(driver); if (errors.length) { - const errorReports = errors.map((err) => err.message) + const errorReports = errors.map((err) => err.message); const errorMessage = `Errors found in browser console:\n${errorReports.join( '\n', - )}` - console.error(new Error(errorMessage)) + )}`; + console.error(new Error(errorMessage)); } } if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest.title) + await driver.verboseReportOnFailure(this.currentTest.title); } - }) + }); after(async function () { - await ganacheServer.quit() - await driver.quit() - }) + await ganacheServer.quit(); + await driver.quit(); + }); describe('Going through the first time flow', function () { it('clicks the continue button on the welcome screen', async function () { - await driver.findElement(By.css('.welcome-page__header')) + await driver.findElement(By.css('.welcome-page__header')); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`, ), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('clicks the "Create New Wallet" option', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Create a Wallet')]`), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('clicks the "No thanks" option on the metametrics opt-in screen', async function () { - await driver.clickElement(By.css('.btn-default')) - await driver.delay(largeDelayMs) - }) + await driver.clickElement(By.css('.btn-default')); + await driver.delay(largeDelayMs); + }); it('accepts a secure password', async function () { const passwordBox = await driver.findElement( By.css('.first-time-flow__form #create-password'), - ) + ); const passwordBoxConfirm = await driver.findElement( By.css('.first-time-flow__form #confirm-password'), - ) + ); - await passwordBox.sendKeys('correct horse battery staple') - await passwordBoxConfirm.sendKeys('correct horse battery staple') + await passwordBox.sendKeys('correct horse battery staple'); + await passwordBoxConfirm.sendKeys('correct horse battery staple'); - await driver.clickElement(By.css('.first-time-flow__checkbox')) + await driver.clickElement(By.css('.first-time-flow__checkbox')); - await driver.clickElement(By.css('.first-time-flow__form button')) - await driver.delay(regularDelayMs) - }) + await driver.clickElement(By.css('.first-time-flow__form button')); + await driver.delay(regularDelayMs); + }); - let seedPhrase + let seedPhrase; it('reveals the seed phrase', async function () { const byRevealButton = By.css( '.reveal-seed-phrase__secret-blocker .reveal-seed-phrase__reveal-button', - ) - await driver.findElement(byRevealButton) - await driver.clickElement(byRevealButton) - await driver.delay(regularDelayMs) + ); + await driver.findElement(byRevealButton); + await driver.clickElement(byRevealButton); + await driver.delay(regularDelayMs); const revealedSeedPhrase = await driver.findElement( By.css('.reveal-seed-phrase__secret-words'), - ) - seedPhrase = await revealedSeedPhrase.getText() - assert.equal(seedPhrase.split(' ').length, 12) - await driver.delay(regularDelayMs) + ); + seedPhrase = await revealedSeedPhrase.getText(); + assert.equal(seedPhrase.split(' ').length, 12); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.next.message}')]`, ), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); async function clickWordAndWait(word) { await driver.clickElement( By.css( `[data-testid="seed-phrase-sorted"] [data-testid="draggable-seed-${word}"]`, ), - ) - await driver.delay(tinyDelayMs) + ); + await driver.delay(tinyDelayMs); } it('can retype the seed phrase', async function () { - const words = seedPhrase.split(' ') + const words = seedPhrase.split(' '); for (const word of words) { - await clickWordAndWait(word) + await clickWordAndWait(word); } await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('clicks through the success screen', async function () { await driver.findElement( By.xpath(`//div[contains(text(), 'Congratulations')]`), - ) + ); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`, ), - ) - await driver.delay(regularDelayMs) - }) - }) + ); + await driver.delay(regularDelayMs); + }); + }); describe('Show account information', function () { it('shows the QR code for the account', async function () { await driver.clickElement( By.css('[data-testid="account-options-menu-button"]'), - ) + ); await driver.clickElement( By.css('[data-testid="account-options-menu__account-details"]'), - ) - await driver.findVisibleElement(By.css('.qr-code__wrapper')) - await driver.delay(regularDelayMs) + ); + await driver.findVisibleElement(By.css('.qr-code__wrapper')); + await driver.delay(regularDelayMs); - const accountModal = await driver.findElement(By.css('span .modal')) - await driver.clickElement(By.css('.account-modal__close')) + const accountModal = await driver.findElement(By.css('span .modal')); + await driver.clickElement(By.css('.account-modal__close')); - await driver.wait(until.stalenessOf(accountModal)) - await driver.delay(regularDelayMs) - }) - }) + await driver.wait(until.stalenessOf(accountModal)); + await driver.delay(regularDelayMs); + }); + }); describe('Lock an unlock', function () { it('logs out of the account', async function () { - await driver.clickElement(By.css('.account-menu__icon')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.account-menu__icon')); + await driver.delay(regularDelayMs); const lockButton = await driver.findClickableElement( By.css('.account-menu__lock-button'), - ) - assert.equal(await lockButton.getText(), 'Lock') - await lockButton.click() - await driver.delay(regularDelayMs) - }) + ); + assert.equal(await lockButton.getText(), 'Lock'); + await lockButton.click(); + await driver.delay(regularDelayMs); + }); it('accepts the account password after lock', async function () { - const passwordField = await driver.findElement(By.id('password')) - await passwordField.sendKeys('correct horse battery staple') - await passwordField.sendKeys(Key.ENTER) - await driver.delay(largeDelayMs * 4) - }) - }) + const passwordField = await driver.findElement(By.id('password')); + await passwordField.sendKeys('correct horse battery staple'); + await passwordField.sendKeys(Key.ENTER); + await driver.delay(largeDelayMs * 4); + }); + }); describe('Add account', function () { it('choose Create Account from the account menu', async function () { - await driver.clickElement(By.css('.account-menu__icon')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.account-menu__icon')); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//div[contains(text(), 'Create Account')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('set account name', async function () { const accountName = await driver.findElement( By.css('.new-account-create-form input'), - ) - await accountName.sendKeys('2nd account') - await driver.delay(regularDelayMs) + ); + await accountName.sendKeys('2nd account'); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//button[contains(text(), 'Create')]`), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('should display correct account name', async function () { const accountName = await driver.findElement( By.css('.selected-account__name'), - ) - assert.equal(await accountName.getText(), '2nd account') - await driver.delay(regularDelayMs) - }) - }) + ); + assert.equal(await accountName.getText(), '2nd account'); + await driver.delay(regularDelayMs); + }); + }); describe('Import seed phrase', function () { it('logs out of the vault', async function () { - await driver.clickElement(By.css('.account-menu__icon')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.account-menu__icon')); + await driver.delay(regularDelayMs); const lockButton = await driver.findClickableElement( By.css('.account-menu__lock-button'), - ) - assert.equal(await lockButton.getText(), 'Lock') - await lockButton.click() - await driver.delay(regularDelayMs) - }) + ); + assert.equal(await lockButton.getText(), 'Lock'); + await lockButton.click(); + await driver.delay(regularDelayMs); + }); it('imports seed phrase', async function () { const restoreSeedLink = await driver.findClickableElement( By.css('.unlock-page__link--import'), - ) + ); assert.equal( await restoreSeedLink.getText(), 'Import using account seed phrase', - ) - await restoreSeedLink.click() - await driver.delay(regularDelayMs) + ); + await restoreSeedLink.click(); + await driver.delay(regularDelayMs); - await driver.clickElement(By.css('.import-account__checkbox-container')) + await driver.clickElement(By.css('.import-account__checkbox-container')); - const seedTextArea = await driver.findElement(By.css('textarea')) - await seedTextArea.sendKeys(testSeedPhrase) - await driver.delay(regularDelayMs) + const seedTextArea = await driver.findElement(By.css('textarea')); + await seedTextArea.sendKeys(testSeedPhrase); + await driver.delay(regularDelayMs); - const passwordInputs = await driver.findElements(By.css('input')) - await driver.delay(regularDelayMs) + const passwordInputs = await driver.findElements(By.css('input')); + await driver.delay(regularDelayMs); - await passwordInputs[0].sendKeys('correct horse battery staple') - await passwordInputs[1].sendKeys('correct horse battery staple') + await passwordInputs[0].sendKeys('correct horse battery staple'); + await passwordInputs[1].sendKeys('correct horse battery staple'); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.restore.message}')]`, ), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('balance renders', async function () { const balance = await driver.findElement( By.css('[data-testid="wallet-balance"] .list-item__heading'), - ) - await driver.wait(until.elementTextMatches(balance, /100\s*ETH/u)) - await driver.delay(regularDelayMs) - }) - }) + ); + await driver.wait(until.elementTextMatches(balance, /100\s*ETH/u)); + await driver.delay(regularDelayMs); + }); + }); describe('Send ETH from inside MetaMask using default gas', function () { it('starts a send transaction', async function () { - await driver.clickElement(By.css('[data-testid="eth-overview-send"]')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('[data-testid="eth-overview-send"]')); + await driver.delay(regularDelayMs); const inputAddress = await driver.findElement( By.css('input[placeholder="Search, public address (0x), or ENS"]'), - ) - await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970') + ); + await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970'); - const inputAmount = await driver.findElement(By.css('.unit-input__input')) - await inputAmount.sendKeys('1000') + const inputAmount = await driver.findElement( + By.css('.unit-input__input'), + ); + await inputAmount.sendKeys('1000'); const errorAmount = await driver.findElement( By.css('.send-v2__error-amount'), - ) + ); assert.equal( await errorAmount.getText(), 'Insufficient funds.', 'send screen should render an insufficient fund error message', - ) + ); - await inputAmount.sendKeys(Key.BACK_SPACE) - await driver.delay(50) - await inputAmount.sendKeys(Key.BACK_SPACE) - await driver.delay(50) - await inputAmount.sendKeys(Key.BACK_SPACE) - await driver.delay(tinyDelayMs) + await inputAmount.sendKeys(Key.BACK_SPACE); + await driver.delay(50); + await inputAmount.sendKeys(Key.BACK_SPACE); + await driver.delay(50); + await inputAmount.sendKeys(Key.BACK_SPACE); + await driver.delay(tinyDelayMs); - await driver.assertElementNotPresent(By.css('.send-v2__error-amount')) + await driver.assertElementNotPresent(By.css('.send-v2__error-amount')); const amountMax = await driver.findClickableElement( By.css('.send-v2__amount-max'), - ) - await amountMax.click() + ); + await amountMax.click(); - let inputValue = await inputAmount.getAttribute('value') + let inputValue = await inputAmount.getAttribute('value'); - assert(Number(inputValue) > 99) + assert(Number(inputValue) > 99); - await amountMax.click() + await amountMax.click(); - assert.equal(await inputAmount.isEnabled(), true) + assert.equal(await inputAmount.isEnabled(), true); - await inputAmount.sendKeys('1') + await inputAmount.sendKeys('1'); - inputValue = await inputAmount.getAttribute('value') - assert.equal(inputValue, '1') - await driver.delay(regularDelayMs) + inputValue = await inputAmount.getAttribute('value'); + assert.equal(inputValue, '1'); + await driver.delay(regularDelayMs); // Continue to next screen - await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await driver.delay(regularDelayMs) - }) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)); + await driver.delay(regularDelayMs); + }); it('confirms the transaction', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - await driver.delay(largeDelayMs * 2) - }) + ); + await driver.delay(largeDelayMs * 2); + }); it('finds the transaction in the transactions list', async function () { - await driver.clickElement(By.css('[data-testid="home__activity-tab"]')) + await driver.clickElement(By.css('[data-testid="home__activity-tab"]')); await driver.wait(async () => { const confirmedTxes = await driver.findElements( By.css( '.transaction-list__completed-transactions .transaction-list-item', ), - ) - return confirmedTxes.length === 1 - }, 10000) + ); + return confirmedTxes.length === 1; + }, 10000); const txValues = await driver.findElement( By.css('.transaction-list-item__primary-currency'), - ) - await driver.wait(until.elementTextMatches(txValues, /-1\s*ETH/u), 10000) - }) - }) + ); + await driver.wait(until.elementTextMatches(txValues, /-1\s*ETH/u), 10000); + }); + }); describe('Send ETH from inside MetaMask using fast gas option', function () { it('starts a send transaction', async function () { - await driver.clickElement(By.css('[data-testid="eth-overview-send"]')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('[data-testid="eth-overview-send"]')); + await driver.delay(regularDelayMs); const inputAddress = await driver.findElement( By.css('input[placeholder="Search, public address (0x), or ENS"]'), - ) - await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970') + ); + await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970'); - const inputAmount = await driver.findElement(By.css('.unit-input__input')) - await inputAmount.sendKeys('1') + const inputAmount = await driver.findElement( + By.css('.unit-input__input'), + ); + await inputAmount.sendKeys('1'); - const inputValue = await inputAmount.getAttribute('value') - assert.equal(inputValue, '1') + const inputValue = await inputAmount.getAttribute('value'); + assert.equal(inputValue, '1'); // Set the gas price await driver.clickElement( By.xpath(`//button/div/div[contains(text(), "Fast")]`), - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); // Continue to next screen - await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await driver.delay(regularDelayMs) - }) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)); + await driver.delay(regularDelayMs); + }); it('confirms the transaction', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('finds the transaction in the transactions list', async function () { await driver.wait(async () => { @@ -392,59 +396,61 @@ describe('MetaMask', function () { By.css( '.transaction-list__completed-transactions .transaction-list-item', ), - ) - return confirmedTxes.length === 2 - }, 10000) + ); + return confirmedTxes.length === 2; + }, 10000); const txValues = await driver.findElement( By.css('.transaction-list-item__primary-currency'), - ) - await driver.wait(until.elementTextMatches(txValues, /-1\s*ETH/u), 10000) - }) - }) + ); + await driver.wait(until.elementTextMatches(txValues, /-1\s*ETH/u), 10000); + }); + }); describe('Send ETH from inside MetaMask using advanced gas modal', function () { it('starts a send transaction', async function () { - await driver.clickElement(By.css('[data-testid="eth-overview-send"]')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('[data-testid="eth-overview-send"]')); + await driver.delay(regularDelayMs); const inputAddress = await driver.findElement( By.css('input[placeholder="Search, public address (0x), or ENS"]'), - ) - await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970') + ); + await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970'); - const inputAmount = await driver.findElement(By.css('.unit-input__input')) - await inputAmount.sendKeys('1') + const inputAmount = await driver.findElement( + By.css('.unit-input__input'), + ); + await inputAmount.sendKeys('1'); - const inputValue = await inputAmount.getAttribute('value') - assert.equal(inputValue, '1') + const inputValue = await inputAmount.getAttribute('value'); + assert.equal(inputValue, '1'); // Set the gas limit - await driver.clickElement(By.css('.advanced-gas-options-btn')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.advanced-gas-options-btn')); + await driver.delay(regularDelayMs); - const gasModal = await driver.findElement(By.css('span .modal')) - await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)) - await driver.wait(until.stalenessOf(gasModal)) - await driver.delay(regularDelayMs) + const gasModal = await driver.findElement(By.css('span .modal')); + await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)); + await driver.wait(until.stalenessOf(gasModal)); + await driver.delay(regularDelayMs); // Continue to next screen - await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await driver.delay(regularDelayMs) - }) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)); + await driver.delay(regularDelayMs); + }); it('confirms the transaction', async function () { const transactionAmounts = await driver.findElements( By.css('.currency-display-component__text'), - ) - const transactionAmount = transactionAmounts[0] - assert.equal(await transactionAmount.getText(), '1') + ); + const transactionAmount = transactionAmounts[0]; + assert.equal(await transactionAmount.getText(), '1'); await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('finds the transaction in the transactions list', async function () { await driver.wait(async () => { @@ -452,140 +458,144 @@ describe('MetaMask', function () { By.css( '.transaction-list__completed-transactions .transaction-list-item', ), - ) - return confirmedTxes.length === 3 - }, 10000) + ); + return confirmedTxes.length === 3; + }, 10000); const txValues = await driver.findElement( By.css('.transaction-list-item__primary-currency'), - ) - await driver.wait(until.elementTextMatches(txValues, /-1\s*ETH/u), 10000) - }) - }) + ); + await driver.wait(until.elementTextMatches(txValues, /-1\s*ETH/u), 10000); + }); + }); describe('Send ETH from dapp using advanced gas controls', function () { - let windowHandles - let extension - let popup - let dapp + let windowHandles; + let extension; + let popup; + let dapp; it('goes to the settings screen', async function () { - await driver.clickElement(By.css('.account-menu__icon')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.account-menu__icon')); + await driver.delay(regularDelayMs); - await driver.clickElement(By.xpath(`//div[contains(text(), 'Settings')]`)) + await driver.clickElement( + By.xpath(`//div[contains(text(), 'Settings')]`), + ); // await driver.findElement(By.css('.tab-bar')) - await driver.clickElement(By.xpath(`//div[contains(text(), 'Advanced')]`)) - await driver.delay(regularDelayMs) + await driver.clickElement( + By.xpath(`//div[contains(text(), 'Advanced')]`), + ); + await driver.delay(regularDelayMs); await driver.clickElement( By.css( '[data-testid="advanced-setting-show-testnet-conversion"] .settings-page__content-item-col > div > div', ), - ) + ); const advancedGasTitle = await driver.findElement( By.xpath(`//span[contains(text(), 'Advanced gas controls')]`), - ) - await driver.scrollToElement(advancedGasTitle) + ); + await driver.scrollToElement(advancedGasTitle); await driver.clickElement( By.css( '[data-testid="advanced-setting-advanced-gas-inline"] .settings-page__content-item-col > div > div', ), - ) - windowHandles = await driver.getAllWindowHandles() - extension = windowHandles[0] - await driver.closeAllWindowHandlesExcept([extension]) + ); + windowHandles = await driver.getAllWindowHandles(); + extension = windowHandles[0]; + await driver.closeAllWindowHandlesExcept([extension]); - await driver.clickElement(By.css('.app-header__logo-container')) + await driver.clickElement(By.css('.app-header__logo-container')); - await driver.delay(largeDelayMs) - }) + await driver.delay(largeDelayMs); + }); it('connects the dapp', async function () { - await driver.openNewPage('http://127.0.0.1:8080/') - await driver.delay(regularDelayMs) + await driver.openNewPage('http://127.0.0.1:8080/'); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//button[contains(text(), 'Connect')]`), - ) + ); - await driver.delay(regularDelayMs) + await driver.delay(regularDelayMs); - await driver.waitUntilXWindowHandles(3) - windowHandles = await driver.getAllWindowHandles() + await driver.waitUntilXWindowHandles(3); + windowHandles = await driver.getAllWindowHandles(); - extension = windowHandles[0] + extension = windowHandles[0]; dapp = await driver.switchToWindowWithTitle( 'E2E Test Dapp', windowHandles, - ) + ); popup = windowHandles.find( (handle) => handle !== extension && handle !== dapp, - ) + ); - await driver.switchToWindow(popup) + await driver.switchToWindow(popup); - await driver.delay(regularDelayMs) + await driver.delay(regularDelayMs); - await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)); await driver.clickElement( By.xpath(`//button[contains(text(), 'Connect')]`), - ) + ); - await driver.waitUntilXWindowHandles(2) - await driver.switchToWindow(dapp) - await driver.delay(regularDelayMs) - }) + await driver.waitUntilXWindowHandles(2); + await driver.switchToWindow(dapp); + await driver.delay(regularDelayMs); + }); it('initiates a send from the dapp', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Send')]`), 10000, - ) - await driver.delay(2000) + ); + await driver.delay(2000); - windowHandles = await driver.getAllWindowHandles() + windowHandles = await driver.getAllWindowHandles(); await driver.switchToWindowWithTitle( 'MetaMask Notification', windowHandles, - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); await driver.assertElementNotPresent( By.xpath(`//li[contains(text(), 'Data')]`), - ) + ); const [gasPriceInput, gasLimitInput] = await driver.findElements( By.css('.advanced-gas-inputs__gas-edit-row__input'), - ) + ); - await gasPriceInput.clear() - await driver.delay(50) - await gasPriceInput.sendKeys('10') - await driver.delay(50) - await driver.delay(tinyDelayMs) - await driver.delay(50) + await gasPriceInput.clear(); + await driver.delay(50); + await gasPriceInput.sendKeys('10'); + await driver.delay(50); + await driver.delay(tinyDelayMs); + await driver.delay(50); - await gasLimitInput.clear() - await driver.delay(50) - await gasLimitInput.sendKeys('25000') + await gasLimitInput.clear(); + await driver.delay(50); + await gasLimitInput.sendKeys('25000'); - await driver.delay(1000) + await driver.delay(1000); await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), 10000, - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); - await driver.waitUntilXWindowHandles(2) - await driver.switchToWindow(extension) - await driver.delay(regularDelayMs) - }) + await driver.waitUntilXWindowHandles(2); + await driver.switchToWindow(extension); + await driver.delay(regularDelayMs); + }); it('finds the transaction in the transactions list', async function () { await driver.wait(async () => { @@ -593,620 +603,624 @@ describe('MetaMask', function () { By.css( '.transaction-list__completed-transactions .transaction-list-item', ), - ) - return confirmedTxes.length === 4 - }, 10000) + ); + return confirmedTxes.length === 4; + }, 10000); const txValue = await driver.findClickableElement( By.css('.transaction-list-item__primary-currency'), - ) - await driver.wait(until.elementTextMatches(txValue, /-3\s*ETH/u), 10000) - }) + ); + await driver.wait(until.elementTextMatches(txValue, /-3\s*ETH/u), 10000); + }); it('the transaction has the expected gas price', async function () { const txValue = await driver.findClickableElement( By.css('.transaction-list-item__primary-currency'), - ) - await txValue.click() + ); + await txValue.click(); const popoverCloseButton = await driver.findClickableElement( By.css('.popover-header__button'), - ) + ); const txGasPrice = await driver.findElement( By.css('[data-testid="transaction-breakdown__gas-price"]'), - ) - await driver.wait(until.elementTextMatches(txGasPrice, /^10$/u), 10000) - await popoverCloseButton.click() - }) - }) + ); + await driver.wait(until.elementTextMatches(txGasPrice, /^10$/u), 10000); + await popoverCloseButton.click(); + }); + }); describe('Navigate transactions', function () { it('adds multiple transactions', async function () { - await driver.delay(regularDelayMs) + await driver.delay(regularDelayMs); - await driver.waitUntilXWindowHandles(2) - const windowHandles = await driver.getAllWindowHandles() - const extension = windowHandles[0] - const dapp = windowHandles[1] + await driver.waitUntilXWindowHandles(2); + const windowHandles = await driver.getAllWindowHandles(); + const extension = windowHandles[0]; + const dapp = windowHandles[1]; - await driver.switchToWindow(dapp) - await driver.delay(largeDelayMs) + await driver.switchToWindow(dapp); + await driver.delay(largeDelayMs); const send3eth = await driver.findClickableElement( By.xpath(`//button[contains(text(), 'Send')]`), - ) - await send3eth.click() - await driver.delay(largeDelayMs) + ); + await send3eth.click(); + await driver.delay(largeDelayMs); const contractDeployment = await driver.findClickableElement( By.xpath(`//button[contains(text(), 'Deploy Contract')]`), - ) - await contractDeployment.click() - await driver.delay(largeDelayMs) + ); + await contractDeployment.click(); + await driver.delay(largeDelayMs); - await send3eth.click() - await driver.delay(largeDelayMs) - await contractDeployment.click() - await driver.delay(largeDelayMs) + await send3eth.click(); + await driver.delay(largeDelayMs); + await contractDeployment.click(); + await driver.delay(largeDelayMs); - await driver.switchToWindow(extension) - await driver.delay(regularDelayMs) + await driver.switchToWindow(extension); + await driver.delay(regularDelayMs); - await driver.clickElement(By.css('.transaction-list-item')) - await driver.delay(largeDelayMs) - }) + await driver.clickElement(By.css('.transaction-list-item')); + await driver.delay(largeDelayMs); + }); it('navigates the transactions', async function () { - await driver.clickElement(By.css('[data-testid="next-page"]')) + await driver.clickElement(By.css('[data-testid="next-page"]')); let navigationElement = await driver.findElement( By.css('.confirm-page-container-navigation'), - ) - let navigationText = await navigationElement.getText() + ); + let navigationText = await navigationElement.getText(); assert.equal( navigationText.includes('2'), true, 'changed transaction right', - ) + ); - await driver.clickElement(By.css('[data-testid="next-page"]')) + await driver.clickElement(By.css('[data-testid="next-page"]')); navigationElement = await driver.findElement( By.css('.confirm-page-container-navigation'), - ) - navigationText = await navigationElement.getText() + ); + navigationText = await navigationElement.getText(); assert.equal( navigationText.includes('3'), true, 'changed transaction right', - ) + ); - await driver.clickElement(By.css('[data-testid="next-page"]')) + await driver.clickElement(By.css('[data-testid="next-page"]')); navigationElement = await driver.findElement( By.css('.confirm-page-container-navigation'), - ) - navigationText = await navigationElement.getText() + ); + navigationText = await navigationElement.getText(); assert.equal( navigationText.includes('4'), true, 'changed transaction right', - ) + ); - await driver.clickElement(By.css('[data-testid="first-page"]')) + await driver.clickElement(By.css('[data-testid="first-page"]')); navigationElement = await driver.findElement( By.css('.confirm-page-container-navigation'), - ) - navigationText = await navigationElement.getText() + ); + navigationText = await navigationElement.getText(); assert.equal( navigationText.includes('1'), true, 'navigate to first transaction', - ) + ); - await driver.clickElement(By.css('[data-testid="last-page"]')) + await driver.clickElement(By.css('[data-testid="last-page"]')); navigationElement = await driver.findElement( By.css('.confirm-page-container-navigation'), - ) - navigationText = await navigationElement.getText() + ); + navigationText = await navigationElement.getText(); assert.equal( navigationText.split('4').length, 3, 'navigate to last transaction', - ) + ); - await driver.clickElement(By.css('[data-testid="previous-page"]')) + await driver.clickElement(By.css('[data-testid="previous-page"]')); navigationElement = await driver.findElement( By.css('.confirm-page-container-navigation'), - ) - navigationText = await navigationElement.getText() + ); + navigationText = await navigationElement.getText(); assert.equal( navigationText.includes('3'), true, 'changed transaction left', - ) + ); - await driver.clickElement(By.css('[data-testid="previous-page"]')) + await driver.clickElement(By.css('[data-testid="previous-page"]')); navigationElement = await driver.findElement( By.css('.confirm-page-container-navigation'), - ) - navigationText = await navigationElement.getText() + ); + navigationText = await navigationElement.getText(); assert.equal( navigationText.includes('2'), true, 'changed transaction left', - ) - }) + ); + }); it('adds a transaction while confirm screen is in focus', async function () { let navigationElement = await driver.findElement( By.css('.confirm-page-container-navigation'), - ) - let navigationText = await navigationElement.getText() + ); + let navigationText = await navigationElement.getText(); assert.equal( navigationText.includes('2'), true, 'second transaction in focus', - ) + ); - const windowHandles = await driver.getAllWindowHandles() - const extension = windowHandles[0] - const dapp = windowHandles[1] + const windowHandles = await driver.getAllWindowHandles(); + const extension = windowHandles[0]; + const dapp = windowHandles[1]; - await driver.switchToWindow(dapp) - await driver.delay(regularDelayMs) + await driver.switchToWindow(dapp); + await driver.delay(regularDelayMs); - await driver.clickElement(By.xpath(`//button[contains(text(), 'Send')]`)) - await driver.delay(regularDelayMs) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Send')]`)); + await driver.delay(regularDelayMs); - await driver.switchToWindow(extension) - await driver.delay(regularDelayMs) + await driver.switchToWindow(extension); + await driver.delay(regularDelayMs); navigationElement = await driver.findElement( By.css('.confirm-page-container-navigation'), - ) - navigationText = await navigationElement.getText() + ); + navigationText = await navigationElement.getText(); assert.equal( navigationText.includes('2'), true, 'correct (same) transaction in focus', - ) - }) + ); + }); it('rejects a transaction', async function () { - await driver.delay(tinyDelayMs) + await driver.delay(tinyDelayMs); await driver.clickElement( By.xpath(`//button[contains(text(), 'Reject')]`), - ) - await driver.delay(largeDelayMs * 2) + ); + await driver.delay(largeDelayMs * 2); const navigationElement = await driver.findElement( By.css('.confirm-page-container-navigation'), - ) - await driver.delay(tinyDelayMs) - const navigationText = await navigationElement.getText() - assert.equal(navigationText.includes('4'), true, 'transaction rejected') - }) + ); + await driver.delay(tinyDelayMs); + const navigationText = await navigationElement.getText(); + assert.equal(navigationText.includes('4'), true, 'transaction rejected'); + }); it('confirms a transaction', async function () { - await driver.delay(tinyDelayMs / 2) + await driver.delay(tinyDelayMs / 2); await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); const navigationElement = await driver.findElement( By.css('.confirm-page-container-navigation'), - ) - await driver.delay(tinyDelayMs / 2) - const navigationText = await navigationElement.getText() - await driver.delay(tinyDelayMs / 2) - assert.equal(navigationText.includes('3'), true, 'transaction confirmed') - }) + ); + await driver.delay(tinyDelayMs / 2); + const navigationText = await navigationElement.getText(); + await driver.delay(tinyDelayMs / 2); + assert.equal(navigationText.includes('3'), true, 'transaction confirmed'); + }); it('rejects the rest of the transactions', async function () { - await driver.clickElement(By.xpath(`//a[contains(text(), 'Reject 3')]`)) - await driver.delay(regularDelayMs) + await driver.clickElement(By.xpath(`//a[contains(text(), 'Reject 3')]`)); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//button[contains(text(), 'Reject All')]`), - ) - await driver.delay(largeDelayMs * 2) + ); + await driver.delay(largeDelayMs * 2); await driver.wait(async () => { const confirmedTxes = await driver.findElements( By.css( '.transaction-list__completed-transactions .transaction-list-item', ), - ) - return confirmedTxes.length === 5 - }, 10000) - }) - }) + ); + return confirmedTxes.length === 5; + }, 10000); + }); + }); describe('Deploy contract and call contract methods', function () { - let extension - let dapp + let extension; + let dapp; it('creates a deploy contract transaction', async function () { - const windowHandles = await driver.getAllWindowHandles() - extension = windowHandles[0] - dapp = windowHandles[1] - await driver.delay(tinyDelayMs) + const windowHandles = await driver.getAllWindowHandles(); + extension = windowHandles[0]; + dapp = windowHandles[1]; + await driver.delay(tinyDelayMs); - await driver.switchToWindow(dapp) - await driver.delay(regularDelayMs) + await driver.switchToWindow(dapp); + await driver.delay(regularDelayMs); - await driver.clickElement(By.css('#deployButton')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('#deployButton')); + await driver.delay(regularDelayMs); - await driver.switchToWindow(extension) - await driver.delay(regularDelayMs) + await driver.switchToWindow(extension); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//h2[contains(text(), 'Contract Deployment')]`), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('displays the contract creation data', async function () { - await driver.clickElement(By.xpath(`//button[contains(text(), 'Data')]`)) - await driver.delay(regularDelayMs) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Data')]`)); + await driver.delay(regularDelayMs); - await driver.findElement(By.xpath(`//div[contains(text(), '127.0.0.1')]`)) + await driver.findElement( + By.xpath(`//div[contains(text(), '127.0.0.1')]`), + ); const confirmDataDiv = await driver.findElement( By.css('.confirm-page-container-content__data-box'), - ) - const confirmDataText = await confirmDataDiv.getText() - assert.ok(confirmDataText.includes('Origin:')) - assert.ok(confirmDataText.includes('127.0.0.1')) - assert.ok(confirmDataText.includes('Bytes:')) - assert.ok(confirmDataText.includes('675')) + ); + const confirmDataText = await confirmDataDiv.getText(); + assert.ok(confirmDataText.includes('Origin:')); + assert.ok(confirmDataText.includes('127.0.0.1')); + assert.ok(confirmDataText.includes('Bytes:')); + assert.ok(confirmDataText.includes('675')); await driver.clickElement( By.xpath(`//button[contains(text(), 'Details')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('confirms a deploy contract transaction', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - await driver.delay(largeDelayMs) + ); + await driver.delay(largeDelayMs); await driver.wait(async () => { const confirmedTxes = await driver.findElements( By.css( '.transaction-list__completed-transactions .transaction-list-item', ), - ) - return confirmedTxes.length === 6 - }, 10000) + ); + return confirmedTxes.length === 6; + }, 10000); - const txAction = await driver.findElements(By.css('.list-item__heading')) + const txAction = await driver.findElements(By.css('.list-item__heading')); await driver.wait( until.elementTextMatches(txAction[0], /Contract\sDeployment/u), 10000, - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('calls and confirms a contract method where ETH is sent', async function () { - await driver.switchToWindow(dapp) - await driver.delay(regularDelayMs) + await driver.switchToWindow(dapp); + await driver.delay(regularDelayMs); - let contractStatus = await driver.findElement(By.css('#contractStatus')) + let contractStatus = await driver.findElement(By.css('#contractStatus')); await driver.wait( until.elementTextMatches(contractStatus, /Deployed/u), 15000, - ) + ); - await driver.clickElement(By.css('#depositButton')) - await driver.delay(largeDelayMs) + await driver.clickElement(By.css('#depositButton')); + await driver.delay(largeDelayMs); - contractStatus = await driver.findElement(By.css('#contractStatus')) + contractStatus = await driver.findElement(By.css('#contractStatus')); await driver.wait( until.elementTextMatches(contractStatus, /Deposit\sinitiated/u), 10000, - ) + ); - await driver.switchToWindow(extension) - await driver.delay(largeDelayMs * 2) + await driver.switchToWindow(extension); + await driver.delay(largeDelayMs * 2); - await driver.findElements(By.css('.transaction-list-item--unconfirmed')) + await driver.findElements(By.css('.transaction-list-item--unconfirmed')); const txListValue = await driver.findClickableElement( By.css('.transaction-list-item__primary-currency'), - ) + ); await driver.wait( until.elementTextMatches(txListValue, /-4\s*ETH/u), 10000, - ) - await txListValue.click() - await driver.delay(regularDelayMs) + ); + await txListValue.click(); + await driver.delay(regularDelayMs); // Set the gas limit await driver.clickElement( By.css('.confirm-detail-row__header-text--edit'), - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); - const gasModal = await driver.findElement(By.css('span .modal')) - await driver.delay(regularDelayMs) - await driver.clickElement(By.css('.page-container__tab:nth-of-type(2)')) - await driver.delay(regularDelayMs) + const gasModal = await driver.findElement(By.css('span .modal')); + await driver.delay(regularDelayMs); + await driver.clickElement(By.css('.page-container__tab:nth-of-type(2)')); + await driver.delay(regularDelayMs); const [gasPriceInput, gasLimitInput] = await driver.findElements( By.css('.advanced-gas-inputs__gas-edit-row__input'), - ) - const gasLimitValue = await gasLimitInput.getAttribute('value') - assert(Number(gasLimitValue) < 100000, 'Gas Limit too high') + ); + const gasLimitValue = await gasLimitInput.getAttribute('value'); + assert(Number(gasLimitValue) < 100000, 'Gas Limit too high'); - await gasPriceInput.clear() - await driver.delay(50) - await gasPriceInput.sendKeys('10') - await driver.delay(50) + await gasPriceInput.clear(); + await driver.delay(50); + await gasPriceInput.sendKeys('10'); + await driver.delay(50); - await gasLimitInput.clear() - await driver.delay(50) - await gasLimitInput.sendKeys('60001') + await gasLimitInput.clear(); + await driver.delay(50); + await gasLimitInput.sendKeys('60001'); - await driver.delay(1000) + await driver.delay(1000); - await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)) - await driver.delay(regularDelayMs) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)); + await driver.delay(regularDelayMs); - await driver.wait(until.stalenessOf(gasModal)) + await driver.wait(until.stalenessOf(gasModal)); await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); await driver.wait(async () => { const confirmedTxes = await driver.findElements( By.css( '.transaction-list__completed-transactions .transaction-list-item', ), - ) - return confirmedTxes.length === 7 - }, 10000) + ); + return confirmedTxes.length === 7; + }, 10000); const txValues = await driver.findElements( By.css('.transaction-list-item__primary-currency'), - ) + ); await driver.wait( until.elementTextMatches(txValues[0], /-4\s*ETH/u), 10000, - ) - }) + ); + }); it('calls and confirms a contract method where ETH is received', async function () { - await driver.switchToWindow(dapp) - await driver.delay(regularDelayMs) + await driver.switchToWindow(dapp); + await driver.delay(regularDelayMs); - await driver.clickElement(By.css('#withdrawButton')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('#withdrawButton')); + await driver.delay(regularDelayMs); - await driver.switchToWindow(extension) - await driver.delay(largeDelayMs * 2) + await driver.switchToWindow(extension); + await driver.delay(largeDelayMs * 2); await driver.clickElement( By.css( '.transaction-list__pending-transactions .transaction-list-item', ), - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); await driver.wait(async () => { const confirmedTxes = await driver.findElements( By.css( '.transaction-list__completed-transactions .transaction-list-item', ), - ) - return confirmedTxes.length === 8 - }, 10000) + ); + return confirmedTxes.length === 8; + }, 10000); const txValues = await driver.findElement( By.css('.transaction-list-item__primary-currency'), - ) - await driver.wait(until.elementTextMatches(txValues, /-0\s*ETH/u), 10000) + ); + await driver.wait(until.elementTextMatches(txValues, /-0\s*ETH/u), 10000); - await driver.closeAllWindowHandlesExcept([extension, dapp]) - await driver.switchToWindow(extension) - }) + await driver.closeAllWindowHandlesExcept([extension, dapp]); + await driver.switchToWindow(extension); + }); it('renders the correct ETH balance', async function () { const balance = await driver.findElement( By.css('[data-testid="eth-overview__primary-currency"]'), - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); await driver.wait( until.elementTextMatches(balance, /^87.*\s*ETH.*$/u), 10000, - ) - const tokenAmount = await balance.getText() - assert.ok(/^87.*\s*ETH.*$/u.test(tokenAmount)) - await driver.delay(regularDelayMs) - }) - }) + ); + const tokenAmount = await balance.getText(); + assert.ok(/^87.*\s*ETH.*$/u.test(tokenAmount)); + await driver.delay(regularDelayMs); + }); + }); describe('Add a custom token from a dapp', function () { it('creates a new token', async function () { - let windowHandles = await driver.getAllWindowHandles() - const extension = windowHandles[0] - const dapp = windowHandles[1] - await driver.delay(regularDelayMs * 2) + let windowHandles = await driver.getAllWindowHandles(); + const extension = windowHandles[0]; + const dapp = windowHandles[1]; + await driver.delay(regularDelayMs * 2); - await driver.switchToWindow(dapp) - await driver.delay(regularDelayMs * 2) + await driver.switchToWindow(dapp); + await driver.delay(regularDelayMs * 2); await driver.clickElement( By.xpath(`//button[contains(text(), 'Create Token')]`), - ) - windowHandles = await driver.waitUntilXWindowHandles(3) + ); + windowHandles = await driver.waitUntilXWindowHandles(3); - const popup = windowHandles[2] - await driver.switchToWindow(popup) - await driver.delay(regularDelayMs) + const popup = windowHandles[2]; + await driver.switchToWindow(popup); + await driver.delay(regularDelayMs); await driver.clickElement( By.css('.confirm-detail-row__header-text--edit'), - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//button[contains(text(), 'Advanced')]`), - ) - await driver.delay(tinyDelayMs) + ); + await driver.delay(tinyDelayMs); const [gasPriceInput, gasLimitInput] = await driver.findElements( By.css('.advanced-gas-inputs__gas-edit-row__input'), - ) - assert(gasPriceInput.getAttribute('value'), 20) - assert(gasLimitInput.getAttribute('value'), 4700000) + ); + assert(gasPriceInput.getAttribute('value'), 20); + assert(gasLimitInput.getAttribute('value'), 4700000); - await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)) - await driver.delay(regularDelayMs) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); - await driver.switchToWindow(dapp) - await driver.delay(tinyDelayMs) + await driver.switchToWindow(dapp); + await driver.delay(tinyDelayMs); const tokenContractAddress = await driver.findElement( By.css('#tokenAddress'), - ) - await driver.wait(until.elementTextMatches(tokenContractAddress, /0x/u)) - tokenAddress = await tokenContractAddress.getText() + ); + await driver.wait(until.elementTextMatches(tokenContractAddress, /0x/u)); + tokenAddress = await tokenContractAddress.getText(); - await driver.delay(regularDelayMs) - await driver.closeAllWindowHandlesExcept([extension, dapp]) - await driver.delay(regularDelayMs) - await driver.switchToWindow(extension) - await driver.delay(largeDelayMs) - }) + await driver.delay(regularDelayMs); + await driver.closeAllWindowHandlesExcept([extension, dapp]); + await driver.delay(regularDelayMs); + await driver.switchToWindow(extension); + await driver.delay(largeDelayMs); + }); it('clicks on the Add Token button', async function () { - await driver.clickElement(By.css(`[data-testid="home__asset-tab"]`)) + await driver.clickElement(By.css(`[data-testid="home__asset-tab"]`)); await driver.clickElement( By.xpath(`//button[contains(text(), 'Add Token')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('picks the newly created Test token', async function () { await driver.clickElement( By.xpath("//button[contains(text(), 'Custom Token')]"), - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); const newTokenAddress = await driver.findElement( By.css('#custom-address'), - ) - await newTokenAddress.sendKeys(tokenAddress) - await driver.delay(regularDelayMs) + ); + await newTokenAddress.sendKeys(tokenAddress); + await driver.delay(regularDelayMs); - await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await driver.delay(regularDelayMs) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//button[contains(text(), 'Add Tokens')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('renders the balance for the new token', async function () { const balance = await driver.findElement( By.css('.wallet-overview .token-overview__primary-balance'), - ) - await driver.wait(until.elementTextMatches(balance, /^10\s*TST\s*$/u)) - const tokenAmount = await balance.getText() - assert.ok(/^10\s*TST\s*$/u.test(tokenAmount)) - await driver.delay(regularDelayMs) - }) - }) + ); + await driver.wait(until.elementTextMatches(balance, /^10\s*TST\s*$/u)); + const tokenAmount = await balance.getText(); + assert.ok(/^10\s*TST\s*$/u.test(tokenAmount)); + await driver.delay(regularDelayMs); + }); + }); describe('Send token from inside MetaMask', function () { - let gasModal + let gasModal; it('starts to send a transaction', async function () { - await driver.clickElement(By.css('[data-testid="eth-overview-send"]')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('[data-testid="eth-overview-send"]')); + await driver.delay(regularDelayMs); const inputAddress = await driver.findElement( By.css('input[placeholder="Search, public address (0x), or ENS"]'), - ) - await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970') + ); + await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970'); - const inputAmount = await driver.findElement(By.css('.unit-input__input')) - await inputAmount.sendKeys('1') + const inputAmount = await driver.findElement( + By.css('.unit-input__input'), + ); + await inputAmount.sendKeys('1'); // Set the gas limit - await driver.clickElement(By.css('.advanced-gas-options-btn')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.advanced-gas-options-btn')); + await driver.delay(regularDelayMs); - gasModal = await driver.findElement(By.css('span .modal')) - await driver.delay(regularDelayMs) - }) + gasModal = await driver.findElement(By.css('span .modal')); + await driver.delay(regularDelayMs); + }); it('opens customize gas modal', async function () { - await driver.findElement(By.css('.page-container__title')) - await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)) - await driver.delay(regularDelayMs) - }) + await driver.findElement(By.css('.page-container__title')); + await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)); + await driver.delay(regularDelayMs); + }); it('transitions to the confirm screen', async function () { - await driver.wait(until.stalenessOf(gasModal)) + await driver.wait(until.stalenessOf(gasModal)); // Continue to next screen - await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await driver.delay(regularDelayMs) - }) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)); + await driver.delay(regularDelayMs); + }); it('displays the token transfer data', async function () { - await driver.clickElement(By.xpath(`//button[contains(text(), 'Data')]`)) - await driver.delay(regularDelayMs) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Data')]`)); + await driver.delay(regularDelayMs); const functionType = await driver.findElement( By.css('.confirm-page-container-content__function-type'), - ) - const functionTypeText = await functionType.getText() - assert.equal(functionTypeText, 'Transfer') + ); + const functionTypeText = await functionType.getText(); + assert.equal(functionTypeText, 'Transfer'); const tokenAmount = await driver.findElement( By.css('.confirm-page-container-summary__title-text'), - ) - const tokenAmountText = await tokenAmount.getText() - assert.equal(tokenAmountText, '1 TST') + ); + const tokenAmountText = await tokenAmount.getText(); + assert.equal(tokenAmountText, '1 TST'); const confirmDataDiv = await driver.findElement( By.css('.confirm-page-container-content__data-box'), - ) - const confirmDataText = await confirmDataDiv.getText() + ); + const confirmDataText = await confirmDataDiv.getText(); - await driver.delay(regularDelayMs) + await driver.delay(regularDelayMs); assert( confirmDataText.match( /0xa9059cbb0000000000000000000000002f318c334780961fb129d2a6c30d0763d9a5c97/u, ), - ) + ); await driver.clickElement( By.xpath(`//button[contains(text(), 'Details')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('submits the transaction', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('finds the transaction in the transactions list', async function () { await driver.wait(async () => { @@ -1214,119 +1228,119 @@ describe('MetaMask', function () { By.css( '.transaction-list__completed-transactions .transaction-list-item', ), - ) - return confirmedTxes.length === 1 - }, 10000) + ); + return confirmedTxes.length === 1; + }, 10000); const txValues = await driver.findElements( By.css('.transaction-list-item__primary-currency'), - ) - assert.equal(txValues.length, 1) + ); + assert.equal(txValues.length, 1); await driver.wait( until.elementTextMatches(txValues[0], /-1\s*TST/u), 10000, - ) + ); const txStatuses = await driver.findElements( By.css('.list-item__heading'), - ) + ); await driver.wait( until.elementTextMatches(txStatuses[0], /Send\sTST/u), 10000, - ) - }) - }) + ); + }); + }); describe('Send a custom token from dapp', function () { - let gasModal + let gasModal; it('sends an already created token', async function () { - const windowHandles = await driver.getAllWindowHandles() - const extension = windowHandles[0] + const windowHandles = await driver.getAllWindowHandles(); + const extension = windowHandles[0]; const dapp = await driver.switchToWindowWithTitle( 'E2E Test Dapp', windowHandles, - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); - await driver.switchToWindow(dapp) - await driver.delay(tinyDelayMs) + await driver.switchToWindow(dapp); + await driver.delay(tinyDelayMs); await driver.clickElement( By.xpath(`//button[contains(text(), 'Transfer Tokens')]`), - ) + ); - await driver.switchToWindow(extension) - await driver.delay(largeDelayMs) + await driver.switchToWindow(extension); + await driver.delay(largeDelayMs); await driver.findElements( By.css('.transaction-list__pending-transactions'), - ) + ); const txListValue = await driver.findClickableElement( By.css('.transaction-list-item__primary-currency'), - ) + ); await driver.wait( until.elementTextMatches(txListValue, /-1.5\s*TST/u), 10000, - ) - await txListValue.click() - await driver.delay(regularDelayMs) + ); + await txListValue.click(); + await driver.delay(regularDelayMs); const transactionAmounts = await driver.findElements( By.css('.currency-display-component__text'), - ) - const transactionAmount = transactionAmounts[0] - assert(await transactionAmount.getText(), '1.5 TST') + ); + const transactionAmount = transactionAmounts[0]; + assert(await transactionAmount.getText(), '1.5 TST'); // Set the gas limit await driver.clickElement( By.css('.confirm-detail-row__header-text--edit'), - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); - gasModal = await driver.findElement(By.css('span .modal')) - }) + gasModal = await driver.findElement(By.css('span .modal')); + }); it('customizes gas', async function () { - await driver.clickElement(By.css('.page-container__tab:nth-of-type(2)')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.page-container__tab:nth-of-type(2)')); + await driver.delay(regularDelayMs); const [gasPriceInput, gasLimitInput] = await driver.findElements( By.css('.advanced-gas-inputs__gas-edit-row__input'), - ) + ); - await gasPriceInput.clear() - await driver.delay(50) - await gasPriceInput.sendKeys('10') - await driver.delay(50) + await gasPriceInput.clear(); + await driver.delay(50); + await gasPriceInput.sendKeys('10'); + await driver.delay(50); - await gasLimitInput.clear() - await driver.delay(50) - await gasLimitInput.sendKeys('60000') + await gasLimitInput.clear(); + await driver.delay(50); + await gasLimitInput.sendKeys('60000'); - await driver.delay(1000) + await driver.delay(1000); - await driver.clickElement(By.css('.page-container__footer-button')) - await driver.wait(until.stalenessOf(gasModal)) + await driver.clickElement(By.css('.page-container__footer-button')); + await driver.wait(until.stalenessOf(gasModal)); const gasFeeInputs = await driver.findElements( By.css('.confirm-detail-row__primary'), - ) - const renderedGasFee = await gasFeeInputs[0].getText() - assert.equal(renderedGasFee, '0.0006') - }) + ); + const renderedGasFee = await gasFeeInputs[0].getText(); + assert.equal(renderedGasFee, '0.0006'); + }); it('submits the transaction', async function () { const tokenAmount = await driver.findElement( By.css('.confirm-page-container-summary__title-text'), - ) - const tokenAmountText = await tokenAmount.getText() - assert.equal(tokenAmountText, '1.5 TST') + ); + const tokenAmountText = await tokenAmount.getText(); + assert.equal(tokenAmountText, '1.5 TST'); await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('finds the transaction in the transactions list', async function () { await driver.wait(async () => { @@ -1334,174 +1348,174 @@ describe('MetaMask', function () { By.css( '.transaction-list__completed-transactions .transaction-list-item', ), - ) - return confirmedTxes.length === 2 - }, 10000) + ); + return confirmedTxes.length === 2; + }, 10000); const txValues = await driver.findElements( By.css('.transaction-list-item__primary-currency'), - ) - await driver.wait(until.elementTextMatches(txValues[0], /-1.5\s*TST/u)) + ); + await driver.wait(until.elementTextMatches(txValues[0], /-1.5\s*TST/u)); const txStatuses = await driver.findElements( By.css('.list-item__heading'), - ) + ); await driver.wait( until.elementTextMatches(txStatuses[0], /Send\sTST/u), 10000, - ) + ); const tokenBalanceAmount = await driver.findElements( By.css('.token-overview__primary-balance'), - ) + ); await driver.wait( until.elementTextMatches(tokenBalanceAmount[0], /7.5\s*TST/u), 10000, - ) - }) - }) + ); + }); + }); describe('Approves a custom token from dapp', function () { - let gasModal + let gasModal; it('approves an already created token', async function () { - const windowHandles = await driver.getAllWindowHandles() - const extension = windowHandles[0] + const windowHandles = await driver.getAllWindowHandles(); + const extension = windowHandles[0]; const dapp = await driver.switchToWindowWithTitle( 'E2E Test Dapp', windowHandles, - ) - await driver.closeAllWindowHandlesExcept([extension, dapp]) - await driver.delay(regularDelayMs) + ); + await driver.closeAllWindowHandlesExcept([extension, dapp]); + await driver.delay(regularDelayMs); - await driver.switchToWindow(dapp) - await driver.delay(tinyDelayMs) + await driver.switchToWindow(dapp); + await driver.delay(tinyDelayMs); await driver.clickElement( By.xpath(`//button[contains(text(), 'Approve Tokens')]`), - ) + ); - await driver.switchToWindow(extension) - await driver.delay(regularDelayMs) + await driver.switchToWindow(extension); + await driver.delay(regularDelayMs); await driver.wait(async () => { const pendingTxes = await driver.findElements( By.css( '.transaction-list__pending-transactions .transaction-list-item', ), - ) - return pendingTxes.length === 1 - }, 10000) + ); + return pendingTxes.length === 1; + }, 10000); const [txtListHeading] = await driver.findElements( By.css('.transaction-list-item .list-item__heading'), - ) + ); await driver.wait( until.elementTextMatches(txtListHeading, /Approve TST spend limit/u), - ) - await driver.clickElement(By.css('.transaction-list-item')) - await driver.delay(regularDelayMs) - }) + ); + await driver.clickElement(By.css('.transaction-list-item')); + await driver.delay(regularDelayMs); + }); it('displays the token approval data', async function () { await driver.clickElement( By.css('.confirm-approve-content__view-full-tx-button'), - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); const functionType = await driver.findElement( By.css( '.confirm-approve-content__data .confirm-approve-content__small-text', ), - ) - const functionTypeText = await functionType.getText() - assert.equal(functionTypeText, 'Function: Approve') + ); + const functionTypeText = await functionType.getText(); + assert.equal(functionTypeText, 'Function: Approve'); const confirmDataDiv = await driver.findElement( By.css('.confirm-approve-content__data__data-block'), - ) - const confirmDataText = await confirmDataDiv.getText() + ); + const confirmDataText = await confirmDataDiv.getText(); assert( confirmDataText.match( /0x095ea7b30000000000000000000000009bc5baf874d2da8d216ae9f137804184ee5afef4/u, ), - ) - }) + ); + }); it('opens the gas edit modal', async function () { await driver.clickElement( By.css('.confirm-approve-content__small-blue-text.cursor-pointer'), - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); - gasModal = await driver.findElement(By.css('span .modal')) - }) + gasModal = await driver.findElement(By.css('span .modal')); + }); it('customizes gas', async function () { - await driver.clickElement(By.css('.page-container__tab:nth-of-type(2)')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.page-container__tab:nth-of-type(2)')); + await driver.delay(regularDelayMs); const [gasPriceInput, gasLimitInput] = await driver.findElements( By.css('.advanced-gas-inputs__gas-edit-row__input'), - ) + ); - await gasPriceInput.clear() - await driver.delay(50) - await gasPriceInput.sendKeys('10') - await driver.delay(50) + await gasPriceInput.clear(); + await driver.delay(50); + await gasPriceInput.sendKeys('10'); + await driver.delay(50); - await gasLimitInput.clear() - await driver.delay(50) - await gasLimitInput.sendKeys('60001') + await gasLimitInput.clear(); + await driver.delay(50); + await gasLimitInput.sendKeys('60001'); - await driver.delay(1000) + await driver.delay(1000); - await driver.clickElement(By.css('.page-container__footer-button')) - await driver.wait(until.stalenessOf(gasModal)) + await driver.clickElement(By.css('.page-container__footer-button')); + await driver.wait(until.stalenessOf(gasModal)); const gasFeeInEth = await driver.findElement( By.css( '.confirm-approve-content__transaction-details-content__secondary-fee', ), - ) - assert.equal(await gasFeeInEth.getText(), '0.0006 ETH') - }) + ); + assert.equal(await gasFeeInEth.getText(), '0.0006 ETH'); + }); it('edits the permission', async function () { const editButtons = await driver.findClickableElements( By.css('.confirm-approve-content__small-blue-text.cursor-pointer'), - ) - await editButtons[1].click() - await driver.delay(regularDelayMs) + ); + await editButtons[1].click(); + await driver.delay(regularDelayMs); - const permissionModal = await driver.findElement(By.css('span .modal')) + const permissionModal = await driver.findElement(By.css('span .modal')); const radioButtons = await driver.findClickableElements( By.css('.edit-approval-permission__edit-section__radio-button'), - ) - await radioButtons[1].click() + ); + await radioButtons[1].click(); - const customInput = await driver.findElement(By.css('input')) - await driver.delay(50) - await customInput.sendKeys('5') - await driver.delay(regularDelayMs) + const customInput = await driver.findElement(By.css('input')); + await driver.delay(50); + await customInput.sendKeys('5'); + await driver.delay(regularDelayMs); - await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)) - await driver.delay(regularDelayMs) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)); + await driver.delay(regularDelayMs); - await driver.wait(until.stalenessOf(permissionModal)) + await driver.wait(until.stalenessOf(permissionModal)); const permissionInfo = await driver.findElements( By.css('.confirm-approve-content__medium-text'), - ) - const amountDiv = permissionInfo[0] - assert.equal(await amountDiv.getText(), '5 TST') - }) + ); + const amountDiv = permissionInfo[0]; + assert.equal(await amountDiv.getText(), '5 TST'); + }); it('submits the transaction', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('finds the transaction in the transactions list', async function () { await driver.wait(async () => { @@ -1509,63 +1523,63 @@ describe('MetaMask', function () { By.css( '.transaction-list__completed-transactions .transaction-list-item', ), - ) - return confirmedTxes.length === 3 - }, 10000) + ); + return confirmedTxes.length === 3; + }, 10000); const txStatuses = await driver.findElements( By.css('.list-item__heading'), - ) + ); await driver.wait( until.elementTextMatches(txStatuses[0], /Approve TST spend limit/u), - ) - }) - }) + ); + }); + }); describe('Transfers a custom token from dapp when no gas value is specified', function () { it('transfers an already created token, without specifying gas', async function () { - const windowHandles = await driver.getAllWindowHandles() - const extension = windowHandles[0] + const windowHandles = await driver.getAllWindowHandles(); + const extension = windowHandles[0]; const dapp = await driver.switchToWindowWithTitle( 'E2E Test Dapp', windowHandles, - ) - await driver.closeAllWindowHandlesExcept([extension, dapp]) - await driver.delay(regularDelayMs) + ); + await driver.closeAllWindowHandlesExcept([extension, dapp]); + await driver.delay(regularDelayMs); - await driver.switchToWindow(dapp) + await driver.switchToWindow(dapp); await driver.clickElement( By.xpath(`//button[contains(text(), 'Transfer Tokens Without Gas')]`), - ) + ); - await driver.switchToWindow(extension) - await driver.delay(regularDelayMs) + await driver.switchToWindow(extension); + await driver.delay(regularDelayMs); await driver.wait(async () => { const pendingTxes = await driver.findElements( By.css( '.transaction-list__pending-transactions .transaction-list-item', ), - ) - return pendingTxes.length === 1 - }, 10000) + ); + return pendingTxes.length === 1; + }, 10000); const [txListValue] = await driver.findElements( By.css('.transaction-list-item__primary-currency'), - ) - await driver.wait(until.elementTextMatches(txListValue, /-1.5\s*TST/u)) - await driver.clickElement(By.css('.transaction-list-item')) - await driver.delay(regularDelayMs) - }) + ); + await driver.wait(until.elementTextMatches(txListValue, /-1.5\s*TST/u)); + await driver.clickElement(By.css('.transaction-list-item')); + await driver.delay(regularDelayMs); + }); it('submits the transaction', async function () { - await driver.delay(largeDelayMs * 2) + await driver.delay(largeDelayMs * 2); await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - await driver.delay(largeDelayMs * 2) - }) + ); + await driver.delay(largeDelayMs * 2); + }); it('finds the transaction in the transactions list', async function () { await driver.wait(async () => { @@ -1573,81 +1587,81 @@ describe('MetaMask', function () { By.css( '.transaction-list__completed-transactions .transaction-list-item', ), - ) - return confirmedTxes.length === 4 - }, 10000) + ); + return confirmedTxes.length === 4; + }, 10000); const txValues = await driver.findElements( By.css('.transaction-list-item__primary-currency'), - ) - await driver.wait(until.elementTextMatches(txValues[0], /-1.5\s*TST/u)) + ); + await driver.wait(until.elementTextMatches(txValues[0], /-1.5\s*TST/u)); const txStatuses = await driver.findElements( By.css('.list-item__heading'), - ) - await driver.wait(until.elementTextMatches(txStatuses[0], /Send TST/u)) - }) - }) + ); + await driver.wait(until.elementTextMatches(txStatuses[0], /Send TST/u)); + }); + }); describe('Approves a custom token from dapp when no gas value is specified', function () { it('approves an already created token', async function () { - const windowHandles = await driver.getAllWindowHandles() - const extension = windowHandles[0] + const windowHandles = await driver.getAllWindowHandles(); + const extension = windowHandles[0]; const dapp = await driver.switchToWindowWithTitle( 'E2E Test Dapp', windowHandles, - ) - await driver.closeAllWindowHandlesExcept([extension, dapp]) - await driver.delay(regularDelayMs) + ); + await driver.closeAllWindowHandlesExcept([extension, dapp]); + await driver.delay(regularDelayMs); - await driver.switchToWindow(dapp) - await driver.delay(tinyDelayMs) + await driver.switchToWindow(dapp); + await driver.delay(tinyDelayMs); await driver.clickElement( By.xpath(`//button[contains(text(), 'Approve Tokens Without Gas')]`), - ) + ); - await driver.switchToWindow(extension) - await driver.delay(regularDelayMs) + await driver.switchToWindow(extension); + await driver.delay(regularDelayMs); await driver.wait(async () => { const pendingTxes = await driver.findElements( By.css( '.transaction-list__pending-transactions .transaction-list-item', ), - ) - return pendingTxes.length === 1 - }, 10000) + ); + return pendingTxes.length === 1; + }, 10000); const [txtListHeading] = await driver.findElements( By.css('.transaction-list-item .list-item__heading'), - ) + ); await driver.wait( until.elementTextMatches(txtListHeading, /Approve TST spend limit/u), - ) - await driver.clickElement(By.css('.transaction-list-item')) - await driver.delay(regularDelayMs) - }) + ); + await driver.clickElement(By.css('.transaction-list-item')); + await driver.delay(regularDelayMs); + }); it('shows the correct recipient', async function () { await driver.clickElement( By.css('.confirm-approve-content__view-full-tx-button'), - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); const permissionInfo = await driver.findElements( By.css('.confirm-approve-content__medium-text'), - ) - const recipientDiv = permissionInfo[1] - assert.equal(await recipientDiv.getText(), '0x2f318C33...C970') - }) + ); + const recipientDiv = permissionInfo[1]; + assert.equal(await recipientDiv.getText(), '0x2f318C33...C970'); + }); it('submits the transaction', async function () { - await driver.delay(1000) + await driver.delay(1000); await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('finds the transaction in the transactions list', async function () { await driver.wait(async () => { @@ -1655,184 +1669,190 @@ describe('MetaMask', function () { By.css( '.transaction-list__completed-transactions .transaction-list-item', ), - ) - return confirmedTxes.length === 5 - }, 10000) + ); + return confirmedTxes.length === 5; + }, 10000); const txStatuses = await driver.findElements( By.css('.list-item__heading'), - ) + ); await driver.wait( until.elementTextMatches(txStatuses[0], /Approve TST spend limit/u), - ) - }) - }) + ); + }); + }); describe('Hide token', function () { it('hides the token when clicked', async function () { - await driver.clickElement(By.css('[data-testid="token-options__button"]')) + await driver.clickElement( + By.css('[data-testid="token-options__button"]'), + ); - await driver.clickElement(By.css('[data-testid="token-options__hide"]')) + await driver.clickElement(By.css('[data-testid="token-options__hide"]')); - const confirmHideModal = await driver.findElement(By.css('span .modal')) + const confirmHideModal = await driver.findElement(By.css('span .modal')); await driver.clickElement( By.css('[data-testid="hide-token-confirmation__hide"]'), - ) + ); - await driver.wait(until.stalenessOf(confirmHideModal)) - }) - }) + await driver.wait(until.stalenessOf(confirmHideModal)); + }); + }); describe('Add existing token using search', function () { it('clicks on the Add Token button', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Add Token')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('can pick a token from the existing options', async function () { - const tokenSearch = await driver.findElement(By.css('#search-tokens')) - await tokenSearch.sendKeys('BAT') - await driver.delay(regularDelayMs) + const tokenSearch = await driver.findElement(By.css('#search-tokens')); + await tokenSearch.sendKeys('BAT'); + await driver.delay(regularDelayMs); - await driver.clickElement(By.xpath("//span[contains(text(), 'BAT')]")) - await driver.delay(regularDelayMs) + await driver.clickElement(By.xpath("//span[contains(text(), 'BAT')]")); + await driver.delay(regularDelayMs); - await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await driver.delay(regularDelayMs) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//button[contains(text(), 'Add Tokens')]`), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('renders the balance for the chosen token', async function () { const balance = await driver.findElement( By.css('.token-overview__primary-balance'), - ) - await driver.wait(until.elementTextMatches(balance, /0\s*BAT/u)) - await driver.delay(regularDelayMs) - }) - }) + ); + await driver.wait(until.elementTextMatches(balance, /0\s*BAT/u)); + await driver.delay(regularDelayMs); + }); + }); describe('Stores custom RPC history', function () { it(`creates first custom RPC entry`, async function () { - const rpcUrl = 'http://127.0.0.1:8545/1' - const chainId = '0x539' // Ganache default, decimal 1337 + const rpcUrl = 'http://127.0.0.1:8545/1'; + const chainId = '0x539'; // Ganache default, decimal 1337 - await driver.clickElement(By.css('.network-display')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.network-display')); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//span[contains(text(), 'Custom RPC')]`), - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); - await driver.findElement(By.css('.settings-page__sub-header-text')) + await driver.findElement(By.css('.settings-page__sub-header-text')); const customRpcInputs = await driver.findElements( By.css('input[type="text"]'), - ) - const rpcUrlInput = customRpcInputs[1] - const chainIdInput = customRpcInputs[2] + ); + const rpcUrlInput = customRpcInputs[1]; + const chainIdInput = customRpcInputs[2]; - await rpcUrlInput.clear() - await rpcUrlInput.sendKeys(rpcUrl) + await rpcUrlInput.clear(); + await rpcUrlInput.sendKeys(rpcUrl); - await chainIdInput.clear() - await chainIdInput.sendKeys(chainId) + await chainIdInput.clear(); + await chainIdInput.sendKeys(chainId); - await driver.clickElement(By.css('.network-form__footer .btn-secondary')) - await driver.findElement(By.xpath(`//div[contains(text(), '${rpcUrl}')]`)) - }) + await driver.clickElement(By.css('.network-form__footer .btn-secondary')); + await driver.findElement( + By.xpath(`//div[contains(text(), '${rpcUrl}')]`), + ); + }); it(`creates second custom RPC entry`, async function () { - const rpcUrl = 'http://127.0.0.1:8545/2' - const chainId = '0x539' // Ganache default, decimal 1337 + const rpcUrl = 'http://127.0.0.1:8545/2'; + const chainId = '0x539'; // Ganache default, decimal 1337 - await driver.clickElement(By.css('.network-display')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.network-display')); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//span[contains(text(), 'Custom RPC')]`), - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); - await driver.findElement(By.css('.settings-page__sub-header-text')) + await driver.findElement(By.css('.settings-page__sub-header-text')); const customRpcInputs = await driver.findElements( By.css('input[type="text"]'), - ) - const rpcUrlInput = customRpcInputs[1] - const chainIdInput = customRpcInputs[2] + ); + const rpcUrlInput = customRpcInputs[1]; + const chainIdInput = customRpcInputs[2]; - await rpcUrlInput.clear() - await rpcUrlInput.sendKeys(rpcUrl) + await rpcUrlInput.clear(); + await rpcUrlInput.sendKeys(rpcUrl); - await chainIdInput.clear() - await chainIdInput.sendKeys(chainId) + await chainIdInput.clear(); + await chainIdInput.sendKeys(chainId); - await driver.clickElement(By.css('.network-form__footer .btn-secondary')) - await driver.findElement(By.xpath(`//div[contains(text(), '${rpcUrl}')]`)) - }) + await driver.clickElement(By.css('.network-form__footer .btn-secondary')); + await driver.findElement( + By.xpath(`//div[contains(text(), '${rpcUrl}')]`), + ); + }); it('selects another provider', async function () { - await driver.clickElement(By.css('.network-display')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.network-display')); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//span[contains(text(), 'Ethereum Mainnet')]`), - ) - await driver.delay(largeDelayMs * 2) - }) + ); + await driver.delay(largeDelayMs * 2); + }); it('finds all recent RPCs in history', async function () { - await driver.clickElement(By.css('.network-display')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.network-display')); + await driver.delay(regularDelayMs); // only recent 3 are found and in correct order (most recent at the top) const customRpcs = await driver.findElements( By.xpath(`//span[contains(text(), 'http://127.0.0.1:8545/')]`), - ) + ); // click Mainnet to dismiss network dropdown await driver.clickElement( By.xpath(`//span[contains(text(), 'Ethereum Mainnet')]`), - ) + ); - assert.equal(customRpcs.length, 2) - }) + assert.equal(customRpcs.length, 2); + }); it('deletes a custom RPC', async function () { const networkListItems = await driver.findClickableElements( By.css('.networks-tab__networks-list-name'), - ) - const lastNetworkListItem = networkListItems[networkListItems.length - 1] - await lastNetworkListItem.click() - await driver.delay(100) + ); + const lastNetworkListItem = networkListItems[networkListItems.length - 1]; + await lastNetworkListItem.click(); + await driver.delay(100); - await driver.clickElement(By.css('.btn-danger')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.btn-danger')); + await driver.delay(regularDelayMs); const confirmDeleteNetworkModal = await driver.findElement( By.css('span .modal'), - ) + ); const byConfirmDeleteNetworkButton = By.css( '.button.btn-danger.modal-container__footer-button', - ) - await driver.clickElement(byConfirmDeleteNetworkButton) + ); + await driver.clickElement(byConfirmDeleteNetworkButton); - await driver.wait(until.stalenessOf(confirmDeleteNetworkModal)) + await driver.wait(until.stalenessOf(confirmDeleteNetworkModal)); const newNetworkListItems = await driver.findElements( By.css('.networks-tab__networks-list-name'), - ) + ); - assert.equal(networkListItems.length - 1, newNetworkListItems.length) - }) - }) -}) + assert.equal(networkListItems.length - 1, newNetworkListItems.length); + }); + }); +}); diff --git a/test/e2e/metrics.spec.js b/test/e2e/metrics.spec.js index 74c8f26d89..4346f59b1a 100644 --- a/test/e2e/metrics.spec.js +++ b/test/e2e/metrics.spec.js @@ -1,14 +1,14 @@ -const { strict: assert } = require('assert') -const { By, Key } = require('selenium-webdriver') -const waitUntilCalled = require('../lib/wait-until-called') -const { withFixtures } = require('./helpers') +const { strict: assert } = require('assert'); +const { By, Key } = require('selenium-webdriver'); +const waitUntilCalled = require('../lib/wait-until-called'); +const { withFixtures } = require('./helpers'); /** * WARNING: These tests must be run using a build created with `yarn build:test:metrics`, so that it has * the correct Segment host and write keys set. Otherwise this test will fail. */ describe('Segment metrics', function () { - this.timeout(0) + this.timeout(0); it('should send first three Page metric events upon fullscreen page load', async function () { const ganacheOptions = { @@ -19,7 +19,7 @@ describe('Segment metrics', function () { balance: 25000000000000000000, }, ], - } + }; await withFixtures( { fixtures: 'metrics-enabled', @@ -30,29 +30,29 @@ describe('Segment metrics', function () { async ({ driver, segmentStub }) => { const threeSegmentEventsReceived = waitUntilCalled(segmentStub, null, { callCount: 3, - }) - await driver.navigate() + }); + await driver.navigate(); - const passwordField = await driver.findElement(By.css('#password')) - await passwordField.sendKeys('correct horse battery staple') - await passwordField.sendKeys(Key.ENTER) + const passwordField = await driver.findElement(By.css('#password')); + await passwordField.sendKeys('correct horse battery staple'); + await passwordField.sendKeys(Key.ENTER); - await threeSegmentEventsReceived() + await threeSegmentEventsReceived(); - assert.ok(segmentStub.called, 'Segment should receive metrics') + assert.ok(segmentStub.called, 'Segment should receive metrics'); - const firstSegmentEvent = segmentStub.getCall(0).args[0] - assert.equal(firstSegmentEvent.name, 'Home') - assert.equal(firstSegmentEvent.context.page.path, '/') + const firstSegmentEvent = segmentStub.getCall(0).args[0]; + assert.equal(firstSegmentEvent.name, 'Home'); + assert.equal(firstSegmentEvent.context.page.path, '/'); - const secondSegmentEvent = segmentStub.getCall(1).args[0] - assert.equal(secondSegmentEvent.name, 'Unlock Page') - assert.equal(secondSegmentEvent.context.page.path, '/unlock') + const secondSegmentEvent = segmentStub.getCall(1).args[0]; + assert.equal(secondSegmentEvent.name, 'Unlock Page'); + assert.equal(secondSegmentEvent.context.page.path, '/unlock'); - const thirdSegmentEvent = segmentStub.getCall(2).args[0] - assert.equal(thirdSegmentEvent.name, 'Home') - assert.equal(thirdSegmentEvent.context.page.path, '/') + const thirdSegmentEvent = segmentStub.getCall(2).args[0]; + assert.equal(thirdSegmentEvent.name, 'Home'); + assert.equal(thirdSegmentEvent.context.page.path, '/'); }, - ) - }) -}) + ); + }); +}); diff --git a/test/e2e/mock-3box/server.js b/test/e2e/mock-3box/server.js index 7094fddd4c..cffb15f4d6 100644 --- a/test/e2e/mock-3box/server.js +++ b/test/e2e/mock-3box/server.js @@ -1,38 +1,38 @@ -const http = require('http') +const http = require('http'); -const port = 8889 +const port = 8889; -const database = {} +const database = {}; const requestHandler = (request, response) => { - response.setHeader('Content-Type', 'application/json') + response.setHeader('Content-Type', 'application/json'); if (request.method === 'POST') { - let body = '' + let body = ''; request.on('data', (chunk) => { - body += chunk.toString() // convert Buffer to string - }) + body += chunk.toString(); // convert Buffer to string + }); request.on('end', () => { - const { key, data } = JSON.parse(body) + const { key, data } = JSON.parse(body); - database[key] = data - response.setHeader('Access-Control-Allow-Headers', '*') - response.end('ok') - }) + database[key] = data; + response.setHeader('Access-Control-Allow-Headers', '*'); + response.end('ok'); + }); } else if (request.method === 'GET') { const key = new URL(request.url, 'https://example.org/').searchParams.get( 'key', - ) - response.setHeader('Access-Control-Allow-Headers', '*') - response.end(JSON.stringify(database[key] || '')) + ); + response.setHeader('Access-Control-Allow-Headers', '*'); + response.end(JSON.stringify(database[key] || '')); } else { - response.end('unknown request') + response.end('unknown request'); } -} +}; -const server = http.createServer(requestHandler) +const server = http.createServer(requestHandler); server.listen(port, (err) => { if (err) { - console.log('mock 3box server error: ', err) + console.log('mock 3box server error: ', err); } -}) +}); diff --git a/test/e2e/permissions.spec.js b/test/e2e/permissions.spec.js index 4f15b625f4..522f625dd8 100644 --- a/test/e2e/permissions.spec.js +++ b/test/e2e/permissions.spec.js @@ -1,20 +1,20 @@ -const assert = require('assert') -const webdriver = require('selenium-webdriver') +const assert = require('assert'); +const webdriver = require('selenium-webdriver'); -const { By, until } = webdriver -const enLocaleMessages = require('../../app/_locales/en/messages.json') -const { regularDelayMs, largeDelayMs } = require('./helpers') -const { buildWebDriver } = require('./webdriver') -const Ganache = require('./ganache') +const { By, until } = webdriver; +const enLocaleMessages = require('../../app/_locales/en/messages.json'); +const { regularDelayMs, largeDelayMs } = require('./helpers'); +const { buildWebDriver } = require('./webdriver'); +const Ganache = require('./ganache'); -const ganacheServer = new Ganache() +const ganacheServer = new Ganache(); describe('MetaMask', function () { - let driver - let publicAddress + let driver; + let publicAddress; - this.timeout(0) - this.bail(true) + this.timeout(0); + this.bail(true); before(async function () { await ganacheServer.start({ @@ -25,175 +25,175 @@ describe('MetaMask', function () { balance: 25000000000000000000, }, ], - }) - const result = await buildWebDriver() - driver = result.driver - await driver.navigate() - }) + }); + const result = await buildWebDriver(); + driver = result.driver; + await driver.navigate(); + }); afterEach(async function () { if (process.env.SELENIUM_BROWSER === 'chrome') { - const errors = await driver.checkBrowserForConsoleErrors(driver) + const errors = await driver.checkBrowserForConsoleErrors(driver); if (errors.length) { - const errorReports = errors.map((err) => err.message) + const errorReports = errors.map((err) => err.message); const errorMessage = `Errors found in browser console:\n${errorReports.join( '\n', - )}` - console.error(new Error(errorMessage)) + )}`; + console.error(new Error(errorMessage)); } } if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest.title) + await driver.verboseReportOnFailure(this.currentTest.title); } - }) + }); after(async function () { - await ganacheServer.quit() - await driver.quit() - }) + await ganacheServer.quit(); + await driver.quit(); + }); describe('Going through the first time flow, but skipping the seed phrase challenge', function () { it('clicks the continue button on the welcome screen', async function () { - await driver.findElement(By.css('.welcome-page__header')) + await driver.findElement(By.css('.welcome-page__header')); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`, ), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('clicks the "Create New Wallet" option', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Create a Wallet')]`), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('clicks the "No thanks" option on the metametrics opt-in screen', async function () { - await driver.clickElement(By.css('.btn-default')) - await driver.delay(largeDelayMs) - }) + await driver.clickElement(By.css('.btn-default')); + await driver.delay(largeDelayMs); + }); it('accepts a secure password', async function () { const passwordBox = await driver.findElement( By.css('.first-time-flow__form #create-password'), - ) + ); const passwordBoxConfirm = await driver.findElement( By.css('.first-time-flow__form #confirm-password'), - ) + ); - await passwordBox.sendKeys('correct horse battery staple') - await passwordBoxConfirm.sendKeys('correct horse battery staple') + await passwordBox.sendKeys('correct horse battery staple'); + await passwordBoxConfirm.sendKeys('correct horse battery staple'); - await driver.clickElement(By.css('.first-time-flow__checkbox')) + await driver.clickElement(By.css('.first-time-flow__checkbox')); - await driver.clickElement(By.css('.first-time-flow__form button')) - await driver.delay(largeDelayMs) - }) + await driver.clickElement(By.css('.first-time-flow__form button')); + await driver.delay(largeDelayMs); + }); it('skips the seed phrase challenge', async function () { await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.remindMeLater.message}')]`, ), - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); await driver.clickElement( By.css('[data-testid="account-options-menu-button"]'), - ) + ); await driver.clickElement( By.css('[data-testid="account-options-menu__account-details"]'), - ) - }) + ); + }); it('gets the current accounts address', async function () { const addressInput = await driver.findElement( By.css('.readonly-input__input'), - ) - publicAddress = await addressInput.getAttribute('value') - const accountModal = await driver.findElement(By.css('span .modal')) + ); + publicAddress = await addressInput.getAttribute('value'); + const accountModal = await driver.findElement(By.css('span .modal')); - await driver.clickElement(By.css('.account-modal__close')) + await driver.clickElement(By.css('.account-modal__close')); - await driver.wait(until.stalenessOf(accountModal)) - await driver.delay(regularDelayMs) - }) - }) + await driver.wait(until.stalenessOf(accountModal)); + await driver.delay(regularDelayMs); + }); + }); describe('sets permissions', function () { - let extension - let popup - let dapp + let extension; + let popup; + let dapp; it('connects to the dapp', async function () { - await driver.openNewPage('http://127.0.0.1:8080/') - await driver.delay(regularDelayMs) + await driver.openNewPage('http://127.0.0.1:8080/'); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//button[contains(text(), 'Connect')]`), - ) + ); - await driver.waitUntilXWindowHandles(3) - const windowHandles = await driver.getAllWindowHandles() + await driver.waitUntilXWindowHandles(3); + const windowHandles = await driver.getAllWindowHandles(); - extension = windowHandles[0] + extension = windowHandles[0]; dapp = await driver.switchToWindowWithTitle( 'E2E Test Dapp', windowHandles, - ) + ); popup = windowHandles.find( (handle) => handle !== extension && handle !== dapp, - ) + ); - await driver.switchToWindow(popup) + await driver.switchToWindow(popup); - await driver.delay(regularDelayMs) + await driver.delay(regularDelayMs); - await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)); await driver.clickElement( By.xpath(`//button[contains(text(), 'Connect')]`), - ) + ); - await driver.waitUntilXWindowHandles(2) - await driver.switchToWindow(extension) - await driver.delay(regularDelayMs) - }) + await driver.waitUntilXWindowHandles(2); + await driver.switchToWindow(extension); + await driver.delay(regularDelayMs); + }); it('shows connected sites', async function () { await driver.clickElement( By.css('[data-testid="account-options-menu-button"]'), - ) + ); await driver.clickElement( By.css('[data-testid="account-options-menu__connected-sites"]'), - ) + ); await driver.findElement( By.xpath(`//h2[contains(text(), 'Connected sites')]`), - ) + ); const domains = await driver.findClickableElements( By.css('.connected-sites-list__domain-name'), - ) - assert.equal(domains.length, 1) - }) + ); + assert.equal(domains.length, 1); + }); it('can get accounts within the dapp', async function () { - await driver.switchToWindow(dapp) - await driver.delay(regularDelayMs) + await driver.switchToWindow(dapp); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//button[contains(text(), 'eth_accounts')]`), - ) + ); const getAccountsResult = await driver.findElement( By.css('#getAccountsResult'), - ) + ); assert.equal( (await getAccountsResult.getText()).toLowerCase(), publicAddress.toLowerCase(), - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/test/e2e/send-edit.spec.js b/test/e2e/send-edit.spec.js index 3c70d67e0f..9ae21e89b9 100644 --- a/test/e2e/send-edit.spec.js +++ b/test/e2e/send-edit.spec.js @@ -1,22 +1,22 @@ -const assert = require('assert') -const webdriver = require('selenium-webdriver') +const assert = require('assert'); +const webdriver = require('selenium-webdriver'); -const { By, until } = webdriver -const enLocaleMessages = require('../../app/_locales/en/messages.json') -const { tinyDelayMs, regularDelayMs, largeDelayMs } = require('./helpers') -const { buildWebDriver } = require('./webdriver') -const Ganache = require('./ganache') +const { By, until } = webdriver; +const enLocaleMessages = require('../../app/_locales/en/messages.json'); +const { tinyDelayMs, regularDelayMs, largeDelayMs } = require('./helpers'); +const { buildWebDriver } = require('./webdriver'); +const Ganache = require('./ganache'); -const ganacheServer = new Ganache() +const ganacheServer = new Ganache(); describe('Using MetaMask with an existing account', function () { - let driver + let driver; const testSeedPhrase = - 'forum vessel pink push lonely enact gentle tail admit parrot grunt dress' + 'forum vessel pink push lonely enact gentle tail admit parrot grunt dress'; - this.timeout(0) - this.bail(true) + this.timeout(0); + this.bail(true); before(async function () { await ganacheServer.start({ @@ -27,224 +27,228 @@ describe('Using MetaMask with an existing account', function () { balance: 25000000000000000000, }, ], - }) - const result = await buildWebDriver() - driver = result.driver - await driver.navigate() - }) + }); + const result = await buildWebDriver(); + driver = result.driver; + await driver.navigate(); + }); afterEach(async function () { if (process.env.SELENIUM_BROWSER === 'chrome') { - const errors = await driver.checkBrowserForConsoleErrors(driver) + const errors = await driver.checkBrowserForConsoleErrors(driver); if (errors.length) { - const errorReports = errors.map((err) => err.message) + const errorReports = errors.map((err) => err.message); const errorMessage = `Errors found in browser console:\n${errorReports.join( '\n', - )}` - console.error(new Error(errorMessage)) + )}`; + console.error(new Error(errorMessage)); } } if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest.title) + await driver.verboseReportOnFailure(this.currentTest.title); } - }) + }); after(async function () { - await ganacheServer.quit() - await driver.quit() - }) + await ganacheServer.quit(); + await driver.quit(); + }); describe('First time flow starting from an existing seed phrase', function () { it('clicks the continue button on the welcome screen', async function () { - await driver.findElement(By.css('.welcome-page__header')) + await driver.findElement(By.css('.welcome-page__header')); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`, ), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('clicks the "Import Wallet" option', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Import wallet')]`), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('clicks the "No thanks" option on the metametrics opt-in screen', async function () { - await driver.clickElement(By.css('.btn-default')) - await driver.delay(largeDelayMs) - }) + await driver.clickElement(By.css('.btn-default')); + await driver.delay(largeDelayMs); + }); it('imports a seed phrase', async function () { const [seedTextArea] = await driver.findElements( By.css('input[placeholder="Paste seed phrase from clipboard"]'), - ) - await seedTextArea.sendKeys(testSeedPhrase) - await driver.delay(regularDelayMs) + ); + await seedTextArea.sendKeys(testSeedPhrase); + await driver.delay(regularDelayMs); - const [password] = await driver.findElements(By.id('password')) - await password.sendKeys('correct horse battery staple') + const [password] = await driver.findElements(By.id('password')); + await password.sendKeys('correct horse battery staple'); const [confirmPassword] = await driver.findElements( By.id('confirm-password'), - ) - confirmPassword.sendKeys('correct horse battery staple') + ); + confirmPassword.sendKeys('correct horse battery staple'); - await driver.clickElement(By.css('.first-time-flow__terms')) + await driver.clickElement(By.css('.first-time-flow__terms')); await driver.clickElement( By.xpath(`//button[contains(text(), 'Import')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('clicks through the success screen', async function () { await driver.findElement( By.xpath(`//div[contains(text(), 'Congratulations')]`), - ) + ); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`, ), - ) - await driver.delay(regularDelayMs) - }) - }) + ); + await driver.delay(regularDelayMs); + }); + }); describe('Send ETH from inside MetaMask', function () { it('starts a send transaction', async function () { - await driver.clickElement(By.css('[data-testid="eth-overview-send"]')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('[data-testid="eth-overview-send"]')); + await driver.delay(regularDelayMs); const inputAddress = await driver.findElement( By.css('input[placeholder="Search, public address (0x), or ENS"]'), - ) - await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970') + ); + await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970'); - const inputAmount = await driver.findElement(By.css('.unit-input__input')) - await inputAmount.sendKeys('1') + const inputAmount = await driver.findElement( + By.css('.unit-input__input'), + ); + await inputAmount.sendKeys('1'); // Set the gas limit - await driver.clickElement(By.css('.advanced-gas-options-btn')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.advanced-gas-options-btn')); + await driver.delay(regularDelayMs); - const gasModal = await driver.findElement(By.css('span .modal')) + const gasModal = await driver.findElement(By.css('span .modal')); const [gasPriceInput, gasLimitInput] = await driver.findElements( By.css('.advanced-gas-inputs__gas-edit-row__input'), - ) + ); - await gasPriceInput.clear() - await driver.delay(50) - await gasPriceInput.sendKeys('10') - await driver.delay(50) - await driver.delay(tinyDelayMs) - await driver.delay(50) + await gasPriceInput.clear(); + await driver.delay(50); + await gasPriceInput.sendKeys('10'); + await driver.delay(50); + await driver.delay(tinyDelayMs); + await driver.delay(50); - await gasLimitInput.clear() - await driver.delay(50) - await gasLimitInput.sendKeys('25000') + await gasLimitInput.clear(); + await driver.delay(50); + await gasLimitInput.sendKeys('25000'); - await driver.delay(1000) + await driver.delay(1000); - await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)) - await driver.wait(until.stalenessOf(gasModal)) - await driver.delay(regularDelayMs) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)); + await driver.wait(until.stalenessOf(gasModal)); + await driver.delay(regularDelayMs); // Continue to next screen - await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await driver.delay(regularDelayMs) - }) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)); + await driver.delay(regularDelayMs); + }); it('has correct value and fee on the confirm screen the transaction', async function () { const transactionAmounts = await driver.findElements( By.css('.currency-display-component__text'), - ) - const transactionAmount = transactionAmounts[0] - assert.equal(await transactionAmount.getText(), '1') + ); + const transactionAmount = transactionAmounts[0]; + assert.equal(await transactionAmount.getText(), '1'); - const transactionFee = transactionAmounts[1] - assert.equal(await transactionFee.getText(), '0.00025') - }) + const transactionFee = transactionAmounts[1]; + assert.equal(await transactionFee.getText(), '0.00025'); + }); it('edits the transaction', async function () { await driver.clickElement( By.css('.confirm-page-container-header__back-button'), - ) + ); - await driver.delay(regularDelayMs) + await driver.delay(regularDelayMs); - const inputAmount = await driver.findElement(By.css('.unit-input__input')) + const inputAmount = await driver.findElement( + By.css('.unit-input__input'), + ); - await inputAmount.clear() - await driver.delay(50) - await inputAmount.sendKeys('2.2') + await inputAmount.clear(); + await driver.delay(50); + await inputAmount.sendKeys('2.2'); - await driver.clickElement(By.css('.advanced-gas-options-btn')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.advanced-gas-options-btn')); + await driver.delay(regularDelayMs); - const gasModal = await driver.findElement(By.css('span .modal')) + const gasModal = await driver.findElement(By.css('span .modal')); const [gasPriceInput, gasLimitInput] = await driver.findElements( By.css('.advanced-gas-inputs__gas-edit-row__input'), - ) + ); - await gasPriceInput.clear() - await driver.delay(50) - await gasPriceInput.sendKeys('8') - await driver.delay(50) - await driver.delay(tinyDelayMs) - await driver.delay(50) + await gasPriceInput.clear(); + await driver.delay(50); + await gasPriceInput.sendKeys('8'); + await driver.delay(50); + await driver.delay(tinyDelayMs); + await driver.delay(50); - await gasLimitInput.clear() - await driver.delay(50) - await gasLimitInput.sendKeys('100000') + await gasLimitInput.clear(); + await driver.delay(50); + await gasLimitInput.sendKeys('100000'); - await driver.delay(1000) + await driver.delay(1000); - await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)) - await driver.wait(until.stalenessOf(gasModal)) - await driver.delay(regularDelayMs) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)); + await driver.wait(until.stalenessOf(gasModal)); + await driver.delay(regularDelayMs); - await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await driver.delay(regularDelayMs) - }) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)); + await driver.delay(regularDelayMs); + }); it('has correct updated value on the confirm screen the transaction', async function () { const transactionAmounts = await driver.findElements( By.css('.currency-display-component__text'), - ) - const transactionAmount = transactionAmounts[0] - assert.equal(await transactionAmount.getText(), '2.2') + ); + const transactionAmount = transactionAmounts[0]; + assert.equal(await transactionAmount.getText(), '2.2'); - const transactionFee = transactionAmounts[1] - assert.equal(await transactionFee.getText(), '0.0008') - }) + const transactionFee = transactionAmounts[1]; + assert.equal(await transactionFee.getText(), '0.0008'); + }); it('confirms the transaction', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Confirm')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('finds the transaction in the transactions list', async function () { - await driver.clickElement(By.css('[data-testid="home__activity-tab"]')) + await driver.clickElement(By.css('[data-testid="home__activity-tab"]')); await driver.wait(async () => { const confirmedTxes = await driver.findElements( By.css( '.transaction-list__completed-transactions .transaction-list-item', ), - ) - return confirmedTxes.length === 1 - }, 10000) + ); + return confirmedTxes.length === 1; + }, 10000); const txValues = await driver.findElements( By.css('.transaction-list-item__primary-currency'), - ) - assert.equal(txValues.length, 1) - assert.ok(/-2.2\s*ETH/u.test(await txValues[0].getText())) - }) - }) -}) + ); + assert.equal(txValues.length, 1); + assert.ok(/-2.2\s*ETH/u.test(await txValues[0].getText())); + }); + }); +}); diff --git a/test/e2e/signature-request.spec.js b/test/e2e/signature-request.spec.js index 3e4307ffaa..da05aa00d6 100644 --- a/test/e2e/signature-request.spec.js +++ b/test/e2e/signature-request.spec.js @@ -1,172 +1,172 @@ -const assert = require('assert') -const path = require('path') -const webdriver = require('selenium-webdriver') +const assert = require('assert'); +const path = require('path'); +const webdriver = require('selenium-webdriver'); -const { By, Key, until } = webdriver -const { regularDelayMs, largeDelayMs } = require('./helpers') -const { buildWebDriver } = require('./webdriver') -const Ganache = require('./ganache') -const FixtureServer = require('./fixture-server') +const { By, Key, until } = webdriver; +const { regularDelayMs, largeDelayMs } = require('./helpers'); +const { buildWebDriver } = require('./webdriver'); +const Ganache = require('./ganache'); +const FixtureServer = require('./fixture-server'); -const fixtureServer = new FixtureServer() +const fixtureServer = new FixtureServer(); -const ganacheServer = new Ganache() +const ganacheServer = new Ganache(); describe('MetaMask', function () { - let driver - let publicAddress + let driver; + let publicAddress; - this.timeout(0) - this.bail(true) + this.timeout(0); + this.bail(true); before(async function () { - await ganacheServer.start() - await fixtureServer.start() + await ganacheServer.start(); + await fixtureServer.start(); await fixtureServer.loadState( path.join(__dirname, 'fixtures', 'imported-account'), - ) - publicAddress = '0x5cfe73b6021e818b776b421b1c4db2474086a7e1' - const result = await buildWebDriver() - driver = result.driver - await driver.navigate() - }) + ); + publicAddress = '0x5cfe73b6021e818b776b421b1c4db2474086a7e1'; + const result = await buildWebDriver(); + driver = result.driver; + await driver.navigate(); + }); afterEach(async function () { if (process.env.SELENIUM_BROWSER === 'chrome') { - const errors = await driver.checkBrowserForConsoleErrors(driver) + const errors = await driver.checkBrowserForConsoleErrors(driver); if (errors.length) { - const errorReports = errors.map((err) => err.message) + const errorReports = errors.map((err) => err.message); const errorMessage = `Errors found in browser console:\n${errorReports.join( '\n', - )}` - console.error(new Error(errorMessage)) + )}`; + console.error(new Error(errorMessage)); } } if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest.title) + await driver.verboseReportOnFailure(this.currentTest.title); } - }) + }); after(async function () { - await ganacheServer.quit() - await fixtureServer.stop() - await driver.quit() - }) + await ganacheServer.quit(); + await fixtureServer.stop(); + await driver.quit(); + }); describe('successfully signs typed data', function () { - let extension - let popup - let dapp - let windowHandles + let extension; + let popup; + let dapp; + let windowHandles; it('accepts the account password after lock', async function () { - await driver.delay(1000) - const passwordField = await driver.findElement(By.id('password')) - await passwordField.sendKeys('correct horse battery staple') - await passwordField.sendKeys(Key.ENTER) - await driver.delay(largeDelayMs * 4) - }) + await driver.delay(1000); + const passwordField = await driver.findElement(By.id('password')); + await passwordField.sendKeys('correct horse battery staple'); + await passwordField.sendKeys(Key.ENTER); + await driver.delay(largeDelayMs * 4); + }); it('connects to the dapp', async function () { - await driver.openNewPage('http://127.0.0.1:8080/') - await driver.delay(regularDelayMs) + await driver.openNewPage('http://127.0.0.1:8080/'); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//button[contains(text(), 'Connect')]`), - ) + ); - await driver.delay(regularDelayMs) + await driver.delay(regularDelayMs); - await driver.waitUntilXWindowHandles(3) - windowHandles = await driver.getAllWindowHandles() + await driver.waitUntilXWindowHandles(3); + windowHandles = await driver.getAllWindowHandles(); - extension = windowHandles[0] + extension = windowHandles[0]; dapp = await driver.switchToWindowWithTitle( 'E2E Test Dapp', windowHandles, - ) + ); popup = windowHandles.find( (handle) => handle !== extension && handle !== dapp, - ) + ); - await driver.switchToWindow(popup) + await driver.switchToWindow(popup); - await driver.delay(regularDelayMs) + await driver.delay(regularDelayMs); - await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)); await driver.clickElement( By.xpath(`//button[contains(text(), 'Connect')]`), - ) + ); - await driver.waitUntilXWindowHandles(2) - await driver.switchToWindow(dapp) - }) + await driver.waitUntilXWindowHandles(2); + await driver.switchToWindow(dapp); + }); it('creates a sign typed data signature request', async function () { - await driver.clickElement(By.id('signTypedDataV4'), 10000) - await driver.delay(largeDelayMs) + await driver.clickElement(By.id('signTypedDataV4'), 10000); + await driver.delay(largeDelayMs); - await driver.delay(regularDelayMs) - windowHandles = await driver.getAllWindowHandles() + await driver.delay(regularDelayMs); + windowHandles = await driver.getAllWindowHandles(); await driver.switchToWindowWithTitle( 'MetaMask Notification', windowHandles, - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); const title = await driver.findElement( By.css('.signature-request-content__title'), - ) + ); const name = await driver.findElement( By.css('.signature-request-content__info--bolded'), - ) + ); const content = await driver.findElements( By.css('.signature-request-content__info'), - ) - const origin = content[0] - const address = content[1] - assert.equal(await title.getText(), 'Signature Request') - assert.equal(await name.getText(), 'Ether Mail') - assert.equal(await origin.getText(), 'http://127.0.0.1:8080') + ); + const origin = content[0]; + const address = content[1]; + assert.equal(await title.getText(), 'Signature Request'); + assert.equal(await name.getText(), 'Ether Mail'); + assert.equal(await origin.getText(), 'http://127.0.0.1:8080'); assert.equal( await address.getText(), `${publicAddress.slice(0, 8)}...${publicAddress.slice( publicAddress.length - 8, )}`, - ) - }) + ); + }); it('signs the transaction', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Sign')]`), 10000, - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); - extension = windowHandles[0] - await driver.switchToWindow(extension) - }) + extension = windowHandles[0]; + await driver.switchToWindow(extension); + }); it('gets the current accounts address', async function () { await driver.clickElement( By.css('[data-testid="account-options-menu-button"]'), - ) + ); await driver.clickElement( By.css('[data-testid="account-options-menu__account-details"]'), - ) - await driver.delay(regularDelayMs) + ); + await driver.delay(regularDelayMs); const addressInput = await driver.findElement( By.css('.readonly-input__input'), - ) - const newPublicAddress = await addressInput.getAttribute('value') - const accountModal = await driver.findElement(By.css('span .modal')) - - await driver.clickElement(By.css('.account-modal__close')) - - await driver.wait(until.stalenessOf(accountModal)) - await driver.delay(regularDelayMs) - assert.equal(newPublicAddress.toLowerCase(), publicAddress) - }) - }) -}) + ); + const newPublicAddress = await addressInput.getAttribute('value'); + const accountModal = await driver.findElement(By.css('span .modal')); + + await driver.clickElement(By.css('.account-modal__close')); + + await driver.wait(until.stalenessOf(accountModal)); + await driver.delay(regularDelayMs); + assert.equal(newPublicAddress.toLowerCase(), publicAddress); + }); + }); +}); diff --git a/test/e2e/tests/localization.spec.js b/test/e2e/tests/localization.spec.js index 5ba5558f7a..27b93a2696 100644 --- a/test/e2e/tests/localization.spec.js +++ b/test/e2e/tests/localization.spec.js @@ -1,6 +1,6 @@ -const { strict: assert } = require('assert') -const { By, Key } = require('selenium-webdriver') -const { withFixtures } = require('../helpers') +const { strict: assert } = require('assert'); +const { By, Key } = require('selenium-webdriver'); +const { withFixtures } = require('../helpers'); describe('Localization', function () { it('can correctly display Philippine peso symbol and code', async function () { @@ -12,22 +12,24 @@ describe('Localization', function () { balance: 25000000000000000000, }, ], - } + }; await withFixtures( { fixtures: 'localization', ganacheOptions, title: this.test.title }, async ({ driver }) => { - await driver.navigate() - const passwordField = await driver.findElement(By.css('#password')) - await passwordField.sendKeys('correct horse battery staple') - await passwordField.sendKeys(Key.ENTER) + await driver.navigate(); + const passwordField = await driver.findElement(By.css('#password')); + await passwordField.sendKeys('correct horse battery staple'); + await passwordField.sendKeys(Key.ENTER); const secondaryBalance = await driver.findElement( By.css('[data-testid="eth-overview__secondary-currency"]'), - ) - const secondaryBalanceText = await secondaryBalance.getText() - const [fiatAmount, fiatUnit] = secondaryBalanceText.trim().split(/\s+/u) - assert.ok(fiatAmount.startsWith('₱')) - assert.equal(fiatUnit, 'PHP') + ); + const secondaryBalanceText = await secondaryBalance.getText(); + const [fiatAmount, fiatUnit] = secondaryBalanceText + .trim() + .split(/\s+/u); + assert.ok(fiatAmount.startsWith('₱')); + assert.equal(fiatUnit, 'PHP'); }, - ) - }) -}) + ); + }); +}); diff --git a/test/e2e/tests/personal-sign.spec.js b/test/e2e/tests/personal-sign.spec.js index 462eab11be..e9efc5ea49 100644 --- a/test/e2e/tests/personal-sign.spec.js +++ b/test/e2e/tests/personal-sign.spec.js @@ -1,6 +1,6 @@ -const { strict: assert } = require('assert') -const { By, Key } = require('selenium-webdriver') -const { withFixtures } = require('../helpers') +const { strict: assert } = require('assert'); +const { By, Key } = require('selenium-webdriver'); +const { withFixtures } = require('../helpers'); describe('Personal sign', function () { it('can initiate and confirm a personal sign', async function () { @@ -12,7 +12,7 @@ describe('Personal sign', function () { balance: 25000000000000000000, }, ], - } + }; await withFixtures( { dapp: true, @@ -21,34 +21,34 @@ describe('Personal sign', function () { title: this.test.title, }, async ({ driver }) => { - await driver.navigate() - const passwordField = await driver.findElement(By.css('#password')) - await passwordField.sendKeys('correct horse battery staple') - await passwordField.sendKeys(Key.ENTER) + await driver.navigate(); + const passwordField = await driver.findElement(By.css('#password')); + await passwordField.sendKeys('correct horse battery staple'); + await passwordField.sendKeys(Key.ENTER); - await driver.openNewPage('http://127.0.0.1:8080/') - await driver.clickElement(By.id('personalSign')) + await driver.openNewPage('http://127.0.0.1:8080/'); + await driver.clickElement(By.id('personalSign')); - await driver.waitUntilXWindowHandles(3) + await driver.waitUntilXWindowHandles(3); - const windowHandles = await driver.getAllWindowHandles() + const windowHandles = await driver.getAllWindowHandles(); await driver.switchToWindowWithTitle( 'MetaMask Notification', windowHandles, - ) + ); const personalMessageRow = await driver.findElement( By.css('.request-signature__row-value'), - ) - const personalMessage = await personalMessageRow.getText() - assert.equal(personalMessage, 'Example `personal_sign` message') + ); + const personalMessage = await personalMessageRow.getText(); + assert.equal(personalMessage, 'Example `personal_sign` message'); await driver.clickElement( By.css('[data-testid="request-signature__sign"]'), - ) + ); - await driver.waitUntilXWindowHandles(2) + await driver.waitUntilXWindowHandles(2); }, - ) - }) -}) + ); + }); +}); diff --git a/test/e2e/tests/simple-send.spec.js b/test/e2e/tests/simple-send.spec.js index 3321179517..e7564a0715 100644 --- a/test/e2e/tests/simple-send.spec.js +++ b/test/e2e/tests/simple-send.spec.js @@ -1,5 +1,5 @@ -const { By, Key } = require('selenium-webdriver') -const { withFixtures } = require('../helpers') +const { By, Key } = require('selenium-webdriver'); +const { withFixtures } = require('../helpers'); describe('Simple send', function () { it('can send a simple transaction from one account to another', async function () { @@ -11,34 +11,34 @@ describe('Simple send', function () { balance: 25000000000000000000, }, ], - } + }; await withFixtures( { fixtures: 'imported-account', ganacheOptions, title: this.test.title }, async ({ driver }) => { - await driver.navigate() - const passwordField = await driver.findElement(By.css('#password')) - await passwordField.sendKeys('correct horse battery staple') - await passwordField.sendKeys(Key.ENTER) - await driver.clickElement(By.css('[data-testid="eth-overview-send"]')) + await driver.navigate(); + const passwordField = await driver.findElement(By.css('#password')); + await passwordField.sendKeys('correct horse battery staple'); + await passwordField.sendKeys(Key.ENTER); + await driver.clickElement(By.css('[data-testid="eth-overview-send"]')); const recipientAddressField = await driver.findElement( By.css('[data-testid="ens-input"]'), - ) + ); await recipientAddressField.sendKeys( '0x985c30949c92df7a0bd42e0f3e3d539ece98db24', - ) + ); const amountField = await driver.findElement( By.css('.unit-input__input'), - ) - await amountField.sendKeys('1') + ); + await amountField.sendKeys('1'); await driver.clickElement( By.css('[data-testid="page-container-footer-next"]'), - ) + ); await driver.clickElement( By.css('[data-testid="page-container-footer-next"]'), - ) - await driver.clickElement(By.css('[data-testid="home__activity-tab"]')) - await driver.findElement(By.css('.transaction-list-item')) + ); + await driver.clickElement(By.css('[data-testid="home__activity-tab"]')); + await driver.findElement(By.css('.transaction-list-item')); }, - ) - }) -}) + ); + }); +}); diff --git a/test/e2e/threebox.spec.js b/test/e2e/threebox.spec.js index 55f771a44f..207f15afd2 100644 --- a/test/e2e/threebox.spec.js +++ b/test/e2e/threebox.spec.js @@ -1,23 +1,23 @@ -const assert = require('assert') -const webdriver = require('selenium-webdriver') -const getPort = require('get-port') +const assert = require('assert'); +const webdriver = require('selenium-webdriver'); +const getPort = require('get-port'); -const { By, until } = webdriver -const enLocaleMessages = require('../../app/_locales/en/messages.json') -const { tinyDelayMs, regularDelayMs, largeDelayMs } = require('./helpers') -const { buildWebDriver } = require('./webdriver') -const Ganache = require('./ganache') +const { By, until } = webdriver; +const enLocaleMessages = require('../../app/_locales/en/messages.json'); +const { tinyDelayMs, regularDelayMs, largeDelayMs } = require('./helpers'); +const { buildWebDriver } = require('./webdriver'); +const Ganache = require('./ganache'); -const ganacheServer = new Ganache() +const ganacheServer = new Ganache(); describe('MetaMask', function () { - let driver + let driver; const testSeedPhrase = - 'forum vessel pink push lonely enact gentle tail admit parrot grunt dress' + 'forum vessel pink push lonely enact gentle tail admit parrot grunt dress'; - this.timeout(0) - this.bail(true) + this.timeout(0); + this.bail(true); before(async function () { await ganacheServer.start({ @@ -28,275 +28,275 @@ describe('MetaMask', function () { balance: 25000000000000000000, }, ], - }) - const result = await buildWebDriver({ port: await getPort() }) - driver = result.driver - await driver.navigate() - }) + }); + const result = await buildWebDriver({ port: await getPort() }); + driver = result.driver; + await driver.navigate(); + }); afterEach(async function () { if (process.env.SELENIUM_BROWSER === 'chrome') { - const errors = await driver.checkBrowserForConsoleErrors(driver) + const errors = await driver.checkBrowserForConsoleErrors(driver); if (errors.length) { - const errorReports = errors.map((err) => err.message) + const errorReports = errors.map((err) => err.message); const errorMessage = `Errors found in browser console:\n${errorReports.join( '\n', - )}` - console.error(new Error(errorMessage)) + )}`; + console.error(new Error(errorMessage)); } } if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest.title) + await driver.verboseReportOnFailure(this.currentTest.title); } - }) + }); after(async function () { - await ganacheServer.quit() - await driver.quit() - }) + await ganacheServer.quit(); + await driver.quit(); + }); describe('set up data to be restored by 3box', function () { describe('First time flow starting from an existing seed phrase', function () { it('clicks the continue button on the welcome screen', async function () { - await driver.findElement(By.css('.welcome-page__header')) + await driver.findElement(By.css('.welcome-page__header')); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`, ), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('clicks the "Import Wallet" option', async function () { await driver.clickElement( By.xpath(`//button[contains(text(), 'Import wallet')]`), - ) - await driver.delay(largeDelayMs) - }) + ); + await driver.delay(largeDelayMs); + }); it('clicks the "No thanks" option on the metametrics opt-in screen', async function () { - await driver.clickElement(By.css('.btn-default')) - await driver.delay(largeDelayMs) - }) + await driver.clickElement(By.css('.btn-default')); + await driver.delay(largeDelayMs); + }); it('imports a seed phrase', async function () { const [seedTextArea] = await driver.findElements( By.css('input[placeholder="Paste seed phrase from clipboard"]'), - ) - await seedTextArea.sendKeys(testSeedPhrase) - await driver.delay(regularDelayMs) + ); + await seedTextArea.sendKeys(testSeedPhrase); + await driver.delay(regularDelayMs); - const [password] = await driver.findElements(By.id('password')) - await password.sendKeys('correct horse battery staple') + const [password] = await driver.findElements(By.id('password')); + await password.sendKeys('correct horse battery staple'); const [confirmPassword] = await driver.findElements( By.id('confirm-password'), - ) - confirmPassword.sendKeys('correct horse battery staple') + ); + confirmPassword.sendKeys('correct horse battery staple'); - await driver.clickElement(By.css('.first-time-flow__terms')) + await driver.clickElement(By.css('.first-time-flow__terms')); await driver.clickElement( By.xpath(`//button[contains(text(), 'Import')]`), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('clicks through the success screen', async function () { await driver.findElement( By.xpath(`//div[contains(text(), 'Congratulations')]`), - ) + ); await driver.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`, ), - ) - await driver.delay(regularDelayMs) - }) + ); + await driver.delay(regularDelayMs); + }); it('balance renders', async function () { const balance = await driver.findElement( By.css('[data-testid="wallet-balance"] .list-item__heading'), - ) - await driver.wait(until.elementTextMatches(balance, /25\s*ETH/u)) - await driver.delay(regularDelayMs) - }) - }) + ); + await driver.wait(until.elementTextMatches(balance, /25\s*ETH/u)); + await driver.delay(regularDelayMs); + }); + }); describe('turns on threebox syncing', function () { it('goes to the settings screen', async function () { - await driver.clickElement(By.css('.account-menu__icon')) - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.account-menu__icon')); + await driver.delay(regularDelayMs); await driver.clickElement( By.xpath(`//div[contains(text(), 'Settings')]`), - ) - }) + ); + }); it('turns on threebox syncing', async function () { await driver.clickElement( By.xpath(`//div[contains(text(), 'Advanced')]`), - ) + ); await driver.clickElement( By.css('[data-testid="advanced-setting-3box"] .toggle-button div'), - ) - }) - }) + ); + }); + }); describe('updates settings and address book', function () { it('navigates to General settings', async function () { await driver.clickElement( By.xpath(`//div[contains(text(), 'General')]`), - ) - }) + ); + }); it('turns on use of blockies', async function () { - await driver.clickElement(By.css('.toggle-button > div')) - }) + await driver.clickElement(By.css('.toggle-button > div')); + }); it('adds an address to the contact list', async function () { await driver.clickElement( By.xpath(`//div[contains(text(), 'Contacts')]`), - ) + ); - await driver.clickElement(By.css('.address-book-add-button__button')) - await driver.delay(tinyDelayMs) + await driver.clickElement(By.css('.address-book-add-button__button')); + await driver.delay(tinyDelayMs); - const addAddressInputs = await driver.findElements(By.css('input')) - await addAddressInputs[0].sendKeys('Test User Name 11') + const addAddressInputs = await driver.findElements(By.css('input')); + await addAddressInputs[0].sendKeys('Test User Name 11'); - await driver.delay(tinyDelayMs) + await driver.delay(tinyDelayMs); await addAddressInputs[1].sendKeys( '0x2f318C334780961FB129D2a6c30D0763d9a5C970', - ) + ); - await driver.delay(largeDelayMs * 2) + await driver.delay(largeDelayMs * 2); await driver.clickElement( By.xpath(`//button[contains(text(), 'Save')]`), - ) + ); await driver.findElement( By.xpath(`//div[contains(text(), 'Test User Name 11')]`), - ) - await driver.delay(regularDelayMs) - }) - }) - }) + ); + await driver.delay(regularDelayMs); + }); + }); + }); describe('restoration from 3box', function () { - let driver2 + let driver2; before(async function () { - const result = await buildWebDriver({ port: await getPort() }) - driver2 = result.driver - await driver2.navigate() - }) + const result = await buildWebDriver({ port: await getPort() }); + driver2 = result.driver; + await driver2.navigate(); + }); after(async function () { - await driver2.quit() - }) + await driver2.quit(); + }); describe('First time flow starting from an existing seed phrase', function () { it('clicks the continue button on the welcome screen', async function () { - await driver2.findElement(By.css('.welcome-page__header')) + await driver2.findElement(By.css('.welcome-page__header')); await driver2.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`, ), - ) - await driver2.delay(largeDelayMs) - }) + ); + await driver2.delay(largeDelayMs); + }); it('clicks the "Import Wallet" option', async function () { await driver2.clickElement( By.xpath(`//button[contains(text(), 'Import wallet')]`), - ) - await driver2.delay(largeDelayMs) - }) + ); + await driver2.delay(largeDelayMs); + }); it('clicks the "No thanks" option on the metametrics opt-in screen', async function () { - await driver2.clickElement(By.css('.btn-default')) - await driver2.delay(largeDelayMs) - }) + await driver2.clickElement(By.css('.btn-default')); + await driver2.delay(largeDelayMs); + }); it('imports a seed phrase', async function () { const [seedTextArea] = await driver2.findElements( By.css('input[placeholder="Paste seed phrase from clipboard"]'), - ) - await seedTextArea.sendKeys(testSeedPhrase) - await driver2.delay(regularDelayMs) + ); + await seedTextArea.sendKeys(testSeedPhrase); + await driver2.delay(regularDelayMs); - const [password] = await driver2.findElements(By.id('password')) - await password.sendKeys('correct horse battery staple') + const [password] = await driver2.findElements(By.id('password')); + await password.sendKeys('correct horse battery staple'); const [confirmPassword] = await driver2.findElements( By.id('confirm-password'), - ) - confirmPassword.sendKeys('correct horse battery staple') + ); + confirmPassword.sendKeys('correct horse battery staple'); - await driver2.clickElement(By.css('.first-time-flow__terms')) + await driver2.clickElement(By.css('.first-time-flow__terms')); await driver2.clickElement( By.xpath(`//button[contains(text(), 'Import')]`), - ) - await driver2.delay(regularDelayMs) - }) + ); + await driver2.delay(regularDelayMs); + }); it('clicks through the success screen', async function () { await driver2.findElement( By.xpath(`//div[contains(text(), 'Congratulations')]`), - ) + ); await driver2.clickElement( By.xpath( `//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`, ), - ) - await driver2.delay(regularDelayMs) - }) + ); + await driver2.delay(regularDelayMs); + }); it('balance renders', async function () { const balance = await driver2.findElement( By.css('[data-testid="wallet-balance"] .list-item__heading'), - ) - await driver2.wait(until.elementTextMatches(balance, /25\s*ETH/u)) - await driver2.delay(regularDelayMs) - }) - }) + ); + await driver2.wait(until.elementTextMatches(balance, /25\s*ETH/u)); + await driver2.delay(regularDelayMs); + }); + }); describe('restores 3box data', function () { it('confirms the 3box restore notification', async function () { - await driver2.clickElement(By.css('.home-notification__accept-button')) - }) + await driver2.clickElement(By.css('.home-notification__accept-button')); + }); it('goes to the settings screen', async function () { - await driver2.clickElement(By.css('.account-menu__icon')) - await driver2.delay(regularDelayMs) + await driver2.clickElement(By.css('.account-menu__icon')); + await driver2.delay(regularDelayMs); await driver2.clickElement( By.xpath(`//div[contains(text(), 'Settings')]`), - ) - }) + ); + }); it('finds the blockies toggle turned on', async function () { - await driver2.delay(regularDelayMs) + await driver2.delay(regularDelayMs); const toggleLabel = await driver2.findElement( By.css('.toggle-button__status'), - ) - const toggleLabelText = await toggleLabel.getText() - assert.equal(toggleLabelText, 'ON') - }) + ); + const toggleLabelText = await toggleLabel.getText(); + assert.equal(toggleLabelText, 'ON'); + }); it('finds the restored address in the contact list', async function () { await driver2.clickElement( By.xpath(`//div[contains(text(), 'Contacts')]`), - ) - await driver2.delay(regularDelayMs) + ); + await driver2.delay(regularDelayMs); await driver2.findElement( By.xpath(`//div[contains(text(), 'Test User Name 11')]`), - ) - await driver2.delay(regularDelayMs) - }) - }) - }) -}) + ); + await driver2.delay(regularDelayMs); + }); + }); + }); +}); diff --git a/test/e2e/webdriver/chrome.js b/test/e2e/webdriver/chrome.js index 75e031475d..e0bb65626d 100644 --- a/test/e2e/webdriver/chrome.js +++ b/test/e2e/webdriver/chrome.js @@ -1,29 +1,31 @@ -const { Builder } = require('selenium-webdriver') -const chrome = require('selenium-webdriver/chrome') +const { Builder } = require('selenium-webdriver'); +const chrome = require('selenium-webdriver/chrome'); /** * A wrapper around a {@code WebDriver} instance exposing Chrome-specific functionality */ class ChromeDriver { static async build({ responsive, port }) { - const args = [`load-extension=dist/chrome`] + const args = [`load-extension=dist/chrome`]; if (responsive) { - args.push('--auto-open-devtools-for-tabs') + args.push('--auto-open-devtools-for-tabs'); } - const options = new chrome.Options().addArguments(args) - const builder = new Builder().forBrowser('chrome').setChromeOptions(options) + const options = new chrome.Options().addArguments(args); + const builder = new Builder() + .forBrowser('chrome') + .setChromeOptions(options); if (port) { - const service = new chrome.ServiceBuilder().setPort(port) - builder.setChromeService(service) + const service = new chrome.ServiceBuilder().setPort(port); + builder.setChromeService(service); } - const driver = builder.build() - const chromeDriver = new ChromeDriver(driver) - const extensionId = await chromeDriver.getExtensionIdByName('MetaMask') + const driver = builder.build(); + const chromeDriver = new ChromeDriver(driver); + const extensionId = await chromeDriver.getExtensionIdByName('MetaMask'); return { driver, extensionUrl: `chrome-extension://${extensionId}`, - } + }; } /** @@ -31,7 +33,7 @@ class ChromeDriver { * @param {!ThenableWebDriver} driver - a {@code WebDriver} instance */ constructor(driver) { - this._driver = driver + this._driver = driver; } /** @@ -40,7 +42,7 @@ class ChromeDriver { * @returns {Promise} the extension ID */ async getExtensionIdByName(extensionName) { - await this._driver.get('chrome://extensions') + await this._driver.get('chrome://extensions'); return await this._driver.executeScript(` const extensions = document.querySelector("extensions-manager").shadowRoot .querySelector("extensions-item-list").shadowRoot @@ -55,8 +57,8 @@ class ChromeDriver { } return undefined - `) + `); } } -module.exports = ChromeDriver +module.exports = ChromeDriver; diff --git a/test/e2e/webdriver/driver.js b/test/e2e/webdriver/driver.js index 9f094e1a65..f1da84a210 100644 --- a/test/e2e/webdriver/driver.js +++ b/test/e2e/webdriver/driver.js @@ -1,6 +1,6 @@ -const { promises: fs } = require('fs') -const { strict: assert } = require('assert') -const { until, error: webdriverError } = require('selenium-webdriver') +const { promises: fs } = require('fs'); +const { strict: assert } = require('assert'); +const { until, error: webdriverError } = require('selenium-webdriver'); class Driver { /** @@ -9,152 +9,152 @@ class Driver { * @param {number} timeout */ constructor(driver, browser, extensionUrl, timeout = 10000) { - this.driver = driver - this.browser = browser - this.extensionUrl = extensionUrl - this.timeout = timeout + this.driver = driver; + this.browser = browser; + this.extensionUrl = extensionUrl; + this.timeout = timeout; } async delay(time) { - await new Promise((resolve) => setTimeout(resolve, time)) + await new Promise((resolve) => setTimeout(resolve, time)); } async wait(condition, timeout = this.timeout) { - await this.driver.wait(condition, timeout) + await this.driver.wait(condition, timeout); } async quit() { - await this.driver.quit() + await this.driver.quit(); } // Element interactions async findElement(locator) { - return await this.driver.wait(until.elementLocated(locator), this.timeout) + return await this.driver.wait(until.elementLocated(locator), this.timeout); } async findVisibleElement(locator) { - const element = await this.findElement(locator) - await this.driver.wait(until.elementIsVisible(element), this.timeout) - return element + const element = await this.findElement(locator); + await this.driver.wait(until.elementIsVisible(element), this.timeout); + return element; } async findClickableElement(locator) { - const element = await this.findElement(locator) + const element = await this.findElement(locator); await Promise.all([ this.driver.wait(until.elementIsVisible(element), this.timeout), this.driver.wait(until.elementIsEnabled(element), this.timeout), - ]) - return element + ]); + return element; } async findElements(locator) { - return await this.driver.wait(until.elementsLocated(locator), this.timeout) + return await this.driver.wait(until.elementsLocated(locator), this.timeout); } async findClickableElements(locator) { - const elements = await this.findElements(locator) + const elements = await this.findElements(locator); await Promise.all( elements.reduce((acc, element) => { acc.push( this.driver.wait(until.elementIsVisible(element), this.timeout), this.driver.wait(until.elementIsEnabled(element), this.timeout), - ) - return acc + ); + return acc; }, []), - ) - return elements + ); + return elements; } async clickElement(locator) { - const element = await this.findClickableElement(locator) - await element.click() + const element = await this.findClickableElement(locator); + await element.click(); } async clickPoint(locator, x, y) { - const element = await this.findElement(locator) + const element = await this.findElement(locator); await this.driver .actions() .move({ origin: element, x, y }) .click() - .perform() + .perform(); } async scrollToElement(element) { await this.driver.executeScript( 'arguments[0].scrollIntoView(true)', element, - ) + ); } async assertElementNotPresent(locator) { - let dataTab + let dataTab; try { - dataTab = await this.findElement(locator) + dataTab = await this.findElement(locator); } catch (err) { assert( err instanceof webdriverError.NoSuchElementError || err instanceof webdriverError.TimeoutError, - ) + ); } - assert.ok(!dataTab, 'Found element that should not be present') + assert.ok(!dataTab, 'Found element that should not be present'); } // Navigation async navigate(page = Driver.PAGES.HOME) { - return await this.driver.get(`${this.extensionUrl}/${page}.html`) + return await this.driver.get(`${this.extensionUrl}/${page}.html`); } // Metrics async collectMetrics() { - return await this.driver.executeScript(collectMetrics) + return await this.driver.executeScript(collectMetrics); } // Window management async openNewPage(url) { - const newHandle = await this.driver.switchTo().newWindow() - await this.driver.get(url) - return newHandle + const newHandle = await this.driver.switchTo().newWindow(); + await this.driver.get(url); + return newHandle; } async switchToWindow(handle) { - await this.driver.switchTo().window(handle) + await this.driver.switchTo().window(handle); } async getAllWindowHandles() { - return await this.driver.getAllWindowHandles() + return await this.driver.getAllWindowHandles(); } async waitUntilXWindowHandles(x, delayStep = 1000, timeout = 5000) { - let timeElapsed = 0 - let windowHandles = [] + let timeElapsed = 0; + let windowHandles = []; while (timeElapsed <= timeout) { - windowHandles = await this.driver.getAllWindowHandles() + windowHandles = await this.driver.getAllWindowHandles(); if (windowHandles.length === x) { - return windowHandles + return windowHandles; } - await this.delay(delayStep) - timeElapsed += delayStep + await this.delay(delayStep); + timeElapsed += delayStep; } - throw new Error('waitUntilXWindowHandles timed out polling window handles') + throw new Error('waitUntilXWindowHandles timed out polling window handles'); } async switchToWindowWithTitle(title, windowHandles) { // eslint-disable-next-line no-param-reassign - windowHandles = windowHandles || (await this.driver.getAllWindowHandles()) + windowHandles = windowHandles || (await this.driver.getAllWindowHandles()); for (const handle of windowHandles) { - await this.driver.switchTo().window(handle) - const handleTitle = await this.driver.getTitle() + await this.driver.switchTo().window(handle); + const handleTitle = await this.driver.getTitle(); if (handleTitle === title) { - return handle + return handle; } } - throw new Error(`No window with title: ${title}`) + throw new Error(`No window with title: ${title}`); } /** @@ -165,14 +165,14 @@ class Driver { */ async closeAllWindowHandlesExcept(exceptions, windowHandles) { // eslint-disable-next-line no-param-reassign - windowHandles = windowHandles || (await this.driver.getAllWindowHandles()) + windowHandles = windowHandles || (await this.driver.getAllWindowHandles()); for (const handle of windowHandles) { if (!exceptions.includes(handle)) { - await this.driver.switchTo().window(handle) - await this.delay(1000) - await this.driver.close() - await this.delay(1000) + await this.driver.switchTo().window(handle); + await this.delay(1000); + await this.driver.close(); + await this.delay(1000); } } } @@ -180,41 +180,41 @@ class Driver { // Error handling async verboseReportOnFailure(title) { - const artifactDir = `./test-artifacts/${this.browser}/${title}` - const filepathBase = `${artifactDir}/test-failure` - await fs.mkdir(artifactDir, { recursive: true }) - const screenshot = await this.driver.takeScreenshot() + const artifactDir = `./test-artifacts/${this.browser}/${title}`; + const filepathBase = `${artifactDir}/test-failure`; + await fs.mkdir(artifactDir, { recursive: true }); + const screenshot = await this.driver.takeScreenshot(); await fs.writeFile(`${filepathBase}-screenshot.png`, screenshot, { encoding: 'base64', - }) - const htmlSource = await this.driver.getPageSource() - await fs.writeFile(`${filepathBase}-dom.html`, htmlSource) + }); + const htmlSource = await this.driver.getPageSource(); + await fs.writeFile(`${filepathBase}-dom.html`, htmlSource); const uiState = await this.driver.executeScript( () => window.getCleanAppState && window.getCleanAppState(), - ) + ); await fs.writeFile( `${filepathBase}-state.json`, JSON.stringify(uiState, null, 2), - ) + ); } async checkBrowserForConsoleErrors() { - const ignoredLogTypes = ['WARNING'] + const ignoredLogTypes = ['WARNING']; const ignoredErrorMessages = [ // Third-party Favicon 404s show up as errors 'favicon.ico - Failed to load resource: the server responded with a status of 404 (Not Found)', - ] - const browserLogs = await this.driver.manage().logs().get('browser') + ]; + const browserLogs = await this.driver.manage().logs().get('browser'); const errorEntries = browserLogs.filter( (entry) => !ignoredLogTypes.includes(entry.level.toString()), - ) - const errorObjects = errorEntries.map((entry) => entry.toJSON()) + ); + const errorObjects = errorEntries.map((entry) => entry.toJSON()); return errorObjects.filter( (entry) => !ignoredErrorMessages.some((message) => entry.message.includes(message), ), - ) + ); } } @@ -222,11 +222,11 @@ function collectMetrics() { const results = { paint: {}, navigation: [], - } + }; window.performance.getEntriesByType('paint').forEach((paintEntry) => { - results.paint[paintEntry.name] = paintEntry.startTime - }) + results.paint[paintEntry.name] = paintEntry.startTime; + }); window.performance .getEntriesByType('navigation') @@ -237,16 +237,16 @@ function collectMetrics() { domInteractive: navigationEntry.domInteractive, redirectCount: navigationEntry.redirectCount, type: navigationEntry.type, - }) - }) + }); + }); - return results + return results; } Driver.PAGES = { HOME: 'home', NOTIFICATION: 'notification', POPUP: 'popup', -} +}; -module.exports = Driver +module.exports = Driver; diff --git a/test/e2e/webdriver/firefox.js b/test/e2e/webdriver/firefox.js index 63c037b023..ed90dc2566 100644 --- a/test/e2e/webdriver/firefox.js +++ b/test/e2e/webdriver/firefox.js @@ -1,16 +1,16 @@ -const fs = require('fs') -const os = require('os') -const path = require('path') -const { Builder, By, until } = require('selenium-webdriver') -const firefox = require('selenium-webdriver/firefox') -const { version } = require('../../../app/manifest/_base.json') +const fs = require('fs'); +const os = require('os'); +const path = require('path'); +const { Builder, By, until } = require('selenium-webdriver'); +const firefox = require('selenium-webdriver/firefox'); +const { version } = require('../../../app/manifest/_base.json'); /** * The prefix for temporary Firefox profiles. All Firefox profiles used for e2e tests * will be created as random directories inside this. * @type {string} */ -const TEMP_PROFILE_PATH_PREFIX = path.join(os.tmpdir(), 'MetaMask-Fx-Profile') +const TEMP_PROFILE_PATH_PREFIX = path.join(os.tmpdir(), 'MetaMask-Fx-Profile'); /** * A wrapper around a {@code WebDriver} instance exposing Firefox-specific functionality @@ -22,32 +22,32 @@ class FirefoxDriver { * @returns {Promise<{driver: !ThenableWebDriver, extensionUrl: string, extensionId: string}>} */ static async build({ responsive, port }) { - const templateProfile = fs.mkdtempSync(TEMP_PROFILE_PATH_PREFIX) - const options = new firefox.Options().setProfile(templateProfile) + const templateProfile = fs.mkdtempSync(TEMP_PROFILE_PATH_PREFIX); + const options = new firefox.Options().setProfile(templateProfile); const builder = new Builder() .forBrowser('firefox') - .setFirefoxOptions(options) + .setFirefoxOptions(options); if (port) { - const service = new firefox.ServiceBuilder().setPort(port) - builder.setFirefoxService(service) + const service = new firefox.ServiceBuilder().setPort(port); + builder.setFirefoxService(service); } - const driver = builder.build() - const fxDriver = new FirefoxDriver(driver) + const driver = builder.build(); + const fxDriver = new FirefoxDriver(driver); const extensionId = await fxDriver.installExtension( `builds/metamask-firefox-${version}.zip`, - ) - const internalExtensionId = await fxDriver.getInternalId() + ); + const internalExtensionId = await fxDriver.getInternalId(); if (responsive) { - await driver.manage().window().setRect({ width: 320, height: 600 }) + await driver.manage().window().setRect({ width: 320, height: 600 }); } return { driver, extensionId, extensionUrl: `moz-extension://${internalExtensionId}`, - } + }; } /** @@ -55,7 +55,7 @@ class FirefoxDriver { * @param {!ThenableWebDriver} driver - a {@code WebDriver} instance */ constructor(driver) { - this._driver = driver + this._driver = driver; } /** @@ -64,7 +64,7 @@ class FirefoxDriver { * @returns {Promise} the extension ID */ async installExtension(addonPath) { - return await this._driver.installAddon(addonPath, true) + return await this._driver.installAddon(addonPath, true); } /** @@ -72,7 +72,7 @@ class FirefoxDriver { * @returns {Promise} the Internal UUID for the given extension */ async getInternalId() { - await this._driver.get('about:debugging#addons') + await this._driver.get('about:debugging#addons'); return await this._driver .wait( until.elementLocated( @@ -80,8 +80,8 @@ class FirefoxDriver { ), 1000, ) - .getText() + .getText(); } } -module.exports = FirefoxDriver +module.exports = FirefoxDriver; diff --git a/test/e2e/webdriver/index.js b/test/e2e/webdriver/index.js index 8a41aac8a6..b7647f96a6 100644 --- a/test/e2e/webdriver/index.js +++ b/test/e2e/webdriver/index.js @@ -1,36 +1,36 @@ -const { Browser } = require('selenium-webdriver') -const fetchMockResponses = require('../../data/fetch-mocks.json') -const Driver = require('./driver') -const ChromeDriver = require('./chrome') -const FirefoxDriver = require('./firefox') +const { Browser } = require('selenium-webdriver'); +const fetchMockResponses = require('../../data/fetch-mocks.json'); +const Driver = require('./driver'); +const ChromeDriver = require('./chrome'); +const FirefoxDriver = require('./firefox'); async function buildWebDriver({ responsive, port } = {}) { - const browser = process.env.SELENIUM_BROWSER + const browser = process.env.SELENIUM_BROWSER; const { driver: seleniumDriver, extensionId, extensionUrl, - } = await buildBrowserWebDriver(browser, { responsive, port }) - await setupFetchMocking(seleniumDriver) - const driver = new Driver(seleniumDriver, browser, extensionUrl) + } = await buildBrowserWebDriver(browser, { responsive, port }); + await setupFetchMocking(seleniumDriver); + const driver = new Driver(seleniumDriver, browser, extensionUrl); return { driver, extensionId, - } + }; } async function buildBrowserWebDriver(browser, webDriverOptions) { switch (browser) { case Browser.CHROME: { - return await ChromeDriver.build(webDriverOptions) + return await ChromeDriver.build(webDriverOptions); } case Browser.FIREFOX: { - return await FirefoxDriver.build(webDriverOptions) + return await FirefoxDriver.build(webDriverOptions); } default: { - throw new Error(`Unrecognized browser: ${browser}`) + throw new Error(`Unrecognized browser: ${browser}`); } } } @@ -38,44 +38,44 @@ async function buildBrowserWebDriver(browser, webDriverOptions) { async function setupFetchMocking(driver) { // define fetchMocking script, to be evaluated in the browser function fetchMocking(mockResponses) { - window.origFetch = window.fetch.bind(window) + window.origFetch = window.fetch.bind(window); window.fetch = async (...args) => { - const url = args[0] + const url = args[0]; // api.metaswap.codefi.network/gasPrices if ( url.match(/^http(s)?:\/\/api\.metaswap\.codefi\.network\/gasPrices/u) ) { - return { json: async () => clone(mockResponses.gasPricesBasic) } + return { json: async () => clone(mockResponses.gasPricesBasic) }; } else if (url.match(/chromeextensionmm/u)) { - return { json: async () => clone(mockResponses.metametrics) } + return { json: async () => clone(mockResponses.metametrics) }; } else if (url.match(/^https:\/\/(api\.metaswap|.*airswap-dev)/u)) { if (url.match(/featureFlag$/u)) { - return { json: async () => clone(mockResponses.swaps.featureFlag) } + return { json: async () => clone(mockResponses.swaps.featureFlag) }; } } - return window.origFetch(...args) - } + return window.origFetch(...args); + }; if (window.chrome && window.chrome.webRequest) { window.chrome.webRequest.onBeforeRequest.addListener( cancelInfuraRequest, { urls: ['https://*.infura.io/*'] }, ['blocking'], - ) + ); } function cancelInfuraRequest(requestDetails) { - console.log(`fetchMocking - Canceling request: "${requestDetails.url}"`) - return { cancel: true } + console.log(`fetchMocking - Canceling request: "${requestDetails.url}"`); + return { cancel: true }; } function clone(obj) { - return JSON.parse(JSON.stringify(obj)) + return JSON.parse(JSON.stringify(obj)); } } // fetchMockResponses are parsed last minute to ensure that objects are uniquely instantiated - const fetchMockResponsesJson = JSON.stringify(fetchMockResponses) + const fetchMockResponsesJson = JSON.stringify(fetchMockResponses); // eval the fetchMocking script in the browser - await driver.executeScript(`(${fetchMocking})(${fetchMockResponsesJson})`) + await driver.executeScript(`(${fetchMocking})(${fetchMockResponsesJson})`); } module.exports = { buildWebDriver, -} +}; diff --git a/test/env.js b/test/env.js index 1fbdad3dff..38e4a6fede 100644 --- a/test/env.js +++ b/test/env.js @@ -1 +1 @@ -process.env.METAMASK_ENV = 'test' +process.env.METAMASK_ENV = 'test'; diff --git a/test/helper.js b/test/helper.js index 38462c6caf..5731a905e0 100644 --- a/test/helper.js +++ b/test/helper.js @@ -1,92 +1,92 @@ -import Ganache from 'ganache-core' -import nock from 'nock' -import Enzyme from 'enzyme' -import Adapter from 'enzyme-adapter-react-16' -import log from 'loglevel' -import { JSDOM } from 'jsdom' +import Ganache from 'ganache-core'; +import nock from 'nock'; +import Enzyme from 'enzyme'; +import Adapter from 'enzyme-adapter-react-16'; +import log from 'loglevel'; +import { JSDOM } from 'jsdom'; -nock.disableNetConnect() -nock.enableNetConnect('localhost') +nock.disableNetConnect(); +nock.enableNetConnect('localhost'); // catch rejections that are still unhandled when tests exit -const unhandledRejections = new Map() +const unhandledRejections = new Map(); process.on('unhandledRejection', (reason, promise) => { - console.log('Unhandled rejection:', reason) - unhandledRejections.set(promise, reason) -}) + console.log('Unhandled rejection:', reason); + unhandledRejections.set(promise, reason); +}); process.on('rejectionHandled', (promise) => { - console.log(`handled: ${unhandledRejections.get(promise)}`) - unhandledRejections.delete(promise) -}) + console.log(`handled: ${unhandledRejections.get(promise)}`); + unhandledRejections.delete(promise); +}); process.on('exit', () => { if (unhandledRejections.size > 0) { - console.error(`Found ${unhandledRejections.size} unhandled rejections:`) + console.error(`Found ${unhandledRejections.size} unhandled rejections:`); for (const reason of unhandledRejections.values()) { - console.error('Unhandled rejection: ', reason) + console.error('Unhandled rejection: ', reason); } - process.exit(1) + process.exit(1); } -}) +}); -Enzyme.configure({ adapter: new Adapter() }) +Enzyme.configure({ adapter: new Adapter() }); // ganache server -const server = Ganache.server() -server.listen(8545) +const server = Ganache.server(); +server.listen(8545); -server.on('error', console.error) -server.on('clientError', console.error) +server.on('error', console.error); +server.on('clientError', console.error); -log.setDefaultLevel(5) -global.log = log +log.setDefaultLevel(5); +global.log = log; // // polyfills // // dom -const jsdom = new JSDOM() -global.window = jsdom.window +const jsdom = new JSDOM(); +global.window = jsdom.window; // required by `trezor-connect/node_modules/whatwg-fetch` -global.self = window +global.self = window; // required by `dom-helpers` and various other libraries -global.document = window.document +global.document = window.document; // required by `react-tippy` -global.navigator = window.navigator -global.Element = window.Element +global.navigator = window.navigator; +global.Element = window.Element; // required by `react-popper` -global.HTMLElement = window.HTMLElement +global.HTMLElement = window.HTMLElement; // required by any components anchored on `popover-content` -const popoverContent = window.document.createElement('div') -popoverContent.setAttribute('id', 'popover-content') -window.document.body.appendChild(popoverContent) +const popoverContent = window.document.createElement('div'); +popoverContent.setAttribute('id', 'popover-content'); +window.document.body.appendChild(popoverContent); // delete AbortController added by jsdom so it can be polyfilled correctly below -delete window.AbortController +delete window.AbortController; // fetch -const fetch = require('node-fetch') +const fetch = require('node-fetch'); -const { Headers, Request, Response } = fetch -Object.assign(window, { fetch, Headers, Request, Response }) +const { Headers, Request, Response } = fetch; +Object.assign(window, { fetch, Headers, Request, Response }); -require('abortcontroller-polyfill/dist/polyfill-patch-fetch') +require('abortcontroller-polyfill/dist/polyfill-patch-fetch'); // localStorage window.localStorage = { removeItem: () => null, -} +}; // override @metamask/logo -window.requestAnimationFrame = () => undefined +window.requestAnimationFrame = () => undefined; // crypto.getRandomValues if (!window.crypto) { - window.crypto = {} + window.crypto = {}; } if (!window.crypto.getRandomValues) { // eslint-disable-next-line node/global-require - window.crypto.getRandomValues = require('polyfill-crypto.getrandomvalues') + window.crypto.getRandomValues = require('polyfill-crypto.getrandomvalues'); } diff --git a/test/lib/createTxMeta.js b/test/lib/createTxMeta.js index c4b680d8ef..035f336a6c 100644 --- a/test/lib/createTxMeta.js +++ b/test/lib/createTxMeta.js @@ -1,16 +1,16 @@ -import { snapshotFromTxMeta } from '../../app/scripts/controllers/transactions/lib/tx-state-history-helpers' -import { TRANSACTION_STATUSES } from '../../shared/constants/transaction' +import { snapshotFromTxMeta } from '../../app/scripts/controllers/transactions/lib/tx-state-history-helpers'; +import { TRANSACTION_STATUSES } from '../../shared/constants/transaction'; export default function createTxMeta(partialMeta) { const txMeta = { status: TRANSACTION_STATUSES.UNAPPROVED, txParams: {}, ...partialMeta, - } + }; // initialize history - txMeta.history = [] + txMeta.history = []; // capture initial snapshot of txMeta for history - const snapshot = snapshotFromTxMeta(txMeta) - txMeta.history.push(snapshot) - return txMeta + const snapshot = snapshotFromTxMeta(txMeta); + txMeta.history.push(snapshot); + return txMeta; } diff --git a/test/lib/mock-encryptor.js b/test/lib/mock-encryptor.js index 4b9f7faee6..75a8488a8a 100644 --- a/test/lib/mock-encryptor.js +++ b/test/lib/mock-encryptor.js @@ -1,36 +1,36 @@ -const mockHex = '0xabcdef0123456789' -const mockKey = Buffer.alloc(32) -let cacheVal +const mockHex = '0xabcdef0123456789'; +const mockKey = Buffer.alloc(32); +let cacheVal; const mockEncryptor = { encrypt(_, dataObj) { - cacheVal = dataObj - return Promise.resolve(mockHex) + cacheVal = dataObj; + return Promise.resolve(mockHex); }, decrypt() { - return Promise.resolve(cacheVal || {}) + return Promise.resolve(cacheVal || {}); }, encryptWithKey(key, dataObj) { - return this.encrypt(key, dataObj) + return this.encrypt(key, dataObj); }, decryptWithKey(key, text) { - return this.decrypt(key, text) + return this.decrypt(key, text); }, keyFromPassword() { - return Promise.resolve(mockKey) + return Promise.resolve(mockKey); }, generateSalt() { - return 'WHADDASALT!' + return 'WHADDASALT!'; }, getRandomValues() { - return 'SOO RANDO!!!1' + return 'SOO RANDO!!!1'; }, -} +}; -export default mockEncryptor +export default mockEncryptor; diff --git a/test/lib/render-helpers.js b/test/lib/render-helpers.js index b8d6be4508..9d6bbe881b 100644 --- a/test/lib/render-helpers.js +++ b/test/lib/render-helpers.js @@ -1,10 +1,10 @@ -import React from 'react' -import { Provider } from 'react-redux' -import { render } from '@testing-library/react' -import { mount } from 'enzyme' -import { MemoryRouter } from 'react-router-dom' -import PropTypes from 'prop-types' -import { LegacyI18nProvider } from '../../ui/app/contexts/i18n' +import React from 'react'; +import { Provider } from 'react-redux'; +import { render } from '@testing-library/react'; +import { mount } from 'enzyme'; +import { MemoryRouter } from 'react-router-dom'; +import PropTypes from 'prop-types'; +import { LegacyI18nProvider } from '../../ui/app/contexts/i18n'; export function mountWithRouter(component, store = {}, pathname = '/') { // Instantiate router context @@ -16,7 +16,7 @@ export function mountWithRouter(component, store = {}, pathname = '/') { }, match: {}, }, - } + }; const createContext = () => ({ context: { @@ -31,15 +31,15 @@ export function mountWithRouter(component, store = {}, pathname = '/') { metricsEvent: PropTypes.func, store: PropTypes.object, }, - }) + }); const Wrapper = () => ( {component} - ) + ); - return mount(, createContext()) + return mount(, createContext()); } export function renderWithProvider(component, store) { @@ -47,7 +47,7 @@ export function renderWithProvider(component, store) { {component} - ) + ); - return render() + return render(); } diff --git a/test/lib/wait-until-called.js b/test/lib/wait-until-called.js index 8252f60494..94a87f0f43 100644 --- a/test/lib/wait-until-called.js +++ b/test/lib/wait-until-called.js @@ -1,4 +1,4 @@ -const DEFAULT_TIMEOUT = 10000 +const DEFAULT_TIMEOUT = 10000; /** * A function that wraps a sinon stub and returns an asynchronous function @@ -25,42 +25,42 @@ function waitUntilCalled( wrappedThis = null, { callCount = 1, timeout = DEFAULT_TIMEOUT } = {}, ) { - let numCalls = 0 - let resolve - let timeoutHandle + let numCalls = 0; + let resolve; + let timeoutHandle; const stubHasBeenCalled = new Promise((_resolve) => { - resolve = _resolve + resolve = _resolve; if (timeout !== null) { timeoutHandle = setTimeout( () => resolve(new Error('Timeout exceeded')), timeout, - ) + ); } - }) + }); stub.callsFake((...args) => { try { if (stub.wrappedMethod) { - stub.wrappedMethod.call(wrappedThis, ...args) + stub.wrappedMethod.call(wrappedThis, ...args); } } finally { if (numCalls < callCount) { - numCalls += 1 + numCalls += 1; if (numCalls === callCount) { if (timeoutHandle) { - clearTimeout(timeoutHandle) + clearTimeout(timeoutHandle); } - resolve() + resolve(); } } } - }) + }); return async () => { - const error = await stubHasBeenCalled + const error = await stubHasBeenCalled; if (error) { - throw error + throw error; } - } + }; } -module.exports = waitUntilCalled +module.exports = waitUntilCalled; diff --git a/test/setup.js b/test/setup.js index abc8d6c30b..a4795b61bd 100644 --- a/test/setup.js +++ b/test/setup.js @@ -1,6 +1,6 @@ -require('@babel/register') +require('@babel/register'); -require('./helper') +require('./helper'); -window.SVGPathElement = window.SVGPathElement || { prototype: {} } -global.indexedDB = {} +window.SVGPathElement = window.SVGPathElement || { prototype: {} }; +global.indexedDB = {}; diff --git a/test/stub/provider.js b/test/stub/provider.js index f9bc729771..7f84e795f0 100644 --- a/test/stub/provider.js +++ b/test/stub/provider.js @@ -1,10 +1,10 @@ -import { JsonRpcEngine } from 'json-rpc-engine' -import scaffoldMiddleware from 'eth-json-rpc-middleware/scaffold' -import providerAsMiddleware from 'eth-json-rpc-middleware/providerAsMiddleware' -import GanacheCore from 'ganache-core' +import { JsonRpcEngine } from 'json-rpc-engine'; +import scaffoldMiddleware from 'eth-json-rpc-middleware/scaffold'; +import providerAsMiddleware from 'eth-json-rpc-middleware/providerAsMiddleware'; +import GanacheCore from 'ganache-core'; export function getTestSeed() { - return 'people carpet cluster attract ankle motor ozone mass dove original primary mask' + return 'people carpet cluster attract ankle motor ozone mass dove original primary mask'; } export function getTestAccounts() { @@ -30,22 +30,22 @@ export function getTestAccounts() { 'hex', ), }, - ] + ]; } export function createEngineForTestData() { - return new JsonRpcEngine() + return new JsonRpcEngine(); } export function providerFromEngine(engine) { - const provider = { sendAsync: engine.handle.bind(engine) } - return provider + const provider = { sendAsync: engine.handle.bind(engine) }; + return provider; } export function createTestProviderTools(opts = {}) { - const engine = createEngineForTestData() + const engine = createEngineForTestData(); // handle provided hooks - engine.push(scaffoldMiddleware(opts.scaffold || {})) + engine.push(scaffoldMiddleware(opts.scaffold || {})); // handle block tracker methods engine.push( providerAsMiddleware( @@ -56,8 +56,8 @@ export function createTestProviderTools(opts = {}) { _chainIdRpc: opts.chainId, }), ), - ) + ); // wrap in standard provider interface - const provider = providerFromEngine(engine) - return { provider, engine } + const provider = providerFromEngine(engine); + return { provider, engine }; } diff --git a/test/unit-global/frozenPromise.js b/test/unit-global/frozenPromise.js index 427d7ffb9c..de24097922 100644 --- a/test/unit-global/frozenPromise.js +++ b/test/unit-global/frozenPromise.js @@ -1,53 +1,53 @@ // Should occur before anything else -import './globalPatch' -import 'ses/lockdown' -import '../../app/scripts/runLockdown' -import assert from 'assert' /* eslint-disable-line import/first,import/order */ +import './globalPatch'; +import 'ses/lockdown'; +import '../../app/scripts/runLockdown'; +import assert from 'assert'; /* eslint-disable-line import/first,import/order */ describe('Promise global is immutable', function () { it('throws when reassinging promise (syntax 1)', function () { try { // eslint-disable-next-line no-global-assign,no-native-reassign - Promise = {} - assert.fail('did not throw error') + Promise = {}; + assert.fail('did not throw error'); } catch (err) { - assert.ok(err, 'did throw error') + assert.ok(err, 'did throw error'); } - }) + }); it('throws when reassinging promise (syntax 2)', function () { try { - global.Promise = {} - assert.fail('did not throw error') + global.Promise = {}; + assert.fail('did not throw error'); } catch (err) { - assert.ok(err, 'did throw error') + assert.ok(err, 'did throw error'); } - }) + }); it('throws when mutating existing Promise property', function () { try { - Promise.all = () => undefined - assert.fail('did not throw error') + Promise.all = () => undefined; + assert.fail('did not throw error'); } catch (err) { - assert.ok(err, 'did throw error') + assert.ok(err, 'did throw error'); } - }) + }); it('throws when adding new Promise property', function () { try { - Promise.foo = 'bar' - assert.fail('did not throw error') + Promise.foo = 'bar'; + assert.fail('did not throw error'); } catch (err) { - assert.ok(err, 'did throw error') + assert.ok(err, 'did throw error'); } - }) + }); it('throws when deleting Promise from global', function () { try { - delete global.Promise - assert.fail('did not throw error') + delete global.Promise; + assert.fail('did not throw error'); } catch (err) { - assert.ok(err, 'did throw error') + assert.ok(err, 'did throw error'); } - }) -}) + }); +}); diff --git a/test/unit-global/globalPatch.js b/test/unit-global/globalPatch.js index 89d392454c..da239953c6 100644 --- a/test/unit-global/globalPatch.js +++ b/test/unit-global/globalPatch.js @@ -1,2 +1,2 @@ // eslint-disable-next-line import/unambiguous,node/no-unsupported-features/es-builtins -global.globalThis = global +global.globalThis = global; diff --git a/test/unit/actions/config_test.js b/test/unit/actions/config_test.js index 35064ad9c2..7b31cd84f2 100644 --- a/test/unit/actions/config_test.js +++ b/test/unit/actions/config_test.js @@ -1,8 +1,8 @@ -import assert from 'assert' -import freeze from 'deep-freeze-strict' -import reducers from '../../../ui/app/ducks' -import * as actionConstants from '../../../ui/app/store/actionConstants' -import { NETWORK_TYPE_RPC } from '../../../shared/constants/network' +import assert from 'assert'; +import freeze from 'deep-freeze-strict'; +import reducers from '../../../ui/app/ducks'; +import * as actionConstants from '../../../ui/app/store/actionConstants'; +import { NETWORK_TYPE_RPC } from '../../../shared/constants/network'; describe('config view actions', function () { const initialState = { @@ -15,19 +15,19 @@ describe('config view actions', function () { name: 'accounts', }, }, - } - freeze(initialState) + }; + freeze(initialState); describe('SET_RPC_TARGET', function () { it('sets the state.metamask.rpcUrl property of the state to the action.value', function () { const action = { type: actionConstants.SET_RPC_TARGET, value: 'foo', - } + }; - const result = reducers(initialState, action) - assert.equal(result.metamask.provider.type, NETWORK_TYPE_RPC) - assert.equal(result.metamask.provider.rpcUrl, 'foo') - }) - }) -}) + const result = reducers(initialState, action); + assert.equal(result.metamask.provider.type, NETWORK_TYPE_RPC); + assert.equal(result.metamask.provider.rpcUrl, 'foo'); + }); + }); +}); diff --git a/test/unit/actions/set_account_label_test.js b/test/unit/actions/set_account_label_test.js index 7a79bd0b4b..7bdb0d22c9 100644 --- a/test/unit/actions/set_account_label_test.js +++ b/test/unit/actions/set_account_label_test.js @@ -1,7 +1,7 @@ -import assert from 'assert' -import freeze from 'deep-freeze-strict' -import reducers from '../../../ui/app/ducks' -import * as actionConstants from '../../../ui/app/store/actionConstants' +import assert from 'assert'; +import freeze from 'deep-freeze-strict'; +import reducers from '../../../ui/app/ducks'; +import * as actionConstants from '../../../ui/app/store/actionConstants'; describe('SET_ACCOUNT_LABEL', function () { it('updates the state.metamask.identities[:i].name property of the state to the action.value.label', function () { @@ -13,8 +13,8 @@ describe('SET_ACCOUNT_LABEL', function () { }, }, }, - } - freeze(initialState) + }; + freeze(initialState); const action = { type: actionConstants.SET_ACCOUNT_LABEL, @@ -22,13 +22,13 @@ describe('SET_ACCOUNT_LABEL', function () { account: 'foo', label: 'baz', }, - } - freeze(action) + }; + freeze(action); - const resultingState = reducers(initialState, action) + const resultingState = reducers(initialState, action); assert.equal( resultingState.metamask.identities.foo.name, action.value.label, - ) - }) -}) + ); + }); +}); diff --git a/test/unit/actions/set_selected_account_test.js b/test/unit/actions/set_selected_account_test.js index 03292c439d..9f9a79036e 100644 --- a/test/unit/actions/set_selected_account_test.js +++ b/test/unit/actions/set_selected_account_test.js @@ -1,7 +1,7 @@ -import assert from 'assert' -import freeze from 'deep-freeze-strict' -import reducers from '../../../ui/app/ducks' -import * as actionConstants from '../../../ui/app/store/actionConstants' +import assert from 'assert'; +import freeze from 'deep-freeze-strict'; +import reducers from '../../../ui/app/ducks'; +import * as actionConstants from '../../../ui/app/store/actionConstants'; describe('SHOW_ACCOUNT_DETAIL', function () { it('updates metamask state', function () { @@ -9,16 +9,16 @@ describe('SHOW_ACCOUNT_DETAIL', function () { metamask: { selectedAddress: 'foo', }, - } - freeze(initialState) + }; + freeze(initialState); const action = { type: actionConstants.SHOW_ACCOUNT_DETAIL, value: 'bar', - } - freeze(action) + }; + freeze(action); - const resultingState = reducers(initialState, action) - assert.equal(resultingState.metamask.selectedAddress, action.value) - }) -}) + const resultingState = reducers(initialState, action); + assert.equal(resultingState.metamask.selectedAddress, action.value); + }); +}); diff --git a/test/unit/actions/tx_test.js b/test/unit/actions/tx_test.js index 99b27689f9..c1a969b75c 100644 --- a/test/unit/actions/tx_test.js +++ b/test/unit/actions/tx_test.js @@ -1,14 +1,14 @@ -import assert from 'assert' -import configureMockStore from 'redux-mock-store' -import thunk from 'redux-thunk' -import * as actions from '../../../ui/app/store/actions' -import * as actionConstants from '../../../ui/app/store/actionConstants' +import assert from 'assert'; +import configureMockStore from 'redux-mock-store'; +import thunk from 'redux-thunk'; +import * as actions from '../../../ui/app/store/actions'; +import * as actionConstants from '../../../ui/app/store/actionConstants'; -const middlewares = [thunk] -const mockStore = configureMockStore(middlewares) +const middlewares = [thunk]; +const mockStore = configureMockStore(middlewares); describe('tx confirmation screen', function () { - const txId = 1457634084250832 + const txId = 1457634084250832; const initialState = { appState: {}, metamask: { @@ -20,31 +20,31 @@ describe('tx confirmation screen', function () { }, }, }, - } + }; - const store = mockStore(initialState) + const store = mockStore(initialState); describe('cancelTx', function () { it('creates COMPLETED_TX with the cancelled transaction ID', async function () { actions._setBackgroundConnection({ approveTransaction(_, cb) { - cb(new Error('An error!')) + cb(new Error('An error!')); }, cancelTransaction(_, cb) { - cb() + cb(); }, getState(cb) { - cb(null, {}) + cb(null, {}); }, - }) + }); - await store.dispatch(actions.cancelTx({ id: txId })) - const storeActions = store.getActions() + await store.dispatch(actions.cancelTx({ id: txId })); + const storeActions = store.getActions(); const completedTxAction = storeActions.find( ({ type }) => type === actionConstants.COMPLETED_TX, - ) - const { id } = completedTxAction.value - assert.equal(id, txId) - }) - }) -}) + ); + const { id } = completedTxAction.value; + assert.equal(id, txId); + }); + }); +}); diff --git a/test/unit/actions/warning_test.js b/test/unit/actions/warning_test.js index a59b40f92f..2ec35525b4 100644 --- a/test/unit/actions/warning_test.js +++ b/test/unit/actions/warning_test.js @@ -1,24 +1,24 @@ -import assert from 'assert' -import freeze from 'deep-freeze-strict' -import * as actions from '../../../ui/app/store/actions' -import reducers from '../../../ui/app/ducks' +import assert from 'assert'; +import freeze from 'deep-freeze-strict'; +import * as actions from '../../../ui/app/store/actions'; +import reducers from '../../../ui/app/ducks'; describe('action DISPLAY_WARNING', function () { it('sets appState.warning to provided value', function () { const initialState = { appState: {}, - } - freeze(initialState) + }; + freeze(initialState); - const warningText = 'This is a sample warning message' + const warningText = 'This is a sample warning message'; - const action = actions.displayWarning(warningText) - const resultingState = reducers(initialState, action) + const action = actions.displayWarning(warningText); + const resultingState = reducers(initialState, action); assert.equal( resultingState.appState.warning, warningText, 'warning text set', - ) - }) -}) + ); + }); +}); diff --git a/test/unit/app/ComposableObservableStore.js b/test/unit/app/ComposableObservableStore.js index 205e0a59ba..816e0de59f 100644 --- a/test/unit/app/ComposableObservableStore.js +++ b/test/unit/app/ComposableObservableStore.js @@ -1,35 +1,35 @@ -import assert from 'assert' -import { ObservableStore } from '@metamask/obs-store' -import ComposableObservableStore from '../../../app/scripts/lib/ComposableObservableStore' +import assert from 'assert'; +import { ObservableStore } from '@metamask/obs-store'; +import ComposableObservableStore from '../../../app/scripts/lib/ComposableObservableStore'; describe('ComposableObservableStore', function () { it('should register initial state', function () { - const store = new ComposableObservableStore('state') - assert.strictEqual(store.getState(), 'state') - }) + const store = new ComposableObservableStore('state'); + assert.strictEqual(store.getState(), 'state'); + }); it('should register initial structure', function () { - const testStore = new ObservableStore() - const store = new ComposableObservableStore(null, { TestStore: testStore }) - testStore.putState('state') - assert.deepEqual(store.getState(), { TestStore: 'state' }) - }) + const testStore = new ObservableStore(); + const store = new ComposableObservableStore(null, { TestStore: testStore }); + testStore.putState('state'); + assert.deepEqual(store.getState(), { TestStore: 'state' }); + }); it('should update structure', function () { - const testStore = new ObservableStore() - const store = new ComposableObservableStore() - store.updateStructure({ TestStore: testStore }) - testStore.putState('state') - assert.deepEqual(store.getState(), { TestStore: 'state' }) - }) + const testStore = new ObservableStore(); + const store = new ComposableObservableStore(); + store.updateStructure({ TestStore: testStore }); + testStore.putState('state'); + assert.deepEqual(store.getState(), { TestStore: 'state' }); + }); it('should return flattened state', function () { - const fooStore = new ObservableStore({ foo: 'foo' }) - const barStore = new ObservableStore({ bar: 'bar' }) + const fooStore = new ObservableStore({ foo: 'foo' }); + const barStore = new ObservableStore({ bar: 'bar' }); const store = new ComposableObservableStore(null, { FooStore: fooStore, BarStore: barStore, - }) - assert.deepEqual(store.getFlatState(), { foo: 'foo', bar: 'bar' }) - }) -}) + }); + assert.deepEqual(store.getFlatState(), { foo: 'foo', bar: 'bar' }); + }); +}); diff --git a/test/unit/app/account-import-strategies.spec.js b/test/unit/app/account-import-strategies.spec.js index 8918bd064b..5dc706b90e 100644 --- a/test/unit/app/account-import-strategies.spec.js +++ b/test/unit/app/account-import-strategies.spec.js @@ -1,72 +1,72 @@ -import assert from 'assert' -import ethUtil from 'ethereumjs-util' -import accountImporter from '../../../app/scripts/account-import-strategies' +import assert from 'assert'; +import ethUtil from 'ethereumjs-util'; +import accountImporter from '../../../app/scripts/account-import-strategies'; describe('Account Import Strategies', function () { const privkey = - '0x4cfd3e90fc78b0f86bf7524722150bb8da9c60cd532564d7ff43f5716514f553' + '0x4cfd3e90fc78b0f86bf7524722150bb8da9c60cd532564d7ff43f5716514f553'; const json = - '{"version":3,"id":"dbb54385-0a99-437f-83c0-647de9f244c3","address":"a7f92ce3fba24196cf6f4bd2e1eb3db282ba998c","Crypto":{"ciphertext":"bde13d9ade5c82df80281ca363320ce254a8a3a06535bbf6ffdeaf0726b1312c","cipherparams":{"iv":"fbf93718a57f26051b292f072f2e5b41"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"7ffe00488319dec48e4c49a120ca49c6afbde9272854c64d9541c83fc6acdffe","n":8192,"r":8,"p":1},"mac":"2adfd9c4bc1cdac4c85bddfb31d9e21a684e0e050247a70c5698facf6b7d4681"}}' + '{"version":3,"id":"dbb54385-0a99-437f-83c0-647de9f244c3","address":"a7f92ce3fba24196cf6f4bd2e1eb3db282ba998c","Crypto":{"ciphertext":"bde13d9ade5c82df80281ca363320ce254a8a3a06535bbf6ffdeaf0726b1312c","cipherparams":{"iv":"fbf93718a57f26051b292f072f2e5b41"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"7ffe00488319dec48e4c49a120ca49c6afbde9272854c64d9541c83fc6acdffe","n":8192,"r":8,"p":1},"mac":"2adfd9c4bc1cdac4c85bddfb31d9e21a684e0e050247a70c5698facf6b7d4681"}}'; describe('private key import', function () { it('imports a private key and strips 0x prefix', async function () { const importPrivKey = await accountImporter.importAccount('Private Key', [ privkey, - ]) - assert.equal(importPrivKey, ethUtil.stripHexPrefix(privkey)) - }) + ]); + assert.equal(importPrivKey, ethUtil.stripHexPrefix(privkey)); + }); it('throws an error for empty string private key', async function () { await assert.rejects( async () => { - await accountImporter.importAccount('Private Key', ['']) + await accountImporter.importAccount('Private Key', ['']); }, Error, 'no empty strings', - ) - }) + ); + }); it('throws an error for undefined string private key', async function () { await assert.rejects(async () => { - await accountImporter.importAccount('Private Key', [undefined]) - }) + await accountImporter.importAccount('Private Key', [undefined]); + }); await assert.rejects(async () => { - await accountImporter.importAccount('Private Key', []) - }) - }) + await accountImporter.importAccount('Private Key', []); + }); + }); it('throws an error for invalid private key', async function () { await assert.rejects(async () => { - await accountImporter.importAccount('Private Key', ['popcorn']) - }) - }) - }) + await accountImporter.importAccount('Private Key', ['popcorn']); + }); + }); + }); describe('JSON keystore import', function () { it('fails when password is incorrect for keystore', async function () { - const wrongPassword = 'password2' + const wrongPassword = 'password2'; try { - await accountImporter.importAccount('JSON File', [json, wrongPassword]) + await accountImporter.importAccount('JSON File', [json, wrongPassword]); } catch (error) { assert.equal( error.message, 'Key derivation failed - possibly wrong passphrase', - ) + ); } - }) + }); it('imports json string and password to return a private key', async function () { - const fileContentsPassword = 'password1' + const fileContentsPassword = 'password1'; const importJson = await accountImporter.importAccount('JSON File', [ json, fileContentsPassword, - ]) + ]); assert.equal( importJson, '0x5733876abe94146069ce8bcbabbde2677f2e35fa33e875e92041ed2ac87e5bc7', - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/test/unit/app/buy-eth-url.spec.js b/test/unit/app/buy-eth-url.spec.js index 749d0a40f2..d9730b4fbf 100644 --- a/test/unit/app/buy-eth-url.spec.js +++ b/test/unit/app/buy-eth-url.spec.js @@ -1,43 +1,43 @@ -import assert from 'assert' -import getBuyEthUrl from '../../../app/scripts/lib/buy-eth-url' +import assert from 'assert'; +import getBuyEthUrl from '../../../app/scripts/lib/buy-eth-url'; describe('buy-eth-url', function () { const mainnet = { network: '1', amount: 5, address: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', - } + }; const ropsten = { network: '3', - } + }; const rinkeby = { network: '4', - } + }; const kovan = { network: '42', - } + }; it('returns wyre url with address for network 1', function () { - const wyreUrl = getBuyEthUrl(mainnet) + const wyreUrl = getBuyEthUrl(mainnet); assert.equal( wyreUrl, 'https://pay.sendwyre.com/purchase?dest=ethereum:0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc&destCurrency=ETH&accountId=AC-7AG3W4XH4N2&paymentMethod=debit-card', - ) - }) + ); + }); it('returns metamask ropsten faucet for network 3', function () { - const ropstenUrl = getBuyEthUrl(ropsten) - assert.equal(ropstenUrl, 'https://faucet.metamask.io/') - }) + const ropstenUrl = getBuyEthUrl(ropsten); + assert.equal(ropstenUrl, 'https://faucet.metamask.io/'); + }); it('returns rinkeby dapp for network 4', function () { - const rinkebyUrl = getBuyEthUrl(rinkeby) - assert.equal(rinkebyUrl, 'https://www.rinkeby.io/') - }) + const rinkebyUrl = getBuyEthUrl(rinkeby); + assert.equal(rinkebyUrl, 'https://www.rinkeby.io/'); + }); it('returns kovan github test faucet for network 42', function () { - const kovanUrl = getBuyEthUrl(kovan) - assert.equal(kovanUrl, 'https://github.com/kovan-testnet/faucet') - }) -}) + const kovanUrl = getBuyEthUrl(kovan); + assert.equal(kovanUrl, 'https://github.com/kovan-testnet/faucet'); + }); +}); diff --git a/test/unit/app/cleanErrorStack.spec.js b/test/unit/app/cleanErrorStack.spec.js index 5aa63cb4ce..e6bf8951f7 100644 --- a/test/unit/app/cleanErrorStack.spec.js +++ b/test/unit/app/cleanErrorStack.spec.js @@ -1,34 +1,34 @@ -import assert from 'assert' -import cleanErrorStack from '../../../app/scripts/lib/cleanErrorStack' +import assert from 'assert'; +import cleanErrorStack from '../../../app/scripts/lib/cleanErrorStack'; describe('Clean Error Stack', function () { - const testMessage = 'Test Message' - const testError = new Error(testMessage) - const undefinedErrorName = new Error(testMessage) - const blankErrorName = new Error(testMessage) - const blankMsgError = new Error() + const testMessage = 'Test Message'; + const testError = new Error(testMessage); + const undefinedErrorName = new Error(testMessage); + const blankErrorName = new Error(testMessage); + const blankMsgError = new Error(); beforeEach(function () { - undefinedErrorName.name = undefined - blankErrorName.name = '' - }) + undefinedErrorName.name = undefined; + blankErrorName.name = ''; + }); it('tests error with message', function () { - assert.equal(cleanErrorStack(testError), 'Error: Test Message') - }) + assert.equal(cleanErrorStack(testError), 'Error: Test Message'); + }); it('tests error with undefined name', function () { assert.equal( cleanErrorStack(undefinedErrorName).toString(), 'Error: Test Message', - ) - }) + ); + }); it('tests error with blank name', function () { - assert.equal(cleanErrorStack(blankErrorName).toString(), 'Test Message') - }) + assert.equal(cleanErrorStack(blankErrorName).toString(), 'Test Message'); + }); it('tests error with blank message', function () { - assert.equal(cleanErrorStack(blankMsgError), 'Error') - }) -}) + assert.equal(cleanErrorStack(blankMsgError), 'Error'); + }); +}); diff --git a/test/unit/app/controllers/cached-balances-test.js b/test/unit/app/controllers/cached-balances-test.js index 8a7fb61ae0..1267e083b5 100644 --- a/test/unit/app/controllers/cached-balances-test.js +++ b/test/unit/app/controllers/cached-balances-test.js @@ -1,6 +1,6 @@ -import assert from 'assert' -import sinon from 'sinon' -import CachedBalancesController from '../../../../app/scripts/controllers/cached-balances' +import assert from 'assert'; +import sinon from 'sinon'; +import CachedBalancesController from '../../../../app/scripts/controllers/cached-balances'; describe('CachedBalancesController', function () { describe('updateCachedBalances', function () { @@ -15,25 +15,25 @@ describe('CachedBalancesController', function () { initState: { cachedBalances: 'mockCachedBalances', }, - }) + }); controller._generateBalancesToCache = sinon .stub() - .callsFake(() => Promise.resolve('mockNewCachedBalances')) + .callsFake(() => Promise.resolve('mockNewCachedBalances')); - await controller.updateCachedBalances({ accounts: 'mockAccounts' }) + await controller.updateCachedBalances({ accounts: 'mockAccounts' }); - assert.equal(controller._generateBalancesToCache.callCount, 1) + assert.equal(controller._generateBalancesToCache.callCount, 1); assert.deepEqual(controller._generateBalancesToCache.args[0], [ 'mockAccounts', 17, - ]) + ]); assert.equal( controller.store.getState().cachedBalances, 'mockNewCachedBalances', - ) - }) - }) + ); + }); + }); describe('_generateBalancesToCache', function () { it('should generate updated account balances where the current network was updated', function () { @@ -57,7 +57,7 @@ describe('CachedBalancesController', function () { }, }, }, - }) + }); const result = controller._generateBalancesToCache( { @@ -66,7 +66,7 @@ describe('CachedBalancesController', function () { c: { balance: '0x5' }, }, 17, - ) + ); assert.deepEqual(result, { 17: { @@ -79,8 +79,8 @@ describe('CachedBalancesController', function () { b: '0xb', c: '0xc', }, - }) - }) + }); + }); it('should generate updated account balances where the a new network was selected', function () { const controller = new CachedBalancesController({ @@ -98,7 +98,7 @@ describe('CachedBalancesController', function () { }, }, }, - }) + }); const result = controller._generateBalancesToCache( { @@ -107,7 +107,7 @@ describe('CachedBalancesController', function () { c: { balance: '0x5' }, }, 16, - ) + ); assert.deepEqual(result, { 17: { @@ -119,13 +119,13 @@ describe('CachedBalancesController', function () { a: '0x4', c: '0x5', }, - }) - }) - }) + }); + }); + }); describe('_registerUpdates', function () { it('should subscribe to the account tracker with the updateCachedBalances method', async function () { - const subscribeSpy = sinon.spy() + const subscribeSpy = sinon.spy(); const controller = new CachedBalancesController({ getNetwork: () => Promise.resolve(17), accountTracker: { @@ -133,18 +133,18 @@ describe('CachedBalancesController', function () { subscribe: subscribeSpy, }, }, - }) - subscribeSpy.resetHistory() + }); + subscribeSpy.resetHistory(); - const updateCachedBalancesSpy = sinon.spy() - controller.updateCachedBalances = updateCachedBalancesSpy - controller._registerUpdates({ accounts: 'mockAccounts' }) + const updateCachedBalancesSpy = sinon.spy(); + controller.updateCachedBalances = updateCachedBalancesSpy; + controller._registerUpdates({ accounts: 'mockAccounts' }); - assert.equal(subscribeSpy.callCount, 1) + assert.equal(subscribeSpy.callCount, 1); - subscribeSpy.args[0][0]() + subscribeSpy.args[0][0](); - assert.equal(updateCachedBalancesSpy.callCount, 1) - }) - }) -}) + assert.equal(updateCachedBalancesSpy.callCount, 1); + }); + }); +}); diff --git a/test/unit/app/controllers/detect-tokens-test.js b/test/unit/app/controllers/detect-tokens-test.js index d76906d26e..458183d8b9 100644 --- a/test/unit/app/controllers/detect-tokens-test.js +++ b/test/unit/app/controllers/detect-tokens-test.js @@ -1,112 +1,112 @@ -import assert from 'assert' -import sinon from 'sinon' -import { ObservableStore } from '@metamask/obs-store' -import contracts from '@metamask/contract-metadata' -import BigNumber from 'bignumber.js' +import assert from 'assert'; +import sinon from 'sinon'; +import { ObservableStore } from '@metamask/obs-store'; +import contracts from '@metamask/contract-metadata'; +import BigNumber from 'bignumber.js'; -import DetectTokensController from '../../../../app/scripts/controllers/detect-tokens' -import NetworkController from '../../../../app/scripts/controllers/network/network' -import PreferencesController from '../../../../app/scripts/controllers/preferences' -import { MAINNET, ROPSTEN } from '../../../../shared/constants/network' +import DetectTokensController from '../../../../app/scripts/controllers/detect-tokens'; +import NetworkController from '../../../../app/scripts/controllers/network/network'; +import PreferencesController from '../../../../app/scripts/controllers/preferences'; +import { MAINNET, ROPSTEN } from '../../../../shared/constants/network'; describe('DetectTokensController', function () { - const sandbox = sinon.createSandbox() - let keyringMemStore, network, preferences + const sandbox = sinon.createSandbox(); + let keyringMemStore, network, preferences; - const noop = () => undefined + const noop = () => undefined; const networkControllerProviderConfig = { getAccounts: noop, - } + }; beforeEach(async function () { - keyringMemStore = new ObservableStore({ isUnlocked: false }) - network = new NetworkController() - network.setInfuraProjectId('foo') - preferences = new PreferencesController({ network }) + keyringMemStore = new ObservableStore({ isUnlocked: false }); + network = new NetworkController(); + network.setInfuraProjectId('foo'); + preferences = new PreferencesController({ network }); preferences.setAddresses([ '0x7e57e2', '0xbc86727e770de68b1060c91f6bb6945c73e10388', - ]) - network.initializeProvider(networkControllerProviderConfig) - }) + ]); + network.initializeProvider(networkControllerProviderConfig); + }); after(function () { - sandbox.restore() - }) + sandbox.restore(); + }); it('should poll on correct interval', async function () { - const stub = sinon.stub(global, 'setInterval') - new DetectTokensController({ interval: 1337 }) // eslint-disable-line no-new - assert.strictEqual(stub.getCall(0).args[1], 1337) - stub.restore() - }) + const stub = sinon.stub(global, 'setInterval'); + new DetectTokensController({ interval: 1337 }); // eslint-disable-line no-new + assert.strictEqual(stub.getCall(0).args[1], 1337); + stub.restore(); + }); it('should be called on every polling period', async function () { - const clock = sandbox.useFakeTimers() - network.setProviderType(MAINNET) + const clock = sandbox.useFakeTimers(); + network.setProviderType(MAINNET); const controller = new DetectTokensController({ preferences, network, keyringMemStore, - }) - controller.isOpen = true - controller.isUnlocked = true - - const stub = sandbox.stub(controller, 'detectNewTokens') - - clock.tick(1) - sandbox.assert.notCalled(stub) - clock.tick(180000) - sandbox.assert.called(stub) - clock.tick(180000) - sandbox.assert.calledTwice(stub) - clock.tick(180000) - sandbox.assert.calledThrice(stub) - }) + }); + controller.isOpen = true; + controller.isUnlocked = true; + + const stub = sandbox.stub(controller, 'detectNewTokens'); + + clock.tick(1); + sandbox.assert.notCalled(stub); + clock.tick(180000); + sandbox.assert.called(stub); + clock.tick(180000); + sandbox.assert.calledTwice(stub); + clock.tick(180000); + sandbox.assert.calledThrice(stub); + }); it('should not check tokens while on test network', async function () { - sandbox.useFakeTimers() - network.setProviderType(ROPSTEN) + sandbox.useFakeTimers(); + network.setProviderType(ROPSTEN); const controller = new DetectTokensController({ preferences, network, keyringMemStore, - }) - controller.isOpen = true - controller.isUnlocked = true + }); + controller.isOpen = true; + controller.isUnlocked = true; - const stub = sandbox.stub(controller, '_getTokenBalances') + const stub = sandbox.stub(controller, '_getTokenBalances'); - await controller.detectNewTokens() - sandbox.assert.notCalled(stub) - }) + await controller.detectNewTokens(); + sandbox.assert.notCalled(stub); + }); it('should skip adding tokens listed in hiddenTokens array', async function () { - sandbox.useFakeTimers() - network.setProviderType(MAINNET) + sandbox.useFakeTimers(); + network.setProviderType(MAINNET); const controller = new DetectTokensController({ preferences, network, keyringMemStore, - }) - controller.isOpen = true - controller.isUnlocked = true + }); + controller.isOpen = true; + controller.isUnlocked = true; - const contractAddresses = Object.keys(contracts) + const contractAddresses = Object.keys(contracts); const erc20ContractAddresses = contractAddresses.filter( (contractAddress) => contracts[contractAddress].erc20 === true, - ) + ); - const existingTokenAddress = erc20ContractAddresses[0] - const existingToken = contracts[existingTokenAddress] + const existingTokenAddress = erc20ContractAddresses[0]; + const existingToken = contracts[existingTokenAddress]; await preferences.addToken( existingTokenAddress, existingToken.symbol, existingToken.decimals, - ) + ); - const tokenAddressToSkip = erc20ContractAddresses[1] + const tokenAddressToSkip = erc20ContractAddresses[1]; sandbox .stub(controller, '_getTokenBalances') @@ -114,11 +114,11 @@ describe('DetectTokensController', function () { tokensToDetect.map((token) => token === tokenAddressToSkip ? new BigNumber(10) : 0, ), - ) + ); - await preferences.removeToken(tokenAddressToSkip) + await preferences.removeToken(tokenAddressToSkip); - await controller.detectNewTokens() + await controller.detectNewTokens(); assert.deepEqual(preferences.store.getState().tokens, [ { @@ -126,51 +126,51 @@ describe('DetectTokensController', function () { decimals: existingToken.decimals, symbol: existingToken.symbol, }, - ]) - }) + ]); + }); it('should check and add tokens while on main network', async function () { - sandbox.useFakeTimers() - network.setProviderType(MAINNET) + sandbox.useFakeTimers(); + network.setProviderType(MAINNET); const controller = new DetectTokensController({ preferences, network, keyringMemStore, - }) - controller.isOpen = true - controller.isUnlocked = true + }); + controller.isOpen = true; + controller.isUnlocked = true; - const contractAddresses = Object.keys(contracts) + const contractAddresses = Object.keys(contracts); const erc20ContractAddresses = contractAddresses.filter( (contractAddress) => contracts[contractAddress].erc20 === true, - ) + ); - const existingTokenAddress = erc20ContractAddresses[0] - const existingToken = contracts[existingTokenAddress] + const existingTokenAddress = erc20ContractAddresses[0]; + const existingToken = contracts[existingTokenAddress]; await preferences.addToken( existingTokenAddress, existingToken.symbol, existingToken.decimals, - ) + ); - const tokenAddressToAdd = erc20ContractAddresses[1] - const tokenToAdd = contracts[tokenAddressToAdd] + const tokenAddressToAdd = erc20ContractAddresses[1]; + const tokenToAdd = contracts[tokenAddressToAdd]; const contractAddresssesToDetect = contractAddresses.filter( (address) => address !== existingTokenAddress, - ) + ); const indexOfTokenToAdd = contractAddresssesToDetect.indexOf( tokenAddressToAdd, - ) + ); - const balances = new Array(contractAddresssesToDetect.length) - balances[indexOfTokenToAdd] = new BigNumber(10) + const balances = new Array(contractAddresssesToDetect.length); + balances[indexOfTokenToAdd] = new BigNumber(10); sandbox .stub(controller, '_getTokenBalances') - .returns(Promise.resolve(balances)) + .returns(Promise.resolve(balances)); - await controller.detectNewTokens() + await controller.detectNewTokens(); assert.deepEqual(preferences.store.getState().tokens, [ { @@ -183,51 +183,51 @@ describe('DetectTokensController', function () { decimals: tokenToAdd.decimals, symbol: tokenToAdd.symbol, }, - ]) - }) + ]); + }); it('should check and add tokens while on non-default Mainnet', async function () { - sandbox.useFakeTimers() - network.setRpcTarget('https://some-fake-RPC-endpoint.metamask.io', '0x1') + sandbox.useFakeTimers(); + network.setRpcTarget('https://some-fake-RPC-endpoint.metamask.io', '0x1'); const controller = new DetectTokensController({ preferences, network, keyringMemStore, - }) - controller.isOpen = true - controller.isUnlocked = true + }); + controller.isOpen = true; + controller.isUnlocked = true; - const contractAddresses = Object.keys(contracts) + const contractAddresses = Object.keys(contracts); const erc20ContractAddresses = contractAddresses.filter( (contractAddress) => contracts[contractAddress].erc20 === true, - ) + ); - const existingTokenAddress = erc20ContractAddresses[0] - const existingToken = contracts[existingTokenAddress] + const existingTokenAddress = erc20ContractAddresses[0]; + const existingToken = contracts[existingTokenAddress]; await preferences.addToken( existingTokenAddress, existingToken.symbol, existingToken.decimals, - ) + ); - const tokenAddressToAdd = erc20ContractAddresses[1] - const tokenToAdd = contracts[tokenAddressToAdd] + const tokenAddressToAdd = erc20ContractAddresses[1]; + const tokenToAdd = contracts[tokenAddressToAdd]; const contractAddresssesToDetect = contractAddresses.filter( (address) => address !== existingTokenAddress, - ) + ); const indexOfTokenToAdd = contractAddresssesToDetect.indexOf( tokenAddressToAdd, - ) + ); - const balances = new Array(contractAddresssesToDetect.length) - balances[indexOfTokenToAdd] = new BigNumber(10) + const balances = new Array(contractAddresssesToDetect.length); + balances[indexOfTokenToAdd] = new BigNumber(10); sandbox .stub(controller, '_getTokenBalances') - .returns(Promise.resolve(balances)) + .returns(Promise.resolve(balances)); - await controller.detectNewTokens() + await controller.detectNewTokens(); assert.deepEqual(preferences.store.getState().tokens, [ { @@ -240,70 +240,70 @@ describe('DetectTokensController', function () { decimals: tokenToAdd.decimals, symbol: tokenToAdd.symbol, }, - ]) - }) + ]); + }); it('should trigger detect new tokens when change address', async function () { - sandbox.useFakeTimers() + sandbox.useFakeTimers(); const controller = new DetectTokensController({ preferences, network, keyringMemStore, - }) - controller.isOpen = true - controller.isUnlocked = true - const stub = sandbox.stub(controller, 'detectNewTokens') + }); + controller.isOpen = true; + controller.isUnlocked = true; + const stub = sandbox.stub(controller, 'detectNewTokens'); await preferences.setSelectedAddress( '0xbc86727e770de68b1060c91f6bb6945c73e10388', - ) - sandbox.assert.called(stub) - }) + ); + sandbox.assert.called(stub); + }); it('should trigger detect new tokens when submit password', async function () { - sandbox.useFakeTimers() + sandbox.useFakeTimers(); const controller = new DetectTokensController({ preferences, network, keyringMemStore, - }) - controller.isOpen = true - controller.selectedAddress = '0x0' - const stub = sandbox.stub(controller, 'detectNewTokens') - await controller._keyringMemStore.updateState({ isUnlocked: true }) - sandbox.assert.called(stub) - }) + }); + controller.isOpen = true; + controller.selectedAddress = '0x0'; + const stub = sandbox.stub(controller, 'detectNewTokens'); + await controller._keyringMemStore.updateState({ isUnlocked: true }); + sandbox.assert.called(stub); + }); it('should not trigger detect new tokens when not unlocked', async function () { - const clock = sandbox.useFakeTimers() - network.setProviderType(MAINNET) + const clock = sandbox.useFakeTimers(); + network.setProviderType(MAINNET); const controller = new DetectTokensController({ preferences, network, keyringMemStore, - }) - controller.isOpen = true - controller.isUnlocked = false - const stub = sandbox.stub(controller, '_getTokenBalances') - clock.tick(180000) - sandbox.assert.notCalled(stub) - }) + }); + controller.isOpen = true; + controller.isUnlocked = false; + const stub = sandbox.stub(controller, '_getTokenBalances'); + clock.tick(180000); + sandbox.assert.notCalled(stub); + }); it('should not trigger detect new tokens when not open', async function () { - const clock = sandbox.useFakeTimers() - network.setProviderType(MAINNET) + const clock = sandbox.useFakeTimers(); + network.setProviderType(MAINNET); const controller = new DetectTokensController({ preferences, network, keyringMemStore, - }) + }); // trigger state update from preferences controller await preferences.setSelectedAddress( '0xbc86727e770de68b1060c91f6bb6945c73e10388', - ) - controller.isOpen = false - controller.isUnlocked = true - const stub = sandbox.stub(controller, '_getTokenBalances') - clock.tick(180000) - sandbox.assert.notCalled(stub) - }) -}) + ); + controller.isOpen = false; + controller.isUnlocked = true; + const stub = sandbox.stub(controller, '_getTokenBalances'); + clock.tick(180000); + sandbox.assert.notCalled(stub); + }); +}); diff --git a/test/unit/app/controllers/ens-controller-test.js b/test/unit/app/controllers/ens-controller-test.js index dd116e69ff..c210fa3f84 100644 --- a/test/unit/app/controllers/ens-controller-test.js +++ b/test/unit/app/controllers/ens-controller-test.js @@ -1,119 +1,119 @@ -import assert from 'assert' -import sinon from 'sinon' -import { ObservableStore } from '@metamask/obs-store' -import EnsController from '../../../../app/scripts/controllers/ens' +import assert from 'assert'; +import sinon from 'sinon'; +import { ObservableStore } from '@metamask/obs-store'; +import EnsController from '../../../../app/scripts/controllers/ens'; -const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' -const ZERO_X_ERROR_ADDRESS = '0x' +const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; +const ZERO_X_ERROR_ADDRESS = '0x'; describe('EnsController', function () { describe('#constructor', function () { it('should construct the controller given a provider and a network', async function () { - const currentNetworkId = '3' - const networkStore = new ObservableStore(currentNetworkId) + const currentNetworkId = '3'; + const networkStore = new ObservableStore(currentNetworkId); const ens = new EnsController({ provider: {}, networkStore, - }) + }); - assert.ok(ens._ens) - }) + assert.ok(ens._ens); + }); it('should construct the controller given an existing ENS instance', async function () { const networkStore = { subscribe: sinon.spy(), - } + }; const ens = new EnsController({ ens: {}, networkStore, - }) + }); - assert.ok(ens._ens) - }) - }) + assert.ok(ens._ens); + }); + }); describe('#reverseResolveName', function () { it('should resolve to an ENS name', async function () { - const address = '0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5' + const address = '0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5'; const networkStore = { subscribe: sinon.spy(), - } + }; const ens = new EnsController({ ens: { reverse: sinon.stub().withArgs(address).returns('peaksignal.eth'), lookup: sinon.stub().withArgs('peaksignal.eth').returns(address), }, networkStore, - }) + }); - const name = await ens.reverseResolveAddress(address) - assert.equal(name, 'peaksignal.eth') - }) + const name = await ens.reverseResolveAddress(address); + assert.equal(name, 'peaksignal.eth'); + }); it('should only resolve an ENS name once', async function () { - const address = '0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5' - const reverse = sinon.stub().withArgs(address).returns('peaksignal.eth') - const lookup = sinon.stub().withArgs('peaksignal.eth').returns(address) + const address = '0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5'; + const reverse = sinon.stub().withArgs(address).returns('peaksignal.eth'); + const lookup = sinon.stub().withArgs('peaksignal.eth').returns(address); const networkStore = { subscribe: sinon.spy(), - } + }; const ens = new EnsController({ ens: { reverse, lookup, }, networkStore, - }) + }); - assert.equal(await ens.reverseResolveAddress(address), 'peaksignal.eth') - assert.equal(await ens.reverseResolveAddress(address), 'peaksignal.eth') - assert.ok(lookup.calledOnce) - assert.ok(reverse.calledOnce) - }) + assert.equal(await ens.reverseResolveAddress(address), 'peaksignal.eth'); + assert.equal(await ens.reverseResolveAddress(address), 'peaksignal.eth'); + assert.ok(lookup.calledOnce); + assert.ok(reverse.calledOnce); + }); it('should fail if the name is registered to a different address than the reverse-resolved', async function () { - const address = '0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5' + const address = '0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5'; const networkStore = { subscribe: sinon.spy(), - } + }; const ens = new EnsController({ ens: { reverse: sinon.stub().withArgs(address).returns('peaksignal.eth'), lookup: sinon.stub().withArgs('peaksignal.eth').returns('0xfoo'), }, networkStore, - }) + }); - const name = await ens.reverseResolveAddress(address) - assert.strictEqual(name, undefined) - }) + const name = await ens.reverseResolveAddress(address); + assert.strictEqual(name, undefined); + }); it('should throw an error when the lookup resolves to the zero address', async function () { - const address = '0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5' + const address = '0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5'; const networkStore = { subscribe: sinon.spy(), - } + }; const ens = new EnsController({ ens: { reverse: sinon.stub().withArgs(address).returns('peaksignal.eth'), lookup: sinon.stub().withArgs('peaksignal.eth').returns(ZERO_ADDRESS), }, networkStore, - }) + }); try { - await ens.reverseResolveAddress(address) - assert.fail('#reverseResolveAddress did not throw') + await ens.reverseResolveAddress(address); + assert.fail('#reverseResolveAddress did not throw'); } catch (e) { - assert.ok(e) + assert.ok(e); } - }) + }); it('should throw an error the lookup resolves to the zero x address', async function () { - const address = '0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5' + const address = '0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5'; const networkStore = { subscribe: sinon.spy(), - } + }; const ens = new EnsController({ ens: { reverse: sinon.stub().withArgs(address).returns('peaksignal.eth'), @@ -123,14 +123,14 @@ describe('EnsController', function () { .returns(ZERO_X_ERROR_ADDRESS), }, networkStore, - }) + }); try { - await ens.reverseResolveAddress(address) - assert.fail('#reverseResolveAddress did not throw') + await ens.reverseResolveAddress(address); + assert.fail('#reverseResolveAddress did not throw'); } catch (e) { - assert.ok(e) + assert.ok(e); } - }) - }) -}) + }); + }); +}); diff --git a/test/unit/app/controllers/incoming-transactions-test.js b/test/unit/app/controllers/incoming-transactions-test.js index af8ac10845..86e629609f 100644 --- a/test/unit/app/controllers/incoming-transactions-test.js +++ b/test/unit/app/controllers/incoming-transactions-test.js @@ -1,10 +1,10 @@ -import assert from 'assert' -import sinon from 'sinon' -import proxyquire from 'proxyquire' -import nock from 'nock' -import { cloneDeep } from 'lodash' +import assert from 'assert'; +import sinon from 'sinon'; +import proxyquire from 'proxyquire'; +import nock from 'nock'; +import { cloneDeep } from 'lodash'; -import waitUntilCalled from '../../../lib/wait-until-called' +import waitUntilCalled from '../../../lib/wait-until-called'; import { GOERLI, KOVAN, @@ -14,22 +14,22 @@ import { ROPSTEN, ROPSTEN_CHAIN_ID, ROPSTEN_NETWORK_ID, -} from '../../../../shared/constants/network' +} from '../../../../shared/constants/network'; import { TRANSACTION_CATEGORIES, TRANSACTION_STATUSES, -} from '../../../../shared/constants/transaction' +} from '../../../../shared/constants/transaction'; const IncomingTransactionsController = proxyquire( '../../../../app/scripts/controllers/incoming-transactions', { '../lib/random-id': { default: () => 54321 }, }, -).default +).default; -const FAKE_CHAIN_ID = '0x1338' -const MOCK_SELECTED_ADDRESS = '0x0101' -const SET_STATE_TIMEOUT = 10 +const FAKE_CHAIN_ID = '0x1338'; +const MOCK_SELECTED_ADDRESS = '0x0101'; +const SET_STATE_TIMEOUT = 10; function getEmptyInitState() { return { @@ -41,7 +41,7 @@ function getEmptyInitState() { [RINKEBY]: null, [ROPSTEN]: null, }, - } + }; } function getNonEmptyInitState() { @@ -56,14 +56,14 @@ function getNonEmptyInitState() { [RINKEBY]: 5, [ROPSTEN]: 4, }, - } + }; } function getMockNetworkController(chainId = FAKE_CHAIN_ID) { return { getCurrentChainId: () => chainId, on: sinon.spy(), - } + }; } function getMockPreferencesController({ @@ -79,7 +79,7 @@ function getMockPreferencesController({ }), subscribe: sinon.spy(), }, - } + }; } function getMockBlockTracker() { @@ -88,7 +88,7 @@ function getMockBlockTracker() { removeListener: sinon.spy(), testProperty: 'fakeBlockTracker', getCurrentBlock: () => '0xa', - } + }; } /** @@ -132,14 +132,14 @@ const getFakeEtherscanTransaction = ( timeStamp: '16000000000000', to: toAddress, value: '0', - } -} + }; +}; describe('IncomingTransactionsController', function () { afterEach(function () { - sinon.restore() - nock.cleanAll() - }) + sinon.restore(); + nock.cleanAll(); + }); describe('constructor', function () { it('should set up correct store, listeners and properties in the constructor', function () { @@ -150,34 +150,34 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: {}, }, - ) - sinon.spy(incomingTransactionsController, '_update') + ); + sinon.spy(incomingTransactionsController, '_update'); assert.deepEqual( incomingTransactionsController.store.getState(), getEmptyInitState(), - ) + ); - assert(incomingTransactionsController.networkController.on.calledOnce) + assert(incomingTransactionsController.networkController.on.calledOnce); assert.equal( incomingTransactionsController.networkController.on.getCall(0).args[0], 'networkDidChange', - ) + ); const networkControllerListenerCallback = incomingTransactionsController.networkController.on.getCall( 0, - ).args[1] - assert.equal(incomingTransactionsController._update.callCount, 0) - networkControllerListenerCallback('testNetworkType') - assert.equal(incomingTransactionsController._update.callCount, 1) + ).args[1]; + assert.equal(incomingTransactionsController._update.callCount, 0); + networkControllerListenerCallback('testNetworkType'); + assert.equal(incomingTransactionsController._update.callCount, 1); assert.deepEqual( incomingTransactionsController._update.getCall(0).args[0], { address: '0x0101', }, - ) + ); - incomingTransactionsController._update.resetHistory() - }) + incomingTransactionsController._update.resetHistory(); + }); it('should set the store to a provided initial state', function () { const incomingTransactionsController = new IncomingTransactionsController( @@ -187,14 +187,14 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) + ); assert.deepEqual( incomingTransactionsController.store.getState(), getNonEmptyInitState(), - ) - }) - }) + ); + }); + }); describe('update events', function () { it('should set up a listener for the latest block', async function () { @@ -205,17 +205,19 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: {}, }, - ) + ); - incomingTransactionsController.start() + incomingTransactionsController.start(); - assert(incomingTransactionsController.blockTracker.addListener.calledOnce) + assert( + incomingTransactionsController.blockTracker.addListener.calledOnce, + ); assert.equal( incomingTransactionsController.blockTracker.addListener.getCall(0) .args[0], 'latest', - ) - }) + ); + }); it('should update upon latest block when started and on supported network', async function () { const incomingTransactionsController = new IncomingTransactionsController( @@ -225,9 +227,9 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) + ); const startBlock = getNonEmptyInitState() - .incomingTxLastFetchedBlocksByNetwork[ROPSTEN] + .incomingTxLastFetchedBlocksByNetwork[ROPSTEN]; nock('https://api-ropsten.etherscan.io') .get( `/api?module=account&action=txlist&address=${MOCK_SELECTED_ADDRESS}&tag=latest&page=1&startBlock=${startBlock}`, @@ -238,29 +240,29 @@ describe('IncomingTransactionsController', function () { status: '1', result: [getFakeEtherscanTransaction()], }), - ) + ); const updateStateStub = sinon.stub( incomingTransactionsController.store, 'updateState', - ) + ); const updateStateCalled = waitUntilCalled( updateStateStub, incomingTransactionsController.store, - ) + ); - incomingTransactionsController.start() - await updateStateCalled() + incomingTransactionsController.start(); + await updateStateCalled(); - const actualState = incomingTransactionsController.store.getState() - const generatedTxId = actualState?.incomingTransactions?.['0xfake']?.id + const actualState = incomingTransactionsController.store.getState(); + const generatedTxId = actualState?.incomingTransactions?.['0xfake']?.id; - const actualStateWithoutGenerated = cloneDeep(actualState) - delete actualStateWithoutGenerated?.incomingTransactions?.['0xfake']?.id + const actualStateWithoutGenerated = cloneDeep(actualState); + delete actualStateWithoutGenerated?.incomingTransactions?.['0xfake']?.id; assert.ok( typeof generatedTxId === 'number' && generatedTxId > 0, 'Generated transaction ID should be a positive number', - ) + ); assert.deepStrictEqual( actualStateWithoutGenerated, { @@ -289,8 +291,8 @@ describe('IncomingTransactionsController', function () { }, }, 'State should have been updated after first block was received', - ) - }) + ); + }); it('should not update upon latest block when started and not on supported network', async function () { const incomingTransactionsController = new IncomingTransactionsController( @@ -300,7 +302,7 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) + ); // reply with a valid request for any supported network, so that this test has every opportunity to fail for (const network of [ GOERLI, @@ -322,40 +324,40 @@ describe('IncomingTransactionsController', function () { status: '1', result: [getFakeEtherscanTransaction()], }), - ) + ); } const updateStateStub = sinon.stub( incomingTransactionsController.store, 'updateState', - ) + ); const updateStateCalled = waitUntilCalled( updateStateStub, incomingTransactionsController.store, - ) + ); const putStateStub = sinon.stub( incomingTransactionsController.store, 'putState', - ) + ); const putStateCalled = waitUntilCalled( putStateStub, incomingTransactionsController.store, - ) + ); - incomingTransactionsController.start() + incomingTransactionsController.start(); try { await Promise.race([ updateStateCalled(), putStateCalled(), new Promise((_, reject) => { - setTimeout(() => reject(new Error('TIMEOUT')), SET_STATE_TIMEOUT) + setTimeout(() => reject(new Error('TIMEOUT')), SET_STATE_TIMEOUT); }), - ]) - assert.fail('Update state should not have been called') + ]); + assert.fail('Update state should not have been called'); } catch (error) { - assert(error.message === 'TIMEOUT', 'TIMEOUT error should be thrown') + assert(error.message === 'TIMEOUT', 'TIMEOUT error should be thrown'); } - }) + }); it('should not update upon latest block when started and incoming transactions disabled', async function () { const incomingTransactionsController = new IncomingTransactionsController( @@ -367,7 +369,7 @@ describe('IncomingTransactionsController', function () { }), initState: getNonEmptyInitState(), }, - ) + ); // reply with a valid request for any supported network, so that this test has every opportunity to fail for (const network of [ GOERLI, @@ -389,40 +391,40 @@ describe('IncomingTransactionsController', function () { status: '1', result: [getFakeEtherscanTransaction()], }), - ) + ); } const updateStateStub = sinon.stub( incomingTransactionsController.store, 'updateState', - ) + ); const updateStateCalled = waitUntilCalled( updateStateStub, incomingTransactionsController.store, - ) + ); const putStateStub = sinon.stub( incomingTransactionsController.store, 'putState', - ) + ); const putStateCalled = waitUntilCalled( putStateStub, incomingTransactionsController.store, - ) + ); - incomingTransactionsController.start() + incomingTransactionsController.start(); try { await Promise.race([ updateStateCalled(), putStateCalled(), new Promise((_, reject) => { - setTimeout(() => reject(new Error('TIMEOUT')), SET_STATE_TIMEOUT) + setTimeout(() => reject(new Error('TIMEOUT')), SET_STATE_TIMEOUT); }), - ]) - assert.fail('Update state should not have been called') + ]); + assert.fail('Update state should not have been called'); } catch (error) { - assert(error.message === 'TIMEOUT', 'TIMEOUT error should be thrown') + assert(error.message === 'TIMEOUT', 'TIMEOUT error should be thrown'); } - }) + }); it('should not update upon latest block when not started', async function () { const incomingTransactionsController = new IncomingTransactionsController( @@ -432,7 +434,7 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) + ); // reply with a valid request for any supported network, so that this test has every opportunity to fail for (const network of [ GOERLI, @@ -454,38 +456,38 @@ describe('IncomingTransactionsController', function () { status: '1', result: [getFakeEtherscanTransaction()], }), - ) + ); } const updateStateStub = sinon.stub( incomingTransactionsController.store, 'updateState', - ) + ); const updateStateCalled = waitUntilCalled( updateStateStub, incomingTransactionsController.store, - ) + ); const putStateStub = sinon.stub( incomingTransactionsController.store, 'putState', - ) + ); const putStateCalled = waitUntilCalled( putStateStub, incomingTransactionsController.store, - ) + ); try { await Promise.race([ updateStateCalled(), putStateCalled(), new Promise((_, reject) => { - setTimeout(() => reject(new Error('TIMEOUT')), SET_STATE_TIMEOUT) + setTimeout(() => reject(new Error('TIMEOUT')), SET_STATE_TIMEOUT); }), - ]) - assert.fail('Update state should not have been called') + ]); + assert.fail('Update state should not have been called'); } catch (error) { - assert(error.message === 'TIMEOUT', 'TIMEOUT error should be thrown') + assert(error.message === 'TIMEOUT', 'TIMEOUT error should be thrown'); } - }) + }); it('should not update upon latest block when stopped', async function () { const incomingTransactionsController = new IncomingTransactionsController( @@ -495,7 +497,7 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) + ); // reply with a valid request for any supported network, so that this test has every opportunity to fail for (const network of [ GOERLI, @@ -517,40 +519,40 @@ describe('IncomingTransactionsController', function () { status: '1', result: [getFakeEtherscanTransaction()], }), - ) + ); } const updateStateStub = sinon.stub( incomingTransactionsController.store, 'updateState', - ) + ); const updateStateCalled = waitUntilCalled( updateStateStub, incomingTransactionsController.store, - ) + ); const putStateStub = sinon.stub( incomingTransactionsController.store, 'putState', - ) + ); const putStateCalled = waitUntilCalled( putStateStub, incomingTransactionsController.store, - ) + ); - incomingTransactionsController.stop() + incomingTransactionsController.stop(); try { await Promise.race([ updateStateCalled(), putStateCalled(), new Promise((_, reject) => { - setTimeout(() => reject(new Error('TIMEOUT')), SET_STATE_TIMEOUT) + setTimeout(() => reject(new Error('TIMEOUT')), SET_STATE_TIMEOUT); }), - ]) - assert.fail('Update state should not have been called') + ]); + assert.fail('Update state should not have been called'); } catch (error) { - assert(error.message === 'TIMEOUT', 'TIMEOUT error should be thrown') + assert(error.message === 'TIMEOUT', 'TIMEOUT error should be thrown'); } - }) + }); it('should update when the selected address changes and on supported network', async function () { const incomingTransactionsController = new IncomingTransactionsController( @@ -560,10 +562,10 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) - const NEW_MOCK_SELECTED_ADDRESS = `${MOCK_SELECTED_ADDRESS}9` + ); + const NEW_MOCK_SELECTED_ADDRESS = `${MOCK_SELECTED_ADDRESS}9`; const startBlock = getNonEmptyInitState() - .incomingTxLastFetchedBlocksByNetwork[ROPSTEN] + .incomingTxLastFetchedBlocksByNetwork[ROPSTEN]; nock('https://api-ropsten.etherscan.io') .get( `/api?module=account&action=txlist&address=${NEW_MOCK_SELECTED_ADDRESS}&tag=latest&page=1&startBlock=${startBlock}`, @@ -574,36 +576,36 @@ describe('IncomingTransactionsController', function () { status: '1', result: [getFakeEtherscanTransaction(NEW_MOCK_SELECTED_ADDRESS)], }), - ) + ); const updateStateStub = sinon.stub( incomingTransactionsController.store, 'updateState', - ) + ); const updateStateCalled = waitUntilCalled( updateStateStub, incomingTransactionsController.store, - ) + ); const subscription = incomingTransactionsController.preferencesController.store.subscribe.getCall( 1, - ).args[0] + ).args[0]; // The incoming transactions controller will always skip the first event // We need to call subscription twice to test the event handling // TODO: stop skipping the first event - await subscription({ selectedAddress: MOCK_SELECTED_ADDRESS }) - await subscription({ selectedAddress: NEW_MOCK_SELECTED_ADDRESS }) - await updateStateCalled() + await subscription({ selectedAddress: MOCK_SELECTED_ADDRESS }); + await subscription({ selectedAddress: NEW_MOCK_SELECTED_ADDRESS }); + await updateStateCalled(); - const actualState = incomingTransactionsController.store.getState() - const generatedTxId = actualState?.incomingTransactions?.['0xfake']?.id + const actualState = incomingTransactionsController.store.getState(); + const generatedTxId = actualState?.incomingTransactions?.['0xfake']?.id; - const actualStateWithoutGenerated = cloneDeep(actualState) - delete actualStateWithoutGenerated?.incomingTransactions?.['0xfake']?.id + const actualStateWithoutGenerated = cloneDeep(actualState); + delete actualStateWithoutGenerated?.incomingTransactions?.['0xfake']?.id; assert.ok( typeof generatedTxId === 'number' && generatedTxId > 0, 'Generated transaction ID should be a positive number', - ) + ); assert.deepStrictEqual( actualStateWithoutGenerated, { @@ -632,8 +634,8 @@ describe('IncomingTransactionsController', function () { }, }, 'State should have been updated after first block was received', - ) - }) + ); + }); it('should not update when the selected address changes and not on supported network', async function () { const incomingTransactionsController = new IncomingTransactionsController( @@ -643,8 +645,8 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) - const NEW_MOCK_SELECTED_ADDRESS = `${MOCK_SELECTED_ADDRESS}9` + ); + const NEW_MOCK_SELECTED_ADDRESS = `${MOCK_SELECTED_ADDRESS}9`; // reply with a valid request for any supported network, so that this test has every opportunity to fail for (const network of [ GOERLI, @@ -666,47 +668,47 @@ describe('IncomingTransactionsController', function () { status: '1', result: [getFakeEtherscanTransaction(NEW_MOCK_SELECTED_ADDRESS)], }), - ) + ); } const updateStateStub = sinon.stub( incomingTransactionsController.store, 'updateState', - ) + ); const updateStateCalled = waitUntilCalled( updateStateStub, incomingTransactionsController.store, - ) + ); const putStateStub = sinon.stub( incomingTransactionsController.store, 'putState', - ) + ); const putStateCalled = waitUntilCalled( putStateStub, incomingTransactionsController.store, - ) + ); const subscription = incomingTransactionsController.preferencesController.store.subscribe.getCall( 1, - ).args[0] + ).args[0]; // The incoming transactions controller will always skip the first event // We need to call subscription twice to test the event handling // TODO: stop skipping the first event - await subscription({ selectedAddress: MOCK_SELECTED_ADDRESS }) - await subscription({ selectedAddress: NEW_MOCK_SELECTED_ADDRESS }) + await subscription({ selectedAddress: MOCK_SELECTED_ADDRESS }); + await subscription({ selectedAddress: NEW_MOCK_SELECTED_ADDRESS }); try { await Promise.race([ updateStateCalled(), putStateCalled(), new Promise((_, reject) => { - setTimeout(() => reject(new Error('TIMEOUT')), SET_STATE_TIMEOUT) + setTimeout(() => reject(new Error('TIMEOUT')), SET_STATE_TIMEOUT); }), - ]) - assert.fail('Update state should not have been called') + ]); + assert.fail('Update state should not have been called'); } catch (error) { - assert(error.message === 'TIMEOUT', 'TIMEOUT error should be thrown') + assert(error.message === 'TIMEOUT', 'TIMEOUT error should be thrown'); } - }) + }); it('should update when switching to a supported network', async function () { const incomingTransactionsController = new IncomingTransactionsController( @@ -716,9 +718,9 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) + ); const startBlock = getNonEmptyInitState() - .incomingTxLastFetchedBlocksByNetwork[ROPSTEN] + .incomingTxLastFetchedBlocksByNetwork[ROPSTEN]; nock('https://api-ropsten.etherscan.io') .get( `/api?module=account&action=txlist&address=${MOCK_SELECTED_ADDRESS}&tag=latest&page=1&startBlock=${startBlock}`, @@ -729,35 +731,35 @@ describe('IncomingTransactionsController', function () { status: '1', result: [getFakeEtherscanTransaction()], }), - ) + ); const updateStateStub = sinon.stub( incomingTransactionsController.store, 'updateState', - ) + ); const updateStateCalled = waitUntilCalled( updateStateStub, incomingTransactionsController.store, - ) + ); const subscription = incomingTransactionsController.networkController.on.getCall( 0, - ).args[1] + ).args[1]; incomingTransactionsController.networkController = getMockNetworkController( ROPSTEN_CHAIN_ID, - ) - await subscription(ROPSTEN) - await updateStateCalled() + ); + await subscription(ROPSTEN); + await updateStateCalled(); - const actualState = incomingTransactionsController.store.getState() - const generatedTxId = actualState?.incomingTransactions?.['0xfake']?.id + const actualState = incomingTransactionsController.store.getState(); + const generatedTxId = actualState?.incomingTransactions?.['0xfake']?.id; - const actualStateWithoutGenerated = cloneDeep(actualState) - delete actualStateWithoutGenerated?.incomingTransactions?.['0xfake']?.id + const actualStateWithoutGenerated = cloneDeep(actualState); + delete actualStateWithoutGenerated?.incomingTransactions?.['0xfake']?.id; assert.ok( typeof generatedTxId === 'number' && generatedTxId > 0, 'Generated transaction ID should be a positive number', - ) + ); assert.deepStrictEqual( actualStateWithoutGenerated, { @@ -786,11 +788,11 @@ describe('IncomingTransactionsController', function () { }, }, 'State should have been updated after first block was received', - ) - }) + ); + }); it('should not update when switching to an unsupported network', async function () { - const networkController = getMockNetworkController(ROPSTEN_CHAIN_ID) + const networkController = getMockNetworkController(ROPSTEN_CHAIN_ID); const incomingTransactionsController = new IncomingTransactionsController( { blockTracker: getMockBlockTracker(), @@ -798,7 +800,7 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) + ); // reply with a valid request for any supported network, so that this test has every opportunity to fail for (const network of [ GOERLI, @@ -820,46 +822,46 @@ describe('IncomingTransactionsController', function () { status: '1', result: [getFakeEtherscanTransaction()], }), - ) + ); } const updateStateStub = sinon.stub( incomingTransactionsController.store, 'updateState', - ) + ); const updateStateCalled = waitUntilCalled( updateStateStub, incomingTransactionsController.store, - ) + ); const putStateStub = sinon.stub( incomingTransactionsController.store, 'putState', - ) + ); const putStateCalled = waitUntilCalled( putStateStub, incomingTransactionsController.store, - ) + ); const subscription = incomingTransactionsController.networkController.on.getCall( 0, - ).args[1] + ).args[1]; - networkController.getCurrentChainId = () => FAKE_CHAIN_ID - await subscription() + networkController.getCurrentChainId = () => FAKE_CHAIN_ID; + await subscription(); try { await Promise.race([ updateStateCalled(), putStateCalled(), new Promise((_, reject) => { - setTimeout(() => reject(new Error('TIMEOUT')), SET_STATE_TIMEOUT) + setTimeout(() => reject(new Error('TIMEOUT')), SET_STATE_TIMEOUT); }), - ]) - assert.fail('Update state should not have been called') + ]); + assert.fail('Update state should not have been called'); } catch (error) { - assert(error.message === 'TIMEOUT', 'TIMEOUT error should be thrown') + assert(error.message === 'TIMEOUT', 'TIMEOUT error should be thrown'); } - }) - }) + }); + }); describe('_getDataForUpdate', function () { it('should call fetchAll with the correct params when passed a new block number and the current network has no stored block', async function () { @@ -870,22 +872,22 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getEmptyInitState(), }, - ) - incomingTransactionsController._fetchAll = sinon.stub().returns({}) + ); + incomingTransactionsController._fetchAll = sinon.stub().returns({}); await incomingTransactionsController._getDataForUpdate({ address: 'fakeAddress', chainId: ROPSTEN_CHAIN_ID, newBlockNumberDec: 999, - }) + }); - assert(incomingTransactionsController._fetchAll.calledOnce) + assert(incomingTransactionsController._fetchAll.calledOnce); assert.deepEqual( incomingTransactionsController._fetchAll.getCall(0).args, ['fakeAddress', 999, ROPSTEN_CHAIN_ID], - ) - }) + ); + }); it('should call fetchAll with the correct params when passed a new block number but the current network has a stored block', async function () { const incomingTransactionsController = new IncomingTransactionsController( @@ -895,22 +897,22 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) - incomingTransactionsController._fetchAll = sinon.stub().returns({}) + ); + incomingTransactionsController._fetchAll = sinon.stub().returns({}); await incomingTransactionsController._getDataForUpdate({ address: 'fakeAddress', chainId: ROPSTEN_CHAIN_ID, newBlockNumberDec: 999, - }) + }); - assert(incomingTransactionsController._fetchAll.calledOnce) + assert(incomingTransactionsController._fetchAll.calledOnce); assert.deepEqual( incomingTransactionsController._fetchAll.getCall(0).args, ['fakeAddress', 4, ROPSTEN_CHAIN_ID], - ) - }) + ); + }); it('should return the expected data', async function () { const incomingTransactionsController = new IncomingTransactionsController( @@ -920,16 +922,16 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) + ); incomingTransactionsController._fetchAll = sinon.stub().returns({ latestIncomingTxBlockNumber: 444, txs: [{ id: 555 }], - }) + }); const result = await incomingTransactionsController._getDataForUpdate({ address: 'fakeAddress', chainId: ROPSTEN_CHAIN_ID, - }) + }); assert.deepEqual(result, { latestIncomingTxBlockNumber: 444, @@ -946,9 +948,9 @@ describe('IncomingTransactionsController', function () { }, fetchedBlockNumber: 4, chainId: ROPSTEN_CHAIN_ID, - }) - }) - }) + }); + }); + }); describe('_updateStateWithNewTxData', function () { const MOCK_INPUT_WITHOUT_LASTEST = { @@ -965,12 +967,12 @@ describe('IncomingTransactionsController', function () { }, fetchedBlockNumber: 1111, chainId: ROPSTEN_CHAIN_ID, - } + }; const MOCK_INPUT_WITH_LASTEST = { ...MOCK_INPUT_WITHOUT_LASTEST, latestIncomingTxBlockNumber: 444, - } + }; it('should update state with correct blockhash and transactions when passed a truthy latestIncomingTxBlockNumber', async function () { const incomingTransactionsController = new IncomingTransactionsController( @@ -980,14 +982,14 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) - sinon.spy(incomingTransactionsController.store, 'updateState') + ); + sinon.spy(incomingTransactionsController.store, 'updateState'); await incomingTransactionsController._updateStateWithNewTxData( MOCK_INPUT_WITH_LASTEST, - ) + ); - assert(incomingTransactionsController.store.updateState.calledOnce) + assert(incomingTransactionsController.store.updateState.calledOnce); assert.deepEqual( incomingTransactionsController.store.updateState.getCall(0).args[0], @@ -1001,8 +1003,8 @@ describe('IncomingTransactionsController', function () { '0xfff': { id: 555, hash: '0xfff' }, }, }, - ) - }) + ); + }); it('should update state with correct blockhash and transactions when passed a falsy latestIncomingTxBlockNumber', async function () { const incomingTransactionsController = new IncomingTransactionsController( @@ -1012,14 +1014,14 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) - sinon.spy(incomingTransactionsController.store, 'updateState') + ); + sinon.spy(incomingTransactionsController.store, 'updateState'); await incomingTransactionsController._updateStateWithNewTxData( MOCK_INPUT_WITHOUT_LASTEST, - ) + ); - assert(incomingTransactionsController.store.updateState.calledOnce) + assert(incomingTransactionsController.store.updateState.calledOnce); assert.deepEqual( incomingTransactionsController.store.updateState.getCall(0).args[0], @@ -1033,26 +1035,26 @@ describe('IncomingTransactionsController', function () { '0xfff': { id: 555, hash: '0xfff' }, }, }, - ) - }) - }) + ); + }); + }); describe('_fetchTxs', function () { const mockFetch = sinon.stub().returns( Promise.resolve({ json: () => Promise.resolve({ someKey: 'someValue' }), }), - ) - let tempFetch + ); + let tempFetch; beforeEach(function () { - tempFetch = window.fetch - window.fetch = mockFetch - }) + tempFetch = window.fetch; + window.fetch = mockFetch; + }); afterEach(function () { - window.fetch = tempFetch - mockFetch.resetHistory() - }) + window.fetch = tempFetch; + mockFetch.resetHistory(); + }); it('should call fetch with the expected url when passed an address, block number and supported network', async function () { const incomingTransactionsController = new IncomingTransactionsController( @@ -1062,20 +1064,20 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) + ); await incomingTransactionsController._fetchTxs( '0xfakeaddress', '789', ROPSTEN_CHAIN_ID, - ) + ); - assert(mockFetch.calledOnce) + assert(mockFetch.calledOnce); assert.equal( mockFetch.getCall(0).args[0], `https://api-${ROPSTEN}.etherscan.io/api?module=account&action=txlist&address=0xfakeaddress&tag=latest&page=1&startBlock=789`, - ) - }) + ); + }); it('should call fetch with the expected url when passed an address, block number and MAINNET', async function () { const incomingTransactionsController = new IncomingTransactionsController( @@ -1085,20 +1087,20 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) + ); await incomingTransactionsController._fetchTxs( '0xfakeaddress', '789', MAINNET_CHAIN_ID, - ) + ); - assert(mockFetch.calledOnce) + assert(mockFetch.calledOnce); assert.equal( mockFetch.getCall(0).args[0], `https://api.etherscan.io/api?module=account&action=txlist&address=0xfakeaddress&tag=latest&page=1&startBlock=789`, - ) - }) + ); + }); it('should call fetch with the expected url when passed an address and supported network, but a falsy block number', async function () { const incomingTransactionsController = new IncomingTransactionsController( @@ -1108,20 +1110,20 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) + ); await incomingTransactionsController._fetchTxs( '0xfakeaddress', null, ROPSTEN_CHAIN_ID, - ) + ); - assert(mockFetch.calledOnce) + assert(mockFetch.calledOnce); assert.equal( mockFetch.getCall(0).args[0], `https://api-${ROPSTEN}.etherscan.io/api?module=account&action=txlist&address=0xfakeaddress&tag=latest&page=1`, - ) - }) + ); + }); it('should return the results from the fetch call, plus the address and currentNetworkID, when passed an address, block number and supported network', async function () { const incomingTransactionsController = new IncomingTransactionsController( @@ -1131,22 +1133,22 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) + ); const result = await incomingTransactionsController._fetchTxs( '0xfakeaddress', '789', ROPSTEN_CHAIN_ID, - ) + ); - assert(mockFetch.calledOnce) + assert(mockFetch.calledOnce); assert.deepEqual(result, { someKey: 'someValue', address: '0xfakeaddress', chainId: ROPSTEN_CHAIN_ID, - }) - }) - }) + }); + }); + }); describe('_processTxFetchResponse', function () { it('should return a null block number and empty tx array if status is 0', function () { @@ -1157,19 +1159,19 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) + ); const result = incomingTransactionsController._processTxFetchResponse({ status: '0', result: [{ id: 1 }], address: '0xfakeaddress', - }) + }); assert.deepEqual(result, { latestIncomingTxBlockNumber: null, txs: [], - }) - }) + }); + }); it('should return a null block number and empty tx array if the passed result array is empty', function () { const incomingTransactionsController = new IncomingTransactionsController( @@ -1179,19 +1181,19 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) + ); const result = incomingTransactionsController._processTxFetchResponse({ status: '1', result: [], address: '0xfakeaddress', - }) + }); assert.deepEqual(result, { latestIncomingTxBlockNumber: null, txs: [], - }) - }) + }); + }); it('should return the expected block number and tx list when passed data from a successful fetch', function () { const incomingTransactionsController = new IncomingTransactionsController( @@ -1201,13 +1203,13 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) + ); incomingTransactionsController._normalizeTxFromEtherscan = (tx) => ({ ...tx, currentNetworkID: ROPSTEN_NETWORK_ID, normalized: true, - }) + }); const result = incomingTransactionsController._processTxFetchResponse({ status: '1', @@ -1263,7 +1265,7 @@ describe('IncomingTransactionsController', function () { time: 13, }, ], - }) + }); assert.deepEqual(result, { latestIncomingTxBlockNumber: 5001, @@ -1309,9 +1311,9 @@ describe('IncomingTransactionsController', function () { currentNetworkID: ROPSTEN_NETWORK_ID, }, ], - }) - }) - }) + }); + }); + }); describe('_normalizeTxFromEtherscan', function () { it('should return the expected data when the tx is in error', function () { @@ -1322,7 +1324,7 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) + ); const result = incomingTransactionsController._normalizeTxFromEtherscan( { @@ -1338,7 +1340,7 @@ describe('IncomingTransactionsController', function () { hash: '0xg', }, ROPSTEN_CHAIN_ID, - ) + ); assert.deepEqual(result, { blockNumber: 333, @@ -1356,8 +1358,8 @@ describe('IncomingTransactionsController', function () { }, hash: '0xg', transactionCategory: TRANSACTION_CATEGORIES.INCOMING, - }) - }) + }); + }); it('should return the expected data when the tx is not in error', function () { const incomingTransactionsController = new IncomingTransactionsController( @@ -1367,7 +1369,7 @@ describe('IncomingTransactionsController', function () { preferencesController: getMockPreferencesController(), initState: getNonEmptyInitState(), }, - ) + ); const result = incomingTransactionsController._normalizeTxFromEtherscan( { @@ -1383,7 +1385,7 @@ describe('IncomingTransactionsController', function () { hash: '0xg', }, ROPSTEN_CHAIN_ID, - ) + ); assert.deepEqual(result, { blockNumber: 333, @@ -1401,7 +1403,7 @@ describe('IncomingTransactionsController', function () { }, hash: '0xg', transactionCategory: TRANSACTION_CATEGORIES.INCOMING, - }) - }) - }) -}) + }); + }); + }); +}); diff --git a/test/unit/app/controllers/metamask-controller-test.js b/test/unit/app/controllers/metamask-controller-test.js index 2e1c4021df..ab7d9d85fa 100644 --- a/test/unit/app/controllers/metamask-controller-test.js +++ b/test/unit/app/controllers/metamask-controller-test.js @@ -1,33 +1,33 @@ -import assert from 'assert' -import sinon from 'sinon' -import { cloneDeep } from 'lodash' -import nock from 'nock' -import ethUtil from 'ethereumjs-util' -import { obj as createThoughStream } from 'through2' -import EthQuery from 'eth-query' -import proxyquire from 'proxyquire' -import firstTimeState from '../../localhostState' -import createTxMeta from '../../../lib/createTxMeta' -import { addHexPrefix } from '../../../../app/scripts/lib/util' -import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction' +import assert from 'assert'; +import sinon from 'sinon'; +import { cloneDeep } from 'lodash'; +import nock from 'nock'; +import ethUtil from 'ethereumjs-util'; +import { obj as createThoughStream } from 'through2'; +import EthQuery from 'eth-query'; +import proxyquire from 'proxyquire'; +import firstTimeState from '../../localhostState'; +import createTxMeta from '../../../lib/createTxMeta'; +import { addHexPrefix } from '../../../../app/scripts/lib/util'; +import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'; const threeBoxSpies = { init: sinon.stub(), getThreeBoxSyncingState: sinon.stub().returns(true), turnThreeBoxSyncingOn: sinon.stub(), _registerUpdates: sinon.spy(), -} +}; class ThreeBoxControllerMock { constructor() { this.store = { subscribe: () => undefined, getState: () => ({}), - } - this.init = threeBoxSpies.init - this.getThreeBoxSyncingState = threeBoxSpies.getThreeBoxSyncingState - this.turnThreeBoxSyncingOn = threeBoxSpies.turnThreeBoxSyncingOn - this._registerUpdates = threeBoxSpies._registerUpdates + }; + this.init = threeBoxSpies.init; + this.getThreeBoxSyncingState = threeBoxSpies.getThreeBoxSyncingState; + this.turnThreeBoxSyncingOn = threeBoxSpies.turnThreeBoxSyncingOn; + this._registerUpdates = threeBoxSpies._registerUpdates; } } @@ -38,30 +38,30 @@ const ExtensionizerMock = { addListener: () => undefined, }, }, -} +}; -let loggerMiddlewareMock +let loggerMiddlewareMock; const initializeMockMiddlewareLog = () => { loggerMiddlewareMock = { requests: [], responses: [], - } -} + }; +}; const tearDownMockMiddlewareLog = () => { - loggerMiddlewareMock = undefined -} + loggerMiddlewareMock = undefined; +}; const createLoggerMiddlewareMock = () => (req, res, next) => { if (loggerMiddlewareMock) { - loggerMiddlewareMock.requests.push(req) + loggerMiddlewareMock.requests.push(req); next((cb) => { - loggerMiddlewareMock.responses.push(res) - cb() - }) - return + loggerMiddlewareMock.responses.push(res); + cb(); + }); + return; } - next() -} + next(); +}; const MetaMaskController = proxyquire( '../../../../app/scripts/metamask-controller', @@ -69,42 +69,42 @@ const MetaMaskController = proxyquire( './controllers/threebox': { default: ThreeBoxControllerMock }, './lib/createLoggerMiddleware': { default: createLoggerMiddlewareMock }, }, -).default +).default; -const currentNetworkId = '42' -const DEFAULT_LABEL = 'Account 1' -const DEFAULT_LABEL_2 = 'Account 2' +const currentNetworkId = '42'; +const DEFAULT_LABEL = 'Account 1'; +const DEFAULT_LABEL_2 = 'Account 2'; const TEST_SEED = - 'debris dizzy just program just float decrease vacant alarm reduce speak stadium' -const TEST_ADDRESS = '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc' -const TEST_ADDRESS_2 = '0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b' -const TEST_ADDRESS_3 = '0xeb9e64b93097bc15f01f13eae97015c57ab64823' + 'debris dizzy just program just float decrease vacant alarm reduce speak stadium'; +const TEST_ADDRESS = '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'; +const TEST_ADDRESS_2 = '0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b'; +const TEST_ADDRESS_3 = '0xeb9e64b93097bc15f01f13eae97015c57ab64823'; const TEST_SEED_ALT = - 'setup olympic issue mobile velvet surge alcohol burger horse view reopen gentle' -const TEST_ADDRESS_ALT = '0xc42edfcc21ed14dda456aa0756c153f7985d8813' -const CUSTOM_RPC_URL = 'http://localhost:8545' -const CUSTOM_RPC_CHAIN_ID = '0x539' + 'setup olympic issue mobile velvet surge alcohol burger horse view reopen gentle'; +const TEST_ADDRESS_ALT = '0xc42edfcc21ed14dda456aa0756c153f7985d8813'; +const CUSTOM_RPC_URL = 'http://localhost:8545'; +const CUSTOM_RPC_CHAIN_ID = '0x539'; describe('MetaMaskController', function () { - let metamaskController - const sandbox = sinon.createSandbox() - const noop = () => undefined + let metamaskController; + const sandbox = sinon.createSandbox(); + const noop = () => undefined; beforeEach(function () { nock('https://min-api.cryptocompare.com') .persist() .get(/.*/u) - .reply(200, '{"JPY":12415.9}') + .reply(200, '{"JPY":12415.9}'); metamaskController = new MetaMaskController({ showUserConfirmation: noop, encryptor: { encrypt(_, object) { - this.object = object - return Promise.resolve('mock-encrypted') + this.object = object; + return Promise.resolve('mock-encrypted'); }, decrypt() { - return Promise.resolve(this.object) + return Promise.resolve(this.object); }, }, initState: cloneDeep(firstTimeState), @@ -115,314 +115,326 @@ describe('MetaMaskController', function () { }, extension: ExtensionizerMock, infuraProjectId: 'foo', - }) + }); // add sinon method spies sandbox.spy( metamaskController.keyringController, 'createNewVaultAndKeychain', - ) + ); sandbox.spy( metamaskController.keyringController, 'createNewVaultAndRestore', - ) - }) + ); + }); afterEach(function () { - nock.cleanAll() - sandbox.restore() - }) + nock.cleanAll(); + sandbox.restore(); + }); describe('#getAccounts', function () { it('returns first address when dapp calls web3.eth.getAccounts', async function () { - const password = 'a-fake-password' - await metamaskController.createNewVaultAndRestore(password, TEST_SEED) + const password = 'a-fake-password'; + await metamaskController.createNewVaultAndRestore(password, TEST_SEED); metamaskController.networkController._baseProviderParams.getAccounts( (err, res) => { - assert.ifError(err) - assert.equal(res.length, 1) - assert.equal(res[0], '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc') + assert.ifError(err); + assert.equal(res.length, 1); + assert.equal(res[0], '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'); }, - ) - }) - }) + ); + }); + }); describe('#importAccountWithStrategy', function () { const importPrivkey = - '4cfd3e90fc78b0f86bf7524722150bb8da9c60cd532564d7ff43f5716514f553' + '4cfd3e90fc78b0f86bf7524722150bb8da9c60cd532564d7ff43f5716514f553'; beforeEach(async function () { - const password = 'a-fake-password' - await metamaskController.createNewVaultAndRestore(password, TEST_SEED) + const password = 'a-fake-password'; + await metamaskController.createNewVaultAndRestore(password, TEST_SEED); await metamaskController.importAccountWithStrategy('Private Key', [ importPrivkey, - ]) - }) + ]); + }); it('adds private key to keyrings in KeyringController', async function () { const simpleKeyrings = metamaskController.keyringController.getKeyringsByType( 'Simple Key Pair', - ) - const privKeyBuffer = simpleKeyrings[0].wallets[0]._privKey - const pubKeyBuffer = simpleKeyrings[0].wallets[0]._pubKey - const addressBuffer = ethUtil.pubToAddress(pubKeyBuffer) - const privKey = ethUtil.bufferToHex(privKeyBuffer) - const pubKey = ethUtil.bufferToHex(addressBuffer) - assert.equal(privKey, addHexPrefix(importPrivkey)) - assert.equal(pubKey, '0xe18035bf8712672935fdb4e5e431b1a0183d2dfc') - }) + ); + const privKeyBuffer = simpleKeyrings[0].wallets[0]._privKey; + const pubKeyBuffer = simpleKeyrings[0].wallets[0]._pubKey; + const addressBuffer = ethUtil.pubToAddress(pubKeyBuffer); + const privKey = ethUtil.bufferToHex(privKeyBuffer); + const pubKey = ethUtil.bufferToHex(addressBuffer); + assert.equal(privKey, addHexPrefix(importPrivkey)); + assert.equal(pubKey, '0xe18035bf8712672935fdb4e5e431b1a0183d2dfc'); + }); it('adds 1 account', async function () { - const keyringAccounts = await metamaskController.keyringController.getAccounts() + const keyringAccounts = await metamaskController.keyringController.getAccounts(); assert.equal( keyringAccounts[keyringAccounts.length - 1], '0xe18035bf8712672935fdb4e5e431b1a0183d2dfc', - ) - }) - }) + ); + }); + }); describe('submitPassword', function () { - const password = 'password' + const password = 'password'; beforeEach(async function () { - await metamaskController.createNewVaultAndKeychain(password) - threeBoxSpies.init.reset() - threeBoxSpies.turnThreeBoxSyncingOn.reset() - }) + await metamaskController.createNewVaultAndKeychain(password); + threeBoxSpies.init.reset(); + threeBoxSpies.turnThreeBoxSyncingOn.reset(); + }); it('removes any identities that do not correspond to known accounts.', async function () { - const fakeAddress = '0xbad0' - metamaskController.preferencesController.addAddresses([fakeAddress]) - await metamaskController.submitPassword(password) + const fakeAddress = '0xbad0'; + metamaskController.preferencesController.addAddresses([fakeAddress]); + await metamaskController.submitPassword(password); const identities = Object.keys( metamaskController.preferencesController.store.getState().identities, - ) - const addresses = await metamaskController.keyringController.getAccounts() + ); + const addresses = await metamaskController.keyringController.getAccounts(); identities.forEach((identity) => { assert.ok( addresses.includes(identity), `addresses should include all IDs: ${identity}`, - ) - }) + ); + }); addresses.forEach((address) => { assert.ok( identities.includes(address), `identities should include all Addresses: ${address}`, - ) - }) - }) + ); + }); + }); it('gets the address from threebox and creates a new 3box instance', async function () { - await metamaskController.submitPassword(password) - assert(threeBoxSpies.init.calledOnce) - assert(threeBoxSpies.turnThreeBoxSyncingOn.calledOnce) - }) + await metamaskController.submitPassword(password); + assert(threeBoxSpies.init.calledOnce); + assert(threeBoxSpies.turnThreeBoxSyncingOn.calledOnce); + }); it('succeeds even if blockTracker or threeBoxController throw', async function () { - const throwErr = sinon.fake.throws('foo') - metamaskController.blockTracker.checkForLatestBlock = throwErr - metamaskController.threeBoxController.getThreeBoxSyncingState = throwErr - await metamaskController.submitPassword(password) + const throwErr = sinon.fake.throws('foo'); + metamaskController.blockTracker.checkForLatestBlock = throwErr; + metamaskController.threeBoxController.getThreeBoxSyncingState = throwErr; + await metamaskController.submitPassword(password); assert.ok( throwErr.calledTwice, 'should have called checkForLatestBlock and getThreeBoxSyncingState', - ) - }) - }) + ); + }); + }); describe('#createNewVaultAndKeychain', function () { it('can only create new vault on keyringController once', async function () { - const selectStub = sandbox.stub(metamaskController, 'selectFirstIdentity') + const selectStub = sandbox.stub( + metamaskController, + 'selectFirstIdentity', + ); - const password = 'a-fake-password' + const password = 'a-fake-password'; - await metamaskController.createNewVaultAndKeychain(password) - await metamaskController.createNewVaultAndKeychain(password) + await metamaskController.createNewVaultAndKeychain(password); + await metamaskController.createNewVaultAndKeychain(password); assert( metamaskController.keyringController.createNewVaultAndKeychain .calledOnce, - ) + ); - selectStub.reset() - }) - }) + selectStub.reset(); + }); + }); describe('#createNewVaultAndRestore', function () { it('should be able to call newVaultAndRestore despite a mistake.', async function () { - const password = 'what-what-what' - sandbox.stub(metamaskController, 'getBalance') + const password = 'what-what-what'; + sandbox.stub(metamaskController, 'getBalance'); metamaskController.getBalance.callsFake(() => { - return Promise.resolve('0x0') - }) + return Promise.resolve('0x0'); + }); await metamaskController .createNewVaultAndRestore(password, TEST_SEED.slice(0, -1)) - .catch(() => null) - await metamaskController.createNewVaultAndRestore(password, TEST_SEED) + .catch(() => null); + await metamaskController.createNewVaultAndRestore(password, TEST_SEED); assert( metamaskController.keyringController.createNewVaultAndRestore .calledTwice, - ) - }) + ); + }); it('should clear previous identities after vault restoration', async function () { - sandbox.stub(metamaskController, 'getBalance') + sandbox.stub(metamaskController, 'getBalance'); metamaskController.getBalance.callsFake(() => { - return Promise.resolve('0x0') - }) + return Promise.resolve('0x0'); + }); - let startTime = Date.now() - await metamaskController.createNewVaultAndRestore('foobar1337', TEST_SEED) - let endTime = Date.now() + let startTime = Date.now(); + await metamaskController.createNewVaultAndRestore( + 'foobar1337', + TEST_SEED, + ); + let endTime = Date.now(); const firstVaultIdentities = cloneDeep( metamaskController.getState().identities, - ) + ); assert.ok( firstVaultIdentities[TEST_ADDRESS].lastSelected >= startTime && firstVaultIdentities[TEST_ADDRESS].lastSelected <= endTime, `'${firstVaultIdentities[TEST_ADDRESS].lastSelected}' expected to be between '${startTime}' and '${endTime}'`, - ) - delete firstVaultIdentities[TEST_ADDRESS].lastSelected + ); + delete firstVaultIdentities[TEST_ADDRESS].lastSelected; assert.deepEqual(firstVaultIdentities, { [TEST_ADDRESS]: { address: TEST_ADDRESS, name: DEFAULT_LABEL }, - }) + }); await metamaskController.preferencesController.setAccountLabel( TEST_ADDRESS, 'Account Foo', - ) + ); const labelledFirstVaultIdentities = cloneDeep( metamaskController.getState().identities, - ) - delete labelledFirstVaultIdentities[TEST_ADDRESS].lastSelected + ); + delete labelledFirstVaultIdentities[TEST_ADDRESS].lastSelected; assert.deepEqual(labelledFirstVaultIdentities, { [TEST_ADDRESS]: { address: TEST_ADDRESS, name: 'Account Foo' }, - }) + }); - startTime = Date.now() + startTime = Date.now(); await metamaskController.createNewVaultAndRestore( 'foobar1337', TEST_SEED_ALT, - ) - endTime = Date.now() + ); + endTime = Date.now(); const secondVaultIdentities = cloneDeep( metamaskController.getState().identities, - ) + ); assert.ok( secondVaultIdentities[TEST_ADDRESS_ALT].lastSelected >= startTime && secondVaultIdentities[TEST_ADDRESS_ALT].lastSelected <= endTime, `'${secondVaultIdentities[TEST_ADDRESS_ALT].lastSelected}' expected to be between '${startTime}' and '${endTime}'`, - ) - delete secondVaultIdentities[TEST_ADDRESS_ALT].lastSelected + ); + delete secondVaultIdentities[TEST_ADDRESS_ALT].lastSelected; assert.deepEqual(secondVaultIdentities, { [TEST_ADDRESS_ALT]: { address: TEST_ADDRESS_ALT, name: DEFAULT_LABEL }, - }) - }) + }); + }); it('should restore any consecutive accounts with balances', async function () { - sandbox.stub(metamaskController, 'getBalance') + sandbox.stub(metamaskController, 'getBalance'); metamaskController.getBalance.withArgs(TEST_ADDRESS).callsFake(() => { - return Promise.resolve('0x14ced5122ce0a000') - }) + return Promise.resolve('0x14ced5122ce0a000'); + }); metamaskController.getBalance.withArgs(TEST_ADDRESS_2).callsFake(() => { - return Promise.resolve('0x0') - }) + return Promise.resolve('0x0'); + }); metamaskController.getBalance.withArgs(TEST_ADDRESS_3).callsFake(() => { - return Promise.resolve('0x14ced5122ce0a000') - }) + return Promise.resolve('0x14ced5122ce0a000'); + }); - const startTime = Date.now() - await metamaskController.createNewVaultAndRestore('foobar1337', TEST_SEED) + const startTime = Date.now(); + await metamaskController.createNewVaultAndRestore( + 'foobar1337', + TEST_SEED, + ); - const identities = cloneDeep(metamaskController.getState().identities) + const identities = cloneDeep(metamaskController.getState().identities); assert.ok( identities[TEST_ADDRESS].lastSelected >= startTime && identities[TEST_ADDRESS].lastSelected <= Date.now(), - ) - delete identities[TEST_ADDRESS].lastSelected + ); + delete identities[TEST_ADDRESS].lastSelected; assert.deepEqual(identities, { [TEST_ADDRESS]: { address: TEST_ADDRESS, name: DEFAULT_LABEL }, [TEST_ADDRESS_2]: { address: TEST_ADDRESS_2, name: DEFAULT_LABEL_2 }, - }) - }) - }) + }); + }); + }); describe('#getBalance', function () { it('should return the balance known by accountTracker', async function () { - const accounts = {} - const balance = '0x14ced5122ce0a000' - accounts[TEST_ADDRESS] = { balance } + const accounts = {}; + const balance = '0x14ced5122ce0a000'; + accounts[TEST_ADDRESS] = { balance }; - metamaskController.accountTracker.store.putState({ accounts }) + metamaskController.accountTracker.store.putState({ accounts }); - const gotten = await metamaskController.getBalance(TEST_ADDRESS) + const gotten = await metamaskController.getBalance(TEST_ADDRESS); - assert.equal(balance, gotten) - }) + assert.equal(balance, gotten); + }); it('should ask the network for a balance when not known by accountTracker', async function () { - const accounts = {} - const balance = '0x14ced5122ce0a000' - const ethQuery = new EthQuery() + const accounts = {}; + const balance = '0x14ced5122ce0a000'; + const ethQuery = new EthQuery(); sinon.stub(ethQuery, 'getBalance').callsFake((_, callback) => { - callback(undefined, balance) - }) + callback(undefined, balance); + }); - metamaskController.accountTracker.store.putState({ accounts }) + metamaskController.accountTracker.store.putState({ accounts }); - const gotten = await metamaskController.getBalance(TEST_ADDRESS, ethQuery) + const gotten = await metamaskController.getBalance( + TEST_ADDRESS, + ethQuery, + ); - assert.equal(balance, gotten) - }) - }) + assert.equal(balance, gotten); + }); + }); describe('#getApi', function () { it('getState', function (done) { - let state - const getApi = metamaskController.getApi() + let state; + const getApi = metamaskController.getApi(); getApi.getState((err, res) => { if (err) { - done(err) + done(err); } else { - state = res + state = res; } - }) - assert.deepEqual(state, metamaskController.getState()) - done() - }) - }) + }); + assert.deepEqual(state, metamaskController.getState()); + done(); + }); + }); describe('preferencesController', function () { it('defaults useBlockie to false', function () { assert.equal( metamaskController.preferencesController.store.getState().useBlockie, false, - ) - }) + ); + }); it('setUseBlockie to true', function () { - metamaskController.setUseBlockie(true, noop) + metamaskController.setUseBlockie(true, noop); assert.equal( metamaskController.preferencesController.store.getState().useBlockie, true, - ) - }) - }) + ); + }); + }); describe('#selectFirstIdentity', function () { - let identities, address + let identities, address; beforeEach(function () { - address = '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc' + address = '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'; identities = { '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc': { address, @@ -432,21 +444,23 @@ describe('MetaMaskController', function () { address: '0xc42edfcc21ed14dda456aa0756c153f7985d8813', name: 'Account 2', }, - } - metamaskController.preferencesController.store.updateState({ identities }) - metamaskController.selectFirstIdentity() - }) + }; + metamaskController.preferencesController.store.updateState({ + identities, + }); + metamaskController.selectFirstIdentity(); + }); it('changes preferences controller select address', function () { - const preferenceControllerState = metamaskController.preferencesController.store.getState() - assert.equal(preferenceControllerState.selectedAddress, address) - }) + const preferenceControllerState = metamaskController.preferencesController.store.getState(); + assert.equal(preferenceControllerState.selectedAddress, address); + }); it('changes metamask controller selected address', function () { - const metamaskState = metamaskController.getState() - assert.equal(metamaskState.selectedAddress, address) - }) - }) + const metamaskState = metamaskController.getState(); + assert.equal(metamaskState.selectedAddress, address); + }); + }); describe('connectHardware', function () { it('should throw if it receives an unknown device name', async function () { @@ -455,41 +469,41 @@ describe('MetaMaskController', function () { 'Some random device name', 0, `m/44/0'/0'`, - ) + ); } catch (e) { assert.equal( e, 'Error: MetamaskController:getKeyringForDevice - Unknown device', - ) + ); } - }) + }); it('should add the Trezor Hardware keyring', async function () { - sinon.spy(metamaskController.keyringController, 'addNewKeyring') - await metamaskController.connectHardware('trezor', 0).catch(() => null) + sinon.spy(metamaskController.keyringController, 'addNewKeyring'); + await metamaskController.connectHardware('trezor', 0).catch(() => null); const keyrings = await metamaskController.keyringController.getKeyringsByType( 'Trezor Hardware', - ) + ); assert.equal( metamaskController.keyringController.addNewKeyring.getCall(0).args, 'Trezor Hardware', - ) - assert.equal(keyrings.length, 1) - }) + ); + assert.equal(keyrings.length, 1); + }); it('should add the Ledger Hardware keyring', async function () { - sinon.spy(metamaskController.keyringController, 'addNewKeyring') - await metamaskController.connectHardware('ledger', 0).catch(() => null) + sinon.spy(metamaskController.keyringController, 'addNewKeyring'); + await metamaskController.connectHardware('ledger', 0).catch(() => null); const keyrings = await metamaskController.keyringController.getKeyringsByType( 'Ledger Hardware', - ) + ); assert.equal( metamaskController.keyringController.addNewKeyring.getCall(0).args, 'Ledger Hardware', - ) - assert.equal(keyrings.length, 1) - }) - }) + ); + assert.equal(keyrings.length, 1); + }); + }); describe('checkHardwareStatus', function () { it('should throw if it receives an unknown device name', async function () { @@ -497,214 +511,217 @@ describe('MetaMaskController', function () { await metamaskController.checkHardwareStatus( 'Some random device name', `m/44/0'/0'`, - ) + ); } catch (e) { assert.equal( e, 'Error: MetamaskController:getKeyringForDevice - Unknown device', - ) + ); } - }) + }); it('should be locked by default', async function () { - await metamaskController.connectHardware('trezor', 0).catch(() => null) - const status = await metamaskController.checkHardwareStatus('trezor') - assert.equal(status, false) - }) - }) + await metamaskController.connectHardware('trezor', 0).catch(() => null); + const status = await metamaskController.checkHardwareStatus('trezor'); + assert.equal(status, false); + }); + }); describe('forgetDevice', function () { it('should throw if it receives an unknown device name', async function () { try { - await metamaskController.forgetDevice('Some random device name') + await metamaskController.forgetDevice('Some random device name'); } catch (e) { assert.equal( e, 'Error: MetamaskController:getKeyringForDevice - Unknown device', - ) + ); } - }) + }); it('should wipe all the keyring info', async function () { - await metamaskController.connectHardware('trezor', 0).catch(() => null) - await metamaskController.forgetDevice('trezor') + await metamaskController.connectHardware('trezor', 0).catch(() => null); + await metamaskController.forgetDevice('trezor'); const keyrings = await metamaskController.keyringController.getKeyringsByType( 'Trezor Hardware', - ) + ); - assert.deepEqual(keyrings[0].accounts, []) - assert.deepEqual(keyrings[0].page, 0) - assert.deepEqual(keyrings[0].isUnlocked(), false) - }) - }) + assert.deepEqual(keyrings[0].accounts, []); + assert.deepEqual(keyrings[0].page, 0); + assert.deepEqual(keyrings[0].isUnlocked(), false); + }); + }); describe('unlockHardwareWalletAccount', function () { - let accountToUnlock - let windowOpenStub - let addNewAccountStub - let getAccountsStub + let accountToUnlock; + let windowOpenStub; + let addNewAccountStub; + let getAccountsStub; beforeEach(async function () { - accountToUnlock = 10 - windowOpenStub = sinon.stub(window, 'open') - windowOpenStub.returns(noop) + accountToUnlock = 10; + windowOpenStub = sinon.stub(window, 'open'); + windowOpenStub.returns(noop); addNewAccountStub = sinon.stub( metamaskController.keyringController, 'addNewAccount', - ) - addNewAccountStub.returns({}) + ); + addNewAccountStub.returns({}); getAccountsStub = sinon.stub( metamaskController.keyringController, 'getAccounts', - ) + ); // Need to return different address to mock the behavior of // adding a new account from the keyring - getAccountsStub.onCall(0).returns(Promise.resolve(['0x1'])) - getAccountsStub.onCall(1).returns(Promise.resolve(['0x2'])) - getAccountsStub.onCall(2).returns(Promise.resolve(['0x3'])) - getAccountsStub.onCall(3).returns(Promise.resolve(['0x4'])) - sinon.spy(metamaskController.preferencesController, 'setAddresses') - sinon.spy(metamaskController.preferencesController, 'setSelectedAddress') - sinon.spy(metamaskController.preferencesController, 'setAccountLabel') + getAccountsStub.onCall(0).returns(Promise.resolve(['0x1'])); + getAccountsStub.onCall(1).returns(Promise.resolve(['0x2'])); + getAccountsStub.onCall(2).returns(Promise.resolve(['0x3'])); + getAccountsStub.onCall(3).returns(Promise.resolve(['0x4'])); + sinon.spy(metamaskController.preferencesController, 'setAddresses'); + sinon.spy(metamaskController.preferencesController, 'setSelectedAddress'); + sinon.spy(metamaskController.preferencesController, 'setAccountLabel'); await metamaskController .connectHardware('trezor', 0, `m/44/0'/0'`) - .catch(() => null) + .catch(() => null); await metamaskController.unlockHardwareWalletAccount( accountToUnlock, 'trezor', `m/44/0'/0'`, - ) - }) + ); + }); afterEach(function () { - window.open.restore() - metamaskController.keyringController.addNewAccount.restore() - metamaskController.keyringController.getAccounts.restore() - metamaskController.preferencesController.setAddresses.restore() - metamaskController.preferencesController.setSelectedAddress.restore() - metamaskController.preferencesController.setAccountLabel.restore() - }) + window.open.restore(); + metamaskController.keyringController.addNewAccount.restore(); + metamaskController.keyringController.getAccounts.restore(); + metamaskController.preferencesController.setAddresses.restore(); + metamaskController.preferencesController.setSelectedAddress.restore(); + metamaskController.preferencesController.setAccountLabel.restore(); + }); it('should set unlockedAccount in the keyring', async function () { const keyrings = await metamaskController.keyringController.getKeyringsByType( 'Trezor Hardware', - ) - assert.equal(keyrings[0].unlockedAccount, accountToUnlock) - }) + ); + assert.equal(keyrings[0].unlockedAccount, accountToUnlock); + }); it('should call keyringController.addNewAccount', async function () { - assert(metamaskController.keyringController.addNewAccount.calledOnce) - }) + assert(metamaskController.keyringController.addNewAccount.calledOnce); + }); it('should call keyringController.getAccounts ', async function () { - assert(metamaskController.keyringController.getAccounts.called) - }) + assert(metamaskController.keyringController.getAccounts.called); + }); it('should call preferencesController.setAddresses', async function () { - assert(metamaskController.preferencesController.setAddresses.calledOnce) - }) + assert(metamaskController.preferencesController.setAddresses.calledOnce); + }); it('should call preferencesController.setSelectedAddress', async function () { assert( metamaskController.preferencesController.setSelectedAddress.calledOnce, - ) - }) + ); + }); it('should call preferencesController.setAccountLabel', async function () { assert( metamaskController.preferencesController.setAccountLabel.calledOnce, - ) - }) - }) + ); + }); + }); describe('#setCustomRpc', function () { - let rpcUrl + let rpcUrl; beforeEach(function () { rpcUrl = metamaskController.setCustomRpc( CUSTOM_RPC_URL, CUSTOM_RPC_CHAIN_ID, - ) - }) + ); + }); it('returns custom RPC that when called', async function () { - assert.equal(await rpcUrl, CUSTOM_RPC_URL) - }) + assert.equal(await rpcUrl, CUSTOM_RPC_URL); + }); it('changes the network controller rpc', function () { - const networkControllerState = metamaskController.networkController.store.getState() - assert.equal(networkControllerState.provider.rpcUrl, CUSTOM_RPC_URL) - }) - }) + const networkControllerState = metamaskController.networkController.store.getState(); + assert.equal(networkControllerState.provider.rpcUrl, CUSTOM_RPC_URL); + }); + }); describe('#setCurrentCurrency', function () { - let defaultMetaMaskCurrency + let defaultMetaMaskCurrency; beforeEach(function () { defaultMetaMaskCurrency = - metamaskController.currencyRateController.state.currentCurrency - }) + metamaskController.currencyRateController.state.currentCurrency; + }); it('defaults to usd', function () { - assert.equal(defaultMetaMaskCurrency, 'usd') - }) + assert.equal(defaultMetaMaskCurrency, 'usd'); + }); it('sets currency to JPY', function () { - metamaskController.setCurrentCurrency('JPY', noop) + metamaskController.setCurrentCurrency('JPY', noop); assert.equal( metamaskController.currencyRateController.state.currentCurrency, 'JPY', - ) - }) - }) + ); + }); + }); describe('#addNewAccount', function () { it('errors when an primary keyring is does not exist', async function () { - const addNewAccount = metamaskController.addNewAccount() + const addNewAccount = metamaskController.addNewAccount(); try { - await addNewAccount - assert.fail('should throw') + await addNewAccount; + assert.fail('should throw'); } catch (e) { - assert.equal(e.message, 'MetamaskController - No HD Key Tree found') + assert.equal(e.message, 'MetamaskController - No HD Key Tree found'); } - }) - }) + }); + }); describe('#verifyseedPhrase', function () { it('errors when no keying is provided', async function () { try { - await metamaskController.verifySeedPhrase() + await metamaskController.verifySeedPhrase(); } catch (error) { - assert.equal(error.message, 'MetamaskController - No HD Key Tree found') + assert.equal( + error.message, + 'MetamaskController - No HD Key Tree found', + ); } - }) + }); beforeEach(async function () { - await metamaskController.createNewVaultAndKeychain('password') - }) + await metamaskController.createNewVaultAndKeychain('password'); + }); it('#addNewAccount', async function () { - await metamaskController.addNewAccount() - const getAccounts = await metamaskController.keyringController.getAccounts() - assert.equal(getAccounts.length, 2) - }) - }) + await metamaskController.addNewAccount(); + const getAccounts = await metamaskController.keyringController.getAccounts(); + assert.equal(getAccounts.length, 2); + }); + }); describe('#resetAccount', function () { it('wipes transactions from only the correct network id and with the selected address', async function () { const selectedAddressStub = sinon.stub( metamaskController.preferencesController, 'getSelectedAddress', - ) + ); const getNetworkstub = sinon.stub( metamaskController.txController.txStateManager, 'getNetwork', - ) + ); - selectedAddressStub.returns('0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc') - getNetworkstub.returns(42) + selectedAddressStub.returns('0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'); + getNetworkstub.returns(42); metamaskController.txController.txStateManager._saveTxList([ createTxMeta({ @@ -730,296 +747,296 @@ describe('MetaMaskController', function () { metamaskNetworkId: currentNetworkId, txParams: { from: '0xB09d8505E1F4EF1CeA089D47094f5DD3464083d4' }, }), - ]) + ]); - await metamaskController.resetAccount() + await metamaskController.resetAccount(); assert.equal( metamaskController.txController.txStateManager.getTx(1), undefined, - ) - }) - }) + ); + }); + }); describe('#removeAccount', function () { - let ret - const addressToRemove = '0x1' + let ret; + const addressToRemove = '0x1'; beforeEach(async function () { - sinon.stub(metamaskController.preferencesController, 'removeAddress') - sinon.stub(metamaskController.accountTracker, 'removeAccount') - sinon.stub(metamaskController.keyringController, 'removeAccount') + sinon.stub(metamaskController.preferencesController, 'removeAddress'); + sinon.stub(metamaskController.accountTracker, 'removeAccount'); + sinon.stub(metamaskController.keyringController, 'removeAccount'); sinon.stub( metamaskController.permissionsController, 'removeAllAccountPermissions', - ) + ); - ret = await metamaskController.removeAccount(addressToRemove) - }) + ret = await metamaskController.removeAccount(addressToRemove); + }); afterEach(function () { - metamaskController.keyringController.removeAccount.restore() - metamaskController.accountTracker.removeAccount.restore() - metamaskController.preferencesController.removeAddress.restore() - metamaskController.permissionsController.removeAllAccountPermissions.restore() - }) + metamaskController.keyringController.removeAccount.restore(); + metamaskController.accountTracker.removeAccount.restore(); + metamaskController.preferencesController.removeAddress.restore(); + metamaskController.permissionsController.removeAllAccountPermissions.restore(); + }); it('should call preferencesController.removeAddress', async function () { assert( metamaskController.preferencesController.removeAddress.calledWith( addressToRemove, ), - ) - }) + ); + }); it('should call accountTracker.removeAccount', async function () { assert( metamaskController.accountTracker.removeAccount.calledWith([ addressToRemove, ]), - ) - }) + ); + }); it('should call keyringController.removeAccount', async function () { assert( metamaskController.keyringController.removeAccount.calledWith( addressToRemove, ), - ) - }) + ); + }); it('should call permissionsController.removeAllAccountPermissions', async function () { assert( metamaskController.permissionsController.removeAllAccountPermissions.calledWith( addressToRemove, ), - ) - }) + ); + }); it('should return address', async function () { - assert.equal(ret, '0x1') - }) - }) + assert.equal(ret, '0x1'); + }); + }); describe('#setCurrentLocale', function () { it('checks the default currentLocale', function () { const preferenceCurrentLocale = metamaskController.preferencesController.store.getState() - .currentLocale - assert.equal(preferenceCurrentLocale, 'en_US') - }) + .currentLocale; + assert.equal(preferenceCurrentLocale, 'en_US'); + }); it('sets current locale in preferences controller', function () { - metamaskController.setCurrentLocale('ja', noop) + metamaskController.setCurrentLocale('ja', noop); const preferenceCurrentLocale = metamaskController.preferencesController.store.getState() - .currentLocale - assert.equal(preferenceCurrentLocale, 'ja') - }) - }) + .currentLocale; + assert.equal(preferenceCurrentLocale, 'ja'); + }); + }); describe('#newUnsignedMessage', function () { - let msgParams, metamaskMsgs, messages, msgId + let msgParams, metamaskMsgs, messages, msgId; - const address = '0xc42edfcc21ed14dda456aa0756c153f7985d8813' - const data = '0x43727970746f6b697474696573' + const address = '0xc42edfcc21ed14dda456aa0756c153f7985d8813'; + const data = '0x43727970746f6b697474696573'; beforeEach(async function () { - sandbox.stub(metamaskController, 'getBalance') + sandbox.stub(metamaskController, 'getBalance'); metamaskController.getBalance.callsFake(() => { - return Promise.resolve('0x0') - }) + return Promise.resolve('0x0'); + }); await metamaskController.createNewVaultAndRestore( 'foobar1337', TEST_SEED_ALT, - ) + ); msgParams = { from: address, data, - } + }; - const promise = metamaskController.newUnsignedMessage(msgParams) + const promise = metamaskController.newUnsignedMessage(msgParams); // handle the promise so it doesn't throw an unhandledRejection - promise.then(noop).catch(noop) + promise.then(noop).catch(noop); - metamaskMsgs = metamaskController.messageManager.getUnapprovedMsgs() - messages = metamaskController.messageManager.messages - msgId = Object.keys(metamaskMsgs)[0] - messages[0].msgParams.metamaskId = parseInt(msgId, 10) - }) + metamaskMsgs = metamaskController.messageManager.getUnapprovedMsgs(); + messages = metamaskController.messageManager.messages; + msgId = Object.keys(metamaskMsgs)[0]; + messages[0].msgParams.metamaskId = parseInt(msgId, 10); + }); it('persists address from msg params', function () { - assert.equal(metamaskMsgs[msgId].msgParams.from, address) - }) + assert.equal(metamaskMsgs[msgId].msgParams.from, address); + }); it('persists data from msg params', function () { - assert.equal(metamaskMsgs[msgId].msgParams.data, data) - }) + assert.equal(metamaskMsgs[msgId].msgParams.data, data); + }); it('sets the status to unapproved', function () { - assert.equal(metamaskMsgs[msgId].status, TRANSACTION_STATUSES.UNAPPROVED) - }) + assert.equal(metamaskMsgs[msgId].status, TRANSACTION_STATUSES.UNAPPROVED); + }); it('sets the type to eth_sign', function () { - assert.equal(metamaskMsgs[msgId].type, 'eth_sign') - }) + assert.equal(metamaskMsgs[msgId].type, 'eth_sign'); + }); it('rejects the message', function () { - const msgIdInt = parseInt(msgId, 10) - metamaskController.cancelMessage(msgIdInt, noop) - assert.equal(messages[0].status, TRANSACTION_STATUSES.REJECTED) - }) + const msgIdInt = parseInt(msgId, 10); + metamaskController.cancelMessage(msgIdInt, noop); + assert.equal(messages[0].status, TRANSACTION_STATUSES.REJECTED); + }); it('errors when signing a message', async function () { try { - await metamaskController.signMessage(messages[0].msgParams) + await metamaskController.signMessage(messages[0].msgParams); } catch (error) { - assert.equal(error.message, 'message length is invalid') + assert.equal(error.message, 'message length is invalid'); } - }) - }) + }); + }); describe('#newUnsignedPersonalMessage', function () { - let msgParams, metamaskPersonalMsgs, personalMessages, msgId + let msgParams, metamaskPersonalMsgs, personalMessages, msgId; - const address = '0xc42edfcc21ed14dda456aa0756c153f7985d8813' - const data = '0x43727970746f6b697474696573' + const address = '0xc42edfcc21ed14dda456aa0756c153f7985d8813'; + const data = '0x43727970746f6b697474696573'; beforeEach(async function () { - sandbox.stub(metamaskController, 'getBalance') + sandbox.stub(metamaskController, 'getBalance'); metamaskController.getBalance.callsFake(() => { - return Promise.resolve('0x0') - }) + return Promise.resolve('0x0'); + }); await metamaskController.createNewVaultAndRestore( 'foobar1337', TEST_SEED_ALT, - ) + ); msgParams = { from: address, data, - } + }; - const promise = metamaskController.newUnsignedPersonalMessage(msgParams) + const promise = metamaskController.newUnsignedPersonalMessage(msgParams); // handle the promise so it doesn't throw an unhandledRejection - promise.then(noop).catch(noop) + promise.then(noop).catch(noop); - metamaskPersonalMsgs = metamaskController.personalMessageManager.getUnapprovedMsgs() - personalMessages = metamaskController.personalMessageManager.messages - msgId = Object.keys(metamaskPersonalMsgs)[0] - personalMessages[0].msgParams.metamaskId = parseInt(msgId, 10) - }) + metamaskPersonalMsgs = metamaskController.personalMessageManager.getUnapprovedMsgs(); + personalMessages = metamaskController.personalMessageManager.messages; + msgId = Object.keys(metamaskPersonalMsgs)[0]; + personalMessages[0].msgParams.metamaskId = parseInt(msgId, 10); + }); it('errors with no from in msgParams', async function () { try { await metamaskController.newUnsignedPersonalMessage({ data, - }) - assert.fail('should have thrown') + }); + assert.fail('should have thrown'); } catch (error) { assert.equal( error.message, 'MetaMask Message Signature: from field is required.', - ) + ); } - }) + }); it('persists address from msg params', function () { - assert.equal(metamaskPersonalMsgs[msgId].msgParams.from, address) - }) + assert.equal(metamaskPersonalMsgs[msgId].msgParams.from, address); + }); it('persists data from msg params', function () { - assert.equal(metamaskPersonalMsgs[msgId].msgParams.data, data) - }) + assert.equal(metamaskPersonalMsgs[msgId].msgParams.data, data); + }); it('sets the status to unapproved', function () { assert.equal( metamaskPersonalMsgs[msgId].status, TRANSACTION_STATUSES.UNAPPROVED, - ) - }) + ); + }); it('sets the type to personal_sign', function () { - assert.equal(metamaskPersonalMsgs[msgId].type, 'personal_sign') - }) + assert.equal(metamaskPersonalMsgs[msgId].type, 'personal_sign'); + }); it('rejects the message', function () { - const msgIdInt = parseInt(msgId, 10) - metamaskController.cancelPersonalMessage(msgIdInt, noop) - assert.equal(personalMessages[0].status, TRANSACTION_STATUSES.REJECTED) - }) + const msgIdInt = parseInt(msgId, 10); + metamaskController.cancelPersonalMessage(msgIdInt, noop); + assert.equal(personalMessages[0].status, TRANSACTION_STATUSES.REJECTED); + }); it('errors when signing a message', async function () { await metamaskController.signPersonalMessage( personalMessages[0].msgParams, - ) + ); assert.equal( metamaskPersonalMsgs[msgId].status, TRANSACTION_STATUSES.SIGNED, - ) + ); assert.equal( metamaskPersonalMsgs[msgId].rawSig, '0x6a1b65e2b8ed53cf398a769fad24738f9fbe29841fe6854e226953542c4b6a173473cb152b6b1ae5f06d601d45dd699a129b0a8ca84e78b423031db5baa734741b', - ) - }) - }) + ); + }); + }); describe('#setupUntrustedCommunication', function () { - const mockTxParams = { from: TEST_ADDRESS } + const mockTxParams = { from: TEST_ADDRESS }; beforeEach(function () { - initializeMockMiddlewareLog() - }) + initializeMockMiddlewareLog(); + }); after(function () { - tearDownMockMiddlewareLog() - }) + tearDownMockMiddlewareLog(); + }); it('sets up phishing stream for untrusted communication', async function () { const phishingMessageSender = { url: 'http://myethereumwalletntw.com', tab: {}, - } + }; - const { promise, resolve } = deferredPromise() + const { promise, resolve } = deferredPromise(); const streamTest = createThoughStream((chunk, _, cb) => { if (chunk.name !== 'phishing') { - cb() - return + cb(); + return; } assert.equal( chunk.data.hostname, new URL(phishingMessageSender.url).hostname, - ) - resolve() - cb() - }) + ); + resolve(); + cb(); + }); metamaskController.setupUntrustedCommunication( streamTest, phishingMessageSender, - ) - await promise - streamTest.end() - }) + ); + await promise; + streamTest.end(); + }); it('adds a tabId and origin to requests', function (done) { const messageSender = { url: 'http://mycrypto.com', tab: { id: 456 }, - } + }; const streamTest = createThoughStream((chunk, _, cb) => { if (chunk.data && chunk.data.method) { - cb(null, chunk) - return + cb(null, chunk); + return; } - cb() - }) + cb(); + }); - metamaskController.setupUntrustedCommunication(streamTest, messageSender) + metamaskController.setupUntrustedCommunication(streamTest, messageSender); const message = { id: 1999133338649204, jsonrpc: '2.0', params: [{ ...mockTxParams }], method: 'eth_sendTransaction', - } + }; streamTest.write( { name: 'metamask-provider', @@ -1032,33 +1049,33 @@ describe('MetaMaskController', function () { ...message, origin: 'http://mycrypto.com', tabId: 456, - }) - done() - }) + }); + done(); + }); }, - ) - }) + ); + }); it('should add only origin to request if tabId not provided', function (done) { const messageSender = { url: 'http://mycrypto.com', - } + }; const streamTest = createThoughStream((chunk, _, cb) => { if (chunk.data && chunk.data.method) { - cb(null, chunk) - return + cb(null, chunk); + return; } - cb() - }) + cb(); + }); - metamaskController.setupUntrustedCommunication(streamTest, messageSender) + metamaskController.setupUntrustedCommunication(streamTest, messageSender); const message = { id: 1999133338649204, jsonrpc: '2.0', params: [{ ...mockTxParams }], method: 'eth_sendTransaction', - } + }; streamTest.write( { name: 'metamask-provider', @@ -1070,103 +1087,103 @@ describe('MetaMaskController', function () { assert.deepStrictEqual(loggerMiddlewareMock.requests[0], { ...message, origin: 'http://mycrypto.com', - }) - done() - }) + }); + done(); + }); }, - ) - }) - }) + ); + }); + }); describe('#setupTrustedCommunication', function () { it('sets up controller dnode api for trusted communication', async function () { const messageSender = { url: 'http://mycrypto.com', tab: {}, - } - const { promise, resolve } = deferredPromise() + }; + const { promise, resolve } = deferredPromise(); const streamTest = createThoughStream((chunk, _, cb) => { - assert.equal(chunk.name, 'controller') - resolve() - cb() - }) + assert.equal(chunk.name, 'controller'); + resolve(); + cb(); + }); - metamaskController.setupTrustedCommunication(streamTest, messageSender) - await promise - streamTest.end() - }) - }) + metamaskController.setupTrustedCommunication(streamTest, messageSender); + await promise; + streamTest.end(); + }); + }); describe('#markPasswordForgotten', function () { it('adds and sets forgottenPassword to config data to true', function () { - metamaskController.markPasswordForgotten(noop) - const state = metamaskController.getState() - assert.equal(state.forgottenPassword, true) - }) - }) + metamaskController.markPasswordForgotten(noop); + const state = metamaskController.getState(); + assert.equal(state.forgottenPassword, true); + }); + }); describe('#unMarkPasswordForgotten', function () { it('adds and sets forgottenPassword to config data to false', function () { - metamaskController.unMarkPasswordForgotten(noop) - const state = metamaskController.getState() - assert.equal(state.forgottenPassword, false) - }) - }) + metamaskController.unMarkPasswordForgotten(noop); + const state = metamaskController.getState(); + assert.equal(state.forgottenPassword, false); + }); + }); describe('#_onKeyringControllerUpdate', function () { it('should do nothing if there are no keyrings in state', async function () { - const syncAddresses = sinon.fake() - const syncWithAddresses = sinon.fake() + const syncAddresses = sinon.fake(); + const syncWithAddresses = sinon.fake(); sandbox.replace(metamaskController, 'preferencesController', { syncAddresses, - }) + }); sandbox.replace(metamaskController, 'accountTracker', { syncWithAddresses, - }) + }); - const oldState = metamaskController.getState() - await metamaskController._onKeyringControllerUpdate({ keyrings: [] }) + const oldState = metamaskController.getState(); + await metamaskController._onKeyringControllerUpdate({ keyrings: [] }); - assert.ok(syncAddresses.notCalled) - assert.ok(syncWithAddresses.notCalled) - assert.deepEqual(metamaskController.getState(), oldState) - }) + assert.ok(syncAddresses.notCalled); + assert.ok(syncWithAddresses.notCalled); + assert.deepEqual(metamaskController.getState(), oldState); + }); it('should sync addresses if there are keyrings in state', async function () { - const syncAddresses = sinon.fake() - const syncWithAddresses = sinon.fake() + const syncAddresses = sinon.fake(); + const syncWithAddresses = sinon.fake(); sandbox.replace(metamaskController, 'preferencesController', { syncAddresses, - }) + }); sandbox.replace(metamaskController, 'accountTracker', { syncWithAddresses, - }) + }); - const oldState = metamaskController.getState() + const oldState = metamaskController.getState(); await metamaskController._onKeyringControllerUpdate({ keyrings: [ { accounts: ['0x1', '0x2'], }, ], - }) + }); - assert.deepEqual(syncAddresses.args, [[['0x1', '0x2']]]) - assert.deepEqual(syncWithAddresses.args, [[['0x1', '0x2']]]) - assert.deepEqual(metamaskController.getState(), oldState) - }) + assert.deepEqual(syncAddresses.args, [[['0x1', '0x2']]]); + assert.deepEqual(syncWithAddresses.args, [[['0x1', '0x2']]]); + assert.deepEqual(metamaskController.getState(), oldState); + }); it('should NOT update selected address if already unlocked', async function () { - const syncAddresses = sinon.fake() - const syncWithAddresses = sinon.fake() + const syncAddresses = sinon.fake(); + const syncWithAddresses = sinon.fake(); sandbox.replace(metamaskController, 'preferencesController', { syncAddresses, - }) + }); sandbox.replace(metamaskController, 'accountTracker', { syncWithAddresses, - }) + }); - const oldState = metamaskController.getState() + const oldState = metamaskController.getState(); await metamaskController._onKeyringControllerUpdate({ isUnlocked: true, keyrings: [ @@ -1174,19 +1191,19 @@ describe('MetaMaskController', function () { accounts: ['0x1', '0x2'], }, ], - }) + }); - assert.deepEqual(syncAddresses.args, [[['0x1', '0x2']]]) - assert.deepEqual(syncWithAddresses.args, [[['0x1', '0x2']]]) - assert.deepEqual(metamaskController.getState(), oldState) - }) - }) -}) + assert.deepEqual(syncAddresses.args, [[['0x1', '0x2']]]); + assert.deepEqual(syncWithAddresses.args, [[['0x1', '0x2']]]); + assert.deepEqual(metamaskController.getState(), oldState); + }); + }); +}); function deferredPromise() { - let resolve + let resolve; const promise = new Promise((_resolve) => { - resolve = _resolve - }) - return { promise, resolve } + resolve = _resolve; + }); + return { promise, resolve }; } diff --git a/test/unit/app/controllers/metametrics-test.js b/test/unit/app/controllers/metametrics-test.js index 11c012bfcd..8f2de0c02c 100644 --- a/test/unit/app/controllers/metametrics-test.js +++ b/test/unit/app/controllers/metametrics-test.js @@ -1,36 +1,36 @@ -import { strict as assert } from 'assert' -import sinon from 'sinon' -import MetaMetricsController from '../../../../app/scripts/controllers/metametrics' -import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../../shared/constants/app' -import { createSegmentMock } from '../../../../app/scripts/lib/segment' +import { strict as assert } from 'assert'; +import sinon from 'sinon'; +import MetaMetricsController from '../../../../app/scripts/controllers/metametrics'; +import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../../shared/constants/app'; +import { createSegmentMock } from '../../../../app/scripts/lib/segment'; import { METAMETRICS_ANONYMOUS_ID, METAMETRICS_BACKGROUND_PAGE_OBJECT, -} from '../../../../shared/constants/metametrics' -import waitUntilCalled from '../../../lib/wait-until-called' +} from '../../../../shared/constants/metametrics'; +import waitUntilCalled from '../../../lib/wait-until-called'; -const segment = createSegmentMock(2, 10000) -const segmentLegacy = createSegmentMock(2, 10000) +const segment = createSegmentMock(2, 10000); +const segmentLegacy = createSegmentMock(2, 10000); -const VERSION = '0.0.1-test' -const NETWORK = 'Mainnet' -const FAKE_CHAIN_ID = '0x1338' -const LOCALE = 'en_US' -const TEST_META_METRICS_ID = '0xabc' +const VERSION = '0.0.1-test'; +const NETWORK = 'Mainnet'; +const FAKE_CHAIN_ID = '0x1338'; +const LOCALE = 'en_US'; +const TEST_META_METRICS_ID = '0xabc'; const DEFAULT_TEST_CONTEXT = { app: { name: 'MetaMask Extension', version: VERSION }, page: METAMETRICS_BACKGROUND_PAGE_OBJECT, referrer: undefined, userAgent: window.navigator.userAgent, -} +}; const DEFAULT_SHARED_PROPERTIES = { chain_id: FAKE_CHAIN_ID, locale: LOCALE.replace('_', '-'), network: NETWORK, environment_type: 'background', -} +}; const DEFAULT_EVENT_PROPERTIES = { category: 'Unit Test', @@ -38,22 +38,22 @@ const DEFAULT_EVENT_PROPERTIES = { value: undefined, currency: undefined, ...DEFAULT_SHARED_PROPERTIES, -} +}; const DEFAULT_PAGE_PROPERTIES = { ...DEFAULT_SHARED_PROPERTIES, -} +}; function getMockNetworkController( chainId = FAKE_CHAIN_ID, provider = { type: NETWORK }, ) { - let networkStore = { chainId, provider } - const on = sinon.stub().withArgs('networkDidChange') + let networkStore = { chainId, provider }; + const on = sinon.stub().withArgs('networkDidChange'); const updateState = (newState) => { - networkStore = { ...networkStore, ...newState } - on.getCall(0).args[1]() - } + networkStore = { ...networkStore, ...newState }; + on.getCall(0).args[1](); + }; return { store: { getState: () => networkStore, @@ -62,23 +62,23 @@ function getMockNetworkController( getCurrentChainId: () => networkStore.chainId, getNetworkIdentifier: () => networkStore.provider.type, on, - } + }; } function getMockPreferencesStore({ currentLocale = LOCALE } = {}) { let preferencesStore = { currentLocale, - } - const subscribe = sinon.stub() + }; + const subscribe = sinon.stub(); const updateState = (newState) => { - preferencesStore = { ...preferencesStore, ...newState } - subscribe.getCall(0).args[0](preferencesStore) - } + preferencesStore = { ...preferencesStore, ...newState }; + subscribe.getCall(0).args[0](preferencesStore); + }; return { getState: sinon.stub().returns(preferencesStore), updateState, subscribe, - } + }; } function getMetaMetricsController({ @@ -109,123 +109,126 @@ function getMetaMetricsController({ metaMetricsId, metaMetricsSendCount, }, - }) + }); } describe('MetaMetricsController', function () { describe('constructor', function () { it('should properly initialize', function () { - const metaMetricsController = getMetaMetricsController() - assert.strictEqual(metaMetricsController.version, VERSION) - assert.strictEqual(metaMetricsController.network, NETWORK) - assert.strictEqual(metaMetricsController.chainId, FAKE_CHAIN_ID) + const metaMetricsController = getMetaMetricsController(); + assert.strictEqual(metaMetricsController.version, VERSION); + assert.strictEqual(metaMetricsController.network, NETWORK); + assert.strictEqual(metaMetricsController.chainId, FAKE_CHAIN_ID); assert.strictEqual( metaMetricsController.state.participateInMetaMetrics, true, - ) + ); assert.strictEqual( metaMetricsController.state.metaMetricsId, TEST_META_METRICS_ID, - ) - assert.strictEqual(metaMetricsController.locale, LOCALE.replace('_', '-')) - }) + ); + assert.strictEqual( + metaMetricsController.locale, + LOCALE.replace('_', '-'), + ); + }); it('should update when network changes', function () { - const networkController = getMockNetworkController() + const networkController = getMockNetworkController(); const metaMetricsController = getMetaMetricsController({ networkController, - }) - assert.strictEqual(metaMetricsController.network, NETWORK) + }); + assert.strictEqual(metaMetricsController.network, NETWORK); networkController.store.updateState({ provider: { type: 'NEW_NETWORK', }, chainId: '0xaab', - }) - assert.strictEqual(metaMetricsController.network, 'NEW_NETWORK') - assert.strictEqual(metaMetricsController.chainId, '0xaab') - }) + }); + assert.strictEqual(metaMetricsController.network, 'NEW_NETWORK'); + assert.strictEqual(metaMetricsController.chainId, '0xaab'); + }); it('should update when preferences changes', function () { - const preferencesStore = getMockPreferencesStore() + const preferencesStore = getMockPreferencesStore(); const metaMetricsController = getMetaMetricsController({ preferencesStore, - }) - assert.strictEqual(metaMetricsController.network, NETWORK) + }); + assert.strictEqual(metaMetricsController.network, NETWORK); preferencesStore.updateState({ currentLocale: 'en_UK', - }) - assert.strictEqual(metaMetricsController.locale, 'en-UK') - }) - }) + }); + assert.strictEqual(metaMetricsController.locale, 'en-UK'); + }); + }); describe('generateMetaMetricsId', function () { it('should generate an 0x prefixed hex string', function () { - const metaMetricsController = getMetaMetricsController() + const metaMetricsController = getMetaMetricsController(); assert.equal( metaMetricsController.generateMetaMetricsId().startsWith('0x'), true, - ) - }) - }) + ); + }); + }); describe('setParticipateInMetaMetrics', function () { it('should update the value of participateInMetaMetrics', function () { const metaMetricsController = getMetaMetricsController({ participateInMetaMetrics: null, metaMetricsId: null, - }) - assert.equal(metaMetricsController.state.participateInMetaMetrics, null) - metaMetricsController.setParticipateInMetaMetrics(true) - assert.equal(metaMetricsController.state.participateInMetaMetrics, true) - metaMetricsController.setParticipateInMetaMetrics(false) - assert.equal(metaMetricsController.state.participateInMetaMetrics, false) - }) + }); + assert.equal(metaMetricsController.state.participateInMetaMetrics, null); + metaMetricsController.setParticipateInMetaMetrics(true); + assert.equal(metaMetricsController.state.participateInMetaMetrics, true); + metaMetricsController.setParticipateInMetaMetrics(false); + assert.equal(metaMetricsController.state.participateInMetaMetrics, false); + }); it('should generate and update the metaMetricsId when set to true', function () { const metaMetricsController = getMetaMetricsController({ participateInMetaMetrics: null, metaMetricsId: null, - }) - assert.equal(metaMetricsController.state.metaMetricsId, null) - metaMetricsController.setParticipateInMetaMetrics(true) - assert.equal(typeof metaMetricsController.state.metaMetricsId, 'string') - }) + }); + assert.equal(metaMetricsController.state.metaMetricsId, null); + metaMetricsController.setParticipateInMetaMetrics(true); + assert.equal(typeof metaMetricsController.state.metaMetricsId, 'string'); + }); it('should nullify the metaMetricsId when set to false', function () { - const metaMetricsController = getMetaMetricsController() - metaMetricsController.setParticipateInMetaMetrics(false) - assert.equal(metaMetricsController.state.metaMetricsId, null) - }) - }) + const metaMetricsController = getMetaMetricsController(); + metaMetricsController.setParticipateInMetaMetrics(false); + assert.equal(metaMetricsController.state.metaMetricsId, null); + }); + }); describe('setMetaMetricsSendCount', function () { it('should update the send count in state', function () { - const metaMetricsController = getMetaMetricsController() - metaMetricsController.setMetaMetricsSendCount(1) - assert.equal(metaMetricsController.state.metaMetricsSendCount, 1) - }) - }) + const metaMetricsController = getMetaMetricsController(); + metaMetricsController.setMetaMetricsSendCount(1); + assert.equal(metaMetricsController.state.metaMetricsSendCount, 1); + }); + }); describe('trackEvent', function () { it('should not track an event if user is not participating in metametrics', function () { - const mock = sinon.mock(segment) + const mock = sinon.mock(segment); const metaMetricsController = getMetaMetricsController({ participateInMetaMetrics: false, - }) - mock.expects('track').never() + }); + mock.expects('track').never(); metaMetricsController.trackEvent({ event: 'Fake Event', category: 'Unit Test', properties: { test: 1, }, - }) - mock.verify() - }) + }); + mock.verify(); + }); it('should track an event if user has not opted in, but isOptIn is true', function () { - const mock = sinon.mock(segment) + const mock = sinon.mock(segment); const metaMetricsController = getMetaMetricsController({ participateInMetaMetrics: false, - }) + }); mock .expects('track') .once() @@ -237,7 +240,7 @@ describe('MetaMetricsController', function () { test: 1, ...DEFAULT_EVENT_PROPERTIES, }, - }) + }); metaMetricsController.trackEvent( { event: 'Fake Event', @@ -247,15 +250,15 @@ describe('MetaMetricsController', function () { }, }, { isOptIn: true }, - ) - mock.verify() - }) + ); + mock.verify(); + }); it('should track an event during optin and allow for metaMetricsId override', function () { - const mock = sinon.mock(segment) + const mock = sinon.mock(segment); const metaMetricsController = getMetaMetricsController({ participateInMetaMetrics: false, - }) + }); mock .expects('track') .once() @@ -267,7 +270,7 @@ describe('MetaMetricsController', function () { test: 1, ...DEFAULT_EVENT_PROPERTIES, }, - }) + }); metaMetricsController.trackEvent( { event: 'Fake Event', @@ -277,13 +280,13 @@ describe('MetaMetricsController', function () { }, }, { isOptIn: true, metaMetricsId: 'TESTID' }, - ) - mock.verify() - }) + ); + mock.verify(); + }); it('should track a legacy event', function () { - const mock = sinon.mock(segmentLegacy) - const metaMetricsController = getMetaMetricsController() + const mock = sinon.mock(segmentLegacy); + const metaMetricsController = getMetaMetricsController(); mock .expects('track') .once() @@ -295,7 +298,7 @@ describe('MetaMetricsController', function () { test: 1, ...DEFAULT_EVENT_PROPERTIES, }, - }) + }); metaMetricsController.trackEvent( { event: 'Fake Event', @@ -305,13 +308,13 @@ describe('MetaMetricsController', function () { }, }, { matomoEvent: true }, - ) - mock.verify() - }) + ); + mock.verify(); + }); it('should track a non legacy event', function () { - const mock = sinon.mock(segment) - const metaMetricsController = getMetaMetricsController() + const mock = sinon.mock(segment); + const metaMetricsController = getMetaMetricsController(); mock .expects('track') .once() @@ -323,22 +326,22 @@ describe('MetaMetricsController', function () { test: 1, ...DEFAULT_EVENT_PROPERTIES, }, - }) + }); metaMetricsController.trackEvent({ event: 'Fake Event', category: 'Unit Test', properties: { test: 1, }, - }) - mock.verify() - }) + }); + mock.verify(); + }); it('should use anonymousId when metametrics send count is not trackable in send flow', function () { - const mock = sinon.mock(segment) + const mock = sinon.mock(segment); const metaMetricsController = getMetaMetricsController({ metaMetricsSendCount: 1, - }) + }); mock .expects('track') .once() @@ -350,20 +353,20 @@ describe('MetaMetricsController', function () { test: 1, ...DEFAULT_EVENT_PROPERTIES, }, - }) + }); metaMetricsController.trackEvent({ event: 'Send Fake Event', category: 'Unit Test', properties: { test: 1, }, - }) - mock.verify() - }) + }); + mock.verify(); + }); it('should use user metametrics id when metametrics send count is trackable in send flow', function () { - const mock = sinon.mock(segment) - const metaMetricsController = getMetaMetricsController() + const mock = sinon.mock(segment); + const metaMetricsController = getMetaMetricsController(); mock .expects('track') .once() @@ -375,7 +378,7 @@ describe('MetaMetricsController', function () { test: 1, ...DEFAULT_EVENT_PROPERTIES, }, - }) + }); metaMetricsController.trackEvent( { event: 'Send Fake Event', @@ -385,41 +388,41 @@ describe('MetaMetricsController', function () { }, }, { metaMetricsSendCount: 0 }, - ) - mock.verify() - }) + ); + mock.verify(); + }); it('should immediately flush queue if flushImmediately set to true', async function () { - const metaMetricsController = getMetaMetricsController() - const flushStub = sinon.stub(segment, 'flush') - const flushCalled = waitUntilCalled(flushStub, segment) + const metaMetricsController = getMetaMetricsController(); + const flushStub = sinon.stub(segment, 'flush'); + const flushCalled = waitUntilCalled(flushStub, segment); metaMetricsController.trackEvent( { event: 'Fake Event', category: 'Unit Test', }, { flushImmediately: true }, - ) - assert.doesNotReject(flushCalled()) - }) + ); + assert.doesNotReject(flushCalled()); + }); it('should throw if event or category not provided', function () { - const metaMetricsController = getMetaMetricsController() + const metaMetricsController = getMetaMetricsController(); assert.rejects( () => metaMetricsController.trackEvent({ event: 'test' }), /Must specify event and category\./u, 'must specify category', - ) + ); assert.rejects( () => metaMetricsController.trackEvent({ category: 'test' }), /Must specify event and category\./u, 'must specify event', - ) - }) + ); + }); it('should throw if provided sensitiveProperties, when excludeMetaMetricsId is true', function () { - const metaMetricsController = getMetaMetricsController() + const metaMetricsController = getMetaMetricsController(); assert.rejects( () => metaMetricsController.trackEvent( @@ -431,18 +434,18 @@ describe('MetaMetricsController', function () { { excludeMetaMetricsId: true }, ), /sensitiveProperties was specified in an event payload that also set the excludeMetaMetricsId flag/u, - ) - }) + ); + }); it('should track sensitiveProperties in a separate, anonymous event', function () { - const metaMetricsController = getMetaMetricsController() - const spy = sinon.spy(segment, 'track') + const metaMetricsController = getMetaMetricsController(); + const spy = sinon.spy(segment, 'track'); metaMetricsController.trackEvent({ event: 'Fake Event', category: 'Unit Test', sensitiveProperties: { foo: 'bar' }, - }) - assert.ok(spy.calledTwice) + }); + assert.ok(spy.calledTwice); assert.ok( spy.calledWith({ event: 'Fake Event', @@ -453,7 +456,7 @@ describe('MetaMetricsController', function () { ...DEFAULT_EVENT_PROPERTIES, }, }), - ) + ); assert.ok( spy.calledWith({ event: 'Fake Event', @@ -461,14 +464,14 @@ describe('MetaMetricsController', function () { context: DEFAULT_TEST_CONTEXT, properties: DEFAULT_EVENT_PROPERTIES, }), - ) - }) - }) + ); + }); + }); describe('trackPage', function () { it('should track a page view', function () { - const mock = sinon.mock(segment) - const metaMetricsController = getMetaMetricsController() + const mock = sinon.mock(segment); + const metaMetricsController = getMetaMetricsController(); mock .expects('page') .once() @@ -480,38 +483,38 @@ describe('MetaMetricsController', function () { params: null, ...DEFAULT_PAGE_PROPERTIES, }, - }) + }); metaMetricsController.trackPage({ name: 'home', params: null, environmentType: ENVIRONMENT_TYPE_BACKGROUND, page: METAMETRICS_BACKGROUND_PAGE_OBJECT, - }) - mock.verify() - }) + }); + mock.verify(); + }); it('should not track a page view if user is not participating in metametrics', function () { - const mock = sinon.mock(segment) + const mock = sinon.mock(segment); const metaMetricsController = getMetaMetricsController({ participateInMetaMetrics: false, - }) - mock.expects('page').never() + }); + mock.expects('page').never(); metaMetricsController.trackPage({ name: 'home', params: null, environmentType: ENVIRONMENT_TYPE_BACKGROUND, page: METAMETRICS_BACKGROUND_PAGE_OBJECT, - }) - mock.verify() - }) + }); + mock.verify(); + }); it('should track a page view if isOptInPath is true and user not yet opted in', function () { - const mock = sinon.mock(segment) + const mock = sinon.mock(segment); const metaMetricsController = getMetaMetricsController({ preferencesStore: getMockPreferencesStore({ participateInMetaMetrics: null, }), - }) + }); mock .expects('page') .once() @@ -523,7 +526,7 @@ describe('MetaMetricsController', function () { params: null, ...DEFAULT_PAGE_PROPERTIES, }, - }) + }); metaMetricsController.trackPage( { name: 'home', @@ -532,15 +535,15 @@ describe('MetaMetricsController', function () { page: METAMETRICS_BACKGROUND_PAGE_OBJECT, }, { isOptInPath: true }, - ) - mock.verify() - }) - }) + ); + mock.verify(); + }); + }); afterEach(function () { // flush the queues manually after each test - segment.flush() - segmentLegacy.flush() - sinon.restore() - }) -}) + segment.flush(); + segmentLegacy.flush(); + sinon.restore(); + }); +}); diff --git a/test/unit/app/controllers/network/network-controller-test.js b/test/unit/app/controllers/network/network-controller-test.js index 2fb123fec0..b7e1ab502f 100644 --- a/test/unit/app/controllers/network/network-controller-test.js +++ b/test/unit/app/controllers/network/network-controller-test.js @@ -1,73 +1,73 @@ -import { strict as assert } from 'assert' -import sinon from 'sinon' -import NetworkController from '../../../../../app/scripts/controllers/network' -import { getNetworkDisplayName } from '../../../../../app/scripts/controllers/network/util' +import { strict as assert } from 'assert'; +import sinon from 'sinon'; +import NetworkController from '../../../../../app/scripts/controllers/network'; +import { getNetworkDisplayName } from '../../../../../app/scripts/controllers/network/util'; describe('NetworkController', function () { describe('controller', function () { - let networkController - const noop = () => undefined + let networkController; + const noop = () => undefined; const networkControllerProviderConfig = { getAccounts: noop, - } + }; beforeEach(function () { - networkController = new NetworkController() - networkController.setInfuraProjectId('foo') - }) + networkController = new NetworkController(); + networkController.setInfuraProjectId('foo'); + }); describe('#provider', function () { it('provider should be updatable without reassignment', function () { - networkController.initializeProvider(networkControllerProviderConfig) + networkController.initializeProvider(networkControllerProviderConfig); const providerProxy = networkController.getProviderAndBlockTracker() - .provider - assert.equal(providerProxy.test, undefined) - providerProxy.setTarget({ test: true }) - assert.equal(providerProxy.test, true) - }) - }) + .provider; + assert.equal(providerProxy.test, undefined); + providerProxy.setTarget({ test: true }); + assert.equal(providerProxy.test, true); + }); + }); describe('#getNetworkState', function () { it('should return "loading" when new', function () { - const networkState = networkController.getNetworkState() - assert.equal(networkState, 'loading', 'network is loading') - }) - }) + const networkState = networkController.getNetworkState(); + assert.equal(networkState, 'loading', 'network is loading'); + }); + }); describe('#setNetworkState', function () { it('should update the network', function () { - networkController.setNetworkState('1') - const networkState = networkController.getNetworkState() - assert.equal(networkState, '1', 'network is 1') - }) - }) + networkController.setNetworkState('1'); + const networkState = networkController.getNetworkState(); + assert.equal(networkState, '1', 'network is 1'); + }); + }); describe('#setProviderType', function () { it('should update provider.type', function () { - networkController.initializeProvider(networkControllerProviderConfig) - networkController.setProviderType('mainnet') - const { type } = networkController.getProviderConfig() - assert.equal(type, 'mainnet', 'provider type is updated') - }) + networkController.initializeProvider(networkControllerProviderConfig); + networkController.setProviderType('mainnet'); + const { type } = networkController.getProviderConfig(); + assert.equal(type, 'mainnet', 'provider type is updated'); + }); it('should set the network to loading', function () { - networkController.initializeProvider(networkControllerProviderConfig) + networkController.initializeProvider(networkControllerProviderConfig); - const spy = sinon.spy(networkController, 'setNetworkState') - networkController.setProviderType('mainnet') + const spy = sinon.spy(networkController, 'setNetworkState'); + networkController.setProviderType('mainnet'); assert.equal( spy.callCount, 1, 'should have called setNetworkState 2 times', - ) + ); assert.ok( spy.calledOnceWithExactly('loading'), 'should have called with "loading" first', - ) - }) - }) - }) + ); + }); + }); + }); describe('utils', function () { it('getNetworkDisplayName should return the correct network name', function () { @@ -116,11 +116,11 @@ describe('NetworkController', function () { input: 'goerli', expected: 'Goerli', }, - ] + ]; tests.forEach(({ input, expected }) => assert.equal(getNetworkDisplayName(input), expected), - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/test/unit/app/controllers/network/pending-middleware-test.js b/test/unit/app/controllers/network/pending-middleware-test.js index 36b917d167..65e011d09d 100644 --- a/test/unit/app/controllers/network/pending-middleware-test.js +++ b/test/unit/app/controllers/network/pending-middleware-test.js @@ -1,56 +1,56 @@ -import assert from 'assert' +import assert from 'assert'; import { createPendingNonceMiddleware, createPendingTxMiddleware, -} from '../../../../../app/scripts/controllers/network/middleware/pending' -import { txMetaStub } from './stubs' +} from '../../../../../app/scripts/controllers/network/middleware/pending'; +import { txMetaStub } from './stubs'; describe('PendingNonceMiddleware', function () { describe('#createPendingNonceMiddleware', function () { - const getPendingNonce = async () => '0x2' - const address = '0xF231D46dD78806E1DD93442cf33C7671f8538748' + const getPendingNonce = async () => '0x2'; + const address = '0xF231D46dD78806E1DD93442cf33C7671f8538748'; const pendingNonceMiddleware = createPendingNonceMiddleware({ getPendingNonce, - }) + }); it('should call next if not a eth_getTransactionCount request', function (done) { - const req = { method: 'eth_getBlockByNumber' } - const res = {} - pendingNonceMiddleware(req, res, () => done()) - }) + const req = { method: 'eth_getBlockByNumber' }; + const res = {}; + pendingNonceMiddleware(req, res, () => done()); + }); it('should call next if not a "pending" block request', function (done) { - const req = { method: 'eth_getTransactionCount', params: [address] } - const res = {} - pendingNonceMiddleware(req, res, () => done()) - }) + const req = { method: 'eth_getTransactionCount', params: [address] }; + const res = {}; + pendingNonceMiddleware(req, res, () => done()); + }); it('should fill the result with a the "pending" nonce', function (done) { const req = { method: 'eth_getTransactionCount', params: [address, 'pending'], - } - const res = {} + }; + const res = {}; pendingNonceMiddleware( req, res, () => { - done(new Error('should not have called next')) + done(new Error('should not have called next')); }, () => { - assert(res.result === '0x2') - done() + assert(res.result === '0x2'); + done(); }, - ) - }) - }) + ); + }); + }); describe('#createPendingTxMiddleware', function () { - let returnUndefined = true + let returnUndefined = true; const getPendingTransactionByHash = () => - returnUndefined ? undefined : txMetaStub - const address = '0xF231D46dD78806E1DD93442cf33C7671f8538748' + returnUndefined ? undefined : txMetaStub; + const address = '0xF231D46dD78806E1DD93442cf33C7671f8538748'; const pendingTxMiddleware = createPendingTxMiddleware({ getPendingTransactionByHash, - }) + }); const spec = { blockHash: null, blockNumber: null, @@ -67,41 +67,41 @@ describe('PendingNonceMiddleware', function () { v: '0x2c', r: '0x5f973e540f2d3c2f06d3725a626b75247593cb36477187ae07ecfe0a4db3cf57', s: '0x0259b52ee8c58baaa385fb05c3f96116e58de89bcc165cb3bfdfc708672fed8a', - } + }; it('should call next if not a eth_getTransactionByHash request', function (done) { - const req = { method: 'eth_getBlockByNumber' } - const res = {} - pendingTxMiddleware(req, res, () => done()) - }) + const req = { method: 'eth_getBlockByNumber' }; + const res = {}; + pendingTxMiddleware(req, res, () => done()); + }); it('should call next if no pending txMeta is in history', function (done) { - const req = { method: 'eth_getTransactionByHash', params: [address] } - const res = {} - pendingTxMiddleware(req, res, () => done()) - }) + const req = { method: 'eth_getTransactionByHash', params: [address] }; + const res = {}; + pendingTxMiddleware(req, res, () => done()); + }); it('should fill the result with a the "pending" tx the result should match the rpc spec', function (done) { - returnUndefined = false + returnUndefined = false; const req = { method: 'eth_getTransactionByHash', params: [address, 'pending'], - } - const res = {} + }; + const res = {}; pendingTxMiddleware( req, res, () => { - done(new Error('should not have called next')) + done(new Error('should not have called next')); }, () => { assert.deepStrictEqual( res.result, spec, new Error('result does not match the spec object'), - ) - done() + ); + done(); }, - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/test/unit/app/controllers/network/stubs.js b/test/unit/app/controllers/network/stubs.js index 0388e8d087..421e125a85 100644 --- a/test/unit/app/controllers/network/stubs.js +++ b/test/unit/app/controllers/network/stubs.js @@ -2,7 +2,7 @@ import { TRANSACTION_CATEGORIES, TRANSACTION_STATUSES, TRANSACTION_TYPES, -} from '../../../../../shared/constants/transaction' +} from '../../../../../shared/constants/transaction'; export const txMetaStub = { firstRetryBlockNumber: '0x51a402', @@ -207,4 +207,4 @@ export const txMetaStub = { }, type: TRANSACTION_TYPES.STANDARD, v: '0x2c', -} +}; diff --git a/test/unit/app/controllers/permissions/helpers.js b/test/unit/app/controllers/permissions/helpers.js index 0524be1e90..d0e4f57ddf 100644 --- a/test/unit/app/controllers/permissions/helpers.js +++ b/test/unit/app/controllers/permissions/helpers.js @@ -1,6 +1,6 @@ -import { strict as assert } from 'assert' +import { strict as assert } from 'assert'; -import { noop } from './mocks' +import { noop } from './mocks'; /** * Grants the given permissions to the given origin, using the given permissions @@ -13,7 +13,7 @@ import { noop } from './mocks' * @param {Object} permissions - The permissions to grant. */ export function grantPermissions(permController, origin, permissions) { - permController.permissions.grantNewPermissions(origin, permissions, {}, noop) + permController.permissions.grantNewPermissions(origin, permissions, {}, noop); } /** @@ -34,8 +34,8 @@ export function getRequestUserApprovalHelper(permController) { return (id, origin = 'defaultOrigin') => { return permController.permissions.requestUserApproval({ metadata: { id, origin }, - }) - } + }); + }; } /** @@ -50,15 +50,15 @@ export function getRequestUserApprovalHelper(permController) { * has been set. */ export function getUserApprovalPromise(permController) { - const originalFunction = permController.permissions.requestUserApproval + const originalFunction = permController.permissions.requestUserApproval; return new Promise((resolveHelperPromise) => { permController.permissions.requestUserApproval = (req) => { - const userApprovalPromise = originalFunction(req) - permController.permissions.requestUserApproval = originalFunction - resolveHelperPromise() - return userApprovalPromise - } - }) + const userApprovalPromise = originalFunction(req); + permController.permissions.requestUserApproval = originalFunction; + resolveHelperPromise(); + return userApprovalPromise; + }; + }); } /** @@ -73,46 +73,50 @@ export function getUserApprovalPromise(permController) { */ export function validateActivityEntry(entry, req, res, methodType, success) { assert.doesNotThrow(() => { - _validateActivityEntry(entry, req, res, methodType, success) - }, 'should have expected activity entry') + _validateActivityEntry(entry, req, res, methodType, success); + }, 'should have expected activity entry'); } function _validateActivityEntry(entry, req, res, methodType, success) { - assert.ok(entry, 'entry should exist') + assert.ok(entry, 'entry should exist'); - assert.equal(entry.id, req.id) - assert.equal(entry.method, req.method) - assert.equal(entry.origin, req.origin) - assert.equal(entry.methodType, methodType) - assert.deepEqual(entry.request, req, 'entry.request should equal the request') + assert.equal(entry.id, req.id); + assert.equal(entry.method, req.method); + assert.equal(entry.origin, req.origin); + assert.equal(entry.methodType, methodType); + assert.deepEqual( + entry.request, + req, + 'entry.request should equal the request', + ); if (res) { assert.ok( Number.isInteger(entry.requestTime) && Number.isInteger(entry.responseTime), 'request and response times should be numbers', - ) + ); assert.ok( entry.requestTime <= entry.responseTime, 'request time should be less than response time', - ) + ); - assert.equal(entry.success, success) + assert.equal(entry.success, success); assert.deepEqual( entry.response, res, 'entry.response should equal the response', - ) + ); } else { assert.ok( Number.isInteger(entry.requestTime) && entry.requestTime > 0, 'entry should have non-zero request time', - ) + ); assert.ok( entry.success === null && entry.responseTime === null && entry.response === null, 'entry response values should be null', - ) + ); } } diff --git a/test/unit/app/controllers/permissions/mocks.js b/test/unit/app/controllers/permissions/mocks.js index be4a2321bb..ddbf9ff417 100644 --- a/test/unit/app/controllers/permissions/mocks.js +++ b/test/unit/app/controllers/permissions/mocks.js @@ -1,15 +1,15 @@ -import { ethErrors, errorCodes } from 'eth-rpc-errors' -import deepFreeze from 'deep-freeze-strict' +import { ethErrors, errorCodes } from 'eth-rpc-errors'; +import deepFreeze from 'deep-freeze-strict'; -import { ApprovalController } from '@metamask/controllers' +import { ApprovalController } from '@metamask/controllers'; -import _getRestrictedMethods from '../../../../../app/scripts/controllers/permissions/restrictedMethods' +import _getRestrictedMethods from '../../../../../app/scripts/controllers/permissions/restrictedMethods'; -import { CAVEAT_NAMES } from '../../../../../shared/constants/permissions' +import { CAVEAT_NAMES } from '../../../../../shared/constants/permissions'; import { CAVEAT_TYPES, NOTIFICATION_NAMES, -} from '../../../../../app/scripts/controllers/permissions/enums' +} from '../../../../../app/scripts/controllers/permissions/enums'; /** * README @@ -21,7 +21,7 @@ import { * - Immutable mock values like Ethereum accounts and expected states */ -export const noop = () => undefined +export const noop = () => undefined; /** * Mock Permissions Controller and Middleware @@ -32,14 +32,14 @@ const keyringAccounts = deepFreeze([ '0xc42edfcc21ed14dda456aa0756c153f7985d8813', '0x7ae1cdd37bcbdb0e1f491974da8022bfdbf9c2bf', '0xcc74c7a59194e5d9268476955650d1e285be703c', -]) +]); const getIdentities = () => { return keyringAccounts.reduce((identities, address, index) => { - identities[address] = { address, name: `Account ${index}` } - return identities - }, {}) -} + identities[address] = { address, name: `Account ${index}` }; + return identities; + }, {}); +}; // perm controller initialization helper const getRestrictedMethods = (permController) => { @@ -52,15 +52,15 @@ const getRestrictedMethods = (permController) => { description: `This method is only for testing.`, method: (req, res, __, end) => { if (req.params[0]) { - res.result = 1 + res.result = 1; } else { - res.result = 0 + res.result = 0; } - end() + end(); }, }, - } -} + }; +}; /** * Gets default mock constructor options for a permissions controller. @@ -84,12 +84,12 @@ export function getPermControllerOpts() { return { identities: getIdentities(), selectedAddress: keyringAccounts[0], - } + }; }, subscribe: noop, }, showPermissionRequest: noop, - } + }; } /** @@ -102,24 +102,24 @@ export function getPermControllerOpts() { * @returns {Function} A Promise-wrapped middleware function with convenient default args. */ export function getPermissionsMiddleware(permController, origin, extensionId) { - const middleware = permController.createMiddleware({ origin, extensionId }) + const middleware = permController.createMiddleware({ origin, extensionId }); return (req, res = {}, next = noop, end) => { return new Promise((resolve, reject) => { // eslint-disable-next-line no-param-reassign - end = end || _end + end = end || _end; - middleware(req, res, next, end) + middleware(req, res, next, end); // emulates json-rpc-engine error handling function _end(err) { if (err || res.error) { - reject(err || res.error) + reject(err || res.error); } else { - resolve(res) + resolve(res); } } - }) - } + }); + }; } /** @@ -132,8 +132,8 @@ export const getNotifyDomain = (notifications = {}) => ( origin, notification, ) => { - notifications[origin].push(notification) -} + notifications[origin].push(notification); +}; /** * @param {Object} notifications - An object that will store notifications produced @@ -143,9 +143,9 @@ export const getNotifyDomain = (notifications = {}) => ( */ export const getNotifyAllDomains = (notifications = {}) => (notification) => { Object.keys(notifications).forEach((origin) => { - notifications[origin].push(notification) - }) -} + notifications[origin].push(notification); + }); +}; /** * Constants and Mock Objects @@ -156,13 +156,13 @@ const DOMAINS = { a: { origin: 'https://foo.xyz', host: 'foo.xyz' }, b: { origin: 'https://bar.abc', host: 'bar.abc' }, c: { origin: 'https://baz.def', host: 'baz.def' }, -} +}; const PERM_NAMES = { eth_accounts: 'eth_accounts', test_method: 'test_method', does_not_exist: 'does_not_exist', -} +}; const ACCOUNTS = { a: { @@ -177,7 +177,7 @@ const ACCOUNTS = { permitted: [keyringAccounts[1]], primary: keyringAccounts[1], }, -} +}; /** * Helpers for getting mock caveats. @@ -201,9 +201,9 @@ const CAVEATS = { value: accounts, name: CAVEAT_NAMES.exposedAccounts, }, - ] + ]; }, -} +}; /** * Each function here corresponds to what would be a type or interface consumed @@ -219,7 +219,7 @@ const PERMS = { return { permissions: { ...permissions }, metadata: { id }, - } + }; }, /** @@ -230,21 +230,21 @@ const PERMS = { * @returns {Object} A permissions request object with eth_accounts */ eth_accounts: () => { - return { eth_accounts: {} } + return { eth_accounts: {} }; }, /** * @returns {Object} A permissions request object with test_method */ test_method: () => { - return { test_method: {} } + return { test_method: {} }; }, /** * @returns {Object} A permissions request object with does_not_exist */ does_not_exist: () => { - return { does_not_exist: {} } + return { does_not_exist: {} }; }, }, @@ -261,7 +261,7 @@ const PERMS = { eth_accounts: { caveats: CAVEATS.eth_accounts(accounts), }, - } + }; }, /** @@ -270,7 +270,7 @@ const PERMS = { test_method: () => { return { test_method: {}, - } + }; }, }, @@ -288,7 +288,7 @@ const PERMS = { return { parentCapability: PERM_NAMES.eth_accounts, caveats: CAVEATS.eth_accounts(accounts), - } + }; }, /** @@ -297,10 +297,10 @@ const PERMS = { test_method: () => { return { parentCapability: PERM_NAMES.test_method, - } + }; }, }, -} +}; /** * Objects with function values for getting correctly formatted permissions, @@ -320,14 +320,14 @@ export const getters = deepFreeze({ return { name: 'Error', message: 'Must provide non-empty array of account(s).', - } + }; }, nonKeyringAccount: (account) => { return { name: 'Error', message: `Unknown account: ${account}`, - } + }; }, }, @@ -337,7 +337,7 @@ export const getters = deepFreeze({ // name: 'EthereumRpcError', message: `Failed to add 'eth_accounts' to '${origin}'.`, code: errorCodes.rpc.internal, - } + }; }, }, @@ -345,17 +345,17 @@ export const getters = deepFreeze({ alreadyPermitted: () => { return { message: 'Account is already permitted for origin', - } + }; }, invalidOrigin: () => { return { message: 'Unrecognized domain', - } + }; }, noEthAccountsPermission: () => { return { message: `Origin does not have 'eth_accounts' permission`, - } + }; }, }, @@ -363,17 +363,17 @@ export const getters = deepFreeze({ notPermitted: () => { return { message: 'Account is not permitted for origin', - } + }; }, invalidOrigin: () => { return { message: 'Unrecognized domain', - } + }; }, noEthAccountsPermission: () => { return { message: `Origin does not have 'eth_accounts' permission`, - } + }; }, }, @@ -382,7 +382,7 @@ export const getters = deepFreeze({ return { name: 'Error', message: 'Selected account should be a non-empty string.', - } + }; }, }, @@ -390,7 +390,7 @@ export const getters = deepFreeze({ noPermsRequested: () => { return { message: 'Must request at least one permission.', - } + }; }, }, @@ -398,12 +398,12 @@ export const getters = deepFreeze({ rejection: () => { return { message: ethErrors.provider.userRejectedRequest().message, - } + }; }, methodNotFound: (methodName) => { return { message: `The method '${methodName}' does not exist / is not available.`, - } + }; }, }, @@ -411,7 +411,7 @@ export const getters = deepFreeze({ badOrigin: () => { return { message: 'Must provide non-empty string origin.', - } + }; }, }, @@ -419,7 +419,7 @@ export const getters = deepFreeze({ unauthorized: () => { return { code: 4100, - } + }; }, }, @@ -427,12 +427,12 @@ export const getters = deepFreeze({ duplicateOriginOrId: (id, origin) => { return { message: `Pending approval with id '${id}' or origin '${origin}' already exists.`, - } + }; }, requestAlreadyPending: (origin) => { return { message: `Request of type 'wallet_requestPermissions' already pending for origin ${origin}. Please wait.`, - } + }; }, }, @@ -440,7 +440,7 @@ export const getters = deepFreeze({ requestAlreadyPending: () => { return { message: 'Already processing eth_requestAccounts. Please wait.', - } + }; }, }, @@ -448,12 +448,12 @@ export const getters = deepFreeze({ invalidOrigin: (origin) => { return { message: `Invalid origin: '${origin}'`, - } + }; }, invalidAccounts: () => { return { message: 'Invalid accounts', - } + }; }, }, }, @@ -471,7 +471,7 @@ export const getters = deepFreeze({ return { method: NOTIFICATION_NAMES.accountsChanged, params: [], - } + }; }, /** @@ -484,7 +484,7 @@ export const getters = deepFreeze({ return { method: NOTIFICATION_NAMES.accountsChanged, params: accounts, - } + }; }, }, @@ -506,11 +506,11 @@ export const getters = deepFreeze({ origin, method, params, - } + }; if (id !== undefined) { - req.id = id + req.id = id; } - return req + return req; }, /** @@ -524,7 +524,7 @@ export const getters = deepFreeze({ origin, method: 'eth_accounts', params: [], - } + }; }, /** @@ -539,7 +539,7 @@ export const getters = deepFreeze({ origin, method: 'test_method', params: [param], - } + }; }, /** @@ -553,7 +553,7 @@ export const getters = deepFreeze({ origin, method: 'eth_requestAccounts', params: [], - } + }; }, /** @@ -569,7 +569,7 @@ export const getters = deepFreeze({ origin, method: 'wallet_requestPermissions', params: [PERMS.requests[permissionName]()], - } + }; }, /** @@ -585,7 +585,7 @@ export const getters = deepFreeze({ origin, method: 'wallet_requestPermissions', params: [permissions], - } + }; }, /** @@ -604,10 +604,10 @@ export const getters = deepFreeze({ ...args, name, }, - } + }; }, }, -}) +}); /** * Objects with immutable mock values. @@ -733,4 +733,4 @@ export const constants = deepFreeze({ }, ], }, -}) +}); diff --git a/test/unit/app/controllers/permissions/permissions-controller-test.js b/test/unit/app/controllers/permissions/permissions-controller-test.js index 2eee261f18..9fb2529a42 100644 --- a/test/unit/app/controllers/permissions/permissions-controller-test.js +++ b/test/unit/app/controllers/permissions/permissions-controller-test.js @@ -1,15 +1,15 @@ -import { strict as assert } from 'assert' -import { find } from 'lodash' -import sinon from 'sinon' +import { strict as assert } from 'assert'; +import { find } from 'lodash'; +import sinon from 'sinon'; import { METADATA_STORE_KEY, METADATA_CACHE_MAX_SIZE, -} from '../../../../../app/scripts/controllers/permissions/enums' +} from '../../../../../app/scripts/controllers/permissions/enums'; -import { PermissionsController } from '../../../../../app/scripts/controllers/permissions' +import { PermissionsController } from '../../../../../app/scripts/controllers/permissions'; -import { getRequestUserApprovalHelper, grantPermissions } from './helpers' +import { getRequestUserApprovalHelper, grantPermissions } from './helpers'; import { constants, @@ -17,9 +17,9 @@ import { getNotifyDomain, getNotifyAllDomains, getPermControllerOpts, -} from './mocks' +} from './mocks'; -const { ERRORS, NOTIFICATIONS, PERMS } = getters +const { ERRORS, NOTIFICATIONS, PERMS } = getters; const { ALL_ACCOUNTS, @@ -29,22 +29,22 @@ const { PERM_NAMES, REQUEST_IDS, EXTRA_ACCOUNT, -} = constants +} = constants; const initNotifications = () => { return Object.values(DOMAINS).reduce((acc, domain) => { - acc[domain.origin] = [] - return acc - }, {}) -} + acc[domain.origin] = []; + return acc; + }, {}); +}; const initPermController = (notifications = initNotifications()) => { return new PermissionsController({ ...getPermControllerOpts(), notifyDomain: getNotifyDomain(notifications), notifyAllDomains: getNotifyAllDomains(notifications), - }) -} + }); +}; describe('permissions controller', function () { describe('constructor', function () { @@ -52,393 +52,393 @@ describe('permissions controller', function () { assert.throws( () => new PermissionsController(), 'should throw on undefined argument', - ) - }) - }) + ); + }); + }); describe('getAccounts', function () { - let permController + let permController; beforeEach(function () { - permController = initPermController() + permController = initPermController(); grantPermissions( permController, DOMAINS.a.origin, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.a.permitted), - ) + ); grantPermissions( permController, DOMAINS.b.origin, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.b.permitted), - ) - }) + ); + }); it('gets permitted accounts for permitted origins', async function () { - const aAccounts = await permController.getAccounts(DOMAINS.a.origin) - const bAccounts = await permController.getAccounts(DOMAINS.b.origin) + const aAccounts = await permController.getAccounts(DOMAINS.a.origin); + const bAccounts = await permController.getAccounts(DOMAINS.b.origin); assert.deepEqual( aAccounts, [ACCOUNTS.a.primary], 'first origin should have correct accounts', - ) + ); assert.deepEqual( bAccounts, [ACCOUNTS.b.primary], 'second origin should have correct accounts', - ) - }) + ); + }); it('does not get accounts for unpermitted origins', async function () { - const cAccounts = await permController.getAccounts(DOMAINS.c.origin) - assert.deepEqual(cAccounts, [], 'origin should have no accounts') - }) + const cAccounts = await permController.getAccounts(DOMAINS.c.origin); + assert.deepEqual(cAccounts, [], 'origin should have no accounts'); + }); it('does not handle "metamask" origin as special case', async function () { - const metamaskAccounts = await permController.getAccounts('metamask') - assert.deepEqual(metamaskAccounts, [], 'origin should have no accounts') - }) - }) + const metamaskAccounts = await permController.getAccounts('metamask'); + assert.deepEqual(metamaskAccounts, [], 'origin should have no accounts'); + }); + }); describe('hasPermission', function () { it('returns correct values', async function () { - const permController = initPermController() + const permController = initPermController(); grantPermissions( permController, DOMAINS.a.origin, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.a.permitted), - ) + ); grantPermissions( permController, DOMAINS.b.origin, PERMS.finalizedRequests.test_method(), - ) + ); assert.ok( permController.hasPermission(DOMAINS.a.origin, 'eth_accounts'), 'should return true for granted permission', - ) + ); assert.ok( permController.hasPermission(DOMAINS.b.origin, 'test_method'), 'should return true for granted permission', - ) + ); assert.ok( !permController.hasPermission(DOMAINS.a.origin, 'test_method'), 'should return false for non-granted permission', - ) + ); assert.ok( !permController.hasPermission(DOMAINS.b.origin, 'eth_accounts'), 'should return true for non-granted permission', - ) + ); assert.ok( !permController.hasPermission('foo', 'eth_accounts'), 'should return false for unknown origin', - ) + ); assert.ok( !permController.hasPermission(DOMAINS.b.origin, 'foo'), 'should return false for unknown permission', - ) - }) - }) + ); + }); + }); describe('clearPermissions', function () { it('notifies all appropriate domains and removes permissions', async function () { - const notifications = initNotifications() - const permController = initPermController(notifications) + const notifications = initNotifications(); + const permController = initPermController(notifications); grantPermissions( permController, DOMAINS.a.origin, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.a.permitted), - ) + ); grantPermissions( permController, DOMAINS.b.origin, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.b.permitted), - ) + ); grantPermissions( permController, DOMAINS.c.origin, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.c.permitted), - ) + ); - let aAccounts = await permController.getAccounts(DOMAINS.a.origin) - let bAccounts = await permController.getAccounts(DOMAINS.b.origin) - let cAccounts = await permController.getAccounts(DOMAINS.c.origin) + let aAccounts = await permController.getAccounts(DOMAINS.a.origin); + let bAccounts = await permController.getAccounts(DOMAINS.b.origin); + let cAccounts = await permController.getAccounts(DOMAINS.c.origin); assert.deepEqual( aAccounts, [ACCOUNTS.a.primary], 'first origin should have correct accounts', - ) + ); assert.deepEqual( bAccounts, [ACCOUNTS.b.primary], 'second origin should have correct accounts', - ) + ); assert.deepEqual( cAccounts, [ACCOUNTS.c.primary], 'third origin should have correct accounts', - ) + ); - permController.clearPermissions() + permController.clearPermissions(); Object.keys(notifications).forEach((origin) => { assert.deepEqual( notifications[origin], [NOTIFICATIONS.removedAccounts()], 'origin should have single metamask_accountsChanged:[] notification', - ) - }) + ); + }); - aAccounts = await permController.getAccounts(DOMAINS.a.origin) - bAccounts = await permController.getAccounts(DOMAINS.b.origin) - cAccounts = await permController.getAccounts(DOMAINS.c.origin) + aAccounts = await permController.getAccounts(DOMAINS.a.origin); + bAccounts = await permController.getAccounts(DOMAINS.b.origin); + cAccounts = await permController.getAccounts(DOMAINS.c.origin); - assert.deepEqual(aAccounts, [], 'first origin should have no accounts') - assert.deepEqual(bAccounts, [], 'second origin should have no accounts') - assert.deepEqual(cAccounts, [], 'third origin should have no accounts') + assert.deepEqual(aAccounts, [], 'first origin should have no accounts'); + assert.deepEqual(bAccounts, [], 'second origin should have no accounts'); + assert.deepEqual(cAccounts, [], 'third origin should have no accounts'); Object.keys(notifications).forEach((origin) => { assert.deepEqual( permController.permissions.getPermissionsForDomain(origin), [], 'origin should have no permissions', - ) - }) + ); + }); assert.deepEqual( Object.keys(permController.permissions.getDomains()), [], 'all domains should be deleted', - ) - }) - }) + ); + }); + }); describe('removePermissionsFor', function () { - let permController, notifications + let permController, notifications; beforeEach(function () { - notifications = initNotifications() - permController = initPermController(notifications) + notifications = initNotifications(); + permController = initPermController(notifications); grantPermissions( permController, DOMAINS.a.origin, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.a.permitted), - ) + ); grantPermissions( permController, DOMAINS.b.origin, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.b.permitted), - ) - }) + ); + }); it('removes permissions for multiple domains', async function () { - let aAccounts = await permController.getAccounts(DOMAINS.a.origin) - let bAccounts = await permController.getAccounts(DOMAINS.b.origin) + let aAccounts = await permController.getAccounts(DOMAINS.a.origin); + let bAccounts = await permController.getAccounts(DOMAINS.b.origin); assert.deepEqual( aAccounts, [ACCOUNTS.a.primary], 'first origin should have correct accounts', - ) + ); assert.deepEqual( bAccounts, [ACCOUNTS.b.primary], 'second origin should have correct accounts', - ) + ); permController.removePermissionsFor({ [DOMAINS.a.origin]: [PERM_NAMES.eth_accounts], [DOMAINS.b.origin]: [PERM_NAMES.eth_accounts], - }) + }); - aAccounts = await permController.getAccounts(DOMAINS.a.origin) - bAccounts = await permController.getAccounts(DOMAINS.b.origin) + aAccounts = await permController.getAccounts(DOMAINS.a.origin); + bAccounts = await permController.getAccounts(DOMAINS.b.origin); - assert.deepEqual(aAccounts, [], 'first origin should have no accounts') - assert.deepEqual(bAccounts, [], 'second origin should have no accounts') + assert.deepEqual(aAccounts, [], 'first origin should have no accounts'); + assert.deepEqual(bAccounts, [], 'second origin should have no accounts'); assert.deepEqual( notifications[DOMAINS.a.origin], [NOTIFICATIONS.removedAccounts()], 'first origin should have correct notification', - ) + ); assert.deepEqual( notifications[DOMAINS.b.origin], [NOTIFICATIONS.removedAccounts()], 'second origin should have correct notification', - ) + ); assert.deepEqual( Object.keys(permController.permissions.getDomains()), [], 'all domains should be deleted', - ) - }) + ); + }); it('only removes targeted permissions from single domain', async function () { grantPermissions( permController, DOMAINS.b.origin, PERMS.finalizedRequests.test_method(), - ) + ); let bPermissions = permController.permissions.getPermissionsForDomain( DOMAINS.b.origin, - ) + ); assert.ok( bPermissions.length === 2 && find(bPermissions, { parentCapability: PERM_NAMES.eth_accounts }) && find(bPermissions, { parentCapability: PERM_NAMES.test_method }), 'origin should have correct permissions', - ) + ); permController.removePermissionsFor({ [DOMAINS.b.origin]: [PERM_NAMES.test_method], - }) + }); bPermissions = permController.permissions.getPermissionsForDomain( DOMAINS.b.origin, - ) + ); assert.ok( bPermissions.length === 1 && find(bPermissions, { parentCapability: PERM_NAMES.eth_accounts }), 'only targeted permission should have been removed', - ) - }) + ); + }); it('removes permissions for a single domain, without affecting another', async function () { permController.removePermissionsFor({ [DOMAINS.b.origin]: [PERM_NAMES.eth_accounts], - }) + }); - const aAccounts = await permController.getAccounts(DOMAINS.a.origin) - const bAccounts = await permController.getAccounts(DOMAINS.b.origin) + const aAccounts = await permController.getAccounts(DOMAINS.a.origin); + const bAccounts = await permController.getAccounts(DOMAINS.b.origin); assert.deepEqual( aAccounts, [ACCOUNTS.a.primary], 'first origin should have correct accounts', - ) - assert.deepEqual(bAccounts, [], 'second origin should have no accounts') + ); + assert.deepEqual(bAccounts, [], 'second origin should have no accounts'); assert.deepEqual( notifications[DOMAINS.a.origin], [], 'first origin should have no notifications', - ) + ); assert.deepEqual( notifications[DOMAINS.b.origin], [NOTIFICATIONS.removedAccounts()], 'second origin should have correct notification', - ) + ); assert.deepEqual( Object.keys(permController.permissions.getDomains()), [DOMAINS.a.origin], 'only first origin should remain', - ) - }) + ); + }); it('send notification but does not affect permissions for unknown domain', async function () { // it knows nothing of this origin permController.removePermissionsFor({ [DOMAINS.c.origin]: [PERM_NAMES.eth_accounts], - }) + }); assert.deepEqual( notifications[DOMAINS.c.origin], [NOTIFICATIONS.removedAccounts()], 'unknown origin should have notification', - ) + ); - const aAccounts = await permController.getAccounts(DOMAINS.a.origin) - const bAccounts = await permController.getAccounts(DOMAINS.b.origin) + const aAccounts = await permController.getAccounts(DOMAINS.a.origin); + const bAccounts = await permController.getAccounts(DOMAINS.b.origin); assert.deepEqual( aAccounts, [ACCOUNTS.a.primary], 'first origin should have correct accounts', - ) + ); assert.deepEqual( bAccounts, [ACCOUNTS.b.primary], 'second origin should have correct accounts', - ) + ); assert.deepEqual( Object.keys(permController.permissions.getDomains()), [DOMAINS.a.origin, DOMAINS.b.origin], 'should have correct domains', - ) - }) - }) + ); + }); + }); describe('validatePermittedAccounts', function () { - let permController + let permController; beforeEach(function () { - permController = initPermController() + permController = initPermController(); grantPermissions( permController, DOMAINS.a.origin, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.a.permitted), - ) + ); grantPermissions( permController, DOMAINS.b.origin, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.b.permitted), - ) - }) + ); + }); it('throws error on non-array accounts', async function () { await assert.throws( () => permController.validatePermittedAccounts(undefined), ERRORS.validatePermittedAccounts.invalidParam(), 'should throw on undefined', - ) + ); await assert.throws( () => permController.validatePermittedAccounts(false), ERRORS.validatePermittedAccounts.invalidParam(), 'should throw on false', - ) + ); await assert.throws( () => permController.validatePermittedAccounts(true), ERRORS.validatePermittedAccounts.invalidParam(), 'should throw on true', - ) + ); await assert.throws( () => permController.validatePermittedAccounts({}), ERRORS.validatePermittedAccounts.invalidParam(), 'should throw on non-array object', - ) - }) + ); + }); it('throws error on empty array of accounts', async function () { await assert.throws( () => permController.validatePermittedAccounts([]), ERRORS.validatePermittedAccounts.invalidParam(), 'should throw on empty array', - ) - }) + ); + }); it('throws error if any account value is not in keyring', async function () { - const keyringAccounts = await permController.getKeyringAccounts() + const keyringAccounts = await permController.getKeyringAccounts(); await assert.throws( () => permController.validatePermittedAccounts([DUMMY_ACCOUNT]), ERRORS.validatePermittedAccounts.nonKeyringAccount(DUMMY_ACCOUNT), 'should throw on non-keyring account', - ) + ); await assert.throws( () => @@ -447,54 +447,54 @@ describe('permissions controller', function () { ), ERRORS.validatePermittedAccounts.nonKeyringAccount(DUMMY_ACCOUNT), 'should throw on non-keyring account with other accounts', - ) - }) + ); + }); it('succeeds if all accounts are in keyring', async function () { - const keyringAccounts = await permController.getKeyringAccounts() + const keyringAccounts = await permController.getKeyringAccounts(); await assert.doesNotThrow( () => permController.validatePermittedAccounts(keyringAccounts), 'should not throw on all keyring accounts', - ) + ); await assert.doesNotThrow( () => permController.validatePermittedAccounts([keyringAccounts[0]]), 'should not throw on single keyring account', - ) + ); await assert.doesNotThrow( () => permController.validatePermittedAccounts([keyringAccounts[1]]), 'should not throw on single keyring account', - ) - }) - }) + ); + }); + }); describe('addPermittedAccount', function () { - let permController, notifications + let permController, notifications; beforeEach(function () { - notifications = initNotifications() - permController = initPermController(notifications) + notifications = initNotifications(); + permController = initPermController(notifications); grantPermissions( permController, DOMAINS.a.origin, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.a.permitted), - ) + ); grantPermissions( permController, DOMAINS.b.origin, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.b.permitted), - ) - }) + ); + }); it('should throw if account is not a string', async function () { await assert.rejects( () => permController.addPermittedAccount(DOMAINS.a.origin, {}), ERRORS.validatePermittedAccounts.nonKeyringAccount({}), 'should throw on non-string account param', - ) - }) + ); + }); it('should throw if given account is not in keyring', async function () { await assert.rejects( @@ -502,16 +502,16 @@ describe('permissions controller', function () { permController.addPermittedAccount(DOMAINS.a.origin, DUMMY_ACCOUNT), ERRORS.validatePermittedAccounts.nonKeyringAccount(DUMMY_ACCOUNT), 'should throw on non-keyring account', - ) - }) + ); + }); it('should throw if origin is invalid', async function () { await assert.rejects( () => permController.addPermittedAccount(false, EXTRA_ACCOUNT), ERRORS.addPermittedAccount.invalidOrigin(), 'should throw on invalid origin', - ) - }) + ); + }); it('should throw if origin lacks any permissions', async function () { await assert.rejects( @@ -519,23 +519,23 @@ describe('permissions controller', function () { permController.addPermittedAccount(DOMAINS.c.origin, EXTRA_ACCOUNT), ERRORS.addPermittedAccount.invalidOrigin(), 'should throw on origin without permissions', - ) - }) + ); + }); it('should throw if origin lacks eth_accounts permission', async function () { grantPermissions( permController, DOMAINS.c.origin, PERMS.finalizedRequests.test_method(), - ) + ); await assert.rejects( () => permController.addPermittedAccount(DOMAINS.c.origin, EXTRA_ACCOUNT), ERRORS.addPermittedAccount.noEthAccountsPermission(), 'should throw on origin without eth_accounts permission', - ) - }) + ); + }); it('should throw if account is already permitted', async function () { await assert.rejects( @@ -546,55 +546,55 @@ describe('permissions controller', function () { ), ERRORS.addPermittedAccount.alreadyPermitted(), 'should throw if account is already permitted', - ) - }) + ); + }); it('should successfully add permitted account', async function () { - await permController.addPermittedAccount(DOMAINS.a.origin, EXTRA_ACCOUNT) + await permController.addPermittedAccount(DOMAINS.a.origin, EXTRA_ACCOUNT); const accounts = await permController._getPermittedAccounts( DOMAINS.a.origin, - ) + ); assert.deepEqual( accounts, [...ACCOUNTS.a.permitted, EXTRA_ACCOUNT], 'origin should have correct accounts', - ) + ); assert.deepEqual( notifications[DOMAINS.a.origin][0], NOTIFICATIONS.newAccounts([ACCOUNTS.a.primary]), 'origin should have correct notification', - ) - }) - }) + ); + }); + }); describe('removePermittedAccount', function () { - let permController, notifications + let permController, notifications; beforeEach(function () { - notifications = initNotifications() - permController = initPermController(notifications) + notifications = initNotifications(); + permController = initPermController(notifications); grantPermissions( permController, DOMAINS.a.origin, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.a.permitted), - ) + ); grantPermissions( permController, DOMAINS.b.origin, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.b.permitted), - ) - }) + ); + }); it('should throw if account is not a string', async function () { await assert.rejects( () => permController.removePermittedAccount(DOMAINS.a.origin, {}), ERRORS.validatePermittedAccounts.nonKeyringAccount({}), 'should throw on non-string account param', - ) - }) + ); + }); it('should throw if given account is not in keyring', async function () { await assert.rejects( @@ -605,16 +605,16 @@ describe('permissions controller', function () { ), ERRORS.validatePermittedAccounts.nonKeyringAccount(DUMMY_ACCOUNT), 'should throw on non-keyring account', - ) - }) + ); + }); it('should throw if origin is invalid', async function () { await assert.rejects( () => permController.removePermittedAccount(false, EXTRA_ACCOUNT), ERRORS.removePermittedAccount.invalidOrigin(), 'should throw on invalid origin', - ) - }) + ); + }); it('should throw if origin lacks any permissions', async function () { await assert.rejects( @@ -625,15 +625,15 @@ describe('permissions controller', function () { ), ERRORS.removePermittedAccount.invalidOrigin(), 'should throw on origin without permissions', - ) - }) + ); + }); it('should throw if origin lacks eth_accounts permission', async function () { grantPermissions( permController, DOMAINS.c.origin, PERMS.finalizedRequests.test_method(), - ) + ); await assert.rejects( () => @@ -643,8 +643,8 @@ describe('permissions controller', function () { ), ERRORS.removePermittedAccount.noEthAccountsPermission(), 'should throw on origin without eth_accounts permission', - ) - }) + ); + }); it('should throw if account is not permitted', async function () { await assert.rejects( @@ -655,174 +655,174 @@ describe('permissions controller', function () { ), ERRORS.removePermittedAccount.notPermitted(), 'should throw if account is not permitted', - ) - }) + ); + }); it('should successfully remove permitted account', async function () { await permController.removePermittedAccount( DOMAINS.a.origin, ACCOUNTS.a.permitted[1], - ) + ); const accounts = await permController._getPermittedAccounts( DOMAINS.a.origin, - ) + ); assert.deepEqual( accounts, ACCOUNTS.a.permitted.filter((acc) => acc !== ACCOUNTS.a.permitted[1]), 'origin should have correct accounts', - ) + ); assert.deepEqual( notifications[DOMAINS.a.origin][0], NOTIFICATIONS.newAccounts([ACCOUNTS.a.primary]), 'origin should have correct notification', - ) - }) + ); + }); it('should remove eth_accounts permission if removing only permitted account', async function () { await permController.removePermittedAccount( DOMAINS.b.origin, ACCOUNTS.b.permitted[0], - ) + ); - const accounts = await permController.getAccounts(DOMAINS.b.origin) + const accounts = await permController.getAccounts(DOMAINS.b.origin); - assert.deepEqual(accounts, [], 'origin should have no accounts') + assert.deepEqual(accounts, [], 'origin should have no accounts'); const permission = await permController.permissions.getPermission( DOMAINS.b.origin, PERM_NAMES.eth_accounts, - ) + ); assert.equal( permission, undefined, 'origin should not have eth_accounts permission', - ) + ); assert.deepEqual( notifications[DOMAINS.b.origin][0], NOTIFICATIONS.removedAccounts(), 'origin should have correct notification', - ) - }) - }) + ); + }); + }); describe('removeAllAccountPermissions', function () { - let permController, notifications + let permController, notifications; beforeEach(function () { - notifications = initNotifications() - permController = initPermController(notifications) + notifications = initNotifications(); + permController = initPermController(notifications); grantPermissions( permController, DOMAINS.a.origin, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.a.permitted), - ) + ); grantPermissions( permController, DOMAINS.b.origin, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.b.permitted), - ) + ); grantPermissions( permController, DOMAINS.c.origin, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.b.permitted), - ) - }) + ); + }); it('should throw if account is not a string', async function () { await assert.rejects( () => permController.removeAllAccountPermissions({}), ERRORS.validatePermittedAccounts.nonKeyringAccount({}), 'should throw on non-string account param', - ) - }) + ); + }); it('should throw if given account is not in keyring', async function () { await assert.rejects( () => permController.removeAllAccountPermissions(DUMMY_ACCOUNT), ERRORS.validatePermittedAccounts.nonKeyringAccount(DUMMY_ACCOUNT), 'should throw on non-keyring account', - ) - }) + ); + }); it('should remove permitted account from single origin', async function () { - await permController.removeAllAccountPermissions(ACCOUNTS.a.permitted[1]) + await permController.removeAllAccountPermissions(ACCOUNTS.a.permitted[1]); const accounts = await permController._getPermittedAccounts( DOMAINS.a.origin, - ) + ); assert.deepEqual( accounts, ACCOUNTS.a.permitted.filter((acc) => acc !== ACCOUNTS.a.permitted[1]), 'origin should have correct accounts', - ) + ); assert.deepEqual( notifications[DOMAINS.a.origin][0], NOTIFICATIONS.newAccounts([ACCOUNTS.a.primary]), 'origin should have correct notification', - ) - }) + ); + }); it('should permitted account from multiple origins', async function () { - await permController.removeAllAccountPermissions(ACCOUNTS.b.permitted[0]) + await permController.removeAllAccountPermissions(ACCOUNTS.b.permitted[0]); - const bAccounts = await permController.getAccounts(DOMAINS.b.origin) - assert.deepEqual(bAccounts, [], 'first origin should no accounts') + const bAccounts = await permController.getAccounts(DOMAINS.b.origin); + assert.deepEqual(bAccounts, [], 'first origin should no accounts'); - const cAccounts = await permController.getAccounts(DOMAINS.c.origin) - assert.deepEqual(cAccounts, [], 'second origin no accounts') + const cAccounts = await permController.getAccounts(DOMAINS.c.origin); + assert.deepEqual(cAccounts, [], 'second origin no accounts'); assert.deepEqual( notifications[DOMAINS.b.origin][0], NOTIFICATIONS.removedAccounts(), 'first origin should have correct notification', - ) + ); assert.deepEqual( notifications[DOMAINS.c.origin][0], NOTIFICATIONS.removedAccounts(), 'second origin should have correct notification', - ) - }) + ); + }); it('should remove eth_accounts permission if removing only permitted account', async function () { - await permController.removeAllAccountPermissions(ACCOUNTS.b.permitted[0]) + await permController.removeAllAccountPermissions(ACCOUNTS.b.permitted[0]); - const accounts = await permController.getAccounts(DOMAINS.b.origin) + const accounts = await permController.getAccounts(DOMAINS.b.origin); - assert.deepEqual(accounts, [], 'origin should have no accounts') + assert.deepEqual(accounts, [], 'origin should have no accounts'); const permission = await permController.permissions.getPermission( DOMAINS.b.origin, PERM_NAMES.eth_accounts, - ) + ); assert.equal( permission, undefined, 'origin should not have eth_accounts permission', - ) + ); assert.deepEqual( notifications[DOMAINS.b.origin][0], NOTIFICATIONS.removedAccounts(), 'origin should have correct notification', - ) - }) - }) + ); + }); + }); describe('finalizePermissionsRequest', function () { - let permController + let permController; beforeEach(function () { - permController = initPermController() - }) + permController = initPermController(); + }); it('throws on non-keyring accounts', async function () { await assert.rejects( @@ -832,71 +832,71 @@ describe('permissions controller', function () { ), ERRORS.validatePermittedAccounts.nonKeyringAccount(DUMMY_ACCOUNT), 'should throw on non-keyring account', - ) - }) + ); + }); it('adds caveat to eth_accounts permission', async function () { const perm = await permController.finalizePermissionsRequest( PERMS.requests.eth_accounts(), ACCOUNTS.a.permitted, - ) + ); assert.deepEqual( perm, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.a.permitted), - ) - }) + ); + }); it('replaces caveat of eth_accounts permission', async function () { const perm = await permController.finalizePermissionsRequest( PERMS.finalizedRequests.eth_accounts(ACCOUNTS.a.permitted), ACCOUNTS.b.permitted, - ) + ); assert.deepEqual( perm, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.b.permitted), 'permission should have correct caveat', - ) - }) + ); + }); it('handles non-eth_accounts permission', async function () { const perm = await permController.finalizePermissionsRequest( PERMS.finalizedRequests.test_method(), ACCOUNTS.b.permitted, - ) + ); assert.deepEqual( perm, PERMS.finalizedRequests.test_method(), 'permission should have correct caveat', - ) - }) - }) + ); + }); + }); describe('preferences state update', function () { - let permController, notifications, preferences, identities + let permController, notifications, preferences, identities; beforeEach(function () { identities = ALL_ACCOUNTS.reduce((identitiesAcc, account) => { - identitiesAcc[account] = {} - return identitiesAcc - }, {}) + identitiesAcc[account] = {}; + return identitiesAcc; + }, {}); preferences = { getState: sinon.stub(), subscribe: sinon.stub(), - } + }; preferences.getState.returns({ identities, selectedAddress: DUMMY_ACCOUNT, - }) - notifications = initNotifications() + }); + notifications = initNotifications(); permController = new PermissionsController({ ...getPermControllerOpts(), notifyDomain: getNotifyDomain(notifications), notifyAllDomains: getNotifyAllDomains(notifications), preferences, - }) + }); grantPermissions( permController, DOMAINS.b.origin, @@ -904,467 +904,467 @@ describe('permissions controller', function () { ...ACCOUNTS.a.permitted, EXTRA_ACCOUNT, ]), - ) + ); grantPermissions( permController, DOMAINS.c.origin, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.a.permitted), - ) - }) + ); + }); it('should throw if given invalid account', async function () { - assert(preferences.subscribe.calledOnce) - assert(preferences.subscribe.firstCall.args.length === 1) - const onPreferencesUpdate = preferences.subscribe.firstCall.args[0] + assert(preferences.subscribe.calledOnce); + assert(preferences.subscribe.firstCall.args.length === 1); + const onPreferencesUpdate = preferences.subscribe.firstCall.args[0]; await assert.rejects( () => onPreferencesUpdate({ selectedAddress: {} }), ERRORS._handleAccountSelected.invalidParams(), 'should throw if account is not a string', - ) - }) + ); + }); it('should do nothing if account not permitted for any origins', async function () { - assert(preferences.subscribe.calledOnce) - assert(preferences.subscribe.firstCall.args.length === 1) - const onPreferencesUpdate = preferences.subscribe.firstCall.args[0] + assert(preferences.subscribe.calledOnce); + assert(preferences.subscribe.firstCall.args.length === 1); + const onPreferencesUpdate = preferences.subscribe.firstCall.args[0]; - await onPreferencesUpdate({ selectedAddress: DUMMY_ACCOUNT }) + await onPreferencesUpdate({ selectedAddress: DUMMY_ACCOUNT }); assert.deepEqual( notifications[DOMAINS.b.origin], [], 'should not have emitted notification', - ) + ); assert.deepEqual( notifications[DOMAINS.c.origin], [], 'should not have emitted notification', - ) - }) + ); + }); it('should emit notification if account already first in array for each connected site', async function () { - identities[ACCOUNTS.a.permitted[0]] = { lastSelected: 1000 } - assert(preferences.subscribe.calledOnce) - assert(preferences.subscribe.firstCall.args.length === 1) - const onPreferencesUpdate = preferences.subscribe.firstCall.args[0] + identities[ACCOUNTS.a.permitted[0]] = { lastSelected: 1000 }; + assert(preferences.subscribe.calledOnce); + assert(preferences.subscribe.firstCall.args.length === 1); + const onPreferencesUpdate = preferences.subscribe.firstCall.args[0]; - await onPreferencesUpdate({ selectedAddress: ACCOUNTS.a.permitted[0] }) + await onPreferencesUpdate({ selectedAddress: ACCOUNTS.a.permitted[0] }); assert.deepEqual( notifications[DOMAINS.b.origin], [NOTIFICATIONS.newAccounts([ACCOUNTS.a.primary])], 'should not have emitted notification', - ) + ); assert.deepEqual( notifications[DOMAINS.c.origin], [NOTIFICATIONS.newAccounts([ACCOUNTS.a.primary])], 'should not have emitted notification', - ) - }) + ); + }); it('should emit notification just for connected domains', async function () { - identities[EXTRA_ACCOUNT] = { lastSelected: 1000 } - assert(preferences.subscribe.calledOnce) - assert(preferences.subscribe.firstCall.args.length === 1) - const onPreferencesUpdate = preferences.subscribe.firstCall.args[0] + identities[EXTRA_ACCOUNT] = { lastSelected: 1000 }; + assert(preferences.subscribe.calledOnce); + assert(preferences.subscribe.firstCall.args.length === 1); + const onPreferencesUpdate = preferences.subscribe.firstCall.args[0]; - await onPreferencesUpdate({ selectedAddress: EXTRA_ACCOUNT }) + await onPreferencesUpdate({ selectedAddress: EXTRA_ACCOUNT }); assert.deepEqual( notifications[DOMAINS.b.origin], [NOTIFICATIONS.newAccounts([EXTRA_ACCOUNT])], 'should have emitted notification', - ) + ); assert.deepEqual( notifications[DOMAINS.c.origin], [], 'should not have emitted notification', - ) - }) + ); + }); it('should emit notification for multiple connected domains', async function () { - identities[ACCOUNTS.a.permitted[1]] = { lastSelected: 1000 } - assert(preferences.subscribe.calledOnce) - assert(preferences.subscribe.firstCall.args.length === 1) - const onPreferencesUpdate = preferences.subscribe.firstCall.args[0] + identities[ACCOUNTS.a.permitted[1]] = { lastSelected: 1000 }; + assert(preferences.subscribe.calledOnce); + assert(preferences.subscribe.firstCall.args.length === 1); + const onPreferencesUpdate = preferences.subscribe.firstCall.args[0]; - await onPreferencesUpdate({ selectedAddress: ACCOUNTS.a.permitted[1] }) + await onPreferencesUpdate({ selectedAddress: ACCOUNTS.a.permitted[1] }); assert.deepEqual( notifications[DOMAINS.b.origin], [NOTIFICATIONS.newAccounts([ACCOUNTS.a.permitted[1]])], 'should have emitted notification', - ) + ); assert.deepEqual( notifications[DOMAINS.c.origin], [NOTIFICATIONS.newAccounts([ACCOUNTS.c.primary])], 'should have emitted notification', - ) - }) - }) + ); + }); + }); describe('approvePermissionsRequest', function () { - let permController, requestUserApproval + let permController, requestUserApproval; beforeEach(function () { - permController = initPermController() - requestUserApproval = getRequestUserApprovalHelper(permController) - }) + permController = initPermController(); + requestUserApproval = getRequestUserApprovalHelper(permController); + }); it('does nothing if called on non-existing request', async function () { - sinon.spy(permController, 'finalizePermissionsRequest') + sinon.spy(permController, 'finalizePermissionsRequest'); - const request = PERMS.approvedRequest(REQUEST_IDS.a, null) + const request = PERMS.approvedRequest(REQUEST_IDS.a, null); await assert.doesNotReject( permController.approvePermissionsRequest(request, null), 'should not throw on non-existing request', - ) + ); assert.ok( permController.finalizePermissionsRequest.notCalled, 'should not call finalizePermissionRequest', - ) - }) + ); + }); it('rejects request with bad accounts param', async function () { const request = PERMS.approvedRequest( REQUEST_IDS.a, PERMS.requests.eth_accounts(), - ) + ); const rejectionPromise = assert.rejects( requestUserApproval(REQUEST_IDS.a), ERRORS.validatePermittedAccounts.invalidParam(), 'should reject with "null" accounts', - ) + ); - await permController.approvePermissionsRequest(request, null) - await rejectionPromise - }) + await permController.approvePermissionsRequest(request, null); + await rejectionPromise; + }); it('rejects request with no permissions', async function () { - const request = PERMS.approvedRequest(REQUEST_IDS.a, {}) + const request = PERMS.approvedRequest(REQUEST_IDS.a, {}); const requestRejection = assert.rejects( requestUserApproval(REQUEST_IDS.a), ERRORS.approvePermissionsRequest.noPermsRequested(), 'should reject if no permissions in request', - ) + ); await permController.approvePermissionsRequest( request, ACCOUNTS.a.permitted, - ) - await requestRejection - }) + ); + await requestRejection; + }); it('approves valid request', async function () { const request = PERMS.approvedRequest( REQUEST_IDS.a, PERMS.requests.eth_accounts(), - ) + ); - let perms + let perms; const requestApproval = assert.doesNotReject(async () => { - perms = await requestUserApproval(REQUEST_IDS.a) - }, 'should not reject single valid request') + perms = await requestUserApproval(REQUEST_IDS.a); + }, 'should not reject single valid request'); await permController.approvePermissionsRequest( request, ACCOUNTS.a.permitted, - ) - await requestApproval + ); + await requestApproval; assert.deepEqual( perms, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.a.permitted), 'should produce expected approved permissions', - ) - }) + ); + }); it('approves valid requests regardless of order', async function () { const request1 = PERMS.approvedRequest( REQUEST_IDS.a, PERMS.requests.eth_accounts(), - ) + ); const request2 = PERMS.approvedRequest( REQUEST_IDS.b, PERMS.requests.eth_accounts(), - ) + ); const request3 = PERMS.approvedRequest( REQUEST_IDS.c, PERMS.requests.eth_accounts(), - ) + ); - let perms1, perms2 + let perms1, perms2; const approval1 = assert.doesNotReject(async () => { - perms1 = await requestUserApproval(REQUEST_IDS.a, DOMAINS.a.origin) - }, 'should not reject request') + perms1 = await requestUserApproval(REQUEST_IDS.a, DOMAINS.a.origin); + }, 'should not reject request'); const approval2 = assert.doesNotReject(async () => { - perms2 = await requestUserApproval(REQUEST_IDS.b, DOMAINS.b.origin) - }, 'should not reject request') + perms2 = await requestUserApproval(REQUEST_IDS.b, DOMAINS.b.origin); + }, 'should not reject request'); // approve out of order await permController.approvePermissionsRequest( request2, ACCOUNTS.b.permitted, - ) + ); // add a non-existing request to the mix await permController.approvePermissionsRequest( request3, ACCOUNTS.c.permitted, - ) + ); await permController.approvePermissionsRequest( request1, ACCOUNTS.a.permitted, - ) + ); - await approval1 - await approval2 + await approval1; + await approval2; assert.deepEqual( perms1, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.a.permitted), 'first request should produce expected approved permissions', - ) + ); assert.deepEqual( perms2, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.b.permitted), 'second request should produce expected approved permissions', - ) - }) - }) + ); + }); + }); describe('rejectPermissionsRequest', function () { - let permController, requestUserApproval + let permController, requestUserApproval; beforeEach(async function () { - permController = initPermController() - requestUserApproval = getRequestUserApprovalHelper(permController) - }) + permController = initPermController(); + requestUserApproval = getRequestUserApprovalHelper(permController); + }); it('does nothing if called on non-existing request', async function () { permController.approvals.add = sinon.fake.throws( new Error('should not call add'), - ) + ); await assert.doesNotReject( permController.rejectPermissionsRequest(REQUEST_IDS.a), 'should not throw on non-existing request', - ) - }) + ); + }); it('rejects single existing request', async function () { const requestRejection = assert.rejects( requestUserApproval(REQUEST_IDS.a), ERRORS.rejectPermissionsRequest.rejection(), 'should reject with expected error', - ) + ); - await permController.rejectPermissionsRequest(REQUEST_IDS.a) - await requestRejection - }) + await permController.rejectPermissionsRequest(REQUEST_IDS.a); + await requestRejection; + }); it('rejects requests regardless of order', async function () { const requestRejection1 = assert.rejects( requestUserApproval(REQUEST_IDS.b, DOMAINS.b.origin), ERRORS.rejectPermissionsRequest.rejection(), 'should reject with expected error', - ) + ); const requestRejection2 = assert.rejects( requestUserApproval(REQUEST_IDS.c, DOMAINS.c.origin), ERRORS.rejectPermissionsRequest.rejection(), 'should reject with expected error', - ) + ); // reject out of order - await permController.rejectPermissionsRequest(REQUEST_IDS.c) + await permController.rejectPermissionsRequest(REQUEST_IDS.c); // add a non-existing request to the mix - await permController.rejectPermissionsRequest(REQUEST_IDS.a) - await permController.rejectPermissionsRequest(REQUEST_IDS.b) + await permController.rejectPermissionsRequest(REQUEST_IDS.a); + await permController.rejectPermissionsRequest(REQUEST_IDS.b); - await requestRejection1 - await requestRejection2 - }) - }) + await requestRejection1; + await requestRejection2; + }); + }); // see permissions-middleware-test for testing the middleware itself describe('createMiddleware', function () { - let permController, clock + let permController, clock; beforeEach(function () { - permController = initPermController() - clock = sinon.useFakeTimers(1) - }) + permController = initPermController(); + clock = sinon.useFakeTimers(1); + }); afterEach(function () { - clock.restore() - }) + clock.restore(); + }); it('should throw on bad origin', function () { assert.throws( () => permController.createMiddleware({ origin: {} }), ERRORS.createMiddleware.badOrigin(), 'should throw expected error', - ) + ); assert.throws( () => permController.createMiddleware({ origin: '' }), ERRORS.createMiddleware.badOrigin(), 'should throw expected error', - ) + ); assert.throws( () => permController.createMiddleware({}), ERRORS.createMiddleware.badOrigin(), 'should throw expected error', - ) - }) + ); + }); it('should create a middleware', function () { - let middleware + let middleware; assert.doesNotThrow(() => { middleware = permController.createMiddleware({ origin: DOMAINS.a.origin, - }) - }, 'should not throw') + }); + }, 'should not throw'); - assert.equal(typeof middleware, 'function', 'should return function') - }) + assert.equal(typeof middleware, 'function', 'should return function'); + }); it('should create a middleware with extensionId', function () { - const extensionId = 'fooExtension' + const extensionId = 'fooExtension'; - let middleware + let middleware; assert.doesNotThrow(() => { middleware = permController.createMiddleware({ origin: DOMAINS.a.origin, extensionId, - }) - }, 'should not throw') + }); + }, 'should not throw'); - assert.equal(typeof middleware, 'function', 'should return function') + assert.equal(typeof middleware, 'function', 'should return function'); - const metadataStore = permController.store.getState()[METADATA_STORE_KEY] + const metadataStore = permController.store.getState()[METADATA_STORE_KEY]; assert.deepEqual( metadataStore[DOMAINS.a.origin], { extensionId, lastUpdated: 1 }, 'metadata should be stored', - ) - }) - }) + ); + }); + }); describe('notifyAccountsChanged', function () { - let notifications, permController + let notifications, permController; beforeEach(function () { - notifications = initNotifications() - permController = initPermController(notifications) - sinon.spy(permController.permissionsLog, 'updateAccountsHistory') - }) + notifications = initNotifications(); + permController = initPermController(notifications); + sinon.spy(permController.permissionsLog, 'updateAccountsHistory'); + }); it('notifyAccountsChanged records history and sends notification', async function () { - sinon.spy(permController, '_isUnlocked') + sinon.spy(permController, '_isUnlocked'); permController.notifyAccountsChanged( DOMAINS.a.origin, ACCOUNTS.a.permitted, - ) + ); assert.ok( permController._isUnlocked.calledOnce, '_isUnlocked should have been called once', - ) + ); assert.ok( permController.permissionsLog.updateAccountsHistory.calledOnce, 'permissionsLog.updateAccountsHistory should have been called once', - ) + ); assert.deepEqual( notifications[DOMAINS.a.origin], [NOTIFICATIONS.newAccounts(ACCOUNTS.a.permitted)], 'origin should have correct notification', - ) - }) + ); + }); it('notifyAccountsChanged does nothing if _isUnlocked returns false', async function () { - permController._isUnlocked = sinon.fake.returns(false) + permController._isUnlocked = sinon.fake.returns(false); permController.notifyAccountsChanged( DOMAINS.a.origin, ACCOUNTS.a.permitted, - ) + ); assert.ok( permController._isUnlocked.calledOnce, '_isUnlocked should have been called once', - ) + ); assert.ok( permController.permissionsLog.updateAccountsHistory.notCalled, 'permissionsLog.updateAccountsHistory should not have been called', - ) - }) + ); + }); it('notifyAccountsChanged throws on invalid origin', async function () { assert.throws( () => permController.notifyAccountsChanged(4, ACCOUNTS.a.permitted), ERRORS.notifyAccountsChanged.invalidOrigin(4), 'should throw expected error for non-string origin', - ) + ); assert.throws( () => permController.notifyAccountsChanged('', ACCOUNTS.a.permitted), ERRORS.notifyAccountsChanged.invalidOrigin(''), 'should throw expected error for empty string origin', - ) - }) + ); + }); it('notifyAccountsChanged throws on invalid accounts', async function () { assert.throws( () => permController.notifyAccountsChanged(DOMAINS.a.origin, 4), ERRORS.notifyAccountsChanged.invalidAccounts(), 'should throw expected error for truthy non-array accounts', - ) + ); assert.throws( () => permController.notifyAccountsChanged(DOMAINS.a.origin, null), ERRORS.notifyAccountsChanged.invalidAccounts(), 'should throw expected error for falsy non-array accounts', - ) - }) - }) + ); + }); + }); describe('addDomainMetadata', function () { - let permController, clock + let permController, clock; function getMockMetadata(size) { - const dummyData = {} + const dummyData = {}; for (let i = 0; i < size; i++) { - const key = i.toString() - dummyData[key] = {} + const key = i.toString(); + dummyData[key] = {}; } - return dummyData + return dummyData; } beforeEach(function () { - permController = initPermController() - permController._setDomainMetadata = sinon.fake() - clock = sinon.useFakeTimers(1) - }) + permController = initPermController(); + permController._setDomainMetadata = sinon.fake(); + clock = sinon.useFakeTimers(1); + }); afterEach(function () { - clock.restore() - }) + clock.restore(); + }); it('calls setter function with expected new state when adding domain', function () { permController.store.getState = sinon.fake.returns({ @@ -1373,19 +1373,19 @@ describe('permissions controller', function () { foo: 'bar', }, }, - }) + }); - permController.addDomainMetadata(DOMAINS.b.origin, { foo: 'bar' }) + permController.addDomainMetadata(DOMAINS.b.origin, { foo: 'bar' }); assert.ok( permController.store.getState.called, 'should have called store.getState', - ) + ); assert.equal( permController._setDomainMetadata.getCalls().length, 1, 'should have called _setDomainMetadata once', - ) + ); assert.deepEqual(permController._setDomainMetadata.lastCall.args, [ { [DOMAINS.a.origin]: { @@ -1397,8 +1397,8 @@ describe('permissions controller', function () { lastUpdated: 1, }, }, - ]) - }) + ]); + }); it('calls setter function with expected new states when updating existing domain', function () { permController.store.getState = sinon.fake.returns({ @@ -1410,19 +1410,19 @@ describe('permissions controller', function () { bar: 'baz', }, }, - }) + }); - permController.addDomainMetadata(DOMAINS.b.origin, { foo: 'bar' }) + permController.addDomainMetadata(DOMAINS.b.origin, { foo: 'bar' }); assert.ok( permController.store.getState.called, 'should have called store.getState', - ) + ); assert.equal( permController._setDomainMetadata.getCalls().length, 1, 'should have called _setDomainMetadata once', - ) + ); assert.deepEqual(permController._setDomainMetadata.lastCall.args, [ { [DOMAINS.a.origin]: { @@ -1435,31 +1435,31 @@ describe('permissions controller', function () { lastUpdated: 1, }, }, - ]) - }) + ]); + }); it('pops metadata on add when too many origins are pending', function () { - sinon.spy(permController._pendingSiteMetadata, 'delete') + sinon.spy(permController._pendingSiteMetadata, 'delete'); - const mockMetadata = getMockMetadata(METADATA_CACHE_MAX_SIZE) - const expectedDeletedOrigin = Object.keys(mockMetadata)[0] + const mockMetadata = getMockMetadata(METADATA_CACHE_MAX_SIZE); + const expectedDeletedOrigin = Object.keys(mockMetadata)[0]; permController.store.getState = sinon.fake.returns({ [METADATA_STORE_KEY]: { ...mockMetadata }, - }) + }); // populate permController._pendingSiteMetadata, as though these origins // were actually added Object.keys(mockMetadata).forEach((origin) => { - permController._pendingSiteMetadata.add(origin) - }) + permController._pendingSiteMetadata.add(origin); + }); - permController.addDomainMetadata(DOMAINS.a.origin, { foo: 'bar' }) + permController.addDomainMetadata(DOMAINS.a.origin, { foo: 'bar' }); assert.ok( permController.store.getState.called, 'should have called store.getState', - ) + ); const expectedMetadata = { ...mockMetadata, @@ -1468,71 +1468,71 @@ describe('permissions controller', function () { host: DOMAINS.a.host, lastUpdated: 1, }, - } - delete expectedMetadata[expectedDeletedOrigin] + }; + delete expectedMetadata[expectedDeletedOrigin]; assert.ok( permController._pendingSiteMetadata.delete.calledOnceWithExactly( expectedDeletedOrigin, ), 'should have called _pendingSiteMetadata.delete once', - ) + ); assert.equal( permController._setDomainMetadata.getCalls().length, 1, 'should have called _setDomainMetadata once', - ) + ); assert.deepEqual(permController._setDomainMetadata.lastCall.args, [ expectedMetadata, - ]) - }) - }) + ]); + }); + }); describe('_trimDomainMetadata', function () { - const permController = initPermController() + const permController = initPermController(); it('trims domain metadata for domains without permissions', function () { const metadataArg = { [DOMAINS.a.origin]: {}, [DOMAINS.b.origin]: {}, - } + }; permController.permissions.getDomains = sinon.fake.returns({ [DOMAINS.a.origin]: {}, - }) + }); - const metadataResult = permController._trimDomainMetadata(metadataArg) + const metadataResult = permController._trimDomainMetadata(metadataArg); assert.equal( permController.permissions.getDomains.getCalls().length, 1, 'should have called permissions.getDomains once', - ) + ); assert.deepEqual( metadataResult, { [DOMAINS.a.origin]: {}, }, 'should have produced expected state', - ) - }) - }) + ); + }); + }); describe('miscellanea and edge cases', function () { it('requestAccountsPermissionWithId calls _requestAccountsPermission with an explicit request ID', async function () { - const permController = initPermController() + const permController = initPermController(); const _requestPermissions = sinon .stub(permController, '_requestPermissions') - .resolves() - await permController.requestAccountsPermissionWithId('example.com') + .resolves(); + await permController.requestAccountsPermissionWithId('example.com'); assert.ok( _requestPermissions.calledOnceWithExactly( sinon.match.object.and(sinon.match.has('origin')), { eth_accounts: {} }, sinon.match.string.and(sinon.match.truthy), ), - ) - _requestPermissions.restore() - }) - }) -}) + ); + _requestPermissions.restore(); + }); + }); +}); diff --git a/test/unit/app/controllers/permissions/permissions-log-controller-test.js b/test/unit/app/controllers/permissions/permissions-log-controller-test.js index d98db8453a..05ff47a379 100644 --- a/test/unit/app/controllers/permissions/permissions-log-controller-test.js +++ b/test/unit/app/controllers/permissions/permissions-log-controller-test.js @@ -1,20 +1,20 @@ -import { strict as assert } from 'assert' -import { ObservableStore } from '@metamask/obs-store' -import nanoid from 'nanoid' -import { useFakeTimers } from 'sinon' +import { strict as assert } from 'assert'; +import { ObservableStore } from '@metamask/obs-store'; +import nanoid from 'nanoid'; +import { useFakeTimers } from 'sinon'; -import PermissionsLogController from '../../../../../app/scripts/controllers/permissions/permissionsLog' +import PermissionsLogController from '../../../../../app/scripts/controllers/permissions/permissionsLog'; import { LOG_LIMIT, LOG_METHOD_TYPES, -} from '../../../../../app/scripts/controllers/permissions/enums' +} from '../../../../../app/scripts/controllers/permissions/enums'; -import { validateActivityEntry } from './helpers' +import { validateActivityEntry } from './helpers'; -import { constants, getters, noop } from './mocks' +import { constants, getters, noop } from './mocks'; -const { PERMS, RPC_REQUESTS } = getters +const { PERMS, RPC_REQUESTS } = getters; const { ACCOUNTS, @@ -23,174 +23,174 @@ const { PERM_NAMES, REQUEST_IDS, RESTRICTED_METHODS, -} = constants +} = constants; -let clock +let clock; const initPermLog = () => { return new PermissionsLogController({ store: new ObservableStore(), restrictedMethods: RESTRICTED_METHODS, - }) -} + }); +}; const mockNext = (handler) => { if (handler) { - handler(noop) + handler(noop); } -} +}; const initMiddleware = (permLog) => { - const middleware = permLog.createMiddleware() + const middleware = permLog.createMiddleware(); return (req, res, next = mockNext) => { - middleware(req, res, next) - } -} + middleware(req, res, next); + }; +}; const initClock = () => { // useFakeTimers, is in fact, not a react-hook // eslint-disable-next-line clock = useFakeTimers(1) -} +}; const tearDownClock = () => { - clock.restore() -} + clock.restore(); +}; const getSavedMockNext = (arr) => (handler) => { - arr.push(handler) -} + arr.push(handler); +}; describe('permissions log', function () { describe('activity log', function () { - let permLog, logMiddleware + let permLog, logMiddleware; beforeEach(function () { - permLog = initPermLog() - logMiddleware = initMiddleware(permLog) - }) + permLog = initPermLog(); + logMiddleware = initMiddleware(permLog); + }); it('records activity for restricted methods', function () { - let log, req, res + let log, req, res; // test_method, success - req = RPC_REQUESTS.test_method(DOMAINS.a.origin) - req.id = REQUEST_IDS.a - res = { foo: 'bar' } + req = RPC_REQUESTS.test_method(DOMAINS.a.origin); + req.id = REQUEST_IDS.a; + res = { foo: 'bar' }; - logMiddleware({ ...req }, res) + logMiddleware({ ...req }, res); - log = permLog.getActivityLog() - const entry1 = log[0] + log = permLog.getActivityLog(); + const entry1 = log[0]; - assert.equal(log.length, 1, 'log should have single entry') + assert.equal(log.length, 1, 'log should have single entry'); validateActivityEntry( entry1, { ...req }, { ...res }, LOG_METHOD_TYPES.restricted, true, - ) + ); // eth_accounts, failure - req = RPC_REQUESTS.eth_accounts(DOMAINS.b.origin) - req.id = REQUEST_IDS.b - res = { error: new Error('Unauthorized.') } + req = RPC_REQUESTS.eth_accounts(DOMAINS.b.origin); + req.id = REQUEST_IDS.b; + res = { error: new Error('Unauthorized.') }; - logMiddleware({ ...req }, res) + logMiddleware({ ...req }, res); - log = permLog.getActivityLog() - const entry2 = log[1] + log = permLog.getActivityLog(); + const entry2 = log[1]; - assert.equal(log.length, 2, 'log should have 2 entries') + assert.equal(log.length, 2, 'log should have 2 entries'); validateActivityEntry( entry2, { ...req }, { ...res }, LOG_METHOD_TYPES.restricted, false, - ) + ); // eth_requestAccounts, success - req = RPC_REQUESTS.eth_requestAccounts(DOMAINS.c.origin) - req.id = REQUEST_IDS.c - res = { result: ACCOUNTS.c.permitted } + req = RPC_REQUESTS.eth_requestAccounts(DOMAINS.c.origin); + req.id = REQUEST_IDS.c; + res = { result: ACCOUNTS.c.permitted }; - logMiddleware({ ...req }, res) + logMiddleware({ ...req }, res); - log = permLog.getActivityLog() - const entry3 = log[2] + log = permLog.getActivityLog(); + const entry3 = log[2]; - assert.equal(log.length, 3, 'log should have 3 entries') + assert.equal(log.length, 3, 'log should have 3 entries'); validateActivityEntry( entry3, { ...req }, { ...res }, LOG_METHOD_TYPES.restricted, true, - ) + ); // test_method, no response - req = RPC_REQUESTS.test_method(DOMAINS.a.origin) - req.id = REQUEST_IDS.a - res = null + req = RPC_REQUESTS.test_method(DOMAINS.a.origin); + req.id = REQUEST_IDS.a; + res = null; - logMiddleware({ ...req }, res) + logMiddleware({ ...req }, res); - log = permLog.getActivityLog() - const entry4 = log[3] + log = permLog.getActivityLog(); + const entry4 = log[3]; - assert.equal(log.length, 4, 'log should have 4 entries') + assert.equal(log.length, 4, 'log should have 4 entries'); validateActivityEntry( entry4, { ...req }, null, LOG_METHOD_TYPES.restricted, false, - ) + ); // validate final state - assert.equal(entry1, log[0], 'first log entry should remain') - assert.equal(entry2, log[1], 'second log entry should remain') - assert.equal(entry3, log[2], 'third log entry should remain') - assert.equal(entry4, log[3], 'fourth log entry should remain') - }) + assert.equal(entry1, log[0], 'first log entry should remain'); + assert.equal(entry2, log[1], 'second log entry should remain'); + assert.equal(entry3, log[2], 'third log entry should remain'); + assert.equal(entry4, log[3], 'fourth log entry should remain'); + }); it('handles responses added out of order', function () { - let log + let log; - const handlerArray = [] + const handlerArray = []; - const id1 = nanoid() - const id2 = nanoid() - const id3 = nanoid() + const id1 = nanoid(); + const id2 = nanoid(); + const id3 = nanoid(); - const req = RPC_REQUESTS.test_method(DOMAINS.a.origin) + const req = RPC_REQUESTS.test_method(DOMAINS.a.origin); // get make requests - req.id = id1 - const res1 = { foo: id1 } - logMiddleware({ ...req }, { ...res1 }, getSavedMockNext(handlerArray)) + req.id = id1; + const res1 = { foo: id1 }; + logMiddleware({ ...req }, { ...res1 }, getSavedMockNext(handlerArray)); - req.id = id2 - const res2 = { foo: id2 } - logMiddleware({ ...req }, { ...res2 }, getSavedMockNext(handlerArray)) + req.id = id2; + const res2 = { foo: id2 }; + logMiddleware({ ...req }, { ...res2 }, getSavedMockNext(handlerArray)); - req.id = id3 - const res3 = { foo: id3 } - logMiddleware({ ...req }, { ...res3 }, getSavedMockNext(handlerArray)) + req.id = id3; + const res3 = { foo: id3 }; + logMiddleware({ ...req }, { ...res3 }, getSavedMockNext(handlerArray)); // verify log state - log = permLog.getActivityLog() - assert.equal(log.length, 3, 'log should have 3 entries') - const entry1 = log[0] - const entry2 = log[1] - const entry3 = log[2] + log = permLog.getActivityLog(); + assert.equal(log.length, 3, 'log should have 3 entries'); + const entry1 = log[0]; + const entry2 = log[1]; + const entry3 = log[2]; assert.ok( entry1.id === id1 && entry1.response === null && @@ -199,19 +199,19 @@ describe('permissions log', function () { entry3.id === id3 && entry3.response === null, 'all entries should be in correct order and without responses', - ) + ); // call response handlers for (const i of [1, 2, 0]) { - handlerArray[i](noop) + handlerArray[i](noop); } // verify log state again - log = permLog.getActivityLog() - assert.equal(log.length, 3, 'log should have 3 entries') + log = permLog.getActivityLog(); + assert.equal(log.length, 3, 'log should have 3 entries'); // verify all entries - log = permLog.getActivityLog() + log = permLog.getActivityLog(); validateActivityEntry( log[0], @@ -219,7 +219,7 @@ describe('permissions log', function () { { ...res1 }, LOG_METHOD_TYPES.restricted, true, - ) + ); validateActivityEntry( log[1], @@ -227,7 +227,7 @@ describe('permissions log', function () { { ...res2 }, LOG_METHOD_TYPES.restricted, true, - ) + ); validateActivityEntry( log[2], @@ -235,90 +235,90 @@ describe('permissions log', function () { { ...res3 }, LOG_METHOD_TYPES.restricted, true, - ) - }) + ); + }); it('handles a lack of response', function () { - let req = RPC_REQUESTS.test_method(DOMAINS.a.origin) - req.id = REQUEST_IDS.a - let res = { foo: 'bar' } + let req = RPC_REQUESTS.test_method(DOMAINS.a.origin); + req.id = REQUEST_IDS.a; + let res = { foo: 'bar' }; // noop for next handler prevents recording of response - logMiddleware({ ...req }, res, noop) + logMiddleware({ ...req }, res, noop); - let log = permLog.getActivityLog() - const entry1 = log[0] + let log = permLog.getActivityLog(); + const entry1 = log[0]; - assert.equal(log.length, 1, 'log should have single entry') + assert.equal(log.length, 1, 'log should have single entry'); validateActivityEntry( entry1, { ...req }, null, LOG_METHOD_TYPES.restricted, true, - ) + ); // next request should be handled as normal - req = RPC_REQUESTS.eth_accounts(DOMAINS.b.origin) - req.id = REQUEST_IDS.b - res = { result: ACCOUNTS.b.permitted } + req = RPC_REQUESTS.eth_accounts(DOMAINS.b.origin); + req.id = REQUEST_IDS.b; + res = { result: ACCOUNTS.b.permitted }; - logMiddleware({ ...req }, res) + logMiddleware({ ...req }, res); - log = permLog.getActivityLog() - const entry2 = log[1] - assert.equal(log.length, 2, 'log should have 2 entries') + log = permLog.getActivityLog(); + const entry2 = log[1]; + assert.equal(log.length, 2, 'log should have 2 entries'); validateActivityEntry( entry2, { ...req }, { ...res }, LOG_METHOD_TYPES.restricted, true, - ) + ); // validate final state - assert.equal(entry1, log[0], 'first log entry remains') - assert.equal(entry2, log[1], 'second log entry remains') - }) + assert.equal(entry1, log[0], 'first log entry remains'); + assert.equal(entry2, log[1], 'second log entry remains'); + }); it('ignores expected methods', function () { - let log = permLog.getActivityLog() - assert.equal(log.length, 0, 'log should be empty') + let log = permLog.getActivityLog(); + assert.equal(log.length, 0, 'log should be empty'); - const res = { foo: 'bar' } + const res = { foo: 'bar' }; const req1 = RPC_REQUESTS.metamask_sendDomainMetadata( DOMAINS.c.origin, 'foobar', - ) - const req2 = RPC_REQUESTS.custom(DOMAINS.b.origin, 'eth_getBlockNumber') - const req3 = RPC_REQUESTS.custom(DOMAINS.b.origin, 'net_version') + ); + const req2 = RPC_REQUESTS.custom(DOMAINS.b.origin, 'eth_getBlockNumber'); + const req3 = RPC_REQUESTS.custom(DOMAINS.b.origin, 'net_version'); - logMiddleware(req1, res) - logMiddleware(req2, res) - logMiddleware(req3, res) + logMiddleware(req1, res); + logMiddleware(req2, res); + logMiddleware(req3, res); - log = permLog.getActivityLog() - assert.equal(log.length, 0, 'log should still be empty') - }) + log = permLog.getActivityLog(); + assert.equal(log.length, 0, 'log should still be empty'); + }); it('enforces log limit', function () { - const req = RPC_REQUESTS.test_method(DOMAINS.a.origin) - const res = { foo: 'bar' } + const req = RPC_REQUESTS.test_method(DOMAINS.a.origin); + const res = { foo: 'bar' }; // max out log - let lastId + let lastId; for (let i = 0; i < LOG_LIMIT; i++) { - lastId = nanoid() - logMiddleware({ ...req, id: lastId }, { ...res }) + lastId = nanoid(); + logMiddleware({ ...req, id: lastId }, { ...res }); } // check last entry valid - let log = permLog.getActivityLog() + let log = permLog.getActivityLog(); assert.equal( log.length, LOG_LIMIT, 'log should have LOG_LIMIT num entries', - ) + ); validateActivityEntry( log[LOG_LIMIT - 1], @@ -326,22 +326,22 @@ describe('permissions log', function () { res, LOG_METHOD_TYPES.restricted, true, - ) + ); // store the id of the current second entry - const nextFirstId = log[1].id + const nextFirstId = log[1].id; // add one more entry to log, putting it over the limit - lastId = nanoid() - logMiddleware({ ...req, id: lastId }, { ...res }) + lastId = nanoid(); + logMiddleware({ ...req, id: lastId }, { ...res }); // check log length - log = permLog.getActivityLog() + log = permLog.getActivityLog(); assert.equal( log.length, LOG_LIMIT, 'log should have LOG_LIMIT num entries', - ) + ); // check first and last entries validateActivityEntry( @@ -350,7 +350,7 @@ describe('permissions log', function () { res, LOG_METHOD_TYPES.restricted, true, - ) + ); validateActivityEntry( log[LOG_LIMIT - 1], @@ -358,122 +358,122 @@ describe('permissions log', function () { res, LOG_METHOD_TYPES.restricted, true, - ) - }) - }) + ); + }); + }); describe('permissions history', function () { - let permLog, logMiddleware + let permLog, logMiddleware; beforeEach(function () { - permLog = initPermLog() - logMiddleware = initMiddleware(permLog) - initClock() - }) + permLog = initPermLog(); + logMiddleware = initMiddleware(permLog); + initClock(); + }); afterEach(function () { - tearDownClock() - }) + tearDownClock(); + }); it('only updates history on responses', function () { - let permHistory + let permHistory; const req = RPC_REQUESTS.requestPermission( DOMAINS.a.origin, PERM_NAMES.test_method, - ) - const res = { result: [PERMS.granted.test_method()] } + ); + const res = { result: [PERMS.granted.test_method()] }; // noop => no response - logMiddleware({ ...req }, { ...res }, noop) + logMiddleware({ ...req }, { ...res }, noop); - permHistory = permLog.getHistory() - assert.deepEqual(permHistory, {}, 'history should not have been updated') + permHistory = permLog.getHistory(); + assert.deepEqual(permHistory, {}, 'history should not have been updated'); // response => records granted permissions - logMiddleware({ ...req }, { ...res }) + logMiddleware({ ...req }, { ...res }); - permHistory = permLog.getHistory() + permHistory = permLog.getHistory(); assert.equal( Object.keys(permHistory).length, 1, 'history should have single origin', - ) + ); assert.ok( Boolean(permHistory[DOMAINS.a.origin]), 'history should have expected origin', - ) - }) + ); + }); it('ignores malformed permissions requests', function () { const req = RPC_REQUESTS.requestPermission( DOMAINS.a.origin, PERM_NAMES.test_method, - ) - delete req.params - const res = { result: [PERMS.granted.test_method()] } + ); + delete req.params; + const res = { result: [PERMS.granted.test_method()] }; // no params => no response - logMiddleware({ ...req }, { ...res }) + logMiddleware({ ...req }, { ...res }); assert.deepEqual( permLog.getHistory(), {}, 'history should not have been updated', - ) - }) + ); + }); it('records and updates account history as expected', async function () { - let permHistory + let permHistory; const req = RPC_REQUESTS.requestPermission( DOMAINS.a.origin, PERM_NAMES.eth_accounts, - ) + ); const res = { result: [PERMS.granted.eth_accounts(ACCOUNTS.a.permitted)], - } + }; - logMiddleware({ ...req }, { ...res }) + logMiddleware({ ...req }, { ...res }); // validate history - permHistory = permLog.getHistory() + permHistory = permLog.getHistory(); assert.deepEqual( permHistory, EXPECTED_HISTORIES.case1[0], 'should have correct history', - ) + ); // mock permission requested again, with another approved account - clock.tick(1) + clock.tick(1); - res.result = [PERMS.granted.eth_accounts([ACCOUNTS.a.permitted[0]])] + res.result = [PERMS.granted.eth_accounts([ACCOUNTS.a.permitted[0]])]; - logMiddleware({ ...req }, { ...res }) + logMiddleware({ ...req }, { ...res }); - permHistory = permLog.getHistory() + permHistory = permLog.getHistory(); assert.deepEqual( permHistory, EXPECTED_HISTORIES.case1[1], 'should have correct history', - ) - }) + ); + }); it('handles eth_accounts response without caveats', async function () { const req = RPC_REQUESTS.requestPermission( DOMAINS.a.origin, PERM_NAMES.eth_accounts, - ) + ); const res = { result: [PERMS.granted.eth_accounts(ACCOUNTS.a.permitted)], - } - delete res.result[0].caveats + }; + delete res.result[0].caveats; - logMiddleware({ ...req }, { ...res }) + logMiddleware({ ...req }, { ...res }); // validate history @@ -481,20 +481,20 @@ describe('permissions log', function () { permLog.getHistory(), EXPECTED_HISTORIES.case2[0], 'should have expected history', - ) - }) + ); + }); it('handles extra caveats for eth_accounts', async function () { const req = RPC_REQUESTS.requestPermission( DOMAINS.a.origin, PERM_NAMES.eth_accounts, - ) + ); const res = { result: [PERMS.granted.eth_accounts(ACCOUNTS.a.permitted)], - } - res.result[0].caveats.push({ foo: 'bar' }) + }; + res.result[0].caveats.push({ foo: 'bar' }); - logMiddleware({ ...req }, { ...res }) + logMiddleware({ ...req }, { ...res }); // validate history @@ -502,8 +502,8 @@ describe('permissions log', function () { permLog.getHistory(), EXPECTED_HISTORIES.case1[0], 'should have correct history', - ) - }) + ); + }); // wallet_requestPermissions returns all permissions approved for the // requesting origin, including old ones @@ -511,15 +511,15 @@ describe('permissions log', function () { const req = RPC_REQUESTS.requestPermission( DOMAINS.a.origin, PERM_NAMES.eth_accounts, - ) + ); const res = { result: [ PERMS.granted.eth_accounts(ACCOUNTS.a.permitted), PERMS.granted.test_method(), ], - } + }; - logMiddleware({ ...req }, { ...res }) + logMiddleware({ ...req }, { ...res }); // validate history @@ -527,19 +527,19 @@ describe('permissions log', function () { permLog.getHistory(), EXPECTED_HISTORIES.case1[0], 'should have correct history', - ) - }) + ); + }); it('does not update history if no new permissions are approved', async function () { let req = RPC_REQUESTS.requestPermission( DOMAINS.a.origin, PERM_NAMES.test_method, - ) + ); let res = { result: [PERMS.granted.test_method()], - } + }; - logMiddleware({ ...req }, { ...res }) + logMiddleware({ ...req }, { ...res }); // validate history @@ -547,21 +547,21 @@ describe('permissions log', function () { permLog.getHistory(), EXPECTED_HISTORIES.case4[0], 'should have correct history', - ) + ); // new permission requested, but not approved - clock.tick(1) + clock.tick(1); req = RPC_REQUESTS.requestPermission( DOMAINS.a.origin, PERM_NAMES.eth_accounts, - ) + ); res = { result: [PERMS.granted.test_method()], - } + }; - logMiddleware({ ...req }, { ...res }) + logMiddleware({ ...req }, { ...res }); // validate history @@ -569,16 +569,16 @@ describe('permissions log', function () { permLog.getHistory(), EXPECTED_HISTORIES.case4[0], 'should have same history as before', - ) - }) + ); + }); it('records and updates history for multiple origins, regardless of response order', async function () { - let permHistory + let permHistory; // make first round of requests - const round1 = [] - const handlers1 = [] + const round1 = []; + const handlers1 = []; // first origin round1.push({ @@ -589,7 +589,7 @@ describe('permissions log', function () { res: { result: [PERMS.granted.test_method()], }, - }) + }); // second origin round1.push({ @@ -600,7 +600,7 @@ describe('permissions log', function () { res: { result: [PERMS.granted.eth_accounts(ACCOUNTS.b.permitted)], }, - }) + }); // third origin round1.push({ @@ -614,31 +614,31 @@ describe('permissions log', function () { PERMS.granted.eth_accounts(ACCOUNTS.c.permitted), ], }, - }) + }); // make requests and process responses out of order round1.forEach((x) => { - logMiddleware({ ...x.req }, { ...x.res }, getSavedMockNext(handlers1)) - }) + logMiddleware({ ...x.req }, { ...x.res }, getSavedMockNext(handlers1)); + }); for (const i of [1, 2, 0]) { - handlers1[i](noop) + handlers1[i](noop); } // validate history - permHistory = permLog.getHistory() + permHistory = permLog.getHistory(); assert.deepEqual( permHistory, EXPECTED_HISTORIES.case3[0], 'should have expected history', - ) + ); // make next round of requests - clock.tick(1) + clock.tick(1); - const round2 = [] + const round2 = []; // we're just gonna process these in order // first origin @@ -650,7 +650,7 @@ describe('permissions log', function () { res: { result: [PERMS.granted.test_method()], }, - }) + }); // nothing for second origin @@ -662,21 +662,21 @@ describe('permissions log', function () { res: { result: [PERMS.granted.eth_accounts(ACCOUNTS.b.permitted)], }, - }) + }); // make requests round2.forEach((x) => { - logMiddleware({ ...x.req }, { ...x.res }) - }) + logMiddleware({ ...x.req }, { ...x.res }); + }); // validate history - permHistory = permLog.getHistory() + permHistory = permLog.getHistory(); assert.deepEqual( permHistory, EXPECTED_HISTORIES.case3[1], 'should have expected history', - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/test/unit/app/controllers/permissions/permissions-middleware-test.js b/test/unit/app/controllers/permissions/permissions-middleware-test.js index 9e2769ed62..acb89ac050 100644 --- a/test/unit/app/controllers/permissions/permissions-middleware-test.js +++ b/test/unit/app/controllers/permissions/permissions-middleware-test.js @@ -1,128 +1,128 @@ -import { strict as assert } from 'assert' -import sinon from 'sinon' +import { strict as assert } from 'assert'; +import sinon from 'sinon'; -import { METADATA_STORE_KEY } from '../../../../../app/scripts/controllers/permissions/enums' +import { METADATA_STORE_KEY } from '../../../../../app/scripts/controllers/permissions/enums'; -import { PermissionsController } from '../../../../../app/scripts/controllers/permissions' +import { PermissionsController } from '../../../../../app/scripts/controllers/permissions'; -import { getUserApprovalPromise, grantPermissions } from './helpers' +import { getUserApprovalPromise, grantPermissions } from './helpers'; import { constants, getters, getPermControllerOpts, getPermissionsMiddleware, -} from './mocks' +} from './mocks'; -const { CAVEATS, ERRORS, PERMS, RPC_REQUESTS } = getters +const { CAVEATS, ERRORS, PERMS, RPC_REQUESTS } = getters; -const { ACCOUNTS, DOMAINS, PERM_NAMES } = constants +const { ACCOUNTS, DOMAINS, PERM_NAMES } = constants; const initPermController = () => { return new PermissionsController({ ...getPermControllerOpts(), - }) -} + }); +}; const createApprovalSpies = (permController) => { - sinon.spy(permController.approvals, '_add') -} + sinon.spy(permController.approvals, '_add'); +}; const getNextApprovalId = (permController) => { - return permController.approvals._approvals.keys().next().value -} + return permController.approvals._approvals.keys().next().value; +}; const validatePermission = (perm, name, origin, caveats) => { assert.equal( name, perm.parentCapability, 'should have expected permission name', - ) - assert.equal(origin, perm.invoker, 'should have expected permission origin') + ); + assert.equal(origin, perm.invoker, 'should have expected permission origin'); if (caveats) { assert.deepEqual( caveats, perm.caveats, 'should have expected permission caveats', - ) + ); } else { - assert.ok(!perm.caveats, 'should not have any caveats') + assert.ok(!perm.caveats, 'should not have any caveats'); } -} +}; describe('permissions middleware', function () { describe('wallet_requestPermissions', function () { - let permController + let permController; beforeEach(function () { - permController = initPermController() - permController.notifyAccountsChanged = sinon.fake() - }) + permController = initPermController(); + permController.notifyAccountsChanged = sinon.fake(); + }); it('grants permissions on user approval', async function () { - createApprovalSpies(permController) + createApprovalSpies(permController); const aMiddleware = getPermissionsMiddleware( permController, DOMAINS.a.origin, - ) + ); const req = RPC_REQUESTS.requestPermission( DOMAINS.a.origin, PERM_NAMES.eth_accounts, - ) - const res = {} + ); + const res = {}; - const userApprovalPromise = getUserApprovalPromise(permController) + const userApprovalPromise = getUserApprovalPromise(permController); const pendingApproval = assert.doesNotReject( aMiddleware(req, res), 'should not reject permissions request', - ) + ); - await userApprovalPromise + await userApprovalPromise; assert.ok( permController.approvals._add.calledOnce, 'should have added single approval request', - ) + ); - const id = getNextApprovalId(permController) + const id = getNextApprovalId(permController); const approvedReq = PERMS.approvedRequest( id, PERMS.requests.eth_accounts(), - ) + ); await permController.approvePermissionsRequest( approvedReq, ACCOUNTS.a.permitted, - ) - await pendingApproval + ); + await pendingApproval; assert.ok( res.result && !res.error, 'response should have result and no error', - ) + ); assert.equal( res.result.length, 1, 'origin should have single approved permission', - ) + ); validatePermission( res.result[0], PERM_NAMES.eth_accounts, DOMAINS.a.origin, CAVEATS.eth_accounts(ACCOUNTS.a.permitted), - ) + ); - const aAccounts = await permController.getAccounts(DOMAINS.a.origin) + const aAccounts = await permController.getAccounts(DOMAINS.a.origin); assert.deepEqual( aAccounts, [ACCOUNTS.a.primary], 'origin should have correct accounts', - ) + ); assert.ok( permController.notifyAccountsChanged.calledOnceWith( @@ -130,71 +130,71 @@ describe('permissions middleware', function () { aAccounts, ), 'expected notification call should have been made', - ) - }) + ); + }); it('handles serial approved requests that overwrite existing permissions', async function () { const aMiddleware = getPermissionsMiddleware( permController, DOMAINS.a.origin, - ) + ); // create first request const req1 = RPC_REQUESTS.requestPermission( DOMAINS.a.origin, PERM_NAMES.eth_accounts, - ) - const res1 = {} + ); + const res1 = {}; // send, approve, and validate first request // note use of ACCOUNTS.a.permitted - let userApprovalPromise = getUserApprovalPromise(permController) + let userApprovalPromise = getUserApprovalPromise(permController); const pendingApproval1 = assert.doesNotReject( aMiddleware(req1, res1), 'should not reject permissions request', - ) + ); - await userApprovalPromise + await userApprovalPromise; - const id1 = getNextApprovalId(permController) + const id1 = getNextApprovalId(permController); const approvedReq1 = PERMS.approvedRequest( id1, PERMS.requests.eth_accounts(), - ) + ); await permController.approvePermissionsRequest( approvedReq1, ACCOUNTS.a.permitted, - ) - await pendingApproval1 + ); + await pendingApproval1; assert.ok( res1.result && !res1.error, 'response should have result and no error', - ) + ); assert.equal( res1.result.length, 1, 'origin should have single approved permission', - ) + ); validatePermission( res1.result[0], PERM_NAMES.eth_accounts, DOMAINS.a.origin, CAVEATS.eth_accounts(ACCOUNTS.a.permitted), - ) + ); - const accounts1 = await permController.getAccounts(DOMAINS.a.origin) + const accounts1 = await permController.getAccounts(DOMAINS.a.origin); assert.deepEqual( accounts1, [ACCOUNTS.a.primary], 'origin should have correct accounts', - ) + ); assert.ok( permController.notifyAccountsChanged.calledOnceWith( @@ -202,77 +202,77 @@ describe('permissions middleware', function () { accounts1, ), 'expected notification call should have been made', - ) + ); // create second request const requestedPerms2 = { ...PERMS.requests.eth_accounts(), ...PERMS.requests.test_method(), - } + }; const req2 = RPC_REQUESTS.requestPermissions(DOMAINS.a.origin, { ...requestedPerms2, - }) - const res2 = {} + }); + const res2 = {}; // send, approve, and validate second request // note use of ACCOUNTS.b.permitted - userApprovalPromise = getUserApprovalPromise(permController) + userApprovalPromise = getUserApprovalPromise(permController); const pendingApproval2 = assert.doesNotReject( aMiddleware(req2, res2), 'should not reject permissions request', - ) + ); - await userApprovalPromise + await userApprovalPromise; - const id2 = getNextApprovalId(permController) - const approvedReq2 = PERMS.approvedRequest(id2, { ...requestedPerms2 }) + const id2 = getNextApprovalId(permController); + const approvedReq2 = PERMS.approvedRequest(id2, { ...requestedPerms2 }); await permController.approvePermissionsRequest( approvedReq2, ACCOUNTS.b.permitted, - ) - await pendingApproval2 + ); + await pendingApproval2; assert.ok( res2.result && !res2.error, 'response should have result and no error', - ) + ); assert.equal( res2.result.length, 2, 'origin should have single approved permission', - ) + ); validatePermission( res2.result[0], PERM_NAMES.eth_accounts, DOMAINS.a.origin, CAVEATS.eth_accounts(ACCOUNTS.b.permitted), - ) + ); validatePermission( res2.result[1], PERM_NAMES.test_method, DOMAINS.a.origin, - ) + ); - const accounts2 = await permController.getAccounts(DOMAINS.a.origin) + const accounts2 = await permController.getAccounts(DOMAINS.a.origin); assert.deepEqual( accounts2, [ACCOUNTS.b.primary], 'origin should have correct accounts', - ) + ); assert.equal( permController.notifyAccountsChanged.callCount, 2, 'should have called notification method 2 times in total', - ) + ); assert.ok( permController.notifyAccountsChanged.lastCall.calledWith( @@ -280,155 +280,155 @@ describe('permissions middleware', function () { accounts2, ), 'expected notification call should have been made', - ) - }) + ); + }); it('rejects permissions on user rejection', async function () { - createApprovalSpies(permController) + createApprovalSpies(permController); const aMiddleware = getPermissionsMiddleware( permController, DOMAINS.a.origin, - ) + ); const req = RPC_REQUESTS.requestPermission( DOMAINS.a.origin, PERM_NAMES.eth_accounts, - ) - const res = {} + ); + const res = {}; - const expectedError = ERRORS.rejectPermissionsRequest.rejection() + const expectedError = ERRORS.rejectPermissionsRequest.rejection(); - const userApprovalPromise = getUserApprovalPromise(permController) + const userApprovalPromise = getUserApprovalPromise(permController); const requestRejection = assert.rejects( aMiddleware(req, res), expectedError, 'request should be rejected with correct error', - ) + ); - await userApprovalPromise + await userApprovalPromise; assert.ok( permController.approvals._add.calledOnce, 'should have added single approval request', - ) + ); - const id = getNextApprovalId(permController) + const id = getNextApprovalId(permController); - await permController.rejectPermissionsRequest(id) - await requestRejection + await permController.rejectPermissionsRequest(id); + await requestRejection; assert.ok( !res.result && res.error && res.error.message === expectedError.message, 'response should have expected error and no result', - ) + ); - const aAccounts = await permController.getAccounts(DOMAINS.a.origin) + const aAccounts = await permController.getAccounts(DOMAINS.a.origin); assert.deepEqual( aAccounts, [], 'origin should have have correct accounts', - ) + ); assert.ok( permController.notifyAccountsChanged.notCalled, 'should not have called notification method', - ) - }) + ); + }); it('rejects requests with unknown permissions', async function () { - createApprovalSpies(permController) + createApprovalSpies(permController); const aMiddleware = getPermissionsMiddleware( permController, DOMAINS.a.origin, - ) + ); const req = RPC_REQUESTS.requestPermissions(DOMAINS.a.origin, { ...PERMS.requests.does_not_exist(), ...PERMS.requests.test_method(), - }) - const res = {} + }); + const res = {}; const expectedError = ERRORS.rejectPermissionsRequest.methodNotFound( PERM_NAMES.does_not_exist, - ) + ); await assert.rejects( aMiddleware(req, res), expectedError, 'request should be rejected with correct error', - ) + ); assert.ok( permController.approvals._add.notCalled, 'no approval requests should have been added', - ) + ); assert.ok( !res.result && res.error && res.error.message === expectedError.message, 'response should have expected error and no result', - ) + ); assert.ok( permController.notifyAccountsChanged.notCalled, 'should not have called notification method', - ) - }) + ); + }); it('accepts only a single pending permissions request per origin', async function () { - createApprovalSpies(permController) + createApprovalSpies(permController); // two middlewares for two origins const aMiddleware = getPermissionsMiddleware( permController, DOMAINS.a.origin, - ) + ); const bMiddleware = getPermissionsMiddleware( permController, DOMAINS.b.origin, - ) + ); // create and start processing first request for first origin const reqA1 = RPC_REQUESTS.requestPermission( DOMAINS.a.origin, PERM_NAMES.test_method, - ) - const resA1 = {} + ); + const resA1 = {}; - let userApprovalPromise = getUserApprovalPromise(permController) + let userApprovalPromise = getUserApprovalPromise(permController); const requestApproval1 = assert.doesNotReject( aMiddleware(reqA1, resA1), 'should not reject permissions request', - ) + ); - await userApprovalPromise + await userApprovalPromise; // create and start processing first request for second origin const reqB1 = RPC_REQUESTS.requestPermission( DOMAINS.b.origin, PERM_NAMES.test_method, - ) - const resB1 = {} + ); + const resB1 = {}; - userApprovalPromise = getUserApprovalPromise(permController) + userApprovalPromise = getUserApprovalPromise(permController); const requestApproval2 = assert.doesNotReject( bMiddleware(reqB1, resB1), 'should not reject permissions request', - ) + ); - await userApprovalPromise + await userApprovalPromise; assert.ok( permController.approvals._add.calledTwice, 'should have added two approval requests', - ) + ); // create and start processing second request for first origin, // which should throw @@ -436,422 +436,422 @@ describe('permissions middleware', function () { const reqA2 = RPC_REQUESTS.requestPermission( DOMAINS.a.origin, PERM_NAMES.test_method, - ) - const resA2 = {} + ); + const resA2 = {}; - userApprovalPromise = getUserApprovalPromise(permController) + userApprovalPromise = getUserApprovalPromise(permController); const expectedError = ERRORS.pendingApprovals.requestAlreadyPending( DOMAINS.a.origin, - ) + ); const requestApprovalFail = assert.rejects( aMiddleware(reqA2, resA2), expectedError, 'request should be rejected with correct error', - ) + ); - await userApprovalPromise - await requestApprovalFail + await userApprovalPromise; + await requestApprovalFail; assert.ok( !resA2.result && resA2.error && resA2.error.message === expectedError.message, 'response should have expected error and no result', - ) + ); assert.equal( permController.approvals._add.callCount, 3, 'should have attempted to create three pending approvals', - ) + ); assert.equal( permController.approvals._approvals.size, 2, 'should only have created two pending approvals', - ) + ); // now, remaining pending requests should be approved without issue for (const id of permController.approvals._approvals.keys()) { await permController.approvePermissionsRequest( PERMS.approvedRequest(id, PERMS.requests.test_method()), - ) + ); } - await requestApproval1 - await requestApproval2 + await requestApproval1; + await requestApproval2; assert.ok( resA1.result && !resA1.error, 'first response should have result and no error', - ) + ); assert.equal( resA1.result.length, 1, 'first origin should have single approved permission', - ) + ); assert.ok( resB1.result && !resB1.error, 'second response should have result and no error', - ) + ); assert.equal( resB1.result.length, 1, 'second origin should have single approved permission', - ) - }) - }) + ); + }); + }); describe('restricted methods', function () { - let permController + let permController; beforeEach(function () { - permController = initPermController() - }) + permController = initPermController(); + }); it('prevents restricted method access for unpermitted domain', async function () { const aMiddleware = getPermissionsMiddleware( permController, DOMAINS.a.origin, - ) + ); - const req = RPC_REQUESTS.test_method(DOMAINS.a.origin) - const res = {} + const req = RPC_REQUESTS.test_method(DOMAINS.a.origin); + const res = {}; - const expectedError = ERRORS.rpcCap.unauthorized() + const expectedError = ERRORS.rpcCap.unauthorized(); await assert.rejects( aMiddleware(req, res), expectedError, 'request should be rejected with correct error', - ) + ); assert.ok( !res.result && res.error && res.error.code === expectedError.code, 'response should have expected error and no result', - ) - }) + ); + }); it('allows restricted method access for permitted domain', async function () { const bMiddleware = getPermissionsMiddleware( permController, DOMAINS.b.origin, - ) + ); grantPermissions( permController, DOMAINS.b.origin, PERMS.finalizedRequests.test_method(), - ) + ); - const req = RPC_REQUESTS.test_method(DOMAINS.b.origin, true) - const res = {} + const req = RPC_REQUESTS.test_method(DOMAINS.b.origin, true); + const res = {}; - await assert.doesNotReject(bMiddleware(req, res), 'should not reject') + await assert.doesNotReject(bMiddleware(req, res), 'should not reject'); assert.ok( res.result && res.result === 1, 'response should have correct result', - ) - }) - }) + ); + }); + }); describe('eth_accounts', function () { - let permController + let permController; beforeEach(function () { - permController = initPermController() - }) + permController = initPermController(); + }); it('returns empty array for non-permitted domain', async function () { const aMiddleware = getPermissionsMiddleware( permController, DOMAINS.a.origin, - ) + ); - const req = RPC_REQUESTS.eth_accounts(DOMAINS.a.origin) - const res = {} + const req = RPC_REQUESTS.eth_accounts(DOMAINS.a.origin); + const res = {}; - await assert.doesNotReject(aMiddleware(req, res), 'should not reject') + await assert.doesNotReject(aMiddleware(req, res), 'should not reject'); assert.ok( res.result && !res.error, 'response should have result and no error', - ) - assert.deepEqual(res.result, [], 'response should have correct result') - }) + ); + assert.deepEqual(res.result, [], 'response should have correct result'); + }); it('returns correct accounts for permitted domain', async function () { const aMiddleware = getPermissionsMiddleware( permController, DOMAINS.a.origin, - ) + ); grantPermissions( permController, DOMAINS.a.origin, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.a.permitted), - ) + ); - const req = RPC_REQUESTS.eth_accounts(DOMAINS.a.origin) - const res = {} + const req = RPC_REQUESTS.eth_accounts(DOMAINS.a.origin); + const res = {}; - await assert.doesNotReject(aMiddleware(req, res), 'should not reject') + await assert.doesNotReject(aMiddleware(req, res), 'should not reject'); assert.ok( res.result && !res.error, 'response should have result and no error', - ) + ); assert.deepEqual( res.result, [ACCOUNTS.a.primary], 'response should have correct result', - ) - }) - }) + ); + }); + }); describe('eth_requestAccounts', function () { - let permController + let permController; beforeEach(function () { - permController = initPermController() - }) + permController = initPermController(); + }); it('requests accounts for unpermitted origin, and approves on user approval', async function () { - createApprovalSpies(permController) + createApprovalSpies(permController); - const userApprovalPromise = getUserApprovalPromise(permController) + const userApprovalPromise = getUserApprovalPromise(permController); const aMiddleware = getPermissionsMiddleware( permController, DOMAINS.a.origin, - ) + ); - const req = RPC_REQUESTS.eth_requestAccounts(DOMAINS.a.origin) - const res = {} + const req = RPC_REQUESTS.eth_requestAccounts(DOMAINS.a.origin); + const res = {}; const pendingApproval = assert.doesNotReject( aMiddleware(req, res), 'should not reject permissions request', - ) + ); - await userApprovalPromise + await userApprovalPromise; assert.ok( permController.approvals._add.calledOnce, 'should have added single approval request', - ) + ); - const id = getNextApprovalId(permController) + const id = getNextApprovalId(permController); const approvedReq = PERMS.approvedRequest( id, PERMS.requests.eth_accounts(), - ) + ); await permController.approvePermissionsRequest( approvedReq, ACCOUNTS.a.permitted, - ) + ); // wait for permission to be granted - await pendingApproval + await pendingApproval; const perms = permController.permissions.getPermissionsForDomain( DOMAINS.a.origin, - ) + ); assert.equal( perms.length, 1, 'domain should have correct number of permissions', - ) + ); validatePermission( perms[0], PERM_NAMES.eth_accounts, DOMAINS.a.origin, CAVEATS.eth_accounts(ACCOUNTS.a.permitted), - ) + ); // we should also see the accounts on the response assert.ok( res.result && !res.error, 'response should have result and no error', - ) + ); assert.deepEqual( res.result, [ACCOUNTS.a.primary], 'result should have correct accounts', - ) + ); // we should also be able to get the accounts independently - const aAccounts = await permController.getAccounts(DOMAINS.a.origin) + const aAccounts = await permController.getAccounts(DOMAINS.a.origin); assert.deepEqual( aAccounts, [ACCOUNTS.a.primary], 'origin should have have correct accounts', - ) - }) + ); + }); it('requests accounts for unpermitted origin, and rejects on user rejection', async function () { - createApprovalSpies(permController) + createApprovalSpies(permController); - const userApprovalPromise = getUserApprovalPromise(permController) + const userApprovalPromise = getUserApprovalPromise(permController); const aMiddleware = getPermissionsMiddleware( permController, DOMAINS.a.origin, - ) + ); - const req = RPC_REQUESTS.eth_requestAccounts(DOMAINS.a.origin) - const res = {} + const req = RPC_REQUESTS.eth_requestAccounts(DOMAINS.a.origin); + const res = {}; - const expectedError = ERRORS.rejectPermissionsRequest.rejection() + const expectedError = ERRORS.rejectPermissionsRequest.rejection(); const requestRejection = assert.rejects( aMiddleware(req, res), expectedError, 'request should be rejected with correct error', - ) + ); - await userApprovalPromise + await userApprovalPromise; assert.ok( permController.approvals._add.calledOnce, 'should have added single approval request', - ) + ); - const id = getNextApprovalId(permController) + const id = getNextApprovalId(permController); - await permController.rejectPermissionsRequest(id) - await requestRejection + await permController.rejectPermissionsRequest(id); + await requestRejection; assert.ok( !res.result && res.error && res.error.message === expectedError.message, 'response should have expected error and no result', - ) + ); - const aAccounts = await permController.getAccounts(DOMAINS.a.origin) + const aAccounts = await permController.getAccounts(DOMAINS.a.origin); assert.deepEqual( aAccounts, [], 'origin should have have correct accounts', - ) - }) + ); + }); it('directly returns accounts for permitted domain', async function () { const cMiddleware = getPermissionsMiddleware( permController, DOMAINS.c.origin, - ) + ); grantPermissions( permController, DOMAINS.c.origin, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.c.permitted), - ) + ); - const req = RPC_REQUESTS.eth_requestAccounts(DOMAINS.c.origin) - const res = {} + const req = RPC_REQUESTS.eth_requestAccounts(DOMAINS.c.origin); + const res = {}; - await assert.doesNotReject(cMiddleware(req, res), 'should not reject') + await assert.doesNotReject(cMiddleware(req, res), 'should not reject'); assert.ok( res.result && !res.error, 'response should have result and no error', - ) + ); assert.deepEqual( res.result, [ACCOUNTS.c.primary], 'response should have correct result', - ) - }) + ); + }); it('rejects new requests when request already pending', async function () { - let unlock + let unlock; const unlockPromise = new Promise((resolve) => { - unlock = resolve - }) + unlock = resolve; + }); - permController.getUnlockPromise = () => unlockPromise + permController.getUnlockPromise = () => unlockPromise; const cMiddleware = getPermissionsMiddleware( permController, DOMAINS.c.origin, - ) + ); grantPermissions( permController, DOMAINS.c.origin, PERMS.finalizedRequests.eth_accounts(ACCOUNTS.c.permitted), - ) + ); - const req = RPC_REQUESTS.eth_requestAccounts(DOMAINS.c.origin) - const res = {} + const req = RPC_REQUESTS.eth_requestAccounts(DOMAINS.c.origin); + const res = {}; // this will block until we resolve the unlock Promise const requestApproval = assert.doesNotReject( cMiddleware(req, res), 'should not reject', - ) + ); // this will reject because of the already pending request await assert.rejects( cMiddleware({ ...req }, {}), ERRORS.eth_requestAccounts.requestAlreadyPending(DOMAINS.c.origin), - ) + ); // now unlock and let through the first request - unlock() + unlock(); - await requestApproval + await requestApproval; assert.ok( res.result && !res.error, 'response should have result and no error', - ) + ); assert.deepEqual( res.result, [ACCOUNTS.c.primary], 'response should have correct result', - ) - }) - }) + ); + }); + }); describe('metamask_sendDomainMetadata', function () { - let permController, clock + let permController, clock; beforeEach(function () { - permController = initPermController() - clock = sinon.useFakeTimers(1) - }) + permController = initPermController(); + clock = sinon.useFakeTimers(1); + }); afterEach(function () { - clock.restore() - }) + clock.restore(); + }); it('records domain metadata', async function () { - const name = 'BAZ' + const name = 'BAZ'; const cMiddleware = getPermissionsMiddleware( permController, DOMAINS.c.origin, - ) + ); const req = RPC_REQUESTS.metamask_sendDomainMetadata( DOMAINS.c.origin, name, - ) - const res = {} + ); + const res = {}; - await assert.doesNotReject(cMiddleware(req, res), 'should not reject') + await assert.doesNotReject(cMiddleware(req, res), 'should not reject'); - assert.ok(res.result, 'result should be true') + assert.ok(res.result, 'result should be true'); - const metadataStore = permController.store.getState()[METADATA_STORE_KEY] + const metadataStore = permController.store.getState()[METADATA_STORE_KEY]; assert.deepEqual( metadataStore, @@ -863,87 +863,87 @@ describe('permissions middleware', function () { }, }, 'metadata should have been added to store', - ) - }) + ); + }); it('records domain metadata and preserves extensionId', async function () { - const extensionId = 'fooExtension' + const extensionId = 'fooExtension'; - const name = 'BAZ' + const name = 'BAZ'; const cMiddleware = getPermissionsMiddleware( permController, DOMAINS.c.origin, extensionId, - ) + ); const req = RPC_REQUESTS.metamask_sendDomainMetadata( DOMAINS.c.origin, name, - ) - const res = {} + ); + const res = {}; - await assert.doesNotReject(cMiddleware(req, res), 'should not reject') + await assert.doesNotReject(cMiddleware(req, res), 'should not reject'); - assert.ok(res.result, 'result should be true') + assert.ok(res.result, 'result should be true'); - const metadataStore = permController.store.getState()[METADATA_STORE_KEY] + const metadataStore = permController.store.getState()[METADATA_STORE_KEY]; assert.deepEqual( metadataStore, { [DOMAINS.c.origin]: { name, extensionId, lastUpdated: 1 } }, 'metadata should have been added to store', - ) - }) + ); + }); it('should not record domain metadata if no name', async function () { - const name = null + const name = null; const cMiddleware = getPermissionsMiddleware( permController, DOMAINS.c.origin, - ) + ); const req = RPC_REQUESTS.metamask_sendDomainMetadata( DOMAINS.c.origin, name, - ) - const res = {} + ); + const res = {}; - await assert.doesNotReject(cMiddleware(req, res), 'should not reject') + await assert.doesNotReject(cMiddleware(req, res), 'should not reject'); - assert.ok(res.result, 'result should be true') + assert.ok(res.result, 'result should be true'); - const metadataStore = permController.store.getState()[METADATA_STORE_KEY] + const metadataStore = permController.store.getState()[METADATA_STORE_KEY]; assert.deepEqual( metadataStore, {}, 'metadata should not have been added to store', - ) - }) + ); + }); it('should not record domain metadata if no metadata', async function () { const cMiddleware = getPermissionsMiddleware( permController, DOMAINS.c.origin, - ) + ); - const req = RPC_REQUESTS.metamask_sendDomainMetadata(DOMAINS.c.origin) - delete req.domainMetadata - const res = {} + const req = RPC_REQUESTS.metamask_sendDomainMetadata(DOMAINS.c.origin); + delete req.domainMetadata; + const res = {}; - await assert.doesNotReject(cMiddleware(req, res), 'should not reject') + await assert.doesNotReject(cMiddleware(req, res), 'should not reject'); - assert.ok(res.result, 'result should be true') + assert.ok(res.result, 'result should be true'); - const metadataStore = permController.store.getState()[METADATA_STORE_KEY] + const metadataStore = permController.store.getState()[METADATA_STORE_KEY]; assert.deepEqual( metadataStore, {}, 'metadata should not have been added to store', - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/test/unit/app/controllers/permissions/restricted-methods-test.js b/test/unit/app/controllers/permissions/restricted-methods-test.js index 2b7361110e..a5cf3dc0bf 100644 --- a/test/unit/app/controllers/permissions/restricted-methods-test.js +++ b/test/unit/app/controllers/permissions/restricted-methods-test.js @@ -1,137 +1,137 @@ -import { strict as assert } from 'assert' -import pify from 'pify' +import { strict as assert } from 'assert'; +import pify from 'pify'; -import getRestrictedMethods from '../../../../../app/scripts/controllers/permissions/restrictedMethods' +import getRestrictedMethods from '../../../../../app/scripts/controllers/permissions/restrictedMethods'; describe('restricted methods', function () { describe('eth_accounts', function () { it('should handle getKeyringAccounts error', async function () { const restrictedMethods = getRestrictedMethods({ getKeyringAccounts: async () => { - throw new Error('foo') + throw new Error('foo'); }, - }) - const ethAccountsMethod = pify(restrictedMethods.eth_accounts.method) + }); + const ethAccountsMethod = pify(restrictedMethods.eth_accounts.method); - const res = {} - const fooError = new Error('foo') + const res = {}; + const fooError = new Error('foo'); await assert.rejects( ethAccountsMethod(null, res, null), fooError, 'Should reject with expected error', - ) + ); assert.deepEqual( res, { error: fooError }, 'response should have expected error and no result', - ) - }) + ); + }); it('should handle missing identity for first account when sorting', async function () { const restrictedMethods = getRestrictedMethods({ getIdentities: () => { - return { '0x7e57e2': {} } + return { '0x7e57e2': {} }; }, getKeyringAccounts: async () => ['0x7e57e2', '0x7e57e3'], - }) - const ethAccountsMethod = pify(restrictedMethods.eth_accounts.method) + }); + const ethAccountsMethod = pify(restrictedMethods.eth_accounts.method); - const res = {} - await assert.rejects(ethAccountsMethod(null, res, null)) - assert.ok(res.error instanceof Error, 'result should have error') + const res = {}; + await assert.rejects(ethAccountsMethod(null, res, null)); + assert.ok(res.error instanceof Error, 'result should have error'); assert.deepEqual( Object.keys(res), ['error'], 'result should only contain error', - ) - }) + ); + }); it('should handle missing identity for second account when sorting', async function () { const restrictedMethods = getRestrictedMethods({ getIdentities: () => { - return { '0x7e57e3': {} } + return { '0x7e57e3': {} }; }, getKeyringAccounts: async () => ['0x7e57e2', '0x7e57e3'], - }) - const ethAccountsMethod = pify(restrictedMethods.eth_accounts.method) + }); + const ethAccountsMethod = pify(restrictedMethods.eth_accounts.method); - const res = {} - await assert.rejects(ethAccountsMethod(null, res, null)) - assert.ok(res.error instanceof Error, 'result should have error') + const res = {}; + await assert.rejects(ethAccountsMethod(null, res, null)); + assert.ok(res.error instanceof Error, 'result should have error'); assert.deepEqual( Object.keys(res), ['error'], 'result should only contain error', - ) - }) + ); + }); it('should return accounts in keyring order when none are selected', async function () { - const keyringAccounts = ['0x7e57e2', '0x7e57e3', '0x7e57e4', '0x7e57e5'] + const keyringAccounts = ['0x7e57e2', '0x7e57e3', '0x7e57e4', '0x7e57e5']; const restrictedMethods = getRestrictedMethods({ getIdentities: () => { return keyringAccounts.reduce((identities, address) => { - identities[address] = {} - return identities - }, {}) + identities[address] = {}; + return identities; + }, {}); }, getKeyringAccounts: async () => [...keyringAccounts], - }) - const ethAccountsMethod = pify(restrictedMethods.eth_accounts.method) + }); + const ethAccountsMethod = pify(restrictedMethods.eth_accounts.method); - const res = {} - await ethAccountsMethod(null, res, null) + const res = {}; + await ethAccountsMethod(null, res, null); assert.deepEqual( res, { result: keyringAccounts }, 'should return accounts in correct order', - ) - }) + ); + }); it('should return accounts in keyring order when all have same last selected time', async function () { - const keyringAccounts = ['0x7e57e2', '0x7e57e3', '0x7e57e4', '0x7e57e5'] + const keyringAccounts = ['0x7e57e2', '0x7e57e3', '0x7e57e4', '0x7e57e5']; const restrictedMethods = getRestrictedMethods({ getIdentities: () => { return keyringAccounts.reduce((identities, address) => { - identities[address] = { lastSelected: 1000 } - return identities - }, {}) + identities[address] = { lastSelected: 1000 }; + return identities; + }, {}); }, getKeyringAccounts: async () => [...keyringAccounts], - }) - const ethAccountsMethod = pify(restrictedMethods.eth_accounts.method) + }); + const ethAccountsMethod = pify(restrictedMethods.eth_accounts.method); - const res = {} - await ethAccountsMethod(null, res, null) + const res = {}; + await ethAccountsMethod(null, res, null); assert.deepEqual( res, { result: keyringAccounts }, 'should return accounts in correct order', - ) - }) + ); + }); it('should return accounts sorted by last selected (descending)', async function () { - const keyringAccounts = ['0x7e57e2', '0x7e57e3', '0x7e57e4', '0x7e57e5'] - const expectedResult = keyringAccounts.slice().reverse() + const keyringAccounts = ['0x7e57e2', '0x7e57e3', '0x7e57e4', '0x7e57e5']; + const expectedResult = keyringAccounts.slice().reverse(); const restrictedMethods = getRestrictedMethods({ getIdentities: () => { return keyringAccounts.reduce((identities, address, index) => { - identities[address] = { lastSelected: index * 1000 } - return identities - }, {}) + identities[address] = { lastSelected: index * 1000 }; + return identities; + }, {}); }, getKeyringAccounts: async () => [...keyringAccounts], - }) - const ethAccountsMethod = pify(restrictedMethods.eth_accounts.method) + }); + const ethAccountsMethod = pify(restrictedMethods.eth_accounts.method); - const res = {} - await ethAccountsMethod(null, res, null) + const res = {}; + await ethAccountsMethod(null, res, null); assert.deepEqual( res, { result: expectedResult }, 'should return accounts in correct order', - ) - }) + ); + }); it('should return accounts sorted by last selected (descending) with unselected accounts last, in keyring order', async function () { const keyringAccounts = [ @@ -140,14 +140,14 @@ describe('restricted methods', function () { '0x7e57e4', '0x7e57e5', '0x7e57e6', - ] + ]; const expectedResult = [ '0x7e57e4', '0x7e57e2', '0x7e57e3', '0x7e57e5', '0x7e57e6', - ] + ]; const restrictedMethods = getRestrictedMethods({ getIdentities: () => { return { @@ -156,19 +156,19 @@ describe('restricted methods', function () { '0x7e57e4': { lastSelected: 2000 }, '0x7e57e5': {}, '0x7e57e6': {}, - } + }; }, getKeyringAccounts: async () => [...keyringAccounts], - }) - const ethAccountsMethod = pify(restrictedMethods.eth_accounts.method) + }); + const ethAccountsMethod = pify(restrictedMethods.eth_accounts.method); - const res = {} - await ethAccountsMethod(null, res, null) + const res = {}; + await ethAccountsMethod(null, res, null); assert.deepEqual( res, { result: expectedResult }, 'should return accounts in correct order', - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/test/unit/app/controllers/preferences-controller-test.js b/test/unit/app/controllers/preferences-controller-test.js index 065d357825..d2a85d12c9 100644 --- a/test/unit/app/controllers/preferences-controller-test.js +++ b/test/unit/app/controllers/preferences-controller-test.js @@ -1,30 +1,30 @@ -import assert from 'assert' -import { ObservableStore } from '@metamask/obs-store' -import sinon from 'sinon' -import PreferencesController from '../../../../app/scripts/controllers/preferences' +import assert from 'assert'; +import { ObservableStore } from '@metamask/obs-store'; +import sinon from 'sinon'; +import PreferencesController from '../../../../app/scripts/controllers/preferences'; describe('preferences controller', function () { - let preferencesController - let network - const migrateAddressBookState = sinon.stub() + let preferencesController; + let network; + const migrateAddressBookState = sinon.stub(); beforeEach(function () { - network = { providerStore: new ObservableStore({ type: 'mainnet' }) } + network = { providerStore: new ObservableStore({ type: 'mainnet' }) }; preferencesController = new PreferencesController({ migrateAddressBookState, network, - }) - }) + }); + }); afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); describe('setAddresses', function () { it('should keep a map of addresses to names and addresses in the store', function () { - preferencesController.setAddresses(['0xda22le', '0x7e57e2']) + preferencesController.setAddresses(['0xda22le', '0x7e57e2']); - const { identities } = preferencesController.store.getState() + const { identities } = preferencesController.store.getState(); assert.deepEqual(identities, { '0xda22le': { name: 'Account 1', @@ -34,25 +34,25 @@ describe('preferences controller', function () { name: 'Account 2', address: '0x7e57e2', }, - }) - }) + }); + }); it('should create account tokens for each account in the store', function () { - preferencesController.setAddresses(['0xda22le', '0x7e57e2']) + preferencesController.setAddresses(['0xda22le', '0x7e57e2']); - const { accountTokens } = preferencesController.store.getState() + const { accountTokens } = preferencesController.store.getState(); assert.deepEqual(accountTokens, { '0xda22le': {}, '0x7e57e2': {}, - }) - }) + }); + }); it('should replace its list of addresses', function () { - preferencesController.setAddresses(['0xda22le', '0x7e57e2']) - preferencesController.setAddresses(['0xda22le77', '0x7e57e277']) + preferencesController.setAddresses(['0xda22le', '0x7e57e2']); + preferencesController.setAddresses(['0xda22le77', '0x7e57e277']); - const { identities } = preferencesController.store.getState() + const { identities } = preferencesController.store.getState(); assert.deepEqual(identities, { '0xda22le77': { name: 'Account 1', @@ -62,46 +62,46 @@ describe('preferences controller', function () { name: 'Account 2', address: '0x7e57e277', }, - }) - }) - }) + }); + }); + }); describe('removeAddress', function () { it('should remove an address from state', function () { - preferencesController.setAddresses(['0xda22le', '0x7e57e2']) + preferencesController.setAddresses(['0xda22le', '0x7e57e2']); - preferencesController.removeAddress('0xda22le') + preferencesController.removeAddress('0xda22le'); assert.equal( preferencesController.store.getState().identities['0xda22le'], undefined, - ) - }) + ); + }); it('should remove an address from state and respective tokens', function () { - preferencesController.setAddresses(['0xda22le', '0x7e57e2']) + preferencesController.setAddresses(['0xda22le', '0x7e57e2']); - preferencesController.removeAddress('0xda22le') + preferencesController.removeAddress('0xda22le'); assert.equal( preferencesController.store.getState().accountTokens['0xda22le'], undefined, - ) - }) + ); + }); it('should switch accounts if the selected address is removed', function () { - preferencesController.setAddresses(['0xda22le', '0x7e57e2']) + preferencesController.setAddresses(['0xda22le', '0x7e57e2']); - preferencesController.setSelectedAddress('0x7e57e2') - preferencesController.removeAddress('0x7e57e2') + preferencesController.setSelectedAddress('0x7e57e2'); + preferencesController.removeAddress('0x7e57e2'); - assert.equal(preferencesController.getSelectedAddress(), '0xda22le') - }) - }) + assert.equal(preferencesController.getSelectedAddress(), '0xda22le'); + }); + }); describe('setAccountLabel', function () { it('should update a label for the given account', function () { - preferencesController.setAddresses(['0xda22le', '0x7e57e2']) + preferencesController.setAddresses(['0xda22le', '0x7e57e2']); assert.deepEqual( preferencesController.store.getState().identities['0xda22le'], @@ -109,408 +109,412 @@ describe('preferences controller', function () { name: 'Account 1', address: '0xda22le', }, - ) + ); - preferencesController.setAccountLabel('0xda22le', 'Dazzle') + preferencesController.setAccountLabel('0xda22le', 'Dazzle'); assert.deepEqual( preferencesController.store.getState().identities['0xda22le'], { name: 'Dazzle', address: '0xda22le', }, - ) - }) - }) + ); + }); + }); describe('getTokens', function () { it('should return an empty list initially', async function () { - preferencesController.setAddresses(['0x7e57e2']) - await preferencesController.setSelectedAddress('0x7e57e2') + preferencesController.setAddresses(['0x7e57e2']); + await preferencesController.setSelectedAddress('0x7e57e2'); - const tokens = preferencesController.getTokens() - assert.equal(tokens.length, 0, 'empty list of tokens') - }) - }) + const tokens = preferencesController.getTokens(); + assert.equal(tokens.length, 0, 'empty list of tokens'); + }); + }); describe('addToken', function () { it('should add that token to its state', async function () { - const address = '0xabcdef1234567' - const symbol = 'ABBR' - const decimals = 5 + const address = '0xabcdef1234567'; + const symbol = 'ABBR'; + const decimals = 5; - preferencesController.setAddresses(['0x7e57e2']) - await preferencesController.setSelectedAddress('0x7e57e2') - await preferencesController.addToken(address, symbol, decimals) + preferencesController.setAddresses(['0x7e57e2']); + await preferencesController.setSelectedAddress('0x7e57e2'); + await preferencesController.addToken(address, symbol, decimals); - const tokens = preferencesController.getTokens() - assert.equal(tokens.length, 1, 'one token added') + const tokens = preferencesController.getTokens(); + assert.equal(tokens.length, 1, 'one token added'); - const added = tokens[0] - assert.equal(added.address, address, 'set address correctly') - assert.equal(added.symbol, symbol, 'set symbol correctly') - assert.equal(added.decimals, decimals, 'set decimals correctly') - }) + const added = tokens[0]; + assert.equal(added.address, address, 'set address correctly'); + assert.equal(added.symbol, symbol, 'set symbol correctly'); + assert.equal(added.decimals, decimals, 'set decimals correctly'); + }); it('should allow updating a token value', async function () { - const address = '0xabcdef1234567' - const symbol = 'ABBR' - const decimals = 5 + const address = '0xabcdef1234567'; + const symbol = 'ABBR'; + const decimals = 5; - preferencesController.setAddresses(['0x7e57e2']) - await preferencesController.setSelectedAddress('0x7e57e2') - await preferencesController.addToken(address, symbol, decimals) + preferencesController.setAddresses(['0x7e57e2']); + await preferencesController.setSelectedAddress('0x7e57e2'); + await preferencesController.addToken(address, symbol, decimals); - const newDecimals = 6 - await preferencesController.addToken(address, symbol, newDecimals) + const newDecimals = 6; + await preferencesController.addToken(address, symbol, newDecimals); - const tokens = preferencesController.getTokens() - assert.equal(tokens.length, 1, 'one token added') + const tokens = preferencesController.getTokens(); + assert.equal(tokens.length, 1, 'one token added'); - const added = tokens[0] - assert.equal(added.address, address, 'set address correctly') - assert.equal(added.symbol, symbol, 'set symbol correctly') - assert.equal(added.decimals, newDecimals, 'updated decimals correctly') - }) + const added = tokens[0]; + assert.equal(added.address, address, 'set address correctly'); + assert.equal(added.symbol, symbol, 'set symbol correctly'); + assert.equal(added.decimals, newDecimals, 'updated decimals correctly'); + }); it('should allow adding tokens to two separate addresses', async function () { - const address = '0xabcdef1234567' - const symbol = 'ABBR' - const decimals = 5 + const address = '0xabcdef1234567'; + const symbol = 'ABBR'; + const decimals = 5; - preferencesController.setAddresses(['0x7e57e2', '0xda22le']) + preferencesController.setAddresses(['0x7e57e2', '0xda22le']); - await preferencesController.setSelectedAddress('0x7e57e2') - await preferencesController.addToken(address, symbol, decimals) + await preferencesController.setSelectedAddress('0x7e57e2'); + await preferencesController.addToken(address, symbol, decimals); assert.equal( preferencesController.getTokens().length, 1, 'one token added for 1st address', - ) + ); - await preferencesController.setSelectedAddress('0xda22le') - await preferencesController.addToken(address, symbol, decimals) + await preferencesController.setSelectedAddress('0xda22le'); + await preferencesController.addToken(address, symbol, decimals); assert.equal( preferencesController.getTokens().length, 1, 'one token added for 2nd address', - ) - }) + ); + }); it('should add token per account', async function () { - const addressFirst = '0xabcdef1234567' - const addressSecond = '0xabcdef1234568' - const symbolFirst = 'ABBR' - const symbolSecond = 'ABBB' - const decimals = 5 + const addressFirst = '0xabcdef1234567'; + const addressSecond = '0xabcdef1234568'; + const symbolFirst = 'ABBR'; + const symbolSecond = 'ABBB'; + const decimals = 5; - preferencesController.setAddresses(['0x7e57e2', '0xda22le']) + preferencesController.setAddresses(['0x7e57e2', '0xda22le']); - await preferencesController.setSelectedAddress('0x7e57e2') - await preferencesController.addToken(addressFirst, symbolFirst, decimals) - const tokensFirstAddress = preferencesController.getTokens() + await preferencesController.setSelectedAddress('0x7e57e2'); + await preferencesController.addToken(addressFirst, symbolFirst, decimals); + const tokensFirstAddress = preferencesController.getTokens(); - await preferencesController.setSelectedAddress('0xda22le') + await preferencesController.setSelectedAddress('0xda22le'); await preferencesController.addToken( addressSecond, symbolSecond, decimals, - ) - const tokensSeconAddress = preferencesController.getTokens() + ); + const tokensSeconAddress = preferencesController.getTokens(); assert.notEqual( tokensFirstAddress, tokensSeconAddress, 'add different tokens for two account and tokens are equal', - ) - }) + ); + }); it('should add token per network', async function () { - const addressFirst = '0xabcdef1234567' - const addressSecond = '0xabcdef1234568' - const symbolFirst = 'ABBR' - const symbolSecond = 'ABBB' - const decimals = 5 + const addressFirst = '0xabcdef1234567'; + const addressSecond = '0xabcdef1234568'; + const symbolFirst = 'ABBR'; + const symbolSecond = 'ABBB'; + const decimals = 5; - network.providerStore.updateState({ type: 'mainnet' }) - await preferencesController.addToken(addressFirst, symbolFirst, decimals) - const tokensFirstAddress = preferencesController.getTokens() + network.providerStore.updateState({ type: 'mainnet' }); + await preferencesController.addToken(addressFirst, symbolFirst, decimals); + const tokensFirstAddress = preferencesController.getTokens(); - network.providerStore.updateState({ type: 'rinkeby' }) + network.providerStore.updateState({ type: 'rinkeby' }); await preferencesController.addToken( addressSecond, symbolSecond, decimals, - ) - const tokensSeconAddress = preferencesController.getTokens() + ); + const tokensSeconAddress = preferencesController.getTokens(); assert.notEqual( tokensFirstAddress, tokensSeconAddress, 'add different tokens for two networks and tokens are equal', - ) - }) - }) + ); + }); + }); describe('removeToken', function () { it('should remove the only token from its state', async function () { - preferencesController.setAddresses(['0x7e57e2']) - await preferencesController.setSelectedAddress('0x7e57e2') - await preferencesController.addToken('0xa', 'A', 5) - await preferencesController.removeToken('0xa') + preferencesController.setAddresses(['0x7e57e2']); + await preferencesController.setSelectedAddress('0x7e57e2'); + await preferencesController.addToken('0xa', 'A', 5); + await preferencesController.removeToken('0xa'); - const tokens = preferencesController.getTokens() - assert.equal(tokens.length, 0, 'one token removed') - }) + const tokens = preferencesController.getTokens(); + assert.equal(tokens.length, 0, 'one token removed'); + }); it('should remove a token from its state', async function () { - preferencesController.setAddresses(['0x7e57e2']) - await preferencesController.setSelectedAddress('0x7e57e2') - await preferencesController.addToken('0xa', 'A', 4) - await preferencesController.addToken('0xb', 'B', 5) - await preferencesController.removeToken('0xa') + preferencesController.setAddresses(['0x7e57e2']); + await preferencesController.setSelectedAddress('0x7e57e2'); + await preferencesController.addToken('0xa', 'A', 4); + await preferencesController.addToken('0xb', 'B', 5); + await preferencesController.removeToken('0xa'); - const tokens = preferencesController.getTokens() - assert.equal(tokens.length, 1, 'one token removed') + const tokens = preferencesController.getTokens(); + assert.equal(tokens.length, 1, 'one token removed'); - const [token1] = tokens - assert.deepEqual(token1, { address: '0xb', symbol: 'B', decimals: 5 }) - }) + const [token1] = tokens; + assert.deepEqual(token1, { address: '0xb', symbol: 'B', decimals: 5 }); + }); it('should remove a token from its state on corresponding address', async function () { - preferencesController.setAddresses(['0x7e57e2', '0x7e57e3']) - await preferencesController.setSelectedAddress('0x7e57e2') - await preferencesController.addToken('0xa', 'A', 4) - await preferencesController.addToken('0xb', 'B', 5) - await preferencesController.setSelectedAddress('0x7e57e3') - await preferencesController.addToken('0xa', 'A', 4) - await preferencesController.addToken('0xb', 'B', 5) - const initialTokensSecond = preferencesController.getTokens() - await preferencesController.setSelectedAddress('0x7e57e2') - await preferencesController.removeToken('0xa') - - const tokensFirst = preferencesController.getTokens() - assert.equal(tokensFirst.length, 1, 'one token removed in account') - - const [token1] = tokensFirst - assert.deepEqual(token1, { address: '0xb', symbol: 'B', decimals: 5 }) - - await preferencesController.setSelectedAddress('0x7e57e3') - const tokensSecond = preferencesController.getTokens() + preferencesController.setAddresses(['0x7e57e2', '0x7e57e3']); + await preferencesController.setSelectedAddress('0x7e57e2'); + await preferencesController.addToken('0xa', 'A', 4); + await preferencesController.addToken('0xb', 'B', 5); + await preferencesController.setSelectedAddress('0x7e57e3'); + await preferencesController.addToken('0xa', 'A', 4); + await preferencesController.addToken('0xb', 'B', 5); + const initialTokensSecond = preferencesController.getTokens(); + await preferencesController.setSelectedAddress('0x7e57e2'); + await preferencesController.removeToken('0xa'); + + const tokensFirst = preferencesController.getTokens(); + assert.equal(tokensFirst.length, 1, 'one token removed in account'); + + const [token1] = tokensFirst; + assert.deepEqual(token1, { address: '0xb', symbol: 'B', decimals: 5 }); + + await preferencesController.setSelectedAddress('0x7e57e3'); + const tokensSecond = preferencesController.getTokens(); assert.deepEqual( tokensSecond, initialTokensSecond, 'token deleted for account', - ) - }) + ); + }); it('should remove a token from its state on corresponding network', async function () { - network.providerStore.updateState({ type: 'mainnet' }) - await preferencesController.addToken('0xa', 'A', 4) - await preferencesController.addToken('0xb', 'B', 5) - network.providerStore.updateState({ type: 'rinkeby' }) - await preferencesController.addToken('0xa', 'A', 4) - await preferencesController.addToken('0xb', 'B', 5) - const initialTokensSecond = preferencesController.getTokens() - network.providerStore.updateState({ type: 'mainnet' }) - await preferencesController.removeToken('0xa') - - const tokensFirst = preferencesController.getTokens() - assert.equal(tokensFirst.length, 1, 'one token removed in network') - - const [token1] = tokensFirst - assert.deepEqual(token1, { address: '0xb', symbol: 'B', decimals: 5 }) - - network.providerStore.updateState({ type: 'rinkeby' }) - const tokensSecond = preferencesController.getTokens() + network.providerStore.updateState({ type: 'mainnet' }); + await preferencesController.addToken('0xa', 'A', 4); + await preferencesController.addToken('0xb', 'B', 5); + network.providerStore.updateState({ type: 'rinkeby' }); + await preferencesController.addToken('0xa', 'A', 4); + await preferencesController.addToken('0xb', 'B', 5); + const initialTokensSecond = preferencesController.getTokens(); + network.providerStore.updateState({ type: 'mainnet' }); + await preferencesController.removeToken('0xa'); + + const tokensFirst = preferencesController.getTokens(); + assert.equal(tokensFirst.length, 1, 'one token removed in network'); + + const [token1] = tokensFirst; + assert.deepEqual(token1, { address: '0xb', symbol: 'B', decimals: 5 }); + + network.providerStore.updateState({ type: 'rinkeby' }); + const tokensSecond = preferencesController.getTokens(); assert.deepEqual( tokensSecond, initialTokensSecond, 'token deleted for network', - ) - }) - }) + ); + }); + }); describe('on setSelectedAddress', function () { it('should update tokens from its state on corresponding address', async function () { - preferencesController.setAddresses(['0x7e57e2', '0x7e57e3']) - await preferencesController.setSelectedAddress('0x7e57e2') - await preferencesController.addToken('0xa', 'A', 4) - await preferencesController.addToken('0xb', 'B', 5) - await preferencesController.setSelectedAddress('0x7e57e3') - await preferencesController.addToken('0xa', 'C', 4) - await preferencesController.addToken('0xb', 'D', 5) - - await preferencesController.setSelectedAddress('0x7e57e2') - const initialTokensFirst = preferencesController.getTokens() - await preferencesController.setSelectedAddress('0x7e57e3') - const initialTokensSecond = preferencesController.getTokens() + preferencesController.setAddresses(['0x7e57e2', '0x7e57e3']); + await preferencesController.setSelectedAddress('0x7e57e2'); + await preferencesController.addToken('0xa', 'A', 4); + await preferencesController.addToken('0xb', 'B', 5); + await preferencesController.setSelectedAddress('0x7e57e3'); + await preferencesController.addToken('0xa', 'C', 4); + await preferencesController.addToken('0xb', 'D', 5); + + await preferencesController.setSelectedAddress('0x7e57e2'); + const initialTokensFirst = preferencesController.getTokens(); + await preferencesController.setSelectedAddress('0x7e57e3'); + const initialTokensSecond = preferencesController.getTokens(); assert.notDeepEqual( initialTokensFirst, initialTokensSecond, 'tokens not equal for different accounts and tokens', - ) + ); - await preferencesController.setSelectedAddress('0x7e57e2') - const tokensFirst = preferencesController.getTokens() - await preferencesController.setSelectedAddress('0x7e57e3') - const tokensSecond = preferencesController.getTokens() + await preferencesController.setSelectedAddress('0x7e57e2'); + const tokensFirst = preferencesController.getTokens(); + await preferencesController.setSelectedAddress('0x7e57e3'); + const tokensSecond = preferencesController.getTokens(); assert.deepEqual( tokensFirst, initialTokensFirst, 'tokens equal for same account', - ) + ); assert.deepEqual( tokensSecond, initialTokensSecond, 'tokens equal for same account', - ) - }) - }) + ); + }); + }); describe('on updateStateNetworkType', function () { it('should remove a token from its state on corresponding network', async function () { - network.providerStore.updateState({ type: 'mainnet' }) - await preferencesController.addToken('0xa', 'A', 4) - await preferencesController.addToken('0xb', 'B', 5) - const initialTokensFirst = preferencesController.getTokens() - network.providerStore.updateState({ type: 'rinkeby' }) - await preferencesController.addToken('0xa', 'C', 4) - await preferencesController.addToken('0xb', 'D', 5) - const initialTokensSecond = preferencesController.getTokens() + network.providerStore.updateState({ type: 'mainnet' }); + await preferencesController.addToken('0xa', 'A', 4); + await preferencesController.addToken('0xb', 'B', 5); + const initialTokensFirst = preferencesController.getTokens(); + network.providerStore.updateState({ type: 'rinkeby' }); + await preferencesController.addToken('0xa', 'C', 4); + await preferencesController.addToken('0xb', 'D', 5); + const initialTokensSecond = preferencesController.getTokens(); assert.notDeepEqual( initialTokensFirst, initialTokensSecond, 'tokens not equal for different networks and tokens', - ) + ); - network.providerStore.updateState({ type: 'mainnet' }) - const tokensFirst = preferencesController.getTokens() - network.providerStore.updateState({ type: 'rinkeby' }) - const tokensSecond = preferencesController.getTokens() + network.providerStore.updateState({ type: 'mainnet' }); + const tokensFirst = preferencesController.getTokens(); + network.providerStore.updateState({ type: 'rinkeby' }); + const tokensSecond = preferencesController.getTokens(); assert.deepEqual( tokensFirst, initialTokensFirst, 'tokens equal for same network', - ) + ); assert.deepEqual( tokensSecond, initialTokensSecond, 'tokens equal for same network', - ) - }) - }) + ); + }); + }); describe('on watchAsset', function () { - let req, stubHandleWatchAssetERC20 - const sandbox = sinon.createSandbox() + let req, stubHandleWatchAssetERC20; + const sandbox = sinon.createSandbox(); beforeEach(function () { - req = { method: 'wallet_watchAsset', params: {} } + req = { method: 'wallet_watchAsset', params: {} }; stubHandleWatchAssetERC20 = sandbox.stub( preferencesController, '_handleWatchAssetERC20', - ) - }) + ); + }); after(function () { - sandbox.restore() - }) + sandbox.restore(); + }); it('should error if passed no type', async function () { await assert.rejects( () => preferencesController.requestWatchAsset(req), { message: 'Asset of type "undefined" not supported.' }, 'should have errored', - ) - }) + ); + }); it('should error if method is not supported', async function () { - req.params.type = 'someasset' + req.params.type = 'someasset'; await assert.rejects( () => preferencesController.requestWatchAsset(req), { message: 'Asset of type "someasset" not supported.' }, 'should have errored', - ) - }) + ); + }); it('should handle ERC20 type', async function () { - req.params.type = 'ERC20' - await preferencesController.requestWatchAsset(req) - sandbox.assert.called(stubHandleWatchAssetERC20) - }) - }) + req.params.type = 'ERC20'; + await preferencesController.requestWatchAsset(req); + sandbox.assert.called(stubHandleWatchAssetERC20); + }); + }); describe('on watchAsset of type ERC20', function () { - let req + let req; - const sandbox = sinon.createSandbox() + const sandbox = sinon.createSandbox(); beforeEach(function () { - req = { params: { type: 'ERC20' } } - }) + req = { params: { type: 'ERC20' } }; + }); after(function () { - sandbox.restore() - }) + sandbox.restore(); + }); it('should add suggested token', async function () { - const address = '0xabcdef1234567' - const symbol = 'ABBR' - const decimals = 5 - const image = 'someimage' - req.params.options = { address, symbol, decimals, image } + const address = '0xabcdef1234567'; + const symbol = 'ABBR'; + const decimals = 5; + const image = 'someimage'; + req.params.options = { address, symbol, decimals, image }; sandbox .stub(preferencesController, '_validateERC20AssetParams') - .returns(true) - preferencesController.openPopup = async () => undefined + .returns(true); + preferencesController.openPopup = async () => undefined; - await preferencesController._handleWatchAssetERC20(req.params.options) - const suggested = preferencesController.getSuggestedTokens() + await preferencesController._handleWatchAssetERC20(req.params.options); + const suggested = preferencesController.getSuggestedTokens(); assert.equal( Object.keys(suggested).length, 1, `one token added ${Object.keys(suggested)}`, - ) + ); - assert.equal(suggested[address].address, address, 'set address correctly') - assert.equal(suggested[address].symbol, symbol, 'set symbol correctly') + assert.equal( + suggested[address].address, + address, + 'set address correctly', + ); + assert.equal(suggested[address].symbol, symbol, 'set symbol correctly'); assert.equal( suggested[address].decimals, decimals, 'set decimals correctly', - ) - assert.equal(suggested[address].image, image, 'set image correctly') - }) + ); + assert.equal(suggested[address].image, image, 'set image correctly'); + }); it('should add token correctly if user confirms', async function () { - const address = '0xabcdef1234567' - const symbol = 'ABBR' - const decimals = 5 - const image = 'someimage' - req.params.options = { address, symbol, decimals, image } + const address = '0xabcdef1234567'; + const symbol = 'ABBR'; + const decimals = 5; + const image = 'someimage'; + req.params.options = { address, symbol, decimals, image }; sandbox .stub(preferencesController, '_validateERC20AssetParams') - .returns(true) + .returns(true); preferencesController.openPopup = async () => { - await preferencesController.addToken(address, symbol, decimals, image) - } - - await preferencesController._handleWatchAssetERC20(req.params.options) - const tokens = preferencesController.getTokens() - assert.equal(tokens.length, 1, `one token added`) - const added = tokens[0] - assert.equal(added.address, address, 'set address correctly') - assert.equal(added.symbol, symbol, 'set symbol correctly') - assert.equal(added.decimals, decimals, 'set decimals correctly') - - const assetImages = preferencesController.getAssetImages() - assert.ok(assetImages[address], `set image correctly`) - }) + await preferencesController.addToken(address, symbol, decimals, image); + }; + + await preferencesController._handleWatchAssetERC20(req.params.options); + const tokens = preferencesController.getTokens(); + assert.equal(tokens.length, 1, `one token added`); + const added = tokens[0]; + assert.equal(added.address, address, 'set address correctly'); + assert.equal(added.symbol, symbol, 'set symbol correctly'); + assert.equal(added.decimals, decimals, 'set decimals correctly'); + + const assetImages = preferencesController.getAssetImages(); + assert.ok(assetImages[address], `set image correctly`); + }); it('should validate ERC20 asset correctly', async function () { - const validate = preferencesController._validateERC20AssetParams + const validate = preferencesController._validateERC20AssetParams; assert.doesNotThrow(() => validate({ @@ -518,11 +522,11 @@ describe('preferences controller', function () { symbol: 'ABC', decimals: 0, }), - ) + ); assert.throws( () => validate({ symbol: 'ABC', decimals: 0 }), 'missing address should fail', - ) + ); assert.throws( () => validate({ @@ -530,7 +534,7 @@ describe('preferences controller', function () { decimals: 0, }), 'missing symbol should fail', - ) + ); assert.throws( () => validate({ @@ -538,7 +542,7 @@ describe('preferences controller', function () { symbol: 'ABC', }), 'missing decimals should fail', - ) + ); assert.throws( () => validate({ @@ -547,7 +551,7 @@ describe('preferences controller', function () { decimals: 0, }), 'invalid symbol should fail', - ) + ); assert.throws( () => validate({ @@ -556,7 +560,7 @@ describe('preferences controller', function () { decimals: -1, }), 'decimals < 0 should fail', - ) + ); assert.throws( () => validate({ @@ -565,69 +569,69 @@ describe('preferences controller', function () { decimals: 38, }), 'decimals > 36 should fail', - ) + ); assert.throws( () => validate({ address: '0x123', symbol: 'ABC', decimals: 0 }), 'invalid address should fail', - ) - }) - }) + ); + }); + }); describe('setPasswordForgotten', function () { it('should default to false', function () { - const state = preferencesController.store.getState() - assert.equal(state.forgottenPassword, false) - }) + const state = preferencesController.store.getState(); + assert.equal(state.forgottenPassword, false); + }); it('should set the forgottenPassword property in state', function () { assert.equal( preferencesController.store.getState().forgottenPassword, false, - ) + ); - preferencesController.setPasswordForgotten(true) + preferencesController.setPasswordForgotten(true); assert.equal( preferencesController.store.getState().forgottenPassword, true, - ) - }) - }) + ); + }); + }); describe('#updateRpc', function () { it('should update the rpcDetails properly', async function () { preferencesController.store.updateState({ frequentRpcListDetail: [{}, { rpcUrl: 'test', chainId: '0x1' }, {}], - }) - await preferencesController.updateRpc({ rpcUrl: 'test', chainId: '0x1' }) + }); + await preferencesController.updateRpc({ rpcUrl: 'test', chainId: '0x1' }); await preferencesController.updateRpc({ rpcUrl: 'test/1', chainId: '0x1', - }) + }); await preferencesController.updateRpc({ rpcUrl: 'test/2', chainId: '0x1', - }) + }); await preferencesController.updateRpc({ rpcUrl: 'test/3', chainId: '0x1', - }) - const list = preferencesController.getFrequentRpcListDetail() - assert.deepEqual(list[1], { rpcUrl: 'test', chainId: '0x1' }) - }) + }); + const list = preferencesController.getFrequentRpcListDetail(); + assert.deepEqual(list[1], { rpcUrl: 'test', chainId: '0x1' }); + }); it('should migrate address book entries if chainId changes', async function () { preferencesController.store.updateState({ frequentRpcListDetail: [{}, { rpcUrl: 'test', chainId: '1' }, {}], - }) - await preferencesController.updateRpc({ rpcUrl: 'test', chainId: '0x1' }) - assert(migrateAddressBookState.calledWith('1', '0x1')) - }) - }) + }); + await preferencesController.updateRpc({ rpcUrl: 'test', chainId: '0x1' }); + assert(migrateAddressBookState.calledWith('1', '0x1')); + }); + }); describe('adding and removing from frequentRpcListDetail', function () { it('should add custom RPC url to state', function () { - preferencesController.addToFrequentRpcList('rpc_url', '0x1') + preferencesController.addToFrequentRpcList('rpc_url', '0x1'); assert.deepEqual( preferencesController.store.getState().frequentRpcListDetail, [ @@ -639,8 +643,8 @@ describe('preferences controller', function () { rpcPrefs: {}, }, ], - ) - preferencesController.addToFrequentRpcList('rpc_url', '0x1') + ); + preferencesController.addToFrequentRpcList('rpc_url', '0x1'); assert.deepEqual( preferencesController.store.getState().frequentRpcListDetail, [ @@ -652,17 +656,17 @@ describe('preferences controller', function () { rpcPrefs: {}, }, ], - ) - }) + ); + }); it('should throw if chainId is invalid', function () { assert.throws(() => { - preferencesController.addToFrequentRpcList('rpc_url', '1') - }, 'should throw on invalid chainId') - }) + preferencesController.addToFrequentRpcList('rpc_url', '1'); + }, 'should throw on invalid chainId'); + }); it('should remove custom RPC url from state', function () { - preferencesController.addToFrequentRpcList('rpc_url', '0x1') + preferencesController.addToFrequentRpcList('rpc_url', '0x1'); assert.deepEqual( preferencesController.store.getState().frequentRpcListDetail, [ @@ -674,27 +678,30 @@ describe('preferences controller', function () { rpcPrefs: {}, }, ], - ) - preferencesController.removeFromFrequentRpcList('other_rpc_url') - preferencesController.removeFromFrequentRpcList('http://localhost:8545') - preferencesController.removeFromFrequentRpcList('rpc_url') + ); + preferencesController.removeFromFrequentRpcList('other_rpc_url'); + preferencesController.removeFromFrequentRpcList('http://localhost:8545'); + preferencesController.removeFromFrequentRpcList('rpc_url'); assert.deepEqual( preferencesController.store.getState().frequentRpcListDetail, [], - ) - }) - }) + ); + }); + }); describe('setUsePhishDetect', function () { it('should default to true', function () { - const state = preferencesController.store.getState() - assert.equal(state.usePhishDetect, true) - }) + const state = preferencesController.store.getState(); + assert.equal(state.usePhishDetect, true); + }); it('should set the usePhishDetect property in state', function () { - assert.equal(preferencesController.store.getState().usePhishDetect, true) - preferencesController.setUsePhishDetect(false) - assert.equal(preferencesController.store.getState().usePhishDetect, false) - }) - }) -}) + assert.equal(preferencesController.store.getState().usePhishDetect, true); + preferencesController.setUsePhishDetect(false); + assert.equal( + preferencesController.store.getState().usePhishDetect, + false, + ); + }); + }); +}); diff --git a/test/unit/app/controllers/swaps-test.js b/test/unit/app/controllers/swaps-test.js index 2622d04ebe..5bd1c85298 100644 --- a/test/unit/app/controllers/swaps-test.js +++ b/test/unit/app/controllers/swaps-test.js @@ -1,19 +1,19 @@ -import assert from 'assert' -import sinon from 'sinon' +import assert from 'assert'; +import sinon from 'sinon'; -import { ethers } from 'ethers' -import { mapValues } from 'lodash' -import BigNumber from 'bignumber.js' -import { ObservableStore } from '@metamask/obs-store' +import { ethers } from 'ethers'; +import { mapValues } from 'lodash'; +import BigNumber from 'bignumber.js'; +import { ObservableStore } from '@metamask/obs-store'; import { ROPSTEN_NETWORK_ID, MAINNET_NETWORK_ID, -} from '../../../../shared/constants/network' -import { ETH_SWAPS_TOKEN_ADDRESS } from '../../../../ui/app/helpers/constants/swaps' -import { createTestProviderTools } from '../../../stub/provider' +} from '../../../../shared/constants/network'; +import { ETH_SWAPS_TOKEN_ADDRESS } from '../../../../ui/app/helpers/constants/swaps'; +import { createTestProviderTools } from '../../../stub/provider'; import SwapsController, { utils, -} from '../../../../app/scripts/controllers/swaps' +} from '../../../../app/scripts/controllers/swaps'; const MOCK_FETCH_PARAMS = { slippage: 3, @@ -23,16 +23,16 @@ const MOCK_FETCH_PARAMS = { value: '1000000000000000000', fromAddress: '0x7F18BB4Dd92CF2404C54CBa1A9BE4A1153bdb078', exchangeList: 'zeroExV1', -} +}; -const TEST_AGG_ID_1 = 'TEST_AGG_1' -const TEST_AGG_ID_2 = 'TEST_AGG_2' -const TEST_AGG_ID_3 = 'TEST_AGG_3' -const TEST_AGG_ID_4 = 'TEST_AGG_4' -const TEST_AGG_ID_5 = 'TEST_AGG_5' -const TEST_AGG_ID_6 = 'TEST_AGG_6' -const TEST_AGG_ID_BEST = 'TEST_AGG_BEST' -const TEST_AGG_ID_APPROVAL = 'TEST_AGG_APPROVAL' +const TEST_AGG_ID_1 = 'TEST_AGG_1'; +const TEST_AGG_ID_2 = 'TEST_AGG_2'; +const TEST_AGG_ID_3 = 'TEST_AGG_3'; +const TEST_AGG_ID_4 = 'TEST_AGG_4'; +const TEST_AGG_ID_5 = 'TEST_AGG_5'; +const TEST_AGG_ID_6 = 'TEST_AGG_6'; +const TEST_AGG_ID_BEST = 'TEST_AGG_BEST'; +const TEST_AGG_ID_APPROVAL = 'TEST_AGG_APPROVAL'; const MOCK_APPROVAL_NEEDED = { data: @@ -42,7 +42,7 @@ const MOCK_APPROVAL_NEEDED = { from: '0x2369267687A84ac7B494daE2f1542C40E37f4455', gas: '12', gasPrice: '34', -} +}; const MOCK_QUOTES_APPROVAL_REQUIRED = { [TEST_AGG_ID_APPROVAL]: { @@ -69,28 +69,28 @@ const MOCK_QUOTES_APPROVAL_REQUIRED = { approvalNeeded: MOCK_APPROVAL_NEEDED, fee: 1, }, -} +}; const MOCK_FETCH_METADATA = { destinationTokenInfo: { symbol: 'FOO', decimals: 18, }, -} +}; const MOCK_TOKEN_RATES_STORE = new ObservableStore({ contractExchangeRates: { '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': 2, '0x1111111111111111111111111111111111111111': 0.1, }, -}) +}); -const MOCK_GET_PROVIDER_CONFIG = () => ({ type: 'FAKE_NETWORK' }) +const MOCK_GET_PROVIDER_CONFIG = () => ({ type: 'FAKE_NETWORK' }); const MOCK_GET_BUFFERED_GAS_LIMIT = async () => ({ gasLimit: 2000000, simulationFails: undefined, -}) +}); function getMockNetworkController() { return { @@ -98,11 +98,11 @@ function getMockNetworkController() { getState: () => { return { network: ROPSTEN_NETWORK_ID, - } + }; }, }, on: sinon.stub().withArgs('networkDidChange').callsArgAsync(1), - } + }; } const EMPTY_INIT_STATE = { @@ -123,15 +123,15 @@ const EMPTY_INIT_STATE = { swapsFeatureIsLive: false, swapsQuoteRefreshTime: 60000, }, -} +}; -const sandbox = sinon.createSandbox() -const fetchTradesInfoStub = sandbox.stub() -const fetchSwapsFeatureLivenessStub = sandbox.stub() -const fetchSwapsQuoteRefreshTimeStub = sandbox.stub() +const sandbox = sinon.createSandbox(); +const fetchTradesInfoStub = sandbox.stub(); +const fetchSwapsFeatureLivenessStub = sandbox.stub(); +const fetchSwapsQuoteRefreshTimeStub = sandbox.stub(); describe('SwapsController', function () { - let provider + let provider; const getSwapsController = () => { return new SwapsController({ @@ -143,8 +143,8 @@ describe('SwapsController', function () { fetchTradesInfo: fetchTradesInfoStub, fetchSwapsFeatureLiveness: fetchSwapsFeatureLivenessStub, fetchSwapsQuoteRefreshTime: fetchSwapsQuoteRefreshTimeStub, - }) - } + }); + }; before(function () { const providerResultStub = { @@ -152,35 +152,38 @@ describe('SwapsController', function () { eth_gasPrice: '0x0de0b6b3a7640000', // by default, all accounts are external accounts (not contracts) eth_getCode: '0x', - } + }; provider = createTestProviderTools({ scaffold: providerResultStub, networkId: 1, chainId: 1, - }).provider - }) + }).provider; + }); afterEach(function () { - sandbox.restore() - }) + sandbox.restore(); + }); describe('constructor', function () { it('should setup correctly', function () { - const swapsController = getSwapsController() - assert.deepStrictEqual(swapsController.store.getState(), EMPTY_INIT_STATE) + const swapsController = getSwapsController(); + assert.deepStrictEqual( + swapsController.store.getState(), + EMPTY_INIT_STATE, + ); assert.deepStrictEqual( swapsController.getBufferedGasLimit, MOCK_GET_BUFFERED_GAS_LIMIT, - ) - assert.strictEqual(swapsController.pollCount, 0) + ); + assert.strictEqual(swapsController.pollCount, 0); assert.deepStrictEqual( swapsController.getProviderConfig, MOCK_GET_PROVIDER_CONFIG, - ) - }) + ); + }); it('should replace ethers instance when network changes', function () { - const networkController = getMockNetworkController() + const networkController = getMockNetworkController(); const swapsController = new SwapsController({ getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT, networkController, @@ -189,22 +192,22 @@ describe('SwapsController', function () { tokenRatesStore: MOCK_TOKEN_RATES_STORE, fetchTradesInfo: fetchTradesInfoStub, fetchSwapsFeatureLiveness: fetchSwapsFeatureLivenessStub, - }) - const currentEthersInstance = swapsController.ethersProvider - const onNetworkDidChange = networkController.on.getCall(0).args[1] + }); + const currentEthersInstance = swapsController.ethersProvider; + const onNetworkDidChange = networkController.on.getCall(0).args[1]; - onNetworkDidChange(MAINNET_NETWORK_ID) + onNetworkDidChange(MAINNET_NETWORK_ID); - const newEthersInstance = swapsController.ethersProvider + const newEthersInstance = swapsController.ethersProvider; assert.notStrictEqual( currentEthersInstance, newEthersInstance, 'Ethers provider should be replaced', - ) - }) + ); + }); it('should not replace ethers instance when network changes to loading', function () { - const networkController = getMockNetworkController() + const networkController = getMockNetworkController(); const swapsController = new SwapsController({ getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT, networkController, @@ -213,22 +216,22 @@ describe('SwapsController', function () { tokenRatesStore: MOCK_TOKEN_RATES_STORE, fetchTradesInfo: fetchTradesInfoStub, fetchSwapsFeatureLiveness: fetchSwapsFeatureLivenessStub, - }) - const currentEthersInstance = swapsController.ethersProvider - const onNetworkDidChange = networkController.on.getCall(0).args[1] + }); + const currentEthersInstance = swapsController.ethersProvider; + const onNetworkDidChange = networkController.on.getCall(0).args[1]; - onNetworkDidChange('loading') + onNetworkDidChange('loading'); - const newEthersInstance = swapsController.ethersProvider + const newEthersInstance = swapsController.ethersProvider; assert.strictEqual( currentEthersInstance, newEthersInstance, 'Ethers provider should not be replaced', - ) - }) + ); + }); it('should not replace ethers instance when network changes to the same network', function () { - const networkController = getMockNetworkController() + const networkController = getMockNetworkController(); const swapsController = new SwapsController({ getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT, networkController, @@ -237,149 +240,149 @@ describe('SwapsController', function () { tokenRatesStore: MOCK_TOKEN_RATES_STORE, fetchTradesInfo: fetchTradesInfoStub, fetchSwapsFeatureLiveness: fetchSwapsFeatureLivenessStub, - }) - const currentEthersInstance = swapsController.ethersProvider - const onNetworkDidChange = networkController.on.getCall(0).args[1] + }); + const currentEthersInstance = swapsController.ethersProvider; + const onNetworkDidChange = networkController.on.getCall(0).args[1]; - onNetworkDidChange(ROPSTEN_NETWORK_ID) + onNetworkDidChange(ROPSTEN_NETWORK_ID); - const newEthersInstance = swapsController.ethersProvider + const newEthersInstance = swapsController.ethersProvider; assert.strictEqual( currentEthersInstance, newEthersInstance, 'Ethers provider should not be replaced', - ) - }) - }) + ); + }); + }); describe('API', function () { - let swapsController + let swapsController; beforeEach(function () { - swapsController = getSwapsController() - }) + swapsController = getSwapsController(); + }); describe('setters', function () { it('should set selected quote agg id', function () { - const selectedAggId = 'test' - swapsController.setSelectedQuoteAggId(selectedAggId) + const selectedAggId = 'test'; + swapsController.setSelectedQuoteAggId(selectedAggId); assert.deepStrictEqual( swapsController.store.getState().swapsState.selectedAggId, selectedAggId, - ) - }) + ); + }); it('should set swaps tokens', function () { - const tokens = [] - swapsController.setSwapsTokens(tokens) + const tokens = []; + swapsController.setSwapsTokens(tokens); assert.deepStrictEqual( swapsController.store.getState().swapsState.tokens, tokens, - ) - }) + ); + }); it('should set trade tx id', function () { - const tradeTxId = 'test' - swapsController.setTradeTxId(tradeTxId) + const tradeTxId = 'test'; + swapsController.setTradeTxId(tradeTxId); assert.strictEqual( swapsController.store.getState().swapsState.tradeTxId, tradeTxId, - ) - }) + ); + }); it('should set swaps tx gas price', function () { - const gasPrice = 1 - swapsController.setSwapsTxGasPrice(gasPrice) + const gasPrice = 1; + swapsController.setSwapsTxGasPrice(gasPrice); assert.deepStrictEqual( swapsController.store.getState().swapsState.customGasPrice, gasPrice, - ) - }) + ); + }); it('should set swaps tx gas limit', function () { - const gasLimit = '1' - swapsController.setSwapsTxGasLimit(gasLimit) + const gasLimit = '1'; + swapsController.setSwapsTxGasLimit(gasLimit); assert.deepStrictEqual( swapsController.store.getState().swapsState.customMaxGas, gasLimit, - ) - }) + ); + }); it('should set background swap route state', function () { - const routeState = 'test' - swapsController.setBackgroundSwapRouteState(routeState) + const routeState = 'test'; + swapsController.setBackgroundSwapRouteState(routeState); assert.deepStrictEqual( swapsController.store.getState().swapsState.routeState, routeState, - ) - }) + ); + }); it('should set swaps error key', function () { - const errorKey = 'test' - swapsController.setSwapsErrorKey(errorKey) + const errorKey = 'test'; + swapsController.setSwapsErrorKey(errorKey); assert.deepStrictEqual( swapsController.store.getState().swapsState.errorKey, errorKey, - ) - }) + ); + }); it('should set initial gas estimate', async function () { - const initialAggId = TEST_AGG_ID_1 - const baseGasEstimate = 10 - const { maxGas, estimatedRefund } = getMockQuotes()[TEST_AGG_ID_1] + const initialAggId = TEST_AGG_ID_1; + const baseGasEstimate = 10; + const { maxGas, estimatedRefund } = getMockQuotes()[TEST_AGG_ID_1]; - const { swapsState } = swapsController.store.getState() + const { swapsState } = swapsController.store.getState(); // Set mock quotes in order to have data for the test agg swapsController.store.updateState({ swapsState: { ...swapsState, quotes: getMockQuotes() }, - }) + }); await swapsController.setInitialGasEstimate( initialAggId, baseGasEstimate, - ) + ); const { gasLimit: bufferedGasLimit, - } = await swapsController.getBufferedGasLimit() + } = await swapsController.getBufferedGasLimit(); const { gasEstimate, gasEstimateWithRefund, - } = swapsController.store.getState().swapsState.quotes[initialAggId] - assert.strictEqual(gasEstimate, bufferedGasLimit) + } = swapsController.store.getState().swapsState.quotes[initialAggId]; + assert.strictEqual(gasEstimate, bufferedGasLimit); assert.strictEqual( gasEstimateWithRefund, new BigNumber(maxGas, 10).minus(estimatedRefund, 10).toString(16), - ) - }) + ); + }); it('should set custom approve tx data', function () { - const data = 'test' - swapsController.setCustomApproveTxData(data) + const data = 'test'; + swapsController.setCustomApproveTxData(data); assert.deepStrictEqual( swapsController.store.getState().swapsState.customApproveTxData, data, - ) - }) - }) + ); + }); + }); describe('_findTopQuoteAndCalculateSavings', function () { beforeEach(function () { - const { swapsState } = swapsController.store.getState() + const { swapsState } = swapsController.store.getState(); swapsController.store.updateState({ swapsState: { ...swapsState, customGasPrice: '0x174876e800' }, - }) - }) + }); + }); it('returns empty object if passed undefined or empty object', async function () { assert.deepStrictEqual( await swapsController._findTopQuoteAndCalculateSavings(), {}, - ) + ); assert.deepStrictEqual( await swapsController._findTopQuoteAndCalculateSavings({}), {}, - ) - }) + ); + }); it('returns the top aggId and quotes with savings and fee values if passed necessary data and an even number of quotes', async function () { const [ @@ -387,34 +390,34 @@ describe('SwapsController', function () { resultQuotes, ] = await swapsController._findTopQuoteAndCalculateSavings( getTopQuoteAndSavingsMockQuotes(), - ) - assert.equal(topAggId, TEST_AGG_ID_1) + ); + assert.equal(topAggId, TEST_AGG_ID_1); assert.deepStrictEqual( resultQuotes, getTopQuoteAndSavingsBaseExpectedResults(), - ) - }) + ); + }); it('returns the top aggId and quotes with savings and fee values if passed necessary data and an odd number of quotes', async function () { - const testInput = getTopQuoteAndSavingsMockQuotes() - delete testInput[TEST_AGG_ID_6] - const expectedResultQuotes = getTopQuoteAndSavingsBaseExpectedResults() - delete expectedResultQuotes[TEST_AGG_ID_6] + const testInput = getTopQuoteAndSavingsMockQuotes(); + delete testInput[TEST_AGG_ID_6]; + const expectedResultQuotes = getTopQuoteAndSavingsBaseExpectedResults(); + delete expectedResultQuotes[TEST_AGG_ID_6]; expectedResultQuotes[TEST_AGG_ID_1].savings = { total: '0.0292', performance: '0.0297', fee: '0.02', metaMaskFee: '0.0205', medianMetaMaskFee: '0.0202', - } + }; const [ topAggId, resultQuotes, - ] = await swapsController._findTopQuoteAndCalculateSavings(testInput) - assert.equal(topAggId, TEST_AGG_ID_1) - assert.deepStrictEqual(resultQuotes, expectedResultQuotes) - }) + ] = await swapsController._findTopQuoteAndCalculateSavings(testInput); + assert.equal(topAggId, TEST_AGG_ID_1); + assert.deepStrictEqual(resultQuotes, expectedResultQuotes); + }); it('returns the top aggId, without best quote flagged, and quotes with fee values if passed necessary data but no custom convert rate exists', async function () { const testInput = mapValues( @@ -423,7 +426,7 @@ describe('SwapsController', function () { ...quote, destinationToken: '0xnoConversionRateExists', }), - ) + ); const expectedResultQuotes = { [TEST_AGG_ID_1]: { ...testInput[TEST_AGG_ID_1], @@ -449,15 +452,15 @@ describe('SwapsController', function () { ...testInput[TEST_AGG_ID_6], ethFee: '0.06', }, - } + }; const [ topAggId, resultQuotes, - ] = await swapsController._findTopQuoteAndCalculateSavings(testInput) - assert.equal(topAggId, TEST_AGG_ID_1) - assert.deepStrictEqual(resultQuotes, expectedResultQuotes) - }) + ] = await swapsController._findTopQuoteAndCalculateSavings(testInput); + assert.equal(topAggId, TEST_AGG_ID_1); + assert.deepStrictEqual(resultQuotes, expectedResultQuotes); + }); it('returns the top aggId and quotes with savings and fee values if passed necessary data and the source token is ETH', async function () { const testInput = mapValues( @@ -468,8 +471,8 @@ describe('SwapsController', function () { destinationToken: '0x1111111111111111111111111111111111111111', trade: { value: '0x8ac7230489e80000' }, }), - ) - const baseExpectedResultQuotes = getTopQuoteAndSavingsBaseExpectedResults() + ); + const baseExpectedResultQuotes = getTopQuoteAndSavingsBaseExpectedResults(); const expectedResultQuotes = { [TEST_AGG_ID_1]: { ...baseExpectedResultQuotes[TEST_AGG_ID_1], @@ -513,15 +516,15 @@ describe('SwapsController', function () { trade: { value: '0x8ac7230489e80000' }, overallValueOfQuote: '1.8705', }, - } + }; const [ topAggId, resultQuotes, - ] = await swapsController._findTopQuoteAndCalculateSavings(testInput) - assert.equal(topAggId, TEST_AGG_ID_1) - assert.deepStrictEqual(resultQuotes, expectedResultQuotes) - }) + ] = await swapsController._findTopQuoteAndCalculateSavings(testInput); + assert.equal(topAggId, TEST_AGG_ID_1); + assert.deepStrictEqual(resultQuotes, expectedResultQuotes); + }); it('returns the top aggId and quotes with savings and fee values if passed necessary data and the source token is ETH and an ETH fee is included in the trade value of what would be the best quote', async function () { const testInput = mapValues( @@ -532,10 +535,10 @@ describe('SwapsController', function () { destinationToken: '0x1111111111111111111111111111111111111111', trade: { value: '0x8ac7230489e80000' }, }), - ) + ); // 0.04 ETH fee included in trade value - testInput[TEST_AGG_ID_1].trade.value = '0x8b553ece48ec0000' - const baseExpectedResultQuotes = getTopQuoteAndSavingsBaseExpectedResults() + testInput[TEST_AGG_ID_1].trade.value = '0x8b553ece48ec0000'; + const baseExpectedResultQuotes = getTopQuoteAndSavingsBaseExpectedResults(); const expectedResultQuotes = { [TEST_AGG_ID_1]: { ...baseExpectedResultQuotes[TEST_AGG_ID_1], @@ -588,23 +591,23 @@ describe('SwapsController', function () { trade: { value: '0x8ac7230489e80000' }, overallValueOfQuote: '1.8705', }, - } - delete expectedResultQuotes[TEST_AGG_ID_1].isBestQuote - delete expectedResultQuotes[TEST_AGG_ID_1].savings + }; + delete expectedResultQuotes[TEST_AGG_ID_1].isBestQuote; + delete expectedResultQuotes[TEST_AGG_ID_1].savings; const [ topAggId, resultQuotes, - ] = await swapsController._findTopQuoteAndCalculateSavings(testInput) - assert.equal(topAggId, TEST_AGG_ID_2) - assert.deepStrictEqual(resultQuotes, expectedResultQuotes) - }) + ] = await swapsController._findTopQuoteAndCalculateSavings(testInput); + assert.equal(topAggId, TEST_AGG_ID_2); + assert.deepStrictEqual(resultQuotes, expectedResultQuotes); + }); it('returns the top aggId and quotes with savings and fee values if passed necessary data and the source token is not ETH and an ETH fee is included in the trade value of what would be the best quote', async function () { - const testInput = getTopQuoteAndSavingsMockQuotes() + const testInput = getTopQuoteAndSavingsMockQuotes(); // 0.04 ETH fee included in trade value - testInput[TEST_AGG_ID_1].trade.value = '0x8e1bc9bf040000' - const baseExpectedResultQuotes = getTopQuoteAndSavingsBaseExpectedResults() + testInput[TEST_AGG_ID_1].trade.value = '0x8e1bc9bf040000'; + const baseExpectedResultQuotes = getTopQuoteAndSavingsBaseExpectedResults(); const expectedResultQuotes = { ...baseExpectedResultQuotes, [TEST_AGG_ID_1]: { @@ -624,37 +627,37 @@ describe('SwapsController', function () { medianMetaMaskFee: '0.0201', }, }, - } - delete expectedResultQuotes[TEST_AGG_ID_1].isBestQuote - delete expectedResultQuotes[TEST_AGG_ID_1].savings + }; + delete expectedResultQuotes[TEST_AGG_ID_1].isBestQuote; + delete expectedResultQuotes[TEST_AGG_ID_1].savings; const [ topAggId, resultQuotes, - ] = await swapsController._findTopQuoteAndCalculateSavings(testInput) - assert.equal(topAggId, [TEST_AGG_ID_2]) - assert.deepStrictEqual(resultQuotes, expectedResultQuotes) - }) - }) + ] = await swapsController._findTopQuoteAndCalculateSavings(testInput); + assert.equal(topAggId, [TEST_AGG_ID_2]); + assert.deepStrictEqual(resultQuotes, expectedResultQuotes); + }); + }); describe('fetchAndSetQuotes', function () { it('returns null if fetchParams is not provided', async function () { - const quotes = await swapsController.fetchAndSetQuotes(undefined) - assert.strictEqual(quotes, null) - }) + const quotes = await swapsController.fetchAndSetQuotes(undefined); + assert.strictEqual(quotes, null); + }); it('calls fetchTradesInfo with the given fetchParams and returns the correct quotes', async function () { - fetchTradesInfoStub.resolves(getMockQuotes()) - fetchSwapsQuoteRefreshTimeStub.resolves(getMockQuoteRefreshTime()) + fetchTradesInfoStub.resolves(getMockQuotes()); + fetchSwapsQuoteRefreshTimeStub.resolves(getMockQuoteRefreshTime()); // Make it so approval is not required sandbox .stub(swapsController, '_getERC20Allowance') - .resolves(ethers.BigNumber.from(1)) + .resolves(ethers.BigNumber.from(1)); const [newQuotes] = await swapsController.fetchAndSetQuotes( MOCK_FETCH_PARAMS, MOCK_FETCH_METADATA, - ) + ); assert.deepStrictEqual(newQuotes[TEST_AGG_ID_BEST], { ...getMockQuotes()[TEST_AGG_ID_BEST], @@ -678,26 +681,26 @@ describe('SwapsController', function () { overallValueOfQuote: '-33554382', metaMaskFeeInEth: '0.5050505050505050505', ethValueOfTokens: '50', - }) + }); assert.strictEqual( fetchTradesInfoStub.calledOnceWithExactly(MOCK_FETCH_PARAMS), true, - ) - }) + ); + }); it('performs the allowance check', async function () { - fetchTradesInfoStub.resolves(getMockQuotes()) - fetchSwapsQuoteRefreshTimeStub.resolves(getMockQuoteRefreshTime()) + fetchTradesInfoStub.resolves(getMockQuotes()); + fetchSwapsQuoteRefreshTimeStub.resolves(getMockQuoteRefreshTime()); // Make it so approval is not required const allowanceStub = sandbox .stub(swapsController, '_getERC20Allowance') - .resolves(ethers.BigNumber.from(1)) + .resolves(ethers.BigNumber.from(1)); await swapsController.fetchAndSetQuotes( MOCK_FETCH_PARAMS, MOCK_FETCH_METADATA, - ) + ); assert.strictEqual( allowanceStub.calledOnceWithExactly( @@ -705,55 +708,55 @@ describe('SwapsController', function () { MOCK_FETCH_PARAMS.fromAddress, ), true, - ) - }) + ); + }); it('gets the gas limit if approval is required', async function () { - fetchTradesInfoStub.resolves(MOCK_QUOTES_APPROVAL_REQUIRED) - fetchSwapsQuoteRefreshTimeStub.resolves(getMockQuoteRefreshTime()) + fetchTradesInfoStub.resolves(MOCK_QUOTES_APPROVAL_REQUIRED); + fetchSwapsQuoteRefreshTimeStub.resolves(getMockQuoteRefreshTime()); // Ensure approval is required sandbox .stub(swapsController, '_getERC20Allowance') - .resolves(ethers.BigNumber.from(0)) + .resolves(ethers.BigNumber.from(0)); - const timedoutGasReturnResult = { gasLimit: 1000000 } + const timedoutGasReturnResult = { gasLimit: 1000000 }; const timedoutGasReturnStub = sandbox .stub(swapsController, 'timedoutGasReturn') - .resolves(timedoutGasReturnResult) + .resolves(timedoutGasReturnResult); await swapsController.fetchAndSetQuotes( MOCK_FETCH_PARAMS, MOCK_FETCH_METADATA, - ) + ); // Mocked quotes approvalNeeded is null, so it will only be called with the gas assert.strictEqual( timedoutGasReturnStub.calledOnceWithExactly(MOCK_APPROVAL_NEEDED), true, - ) - }) + ); + }); it('marks the best quote', async function () { - fetchTradesInfoStub.resolves(getMockQuotes()) - fetchSwapsQuoteRefreshTimeStub.resolves(getMockQuoteRefreshTime()) + fetchTradesInfoStub.resolves(getMockQuotes()); + fetchSwapsQuoteRefreshTimeStub.resolves(getMockQuoteRefreshTime()); // Make it so approval is not required sandbox .stub(swapsController, '_getERC20Allowance') - .resolves(ethers.BigNumber.from(1)) + .resolves(ethers.BigNumber.from(1)); const [newQuotes, topAggId] = await swapsController.fetchAndSetQuotes( MOCK_FETCH_PARAMS, MOCK_FETCH_METADATA, - ) + ); - assert.strictEqual(topAggId, TEST_AGG_ID_BEST) - assert.strictEqual(newQuotes[topAggId].isBestQuote, true) - }) + assert.strictEqual(topAggId, TEST_AGG_ID_BEST); + assert.strictEqual(newQuotes[topAggId].isBestQuote, true); + }); it('selects the best quote', async function () { - const bestAggId = 'bestAggId' + const bestAggId = 'bestAggId'; // Clone the existing mock quote and increase destination amount const bestQuote = { @@ -764,101 +767,101 @@ describe('SwapsController', function () { ) .add((100e18).toString()) .toString(), - } - const quotes = { ...getMockQuotes(), [bestAggId]: bestQuote } - fetchTradesInfoStub.resolves(quotes) - fetchSwapsQuoteRefreshTimeStub.resolves(getMockQuoteRefreshTime()) + }; + const quotes = { ...getMockQuotes(), [bestAggId]: bestQuote }; + fetchTradesInfoStub.resolves(quotes); + fetchSwapsQuoteRefreshTimeStub.resolves(getMockQuoteRefreshTime()); // Make it so approval is not required sandbox .stub(swapsController, '_getERC20Allowance') - .resolves(ethers.BigNumber.from(1)) + .resolves(ethers.BigNumber.from(1)); const [newQuotes, topAggId] = await swapsController.fetchAndSetQuotes( MOCK_FETCH_PARAMS, MOCK_FETCH_METADATA, - ) + ); - assert.strictEqual(topAggId, bestAggId) - assert.strictEqual(newQuotes[topAggId].isBestQuote, true) - }) + assert.strictEqual(topAggId, bestAggId); + assert.strictEqual(newQuotes[topAggId].isBestQuote, true); + }); it('does not mark as best quote if no conversion rate exists for destination token', async function () { - fetchTradesInfoStub.resolves(getMockQuotes()) - fetchSwapsQuoteRefreshTimeStub.resolves(getMockQuoteRefreshTime()) + fetchTradesInfoStub.resolves(getMockQuotes()); + fetchSwapsQuoteRefreshTimeStub.resolves(getMockQuoteRefreshTime()); // Make it so approval is not required sandbox .stub(swapsController, '_getERC20Allowance') - .resolves(ethers.BigNumber.from(1)) + .resolves(ethers.BigNumber.from(1)); swapsController.tokenRatesStore.updateState({ contractExchangeRates: {}, - }) + }); const [newQuotes, topAggId] = await swapsController.fetchAndSetQuotes( MOCK_FETCH_PARAMS, MOCK_FETCH_METADATA, - ) + ); - assert.strictEqual(newQuotes[topAggId].isBestQuote, undefined) - }) - }) + assert.strictEqual(newQuotes[topAggId].isBestQuote, undefined); + }); + }); describe('resetSwapsState', function () { it('resets the swaps state correctly', function () { - const { swapsState: old } = swapsController.store.getState() - swapsController.resetSwapsState() - const { swapsState } = swapsController.store.getState() + const { swapsState: old } = swapsController.store.getState(); + swapsController.resetSwapsState(); + const { swapsState } = swapsController.store.getState(); assert.deepStrictEqual(swapsState, { ...EMPTY_INIT_STATE.swapsState, tokens: old.tokens, swapsQuoteRefreshTime: old.swapsQuoteRefreshTime, - }) - }) + }); + }); it('clears polling timeout', function () { swapsController.pollingTimeout = setTimeout( () => assert.fail(), 1000000, - ) - swapsController.resetSwapsState() - assert.strictEqual(swapsController.pollingTimeout._idleTimeout, -1) - }) - }) + ); + swapsController.resetSwapsState(); + assert.strictEqual(swapsController.pollingTimeout._idleTimeout, -1); + }); + }); describe('stopPollingForQuotes', function () { it('clears polling timeout', function () { swapsController.pollingTimeout = setTimeout( () => assert.fail(), 1000000, - ) - swapsController.stopPollingForQuotes() - assert.strictEqual(swapsController.pollingTimeout._idleTimeout, -1) - }) + ); + swapsController.stopPollingForQuotes(); + assert.strictEqual(swapsController.pollingTimeout._idleTimeout, -1); + }); it('resets quotes state correctly', function () { - swapsController.stopPollingForQuotes() - const { swapsState } = swapsController.store.getState() - assert.deepStrictEqual(swapsState.quotes, {}) - assert.strictEqual(swapsState.quotesLastFetched, null) - }) - }) + swapsController.stopPollingForQuotes(); + const { swapsState } = swapsController.store.getState(); + assert.deepStrictEqual(swapsState.quotes, {}); + assert.strictEqual(swapsState.quotesLastFetched, null); + }); + }); describe('resetPostFetchState', function () { it('clears polling timeout', function () { swapsController.pollingTimeout = setTimeout( () => assert.fail(), 1000000, - ) - swapsController.resetPostFetchState() - assert.strictEqual(swapsController.pollingTimeout._idleTimeout, -1) - }) + ); + swapsController.resetPostFetchState(); + assert.strictEqual(swapsController.pollingTimeout._idleTimeout, -1); + }); it('updates state correctly', function () { - const tokens = 'test' - const fetchParams = 'test' - const swapsFeatureIsLive = false - const swapsQuoteRefreshTime = 0 + const tokens = 'test'; + const fetchParams = 'test'; + const swapsFeatureIsLive = false; + const swapsQuoteRefreshTime = 0; swapsController.store.updateState({ swapsState: { tokens, @@ -866,28 +869,28 @@ describe('SwapsController', function () { swapsFeatureIsLive, swapsQuoteRefreshTime, }, - }) + }); - swapsController.resetPostFetchState() + swapsController.resetPostFetchState(); - const { swapsState } = swapsController.store.getState() + const { swapsState } = swapsController.store.getState(); assert.deepStrictEqual(swapsState, { ...EMPTY_INIT_STATE.swapsState, tokens, fetchParams, swapsFeatureIsLive, swapsQuoteRefreshTime, - }) - }) - }) + }); + }); + }); describe('_setupSwapsLivenessFetching ', function () { - let clock - const EXPECTED_TIME = 600000 + let clock; + const EXPECTED_TIME = 600000; const getLivenessState = () => { - return swapsController.store.getState().swapsState.swapsFeatureIsLive - } + return swapsController.store.getState().swapsState.swapsFeatureIsLive; + }; // We have to do this to overwrite window.navigator.onLine const stubWindow = () => { @@ -896,104 +899,104 @@ describe('SwapsController', function () { navigator: { onLine: true }, dispatchEvent: window.dispatchEvent, Event: window.Event, - }) - } + }); + }; beforeEach(function () { - stubWindow() - clock = sandbox.useFakeTimers() - sandbox.spy(clock, 'setInterval') + stubWindow(); + clock = sandbox.useFakeTimers(); + sandbox.spy(clock, 'setInterval'); sandbox .stub(SwapsController.prototype, '_fetchAndSetSwapsLiveness') - .resolves(undefined) + .resolves(undefined); - sandbox.spy(SwapsController.prototype, '_setupSwapsLivenessFetching') + sandbox.spy(SwapsController.prototype, '_setupSwapsLivenessFetching'); - sandbox.spy(window, 'addEventListener') - }) + sandbox.spy(window, 'addEventListener'); + }); afterEach(function () { - sandbox.restore() - }) + sandbox.restore(); + }); it('calls _setupSwapsLivenessFetching in constructor', function () { - swapsController = getSwapsController() + swapsController = getSwapsController(); assert.ok( swapsController._setupSwapsLivenessFetching.calledOnce, 'should have called _setupSwapsLivenessFetching once', - ) - assert.ok(window.addEventListener.calledWith('online')) - assert.ok(window.addEventListener.calledWith('offline')) + ); + assert.ok(window.addEventListener.calledWith('online')); + assert.ok(window.addEventListener.calledWith('offline')); assert.ok( clock.setInterval.calledOnceWithExactly( sinon.match.func, EXPECTED_TIME, ), 'should have set an interval', - ) - }) + ); + }); it('handles browser being offline on boot, then coming online', async function () { - window.navigator.onLine = false + window.navigator.onLine = false; - swapsController = getSwapsController() + swapsController = getSwapsController(); assert.ok( swapsController._setupSwapsLivenessFetching.calledOnce, 'should have called _setupSwapsLivenessFetching once', - ) + ); assert.ok( swapsController._fetchAndSetSwapsLiveness.notCalled, 'should not have called _fetchAndSetSwapsLiveness', - ) + ); assert.ok( clock.setInterval.notCalled, 'should not have set an interval', - ) + ); assert.strictEqual( getLivenessState(), false, 'swaps feature should be disabled', - ) + ); const fetchPromise = new Promise((resolve) => { - const originalFunction = swapsController._fetchAndSetSwapsLiveness + const originalFunction = swapsController._fetchAndSetSwapsLiveness; swapsController._fetchAndSetSwapsLiveness = () => { - originalFunction() - resolve() - swapsController._fetchAndSetSwapsLiveness = originalFunction - } - }) + originalFunction(); + resolve(); + swapsController._fetchAndSetSwapsLiveness = originalFunction; + }; + }); // browser comes online - window.navigator.onLine = true - window.dispatchEvent(new window.Event('online')) - await fetchPromise + window.navigator.onLine = true; + window.dispatchEvent(new window.Event('online')); + await fetchPromise; assert.ok( swapsController._fetchAndSetSwapsLiveness.calledOnce, 'should have called _fetchAndSetSwapsLiveness once', - ) + ); assert.ok( clock.setInterval.calledOnceWithExactly( sinon.match.func, EXPECTED_TIME, ), 'should have set an interval', - ) - }) + ); + }); it('clears interval if browser goes offline', async function () { - swapsController = getSwapsController() + swapsController = getSwapsController(); // set feature to live - const { swapsState } = swapsController.store.getState() + const { swapsState } = swapsController.store.getState(); swapsController.store.updateState({ swapsState: { ...swapsState, swapsFeatureIsLive: true }, - }) + }); - sandbox.spy(swapsController.store, 'updateState') + sandbox.spy(swapsController.store, 'updateState'); assert.ok( clock.setInterval.calledOnceWithExactly( @@ -1001,172 +1004,172 @@ describe('SwapsController', function () { EXPECTED_TIME, ), 'should have set an interval', - ) + ); const clearIntervalPromise = new Promise((resolve) => { - const originalFunction = clock.clearInterval + const originalFunction = clock.clearInterval; clock.clearInterval = (intervalId) => { - originalFunction(intervalId) - clock.clearInterval = originalFunction - resolve() - } - }) + originalFunction(intervalId); + clock.clearInterval = originalFunction; + resolve(); + }; + }); // browser goes offline - window.navigator.onLine = false - window.dispatchEvent(new window.Event('offline')) + window.navigator.onLine = false; + window.dispatchEvent(new window.Event('offline')); // if this resolves, clearInterval was called - await clearIntervalPromise + await clearIntervalPromise; assert.ok( swapsController._fetchAndSetSwapsLiveness.calledOnce, 'should have called _fetchAndSetSwapsLiveness once', - ) + ); assert.ok( swapsController.store.updateState.calledOnce, 'should have called updateState once', - ) + ); assert.strictEqual( getLivenessState(), false, 'swaps feature should be disabled', - ) - }) - }) + ); + }); + }); describe('_fetchAndSetSwapsLiveness', function () { const getLivenessState = () => { - return swapsController.store.getState().swapsState.swapsFeatureIsLive - } + return swapsController.store.getState().swapsState.swapsFeatureIsLive; + }; beforeEach(function () { - fetchSwapsFeatureLivenessStub.reset() - sandbox.stub(SwapsController.prototype, '_setupSwapsLivenessFetching') - swapsController = getSwapsController() - }) + fetchSwapsFeatureLivenessStub.reset(); + sandbox.stub(SwapsController.prototype, '_setupSwapsLivenessFetching'); + swapsController = getSwapsController(); + }); afterEach(function () { - sandbox.restore() - }) + sandbox.restore(); + }); it('fetches feature liveness as expected when API is live', async function () { - fetchSwapsFeatureLivenessStub.resolves(true) + fetchSwapsFeatureLivenessStub.resolves(true); assert.strictEqual( getLivenessState(), false, 'liveness should be false on boot', - ) + ); - await swapsController._fetchAndSetSwapsLiveness() + await swapsController._fetchAndSetSwapsLiveness(); assert.ok( fetchSwapsFeatureLivenessStub.calledOnce, 'should have called fetch function once', - ) + ); assert.strictEqual( getLivenessState(), true, 'liveness should be true after call', - ) - }) + ); + }); it('does not update state if fetched value is same as state value', async function () { - fetchSwapsFeatureLivenessStub.resolves(false) - sandbox.spy(swapsController.store, 'updateState') + fetchSwapsFeatureLivenessStub.resolves(false); + sandbox.spy(swapsController.store, 'updateState'); assert.strictEqual( getLivenessState(), false, 'liveness should be false on boot', - ) + ); - await swapsController._fetchAndSetSwapsLiveness() + await swapsController._fetchAndSetSwapsLiveness(); assert.ok( fetchSwapsFeatureLivenessStub.calledOnce, 'should have called fetch function once', - ) + ); assert.ok( swapsController.store.updateState.notCalled, 'should not have called store.updateState', - ) + ); assert.strictEqual( getLivenessState(), false, 'liveness should remain false after call', - ) - }) + ); + }); it('tries three times before giving up if fetching fails', async function () { - const clock = sandbox.useFakeTimers() - fetchSwapsFeatureLivenessStub.rejects(new Error('foo')) - sandbox.spy(swapsController.store, 'updateState') + const clock = sandbox.useFakeTimers(); + fetchSwapsFeatureLivenessStub.rejects(new Error('foo')); + sandbox.spy(swapsController.store, 'updateState'); assert.strictEqual( getLivenessState(), false, 'liveness should be false on boot', - ) + ); - swapsController._fetchAndSetSwapsLiveness() - await clock.runAllAsync() + swapsController._fetchAndSetSwapsLiveness(); + await clock.runAllAsync(); assert.ok( fetchSwapsFeatureLivenessStub.calledThrice, 'should have called fetch function three times', - ) + ); assert.ok( swapsController.store.updateState.notCalled, 'should not have called store.updateState', - ) + ); assert.strictEqual( getLivenessState(), false, 'liveness should remain false after call', - ) - }) + ); + }); it('sets state after fetching on successful retry', async function () { - const clock = sandbox.useFakeTimers() - fetchSwapsFeatureLivenessStub.onCall(0).rejects(new Error('foo')) - fetchSwapsFeatureLivenessStub.onCall(1).rejects(new Error('foo')) - fetchSwapsFeatureLivenessStub.onCall(2).resolves(true) + const clock = sandbox.useFakeTimers(); + fetchSwapsFeatureLivenessStub.onCall(0).rejects(new Error('foo')); + fetchSwapsFeatureLivenessStub.onCall(1).rejects(new Error('foo')); + fetchSwapsFeatureLivenessStub.onCall(2).resolves(true); assert.strictEqual( getLivenessState(), false, 'liveness should be false on boot', - ) + ); - swapsController._fetchAndSetSwapsLiveness() - await clock.runAllAsync() + swapsController._fetchAndSetSwapsLiveness(); + await clock.runAllAsync(); assert.strictEqual( fetchSwapsFeatureLivenessStub.callCount, 3, 'should have called fetch function three times', - ) + ); assert.strictEqual( getLivenessState(), true, 'liveness should be true after call', - ) - }) - }) - }) + ); + }); + }); + }); describe('utils', function () { describe('getMedianEthValueQuote', function () { - const { getMedianEthValueQuote } = utils + const { getMedianEthValueQuote } = utils; it('calculates median correctly with uneven sample', function () { const expectedResult = { ethFee: '10', metaMaskFeeInEth: '5', ethValueOfTokens: '0.3', - } + }; const values = [ { overallValueOfQuote: '3', @@ -1186,23 +1189,23 @@ describe('SwapsController', function () { metaMaskFeeInEth: '6', ethValueOfTokens: '0.6', }, - ] + ]; - const median = getMedianEthValueQuote(values) + const median = getMedianEthValueQuote(values); assert.deepEqual( median, expectedResult, 'should have returned correct median quote object', - ) - }) + ); + }); it('calculates median correctly with even sample', function () { const expectedResult = { ethFee: '20', metaMaskFeeInEth: '6.5', ethValueOfTokens: '0.25', - } + }; const values = [ { overallValueOfQuote: '3', @@ -1228,22 +1231,22 @@ describe('SwapsController', function () { metaMaskFeeInEth: '6', ethValueOfTokens: '0.6', }, - ] - const median = getMedianEthValueQuote(values) + ]; + const median = getMedianEthValueQuote(values); assert.deepEqual( median, expectedResult, 'should have returned correct median quote object', - ) - }) + ); + }); it('calculates median correctly with an uneven sample where multiple quotes have the median overall value', function () { const expectedResult = { ethFee: '2', metaMaskFeeInEth: '0.5', ethValueOfTokens: '5', - } + }; const values = [ { @@ -1288,22 +1291,22 @@ describe('SwapsController', function () { ethFee: '2', metaMaskFeeInEth: '0.8', }, - ] - const median = getMedianEthValueQuote(values) + ]; + const median = getMedianEthValueQuote(values); assert.deepEqual( median, expectedResult, 'should have returned correct median quote object', - ) - }) + ); + }); it('calculates median correctly with an even sample where multiple quotes have the same overall value as either of the two middle values', function () { const expectedResult = { ethFee: '2', metaMaskFeeInEth: '0.55', ethValueOfTokens: '5.5', - } + }; const values = [ { @@ -1342,35 +1345,35 @@ describe('SwapsController', function () { ethFee: '2', metaMaskFeeInEth: '0.8', }, - ] - const median = getMedianEthValueQuote(values) + ]; + const median = getMedianEthValueQuote(values); assert.deepEqual( median, expectedResult, 'should have returned correct median quote object', - ) - }) + ); + }); it('throws on empty or non-array sample', function () { assert.throws( () => getMedianEthValueQuote([]), 'should throw on empty array', - ) + ); assert.throws( () => getMedianEthValueQuote(), 'should throw on non-array param', - ) + ); assert.throws( () => getMedianEthValueQuote({}), 'should throw on non-array param', - ) - }) - }) - }) -}) + ); + }); + }); + }); +}); function getMockQuotes() { return { @@ -1475,7 +1478,7 @@ function getMockQuotes() { }, fee: 1, }, - } + }; } function getTopQuoteAndSavingsMockQuotes() { @@ -1572,11 +1575,11 @@ function getTopQuoteAndSavingsMockQuotes() { }, fee: 1, }, - } + }; } function getTopQuoteAndSavingsBaseExpectedResults() { - const baseTestInput = getTopQuoteAndSavingsMockQuotes() + const baseTestInput = getTopQuoteAndSavingsMockQuotes(); return { [TEST_AGG_ID_1]: { ...baseTestInput[TEST_AGG_ID_1], @@ -1628,9 +1631,9 @@ function getTopQuoteAndSavingsBaseExpectedResults() { metaMaskFeeInEth: '0.0195', ethValueOfTokens: '1.9305', }, - } + }; } function getMockQuoteRefreshTime() { - return 45000 + return 45000; } diff --git a/test/unit/app/controllers/token-rates-controller.js b/test/unit/app/controllers/token-rates-controller.js index 58e0009a12..c1f69d54fb 100644 --- a/test/unit/app/controllers/token-rates-controller.js +++ b/test/unit/app/controllers/token-rates-controller.js @@ -1,25 +1,25 @@ -import assert from 'assert' -import sinon from 'sinon' -import { ObservableStore } from '@metamask/obs-store' -import TokenRatesController from '../../../../app/scripts/controllers/token-rates' +import assert from 'assert'; +import sinon from 'sinon'; +import { ObservableStore } from '@metamask/obs-store'; +import TokenRatesController from '../../../../app/scripts/controllers/token-rates'; describe('TokenRatesController', function () { it('should listen for preferences store updates', function () { - const preferences = new ObservableStore({ tokens: [] }) - preferences.putState({ tokens: ['foo'] }) - const controller = new TokenRatesController({ preferences }) - assert.deepEqual(controller._tokens, ['foo']) - }) + const preferences = new ObservableStore({ tokens: [] }); + preferences.putState({ tokens: ['foo'] }); + const controller = new TokenRatesController({ preferences }); + assert.deepEqual(controller._tokens, ['foo']); + }); it('should poll on correct interval', async function () { - const stub = sinon.stub(global, 'setInterval') - const preferences = new ObservableStore({ tokens: [] }) - preferences.putState({ tokens: ['foo'] }) - const controller = new TokenRatesController({ preferences }) - controller.start(1337) + const stub = sinon.stub(global, 'setInterval'); + const preferences = new ObservableStore({ tokens: [] }); + preferences.putState({ tokens: ['foo'] }); + const controller = new TokenRatesController({ preferences }); + controller.start(1337); - assert.strictEqual(stub.getCall(0).args[1], 1337) - stub.restore() - controller.stop() - }) -}) + assert.strictEqual(stub.getCall(0).args[1], 1337); + stub.restore(); + controller.stop(); + }); +}); diff --git a/test/unit/app/controllers/transactions/pending-tx-tracker-test.js b/test/unit/app/controllers/transactions/pending-tx-tracker-test.js index 6252da35a3..db0f4d1d3a 100644 --- a/test/unit/app/controllers/transactions/pending-tx-tracker-test.js +++ b/test/unit/app/controllers/transactions/pending-tx-tracker-test.js @@ -1,13 +1,13 @@ -import { strict as assert } from 'assert' -import sinon from 'sinon' -import BN from 'bn.js' -import PendingTransactionTracker from '../../../../../app/scripts/controllers/transactions/pending-tx-tracker' -import { TRANSACTION_STATUSES } from '../../../../../shared/constants/transaction' +import { strict as assert } from 'assert'; +import sinon from 'sinon'; +import BN from 'bn.js'; +import PendingTransactionTracker from '../../../../../app/scripts/controllers/transactions/pending-tx-tracker'; +import { TRANSACTION_STATUSES } from '../../../../../shared/constants/transaction'; describe('PendingTransactionTracker', function () { describe('#resubmitPendingTxs', function () { it('should return early if there are no pending transactions', async function () { - const getPendingTransactions = sinon.stub().returns([]) + const getPendingTransactions = sinon.stub().returns([]); const pendingTxTracker = new PendingTransactionTracker({ query: { getTransactionReceipt: sinon.stub(), @@ -22,20 +22,20 @@ describe('PendingTransactionTracker', function () { approveTransaction: sinon.spy(), publishTransaction: sinon.spy(), confirmTransaction: sinon.spy(), - }) - const resubmitTx = sinon.stub(pendingTxTracker, '_resubmitTx').rejects() - const warningListener = sinon.spy() + }); + const resubmitTx = sinon.stub(pendingTxTracker, '_resubmitTx').rejects(); + const warningListener = sinon.spy(); - pendingTxTracker.on('tx:warning', warningListener) - await pendingTxTracker.resubmitPendingTxs('0x1') + pendingTxTracker.on('tx:warning', warningListener); + await pendingTxTracker.resubmitPendingTxs('0x1'); assert.ok( getPendingTransactions.calledOnceWithExactly(), 'should call getPendingTransaction', - ) - assert.ok(resubmitTx.notCalled, 'should NOT call _resubmitTx') - assert.ok(warningListener.notCalled, "should NOT emit 'tx:warning'") - }) + ); + assert.ok(resubmitTx.notCalled, 'should NOT call _resubmitTx'); + assert.ok(warningListener.notCalled, "should NOT emit 'tx:warning'"); + }); it('should resubmit each pending transaction', async function () { const getPendingTransactions = sinon.stub().returns([ @@ -45,7 +45,7 @@ describe('PendingTransactionTracker', function () { { id: 2, }, - ]) + ]); const pendingTxTracker = new PendingTransactionTracker({ query: { getTransactionReceipt: sinon.stub(), @@ -60,27 +60,27 @@ describe('PendingTransactionTracker', function () { approveTransaction: sinon.spy(), publishTransaction: sinon.spy(), confirmTransaction: sinon.spy(), - }) - const resubmitTx = sinon.stub(pendingTxTracker, '_resubmitTx').resolves() - const warningListener = sinon.spy() + }); + const resubmitTx = sinon.stub(pendingTxTracker, '_resubmitTx').resolves(); + const warningListener = sinon.spy(); - pendingTxTracker.on('tx:warning', warningListener) - await pendingTxTracker.resubmitPendingTxs('0x1') + pendingTxTracker.on('tx:warning', warningListener); + await pendingTxTracker.resubmitPendingTxs('0x1'); assert.ok( getPendingTransactions.calledOnceWithExactly(), 'should call getPendingTransaction', - ) - assert.ok(resubmitTx.calledTwice, 'should call _resubmitTx') - assert.ok(warningListener.notCalled, "should NOT emit 'tx:warning'") - }) + ); + assert.ok(resubmitTx.calledTwice, 'should call _resubmitTx'); + assert.ok(warningListener.notCalled, "should NOT emit 'tx:warning'"); + }); it("should NOT emit 'tx:warning' for known failed resubmission", async function () { const getPendingTransactions = sinon.stub().returns([ { id: 1, }, - ]) + ]); const pendingTxTracker = new PendingTransactionTracker({ query: { getTransactionReceipt: sinon.stub(), @@ -95,29 +95,29 @@ describe('PendingTransactionTracker', function () { approveTransaction: sinon.spy(), publishTransaction: sinon.spy(), confirmTransaction: sinon.spy(), - }) + }); const resubmitTx = sinon .stub(pendingTxTracker, '_resubmitTx') - .rejects({ message: 'known transaction' }) - const warningListener = sinon.spy() + .rejects({ message: 'known transaction' }); + const warningListener = sinon.spy(); - pendingTxTracker.on('tx:warning', warningListener) - await pendingTxTracker.resubmitPendingTxs('0x1') + pendingTxTracker.on('tx:warning', warningListener); + await pendingTxTracker.resubmitPendingTxs('0x1'); assert.ok( getPendingTransactions.calledOnceWithExactly(), 'should call getPendingTransaction', - ) - assert.ok(resubmitTx.calledOnce, 'should call _resubmitTx') - assert.ok(warningListener.notCalled, "should NOT emit 'tx:warning'") - }) + ); + assert.ok(resubmitTx.calledOnce, 'should call _resubmitTx'); + assert.ok(warningListener.notCalled, "should NOT emit 'tx:warning'"); + }); it("should emit 'tx:warning' for unknown failed resubmission", async function () { const getPendingTransactions = sinon.stub().returns([ { id: 1, }, - ]) + ]); const pendingTxTracker = new PendingTransactionTracker({ query: { getTransactionReceipt: sinon.stub(), @@ -132,23 +132,23 @@ describe('PendingTransactionTracker', function () { approveTransaction: sinon.spy(), publishTransaction: sinon.spy(), confirmTransaction: sinon.spy(), - }) + }); const resubmitTx = sinon .stub(pendingTxTracker, '_resubmitTx') - .rejects({ message: 'who dis' }) - const warningListener = sinon.spy() + .rejects({ message: 'who dis' }); + const warningListener = sinon.spy(); - pendingTxTracker.on('tx:warning', warningListener) - await pendingTxTracker.resubmitPendingTxs('0x1') + pendingTxTracker.on('tx:warning', warningListener); + await pendingTxTracker.resubmitPendingTxs('0x1'); assert.ok( getPendingTransactions.calledOnceWithExactly(), 'should call getPendingTransaction', - ) - assert.ok(resubmitTx.calledOnce, 'should call _resubmitTx') - assert.ok(warningListener.calledOnce, "should emit 'tx:warning'") - }) - }) + ); + assert.ok(resubmitTx.calledOnce, 'should call _resubmitTx'); + assert.ok(warningListener.calledOnce, "should emit 'tx:warning'"); + }); + }); describe('#updatePendingTxs', function () { it('should call _checkPendingTx for each pending transaction', async function () { @@ -165,48 +165,48 @@ describe('PendingTransactionTracker', function () { history: [{}], rawTx: '0xf86c808504a817c800827b0d940c62bb85faa3311a998d3aba8098c1235c564966880de0b6b3a7640000802aa08ff665feb887a25d4099e40e11f0fef93ee9608f404bd3f853dd9e84ed3317a6a02ec9d3d1d6e176d4d2593dd760e74ccac753e6a0ea0d00cc9789d0d7ff1f471d', - } - const txList = [1, 2, 3].map((id) => ({ ...txMeta, id })) + }; + const txList = [1, 2, 3].map((id) => ({ ...txMeta, id })); const pendingTxTracker = new PendingTransactionTracker({ query: { getTransactionReceipt: sinon.stub(), }, nonceTracker: { getGlobalLock: async () => { - return { releaseLock: () => undefined } + return { releaseLock: () => undefined }; }, }, getPendingTransactions: () => txList, getCompletedTransactions: () => { - return [] + return []; }, publishTransaction: () => undefined, confirmTransaction: () => undefined, - }) + }); const checkPendingTxStub = sinon .stub(pendingTxTracker, '_checkPendingTx') - .resolves() - await pendingTxTracker.updatePendingTxs() + .resolves(); + await pendingTxTracker.updatePendingTxs(); - assert.ok(checkPendingTxStub.calledThrice) + assert.ok(checkPendingTxStub.calledThrice); assert.ok( checkPendingTxStub.firstCall.calledWithExactly( sinon.match.has('id', 1), ), - ) + ); assert.ok( checkPendingTxStub.secondCall.calledWithExactly( sinon.match.has('id', 2), ), - ) + ); assert.ok( checkPendingTxStub.thirdCall.calledWithExactly( sinon.match.has('id', 3), ), - ) - }) - }) + ); + }); + }); describe('#_resubmitTx', function () { it('should publish a new transaction', async function () { @@ -223,9 +223,9 @@ describe('PendingTransactionTracker', function () { history: [{}], rawTx: '0xf86c808504a817c80086a02ec9d3d1d6e176d4d2593dd760e74ccac753e6a0ea0d00cc9789d0d7ff1f471d', - } - const approveTransaction = sinon.spy() - const publishTransaction = sinon.spy() + }; + const approveTransaction = sinon.spy(); + const publishTransaction = sinon.spy(); const pendingTxTracker = new PendingTransactionTracker({ query: { getTransactionReceipt: sinon.stub(), @@ -240,19 +240,19 @@ describe('PendingTransactionTracker', function () { approveTransaction, publishTransaction, confirmTransaction: sinon.spy(), - }) + }); - await pendingTxTracker._resubmitTx(txMeta) + await pendingTxTracker._resubmitTx(txMeta); assert.ok( publishTransaction.calledOnceWithExactly(txMeta.rawTx), 'should call publish transaction with the rawTx', - ) + ); assert.ok( approveTransaction.notCalled, 'should NOT try to approve transaction', - ) - }) + ); + }); it('should publish the given transaction if more than 2**retryCount blocks have passed', async function () { const txMeta = { @@ -270,9 +270,9 @@ describe('PendingTransactionTracker', function () { '0xf86c808504a817c800827b0d940c62bb85faa3311a996e176d4d2593dd760e74ccac753e6a0ea0d00cc9789d0d7ff1f471d', retryCount: 4, firstRetryBlockNumber: '0x1', - } - const approveTransaction = sinon.spy() - const publishTransaction = sinon.spy() + }; + const approveTransaction = sinon.spy(); + const publishTransaction = sinon.spy(); const pendingTxTracker = new PendingTransactionTracker({ query: { getTransactionReceipt: sinon.stub(), @@ -287,19 +287,19 @@ describe('PendingTransactionTracker', function () { publishTransaction, approveTransaction, confirmTransaction: sinon.spy(), - }) + }); - await pendingTxTracker._resubmitTx(txMeta, '0x11' /* 16 */) + await pendingTxTracker._resubmitTx(txMeta, '0x11' /* 16 */); assert.ok( publishTransaction.calledOnceWithExactly(txMeta.rawTx), 'should try to publish transaction', - ) + ); assert.ok( approveTransaction.notCalled, 'should NOT try to approve transaction', - ) - }) + ); + }); it('should NOT publish the given transaction if fewer than 2**retryCount blocks have passed', async function () { const txMeta = { @@ -317,9 +317,9 @@ describe('PendingTransactionTracker', function () { '0xf86c808504a817c800827b0d940c62bb85faa3311a996e176d4d2593dd760e74ccac753e6a0ea0d00cc9789d0d7ff1f471d', retryCount: 4, firstRetryBlockNumber: '0x1', - } - const approveTransaction = sinon.spy() - const publishTransaction = sinon.spy() + }; + const approveTransaction = sinon.spy(); + const publishTransaction = sinon.spy(); const pendingTxTracker = new PendingTransactionTracker({ query: { getTransactionReceipt: sinon.stub(), @@ -334,23 +334,23 @@ describe('PendingTransactionTracker', function () { publishTransaction, approveTransaction, confirmTransaction: sinon.spy(), - }) + }); - await pendingTxTracker._resubmitTx(txMeta, '0x5') + await pendingTxTracker._resubmitTx(txMeta, '0x5'); assert.ok( publishTransaction.notCalled, 'should NOT try to publish transaction', - ) + ); assert.ok( approveTransaction.notCalled, 'should NOT try to approve transaction', - ) - }) + ); + }); it('should call approveTransaction if the tx is not yet signed', async function () { - const approveTransaction = sinon.spy() - const publishTransaction = sinon.spy() + const approveTransaction = sinon.spy(); + const publishTransaction = sinon.spy(); const pendingTxTracker = new PendingTransactionTracker({ query: { getTransactionReceipt: sinon.stub(), @@ -365,24 +365,24 @@ describe('PendingTransactionTracker', function () { approveTransaction, publishTransaction, confirmTransaction: sinon.spy(), - }) + }); - await pendingTxTracker._resubmitTx({ id: 40 }) + await pendingTxTracker._resubmitTx({ id: 40 }); assert.ok( approveTransaction.calledOnceWithExactly(40), 'should call approveTransaction with the tx ID', - ) + ); assert.ok( publishTransaction.notCalled, 'should NOT try to publish transaction', - ) - }) - }) + ); + }); + }); describe('#_checkIfTxWasDropped', function () { it('should return true when the given nonce is lower than the network nonce', async function () { - const nonceBN = new BN(2) + const nonceBN = new BN(2); const pendingTxTracker = new PendingTransactionTracker({ query: { getTransactionReceipt: sinon.stub(), @@ -397,9 +397,9 @@ describe('PendingTransactionTracker', function () { getCompletedTransactions: sinon.stub().returns([]), publishTransaction: sinon.spy(), confirmTransaction: sinon.spy(), - }) + }); - pendingTxTracker.DROPPED_BUFFER_COUNT = 0 + pendingTxTracker.DROPPED_BUFFER_COUNT = 0; assert.ok( await pendingTxTracker._checkIfTxWasDropped({ @@ -414,11 +414,11 @@ describe('PendingTransactionTracker', function () { }, rawTx: '0xf86c808504a817c800827b0d940c62bba0ea0d00cc9789d0d7ff1f471d', }), - ) - }) + ); + }); it('should return false when the given nonce is the network nonce', async function () { - const nonceBN = new BN(1) + const nonceBN = new BN(1); const pendingTxTracker = new PendingTransactionTracker({ query: { getTransactionReceipt: sinon.stub(), @@ -433,7 +433,7 @@ describe('PendingTransactionTracker', function () { getCompletedTransactions: sinon.stub().returns([]), publishTransaction: sinon.spy(), confirmTransaction: sinon.spy(), - }) + }); const dropped = await pendingTxTracker._checkIfTxWasDropped({ id: 1, @@ -447,11 +447,11 @@ describe('PendingTransactionTracker', function () { }, rawTx: '0xf86c808504a89e84ed3317a6a02ec9d3d1d6e176d4d2593dd760e74ccac753e6a0ea0d00cc9789d0d7ff1f471d', - }) + }); - assert.ok(!dropped, 'should be false') - }) - }) + assert.ok(!dropped, 'should be false'); + }); + }); describe('#_checkIfNonceIsTaken', function () { it('should return false if the given nonce is not taken', async function () { @@ -482,8 +482,8 @@ describe('PendingTransactionTracker', function () { rawTx: '0xf86c808507a6a02ec9d3d1d6e176d4d2593dd760e74ccac753e6a0ea0d00cc9789d0d7ff1f471d', }, - ] - const getCompletedTransactions = sinon.stub().returns(confirmedTxList) + ]; + const getCompletedTransactions = sinon.stub().returns(confirmedTxList); const pendingTxTracker = new PendingTransactionTracker({ query: sinon.spy(), nonceTracker: { @@ -495,7 +495,7 @@ describe('PendingTransactionTracker', function () { getCompletedTransactions, publishTransaction: sinon.spy(), confirmTransaction: sinon.spy(), - }) + }); const taken = await pendingTxTracker._checkIfNonceIsTaken({ txParams: { @@ -503,15 +503,15 @@ describe('PendingTransactionTracker', function () { nonce: '0x3', value: '0xfffff', }, - }) + }); assert.ok( getCompletedTransactions.calledOnceWithExactly( '0x1678a085c290ebd122dc42cba69373b5953b831d', ), - ) - assert.ok(!taken) - }) + ); + assert.ok(!taken); + }); it('should return true if the nonce is taken', async function () { const confirmedTxList = [ @@ -541,8 +541,8 @@ describe('PendingTransactionTracker', function () { rawTx: '0xf86c808504a817c800827b0d940c62bb760e74ccac753e6a0ea0d00cc9789d0d7ff1f471d', }, - ] - const getCompletedTransactions = sinon.stub().returns(confirmedTxList) + ]; + const getCompletedTransactions = sinon.stub().returns(confirmedTxList); const pendingTxTracker = new PendingTransactionTracker({ query: sinon.spy(), nonceTracker: { @@ -554,7 +554,7 @@ describe('PendingTransactionTracker', function () { getCompletedTransactions, publishTransaction: sinon.spy(), confirmTransaction: sinon.spy(), - }) + }); const taken = await pendingTxTracker._checkIfNonceIsTaken({ txParams: { @@ -562,16 +562,16 @@ describe('PendingTransactionTracker', function () { nonce: '0x2', value: '0xfffff', }, - }) + }); assert.ok( getCompletedTransactions.calledOnceWithExactly( '0x1678a085c290ebd122dc42cba69373b5953b831d', ), - ) - assert.ok(taken) - }) - }) + ); + assert.ok(taken); + }); + }); describe('#_checkPendingTx', function () { it("should emit 'tx:warning' if getTransactionReceipt rejects", async function () { @@ -587,8 +587,8 @@ describe('PendingTransactionTracker', function () { }, history: [{}], rawTx: '0xf86c808504a817c80082471d', - } - const nonceBN = new BN(2) + }; + const nonceBN = new BN(2); const pendingTxTracker = new PendingTransactionTracker({ query: { getTransactionReceipt: sinon.stub().rejects(), @@ -603,25 +603,28 @@ describe('PendingTransactionTracker', function () { getCompletedTransactions: sinon.stub().returns([]), publishTransaction: sinon.spy(), confirmTransaction: sinon.spy(), - }) + }); const listeners = { confirmed: sinon.spy(), dropped: sinon.spy(), failed: sinon.spy(), warning: sinon.spy(), - } + }; - pendingTxTracker.once('tx:confirmed', listeners.confirmed) - pendingTxTracker.once('tx:dropped', listeners.dropped) - pendingTxTracker.once('tx:failed', listeners.failed) - pendingTxTracker.once('tx:warning', listeners.warning) - await pendingTxTracker._checkPendingTx(txMeta) + pendingTxTracker.once('tx:confirmed', listeners.confirmed); + pendingTxTracker.once('tx:dropped', listeners.dropped); + pendingTxTracker.once('tx:failed', listeners.failed); + pendingTxTracker.once('tx:warning', listeners.warning); + await pendingTxTracker._checkPendingTx(txMeta); - assert.ok(listeners.dropped.notCalled, "should not emit 'tx:dropped") - assert.ok(listeners.confirmed.notCalled, "should not emit 'tx:confirmed'") - assert.ok(listeners.failed.notCalled, "should not emit 'tx:failed'") - assert.ok(listeners.warning.calledOnce, "should emit 'tx:warning'") - }) + assert.ok(listeners.dropped.notCalled, "should not emit 'tx:dropped"); + assert.ok( + listeners.confirmed.notCalled, + "should not emit 'tx:confirmed'", + ); + assert.ok(listeners.failed.notCalled, "should not emit 'tx:failed'"); + assert.ok(listeners.warning.calledOnce, "should emit 'tx:warning'"); + }); it('should NOT emit anything if the tx is already not submitted', async function () { const pendingTxTracker = new PendingTransactionTracker({ @@ -635,18 +638,18 @@ describe('PendingTransactionTracker', function () { getCompletedTransactions: sinon.stub().returns([]), publishTransaction: sinon.spy(), confirmTransaction: sinon.spy(), - }) + }); const listeners = { confirmed: sinon.spy(), dropped: sinon.spy(), failed: sinon.spy(), warning: sinon.spy(), - } + }; - pendingTxTracker.once('tx:confirmed', listeners.confirmed) - pendingTxTracker.once('tx:dropped', listeners.dropped) - pendingTxTracker.once('tx:failed', listeners.failed) - pendingTxTracker.once('tx:warning', listeners.warning) + pendingTxTracker.once('tx:confirmed', listeners.confirmed); + pendingTxTracker.once('tx:dropped', listeners.dropped); + pendingTxTracker.once('tx:failed', listeners.failed); + pendingTxTracker.once('tx:warning', listeners.warning); await pendingTxTracker._checkPendingTx({ status: TRANSACTION_STATUSES.CONFIRMED, history: [{}], @@ -654,13 +657,16 @@ describe('PendingTransactionTracker', function () { id: '456', value: '0x01', hash: '0xbad', - }) + }); - assert.ok(listeners.failed.notCalled, "should not emit 'tx:failed'") - assert.ok(listeners.confirmed.notCalled, "should not emit 'tx:confirmed'") - assert.ok(listeners.dropped.notCalled, "should not emit 'tx:dropped'") - assert.ok(listeners.warning.notCalled, "should not emit 'tx:warning'") - }) + assert.ok(listeners.failed.notCalled, "should not emit 'tx:failed'"); + assert.ok( + listeners.confirmed.notCalled, + "should not emit 'tx:confirmed'", + ); + assert.ok(listeners.dropped.notCalled, "should not emit 'tx:dropped'"); + assert.ok(listeners.warning.notCalled, "should not emit 'tx:warning'"); + }); it("should emit 'tx:failed' if the txMeta does NOT have a hash", async function () { const pendingTxTracker = new PendingTransactionTracker({ @@ -674,24 +680,24 @@ describe('PendingTransactionTracker', function () { getCompletedTransactions: sinon.stub().returns([]), publishTransaction: sinon.spy(), confirmTransaction: sinon.spy(), - }) + }); const listeners = { confirmed: sinon.spy(), dropped: sinon.spy(), failed: sinon.spy(), warning: sinon.spy(), - } + }; - pendingTxTracker.once('tx:confirmed', listeners.confirmed) - pendingTxTracker.once('tx:dropped', listeners.dropped) - pendingTxTracker.once('tx:failed', listeners.failed) - pendingTxTracker.once('tx:warning', listeners.warning) + pendingTxTracker.once('tx:confirmed', listeners.confirmed); + pendingTxTracker.once('tx:dropped', listeners.dropped); + pendingTxTracker.once('tx:failed', listeners.failed); + pendingTxTracker.once('tx:warning', listeners.warning); await pendingTxTracker._checkPendingTx({ id: '2', history: [{}], status: TRANSACTION_STATUSES.SUBMITTED, txParams: { from: '0x1678a085c290ebd122dc42cba69373b5953b831d' }, - }) + }); assert.ok( listeners.failed.calledOnceWithExactly( @@ -699,11 +705,14 @@ describe('PendingTransactionTracker', function () { sinon.match.instanceOf(Error), ), "should pass txId to 'tx:failed' listener", - ) - assert.ok(listeners.confirmed.notCalled, "should not emit 'tx:confirmed'") - assert.ok(listeners.dropped.notCalled, "should not emit 'tx:dropped'") - assert.ok(listeners.warning.notCalled, "should not emit 'tx:warning'") - }) + ); + assert.ok( + listeners.confirmed.notCalled, + "should not emit 'tx:confirmed'", + ); + assert.ok(listeners.dropped.notCalled, "should not emit 'tx:dropped'"); + assert.ok(listeners.warning.notCalled, "should not emit 'tx:warning'"); + }); it("should emit 'tx:dropped' if another tx with the same nonce succeeds", async function () { const txs = [ @@ -724,7 +733,7 @@ describe('PendingTransactionTracker', function () { hash: '0x2a919d2512ec963f524bfd9730fb66b6d5a2e399d1dd957abb5e2b544a12644b', }, - ] + ]; const pendingTxTracker = new PendingTransactionTracker({ query: { getTransactionReceipt: sinon.stub().resolves(null), @@ -738,28 +747,31 @@ describe('PendingTransactionTracker', function () { getCompletedTransactions: sinon.stub().returns(txs), publishTransaction: sinon.spy(), confirmTransaction: sinon.spy(), - }) + }); const listeners = { confirmed: sinon.spy(), dropped: sinon.spy(), failed: sinon.spy(), warning: sinon.spy(), - } + }; - pendingTxTracker.once('tx:confirmed', listeners.confirmed) - pendingTxTracker.once('tx:dropped', listeners.dropped) - pendingTxTracker.once('tx:failed', listeners.failed) - pendingTxTracker.once('tx:warning', listeners.warning) - await pendingTxTracker._checkPendingTx(txs[1]) + pendingTxTracker.once('tx:confirmed', listeners.confirmed); + pendingTxTracker.once('tx:dropped', listeners.dropped); + pendingTxTracker.once('tx:failed', listeners.failed); + pendingTxTracker.once('tx:warning', listeners.warning); + await pendingTxTracker._checkPendingTx(txs[1]); - assert.ok(listeners.dropped.calledOnceWithExactly('123')) - assert.ok(listeners.confirmed.notCalled, "should not emit 'tx:confirmed'") - assert.ok(listeners.failed.notCalled, "should not emit 'tx:failed'") - assert.ok(listeners.warning.notCalled, "should not emit 'tx:warning'") - }) + assert.ok(listeners.dropped.calledOnceWithExactly('123')); + assert.ok( + listeners.confirmed.notCalled, + "should not emit 'tx:confirmed'", + ); + assert.ok(listeners.failed.notCalled, "should not emit 'tx:failed'"); + assert.ok(listeners.warning.notCalled, "should not emit 'tx:warning'"); + }); it("should emit 'tx:dropped' with the txMetas id only after the fourth call", async function () { - const nonceBN = new BN(2) + const nonceBN = new BN(2); const txMeta = { id: 1, hash: @@ -772,7 +784,7 @@ describe('PendingTransactionTracker', function () { }, history: [{}], rawTx: '0xf86c808504a817c80082471d', - } + }; const pendingTxTracker = new PendingTransactionTracker({ query: { getTransactionReceipt: sinon.stub().resolves(null), @@ -787,27 +799,30 @@ describe('PendingTransactionTracker', function () { getCompletedTransactions: sinon.stub().returns([]), publishTransaction: sinon.spy(), confirmTransaction: sinon.spy(), - }) + }); const listeners = { confirmed: sinon.spy(), dropped: sinon.spy(), failed: sinon.spy(), warning: sinon.spy(), - } - - pendingTxTracker.once('tx:confirmed', listeners.confirmed) - pendingTxTracker.once('tx:dropped', listeners.dropped) - pendingTxTracker.once('tx:failed', listeners.failed) - pendingTxTracker.once('tx:warning', listeners.warning) - await pendingTxTracker._checkPendingTx(txMeta) - await pendingTxTracker._checkPendingTx(txMeta) - await pendingTxTracker._checkPendingTx(txMeta) - await pendingTxTracker._checkPendingTx(txMeta) - - assert.ok(listeners.dropped.calledOnceWithExactly(1)) - assert.ok(listeners.confirmed.notCalled, "should not emit 'tx:confirmed'") - assert.ok(listeners.failed.notCalled, "should not emit 'tx:failed'") - assert.ok(listeners.warning.notCalled, "should not emit 'tx:warning'") - }) - }) -}) + }; + + pendingTxTracker.once('tx:confirmed', listeners.confirmed); + pendingTxTracker.once('tx:dropped', listeners.dropped); + pendingTxTracker.once('tx:failed', listeners.failed); + pendingTxTracker.once('tx:warning', listeners.warning); + await pendingTxTracker._checkPendingTx(txMeta); + await pendingTxTracker._checkPendingTx(txMeta); + await pendingTxTracker._checkPendingTx(txMeta); + await pendingTxTracker._checkPendingTx(txMeta); + + assert.ok(listeners.dropped.calledOnceWithExactly(1)); + assert.ok( + listeners.confirmed.notCalled, + "should not emit 'tx:confirmed'", + ); + assert.ok(listeners.failed.notCalled, "should not emit 'tx:failed'"); + assert.ok(listeners.warning.notCalled, "should not emit 'tx:warning'"); + }); + }); +}); diff --git a/test/unit/app/controllers/transactions/tx-controller-test.js b/test/unit/app/controllers/transactions/tx-controller-test.js index e37c44a470..ca7bfede6c 100644 --- a/test/unit/app/controllers/transactions/tx-controller-test.js +++ b/test/unit/app/controllers/transactions/tx-controller-test.js @@ -1,27 +1,27 @@ -import { strict as assert } from 'assert' -import EventEmitter from 'events' -import ethUtil from 'ethereumjs-util' -import EthTx from 'ethereumjs-tx' -import { ObservableStore } from '@metamask/obs-store' -import sinon from 'sinon' -import TransactionController from '../../../../../app/scripts/controllers/transactions' +import { strict as assert } from 'assert'; +import EventEmitter from 'events'; +import ethUtil from 'ethereumjs-util'; +import EthTx from 'ethereumjs-tx'; +import { ObservableStore } from '@metamask/obs-store'; +import sinon from 'sinon'; +import TransactionController from '../../../../../app/scripts/controllers/transactions'; import { createTestProviderTools, getTestAccounts, -} from '../../../../stub/provider' +} from '../../../../stub/provider'; import { TRANSACTION_CATEGORIES, TRANSACTION_STATUSES, TRANSACTION_TYPES, -} from '../../../../../shared/constants/transaction' +} from '../../../../../shared/constants/transaction'; -const noop = () => true -const currentNetworkId = '42' -const currentChainId = '0x2a' +const noop = () => true; +const currentNetworkId = '42'; +const currentChainId = '0x2a'; describe('Transaction Controller', function () { - let txController, provider, providerResultStub, fromAccount + let txController, provider, providerResultStub, fromAccount; beforeEach(function () { providerResultStub = { @@ -29,55 +29,55 @@ describe('Transaction Controller', function () { eth_gasPrice: '0x0de0b6b3a7640000', // by default, all accounts are external accounts (not contracts) eth_getCode: '0x', - } + }; provider = createTestProviderTools({ scaffold: providerResultStub }) - .provider - fromAccount = getTestAccounts()[0] - const blockTrackerStub = new EventEmitter() - blockTrackerStub.getCurrentBlock = noop - blockTrackerStub.getLatestBlock = noop + .provider; + fromAccount = getTestAccounts()[0]; + const blockTrackerStub = new EventEmitter(); + blockTrackerStub.getCurrentBlock = noop; + blockTrackerStub.getLatestBlock = noop; txController = new TransactionController({ provider, getGasPrice() { - return '0xee6b2800' + return '0xee6b2800'; }, networkStore: new ObservableStore(currentNetworkId), txHistoryLimit: 10, blockTracker: blockTrackerStub, signTransaction: (ethTx) => new Promise((resolve) => { - ethTx.sign(fromAccount.key) - resolve() + ethTx.sign(fromAccount.key); + resolve(); }), getPermittedAccounts: () => undefined, getCurrentChainId: () => currentChainId, getParticipateInMetrics: () => false, - }) + }); txController.nonceTracker.getNonceLock = () => - Promise.resolve({ nextNonce: 0, releaseLock: noop }) - }) + Promise.resolve({ nextNonce: 0, releaseLock: noop }); + }); describe('#getState', function () { it('should return a state object with the right keys and data types', function () { - const exposedState = txController.getState() + const exposedState = txController.getState(); assert.ok( 'unapprovedTxs' in exposedState, 'state should have the key unapprovedTxs', - ) + ); assert.ok( 'currentNetworkTxList' in exposedState, 'state should have the key currentNetworkTxList', - ) + ); assert.ok( typeof exposedState?.unapprovedTxs === 'object', 'should be an object', - ) + ); assert.ok( Array.isArray(exposedState.currentNetworkTxList), 'should be an array', - ) - }) - }) + ); + }); + }); describe('#getUnapprovedTxCount', function () { it('should return the number of unapproved txs', function () { @@ -103,11 +103,11 @@ describe('Transaction Controller', function () { txParams: {}, history: [{}], }, - ]) - const unapprovedTxCount = txController.getUnapprovedTxCount() - assert.equal(unapprovedTxCount, 3, 'should be 3') - }) - }) + ]); + const unapprovedTxCount = txController.getUnapprovedTxCount(); + assert.equal(unapprovedTxCount, 3, 'should be 3'); + }); + }); describe('#getPendingTxCount', function () { it('should return the number of pending txs', function () { @@ -133,19 +133,19 @@ describe('Transaction Controller', function () { txParams: {}, history: [{}], }, - ]) - const pendingTxCount = txController.getPendingTxCount() - assert.equal(pendingTxCount, 3, 'should be 3') - }) - }) + ]); + const pendingTxCount = txController.getPendingTxCount(); + assert.equal(pendingTxCount, 3, 'should be 3'); + }); + }); describe('#getConfirmedTransactions', function () { it('should return the number of confirmed txs', function () { - const address = '0xc684832530fcbddae4b4230a47e991ddcec2831d' + const address = '0xc684832530fcbddae4b4230a47e991ddcec2831d'; const txParams = { from: address, to: '0xc684832530fcbddae4b4230a47e991ddcec2831d', - } + }; txController.txStateManager._saveTxList([ { id: 0, @@ -210,136 +210,136 @@ describe('Transaction Controller', function () { txParams, history: [{}], }, - ]) + ]); assert.equal( txController.nonceTracker.getConfirmedTransactions(address).length, 3, - ) - }) - }) + ); + }); + }); describe('#newUnapprovedTransaction', function () { - let stub, txMeta, txParams + let stub, txMeta, txParams; beforeEach(function () { txParams = { from: '0xc684832530fcbddae4b4230a47e991ddcec2831d', to: '0xc684832530fcbddae4b4230a47e991ddcec2831d', - } + }; txMeta = { status: TRANSACTION_STATUSES.UNAPPROVED, id: 1, metamaskNetworkId: currentNetworkId, txParams, history: [{}], - } - txController.txStateManager._saveTxList([txMeta]) + }; + txController.txStateManager._saveTxList([txMeta]); stub = sinon .stub(txController, 'addUnapprovedTransaction') .callsFake(() => { - txController.emit('newUnapprovedTx', txMeta) - return Promise.resolve(txController.txStateManager.addTx(txMeta)) - }) - }) + txController.emit('newUnapprovedTx', txMeta); + return Promise.resolve(txController.txStateManager.addTx(txMeta)); + }); + }); afterEach(function () { - txController.txStateManager._saveTxList([]) - stub.restore() - }) + txController.txStateManager._saveTxList([]); + stub.restore(); + }); it('should resolve when finished and status is submitted and resolve with the hash', async function () { txController.once('newUnapprovedTx', (txMetaFromEmit) => { setTimeout(() => { - txController.setTxHash(txMetaFromEmit.id, '0x0') - txController.txStateManager.setTxStatusSubmitted(txMetaFromEmit.id) - }) - }) + txController.setTxHash(txMetaFromEmit.id, '0x0'); + txController.txStateManager.setTxStatusSubmitted(txMetaFromEmit.id); + }); + }); - const hash = await txController.newUnapprovedTransaction(txParams) - assert.ok(hash, 'newUnapprovedTransaction needs to return the hash') - }) + const hash = await txController.newUnapprovedTransaction(txParams); + assert.ok(hash, 'newUnapprovedTransaction needs to return the hash'); + }); it('should reject when finished and status is rejected', async function () { txController.once('newUnapprovedTx', (txMetaFromEmit) => { setTimeout(() => { - txController.txStateManager.setTxStatusRejected(txMetaFromEmit.id) - }) - }) + txController.txStateManager.setTxStatusRejected(txMetaFromEmit.id); + }); + }); await assert.rejects( () => txController.newUnapprovedTransaction(txParams), { message: 'MetaMask Tx Signature: User denied transaction signature.', }, - ) - }) - }) + ); + }); + }); describe('#addUnapprovedTransaction', function () { - const selectedAddress = '0x1678a085c290ebd122dc42cba69373b5953b831d' - const recipientAddress = '0xc42edfcc21ed14dda456aa0756c153f7985d8813' + const selectedAddress = '0x1678a085c290ebd122dc42cba69373b5953b831d'; + const recipientAddress = '0xc42edfcc21ed14dda456aa0756c153f7985d8813'; - let getSelectedAddress, getPermittedAccounts + let getSelectedAddress, getPermittedAccounts; beforeEach(function () { getSelectedAddress = sinon .stub(txController, 'getSelectedAddress') - .returns(selectedAddress) + .returns(selectedAddress); getPermittedAccounts = sinon .stub(txController, 'getPermittedAccounts') - .returns([selectedAddress]) - }) + .returns([selectedAddress]); + }); afterEach(function () { - getSelectedAddress.restore() - getPermittedAccounts.restore() - }) + getSelectedAddress.restore(); + getPermittedAccounts.restore(); + }); it('should add an unapproved transaction and return a valid txMeta', async function () { const txMeta = await txController.addUnapprovedTransaction({ from: selectedAddress, to: recipientAddress, - }) - assert.ok('id' in txMeta, 'should have a id') - assert.ok('time' in txMeta, 'should have a time stamp') + }); + assert.ok('id' in txMeta, 'should have a id'); + assert.ok('time' in txMeta, 'should have a time stamp'); assert.ok( 'metamaskNetworkId' in txMeta, 'should have a metamaskNetworkId', - ) - assert.ok('txParams' in txMeta, 'should have a txParams') - assert.ok('history' in txMeta, 'should have a history') + ); + assert.ok('txParams' in txMeta, 'should have a txParams'); + assert.ok('history' in txMeta, 'should have a history'); assert.equal( txMeta.txParams.value, '0x0', 'should have added 0x0 as the value', - ) + ); - const memTxMeta = txController.txStateManager.getTx(txMeta.id) - assert.deepEqual(txMeta, memTxMeta) - }) + const memTxMeta = txController.txStateManager.getTx(txMeta.id); + assert.deepEqual(txMeta, memTxMeta); + }); it('should emit newUnapprovedTx event and pass txMeta as the first argument', function (done) { - providerResultStub.eth_gasPrice = '4a817c800' + providerResultStub.eth_gasPrice = '4a817c800'; txController.once('newUnapprovedTx', (txMetaFromEmit) => { - assert.ok(txMetaFromEmit, 'txMeta is falsy') - done() - }) + assert.ok(txMetaFromEmit, 'txMeta is falsy'); + done(); + }); txController .addUnapprovedTransaction({ from: selectedAddress, to: recipientAddress, }) - .catch(done) - }) + .catch(done); + }); it("should fail if the from address isn't the selected address", async function () { await assert.rejects(() => txController.addUnapprovedTransaction({ from: '0x0d1d4e623D10F9FBA5Db95830F7d3839406C6AF2', }), - ) - }) + ); + }); it('should fail if netId is loading', async function () { - txController.networkStore = new ObservableStore('loading') + txController.networkStore = new ObservableStore('loading'); await assert.rejects( () => txController.addUnapprovedTransaction({ @@ -347,9 +347,9 @@ describe('Transaction Controller', function () { to: '0x0d1d4e623D10F9FBA5Db95830F7d3839406C6AF2', }), { message: 'MetaMask is having trouble connecting to the network' }, - ) - }) - }) + ); + }); + }); describe('#addTxGasDefaults', function () { it('should add the tx defaults if their are none', async function () { @@ -361,7 +361,7 @@ describe('Transaction Controller', function () { txParams: {}, history: [{}], }, - ]) + ]); const txMeta = { id: 1, txParams: { @@ -369,22 +369,22 @@ describe('Transaction Controller', function () { to: '0xc684832530fcbddae4b4230a47e991ddcec2831d', }, history: [{}], - } - providerResultStub.eth_gasPrice = '4a817c800' - providerResultStub.eth_getBlockByNumber = { gasLimit: '47b784' } - providerResultStub.eth_estimateGas = '5209' + }; + providerResultStub.eth_gasPrice = '4a817c800'; + providerResultStub.eth_getBlockByNumber = { gasLimit: '47b784' }; + providerResultStub.eth_estimateGas = '5209'; - const txMetaWithDefaults = await txController.addTxGasDefaults(txMeta) + const txMetaWithDefaults = await txController.addTxGasDefaults(txMeta); assert.ok( txMetaWithDefaults.txParams.gasPrice, 'should have added the gas price', - ) + ); assert.ok( txMetaWithDefaults.txParams.gas, 'should have added the gas field', - ) - }) - }) + ); + }); + }); describe('#addTx', function () { it('should emit updates', function (done) { @@ -393,36 +393,36 @@ describe('Transaction Controller', function () { status: TRANSACTION_STATUSES.UNAPPROVED, metamaskNetworkId: currentNetworkId, txParams: {}, - } + }; - const eventNames = ['update:badge', '1:unapproved'] - const listeners = [] + const eventNames = ['update:badge', '1:unapproved']; + const listeners = []; eventNames.forEach((eventName) => { listeners.push( new Promise((resolve) => { txController.once(eventName, (arg) => { - resolve(arg) - }) + resolve(arg); + }); }), - ) - }) + ); + }); Promise.all(listeners) .then((returnValues) => { assert.deepEqual( returnValues.pop(), txMeta, 'last event 1:unapproved should return txMeta', - ) - done() + ); + done(); }) - .catch(done) - txController.addTx(txMeta) - }) - }) + .catch(done); + txController.addTx(txMeta); + }); + }); describe('#approveTransaction', function () { it('does not overwrite set values', async function () { - const originalValue = '0x01' + const originalValue = '0x01'; const txMeta = { id: '1', status: TRANSACTION_STATUSES.UNAPPROVED, @@ -432,41 +432,41 @@ describe('Transaction Controller', function () { gas: originalValue, gasPrice: originalValue, }, - } - this.timeout(15000) - const wrongValue = '0x05' + }; + this.timeout(15000); + const wrongValue = '0x05'; - txController.addTx(txMeta) - providerResultStub.eth_gasPrice = wrongValue - providerResultStub.eth_estimateGas = '0x5209' + txController.addTx(txMeta); + providerResultStub.eth_gasPrice = wrongValue; + providerResultStub.eth_estimateGas = '0x5209'; const signStub = sinon .stub(txController, 'signTransaction') - .callsFake(() => Promise.resolve()) + .callsFake(() => Promise.resolve()); const pubStub = sinon .stub(txController, 'publishTransaction') .callsFake(() => { - txController.setTxHash('1', originalValue) - txController.txStateManager.setTxStatusSubmitted('1') - }) + txController.setTxHash('1', originalValue); + txController.txStateManager.setTxStatusSubmitted('1'); + }); - await txController.approveTransaction(txMeta.id) - const result = txController.txStateManager.getTx(txMeta.id) - const params = result.txParams + await txController.approveTransaction(txMeta.id); + const result = txController.txStateManager.getTx(txMeta.id); + const params = result.txParams; - assert.equal(params.gas, originalValue, 'gas unmodified') - assert.equal(params.gasPrice, originalValue, 'gas price unmodified') - assert.equal(result.hash, originalValue) + assert.equal(params.gas, originalValue, 'gas unmodified'); + assert.equal(params.gasPrice, originalValue, 'gas price unmodified'); + assert.equal(result.hash, originalValue); assert.equal( result.status, TRANSACTION_STATUSES.SUBMITTED, 'should have reached the submitted status.', - ) - signStub.restore() - pubStub.restore() - }) - }) + ); + signStub.restore(); + pubStub.restore(); + }); + }); describe('#sign replay-protected tx', function () { it('prepares a tx with the chainId set', async function () { @@ -478,12 +478,12 @@ describe('Transaction Controller', function () { txParams: {}, }, noop, - ) - const rawTx = await txController.signTransaction('1') - const ethTx = new EthTx(ethUtil.toBuffer(rawTx)) - assert.equal(ethTx.getChainId(), 42) - }) - }) + ); + const rawTx = await txController.signTransaction('1'); + const ethTx = new EthTx(ethUtil.toBuffer(rawTx)); + assert.equal(ethTx.getChainId(), 42); + }); + }); describe('#updateAndApproveTransaction', function () { it('should update and approve transactions', async function () { @@ -498,21 +498,21 @@ describe('Transaction Controller', function () { nonce: '0x4b', }, metamaskNetworkId: currentNetworkId, - } - txController.txStateManager.addTx(txMeta) - const approvalPromise = txController.updateAndApproveTransaction(txMeta) - const tx = txController.txStateManager.getTx(1) - assert.equal(tx.status, TRANSACTION_STATUSES.APPROVED) - await approvalPromise - }) - }) + }; + txController.txStateManager.addTx(txMeta); + const approvalPromise = txController.updateAndApproveTransaction(txMeta); + const tx = txController.txStateManager.getTx(1); + assert.equal(tx.status, TRANSACTION_STATUSES.APPROVED); + await approvalPromise; + }); + }); describe('#getChainId', function () { it('returns 0 when the chainId is NaN', function () { - txController.networkStore = new ObservableStore('loading') - assert.equal(txController.getChainId(), 0) - }) - }) + txController.networkStore = new ObservableStore('loading'); + assert.equal(txController.getChainId(), 0); + }); + }); describe('#cancelTransaction', function () { it('should emit a status change to rejected', function (done) { @@ -566,7 +566,7 @@ describe('Transaction Controller', function () { metamaskNetworkId: currentNetworkId, history: [{}], }, - ]) + ]); txController.once('tx:status-update', (txId, status) => { try { @@ -574,27 +574,27 @@ describe('Transaction Controller', function () { status, TRANSACTION_STATUSES.REJECTED, 'status should be rejected', - ) - assert.equal(txId, 0, 'id should e 0') - done() + ); + assert.equal(txId, 0, 'id should e 0'); + done(); } catch (e) { - done(e) + done(e); } - }) + }); - txController.cancelTransaction(0) - }) - }) + txController.cancelTransaction(0); + }); + }); describe('#createSpeedUpTransaction', function () { - let addTxSpy - let approveTransactionSpy - let txParams - let expectedTxParams + let addTxSpy; + let approveTransactionSpy; + let txParams; + let expectedTxParams; beforeEach(function () { - addTxSpy = sinon.spy(txController, 'addTx') - approveTransactionSpy = sinon.spy(txController, 'approveTransaction') + addTxSpy = sinon.spy(txController, 'addTx'); + approveTransactionSpy = sinon.spy(txController, 'approveTransaction'); txParams = { nonce: '0x00', @@ -602,7 +602,7 @@ describe('Transaction Controller', function () { to: '0xB09d8505E1F4EF1CeA089D47094f5DD3464083d4', gas: '0x5209', gasPrice: '0xa', - } + }; txController.txStateManager._saveTxList([ { id: 1, @@ -611,97 +611,97 @@ describe('Transaction Controller', function () { txParams, history: [{}], }, - ]) + ]); - expectedTxParams = { ...txParams, gasPrice: '0xb' } - }) + expectedTxParams = { ...txParams, gasPrice: '0xb' }; + }); afterEach(function () { - addTxSpy.restore() - approveTransactionSpy.restore() - }) + addTxSpy.restore(); + approveTransactionSpy.restore(); + }); it('should call this.addTx and this.approveTransaction with the expected args', async function () { - await txController.createSpeedUpTransaction(1) - assert.equal(addTxSpy.callCount, 1) + await txController.createSpeedUpTransaction(1); + assert.equal(addTxSpy.callCount, 1); - const addTxArgs = addTxSpy.getCall(0).args[0] - assert.deepEqual(addTxArgs.txParams, expectedTxParams) + const addTxArgs = addTxSpy.getCall(0).args[0]; + assert.deepEqual(addTxArgs.txParams, expectedTxParams); - const { lastGasPrice, type } = addTxArgs + const { lastGasPrice, type } = addTxArgs; assert.deepEqual( { lastGasPrice, type }, { lastGasPrice: '0xa', type: TRANSACTION_TYPES.RETRY, }, - ) - }) + ); + }); it('should call this.approveTransaction with the id of the returned tx', async function () { - const result = await txController.createSpeedUpTransaction(1) - assert.equal(approveTransactionSpy.callCount, 1) + const result = await txController.createSpeedUpTransaction(1); + assert.equal(approveTransactionSpy.callCount, 1); - const approveTransactionArg = approveTransactionSpy.getCall(0).args[0] - assert.equal(result.id, approveTransactionArg) - }) + const approveTransactionArg = approveTransactionSpy.getCall(0).args[0]; + assert.equal(result.id, approveTransactionArg); + }); it('should return the expected txMeta', async function () { - const result = await txController.createSpeedUpTransaction(1) + const result = await txController.createSpeedUpTransaction(1); - assert.deepEqual(result.txParams, expectedTxParams) + assert.deepEqual(result.txParams, expectedTxParams); - const { lastGasPrice, type } = result + const { lastGasPrice, type } = result; assert.deepEqual( { lastGasPrice, type }, { lastGasPrice: '0xa', type: TRANSACTION_TYPES.RETRY, }, - ) - }) - }) + ); + }); + }); describe('#publishTransaction', function () { - let hash, txMeta + let hash, txMeta; beforeEach(function () { hash = - '0x2a5523c6fa98b47b7d9b6c8320179785150b42a16bcff36b398c5062b65657e8' + '0x2a5523c6fa98b47b7d9b6c8320179785150b42a16bcff36b398c5062b65657e8'; txMeta = { id: 1, status: TRANSACTION_STATUSES.UNAPPROVED, txParams: {}, metamaskNetworkId: currentNetworkId, - } - providerResultStub.eth_sendRawTransaction = hash - }) + }; + providerResultStub.eth_sendRawTransaction = hash; + }); it('should publish a tx, updates the rawTx when provided a one', async function () { const rawTx = - '0x477b2e6553c917af0db0388ae3da62965ff1a184558f61b749d1266b2e6d024c' - txController.txStateManager.addTx(txMeta) - await txController.publishTransaction(txMeta.id, rawTx) - const publishedTx = txController.txStateManager.getTx(1) - assert.equal(publishedTx.hash, hash) - assert.equal(publishedTx.status, TRANSACTION_STATUSES.SUBMITTED) - }) + '0x477b2e6553c917af0db0388ae3da62965ff1a184558f61b749d1266b2e6d024c'; + txController.txStateManager.addTx(txMeta); + await txController.publishTransaction(txMeta.id, rawTx); + const publishedTx = txController.txStateManager.getTx(1); + assert.equal(publishedTx.hash, hash); + assert.equal(publishedTx.status, TRANSACTION_STATUSES.SUBMITTED); + }); it('should ignore the error "Transaction Failed: known transaction" and be as usual', async function () { providerResultStub.eth_sendRawTransaction = async (_, __, ___, end) => { - end('Transaction Failed: known transaction') - } + end('Transaction Failed: known transaction'); + }; const rawTx = - '0xf86204831e848082520894f231d46dd78806e1dd93442cf33c7671f853874880802ca05f973e540f2d3c2f06d3725a626b75247593cb36477187ae07ecfe0a4db3cf57a00259b52ee8c58baaa385fb05c3f96116e58de89bcc165cb3bfdfc708672fed8a' - txController.txStateManager.addTx(txMeta) - await txController.publishTransaction(txMeta.id, rawTx) - const publishedTx = txController.txStateManager.getTx(1) + '0xf86204831e848082520894f231d46dd78806e1dd93442cf33c7671f853874880802ca05f973e540f2d3c2f06d3725a626b75247593cb36477187ae07ecfe0a4db3cf57a00259b52ee8c58baaa385fb05c3f96116e58de89bcc165cb3bfdfc708672fed8a'; + txController.txStateManager.addTx(txMeta); + await txController.publishTransaction(txMeta.id, rawTx); + const publishedTx = txController.txStateManager.getTx(1); assert.equal( publishedTx.hash, '0x2cc5a25744486f7383edebbf32003e5a66e18135799593d6b5cdd2bb43674f09', - ) - assert.equal(publishedTx.status, TRANSACTION_STATUSES.SUBMITTED) - }) - }) + ); + assert.equal(publishedTx.status, TRANSACTION_STATUSES.SUBMITTED); + }); + }); describe('#_markNonceDuplicatesDropped', function () { it('should mark all nonce duplicates as dropped without marking the confirmed transaction as dropped', function () { @@ -755,90 +755,90 @@ describe('Transaction Controller', function () { history: [{}], txParams: { nonce: '0x01' }, }, - ]) - txController._markNonceDuplicatesDropped(1) - const confirmedTx = txController.txStateManager.getTx(1) + ]); + txController._markNonceDuplicatesDropped(1); + const confirmedTx = txController.txStateManager.getTx(1); const droppedTxs = txController.txStateManager.getFilteredTxList({ nonce: '0x01', status: TRANSACTION_STATUSES.DROPPED, - }) + }); assert.equal( confirmedTx.status, TRANSACTION_STATUSES.CONFIRMED, 'the confirmedTx should remain confirmed', - ) - assert.equal(droppedTxs.length, 6, 'their should be 6 dropped txs') - }) - }) + ); + assert.equal(droppedTxs.length, 6, 'their should be 6 dropped txs'); + }); + }); describe('#_determineTransactionCategory', function () { it('should return a simple send transactionCategory when to is truthy but data is falsy', async function () { const result = await txController._determineTransactionCategory({ to: '0xabc', data: '', - }) + }); assert.deepEqual(result, { transactionCategory: TRANSACTION_CATEGORIES.SENT_ETHER, getCodeResponse: null, - }) - }) + }); + }); it('should return a token transfer transactionCategory when data is for the respective method call', async function () { const result = await txController._determineTransactionCategory({ to: '0xabc', data: '0xa9059cbb0000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C970000000000000000000000000000000000000000000000000000000000000000a', - }) + }); assert.deepEqual(result, { transactionCategory: TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER, getCodeResponse: undefined, - }) - }) + }); + }); it('should return a token approve transactionCategory when data is for the respective method call', async function () { const result = await txController._determineTransactionCategory({ to: '0xabc', data: '0x095ea7b30000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C9700000000000000000000000000000000000000000000000000000000000000005', - }) + }); assert.deepEqual(result, { transactionCategory: TRANSACTION_CATEGORIES.TOKEN_METHOD_APPROVE, getCodeResponse: undefined, - }) - }) + }); + }); it('should return a contract deployment transactionCategory when to is falsy and there is data', async function () { const result = await txController._determineTransactionCategory({ to: '', data: '0xabd', - }) + }); assert.deepEqual(result, { transactionCategory: TRANSACTION_CATEGORIES.DEPLOY_CONTRACT, getCodeResponse: undefined, - }) - }) + }); + }); it('should return a simple send transactionCategory with a 0x getCodeResponse when there is data and but the to address is not a contract address', async function () { const result = await txController._determineTransactionCategory({ to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9', data: '0xabd', - }) + }); assert.deepEqual(result, { transactionCategory: TRANSACTION_CATEGORIES.SENT_ETHER, getCodeResponse: '0x', - }) - }) + }); + }); it('should return a simple send transactionCategory with a null getCodeResponse when to is truthy and there is data and but getCode returns an error', async function () { const result = await txController._determineTransactionCategory({ to: '0xabc', data: '0xabd', - }) + }); assert.deepEqual(result, { transactionCategory: TRANSACTION_CATEGORIES.SENT_ETHER, getCodeResponse: null, - }) - }) + }); + }); it('should return a contract interaction transactionCategory with the correct getCodeResponse when to is truthy and there is data and it is not a token transaction', async function () { const _providerResultStub = { @@ -846,38 +846,38 @@ describe('Transaction Controller', function () { eth_gasPrice: '0x0de0b6b3a7640000', // by default, all accounts are external accounts (not contracts) eth_getCode: '0xa', - } + }; const _provider = createTestProviderTools({ scaffold: _providerResultStub, - }).provider - const _fromAccount = getTestAccounts()[0] - const _blockTrackerStub = new EventEmitter() - _blockTrackerStub.getCurrentBlock = noop - _blockTrackerStub.getLatestBlock = noop + }).provider; + const _fromAccount = getTestAccounts()[0]; + const _blockTrackerStub = new EventEmitter(); + _blockTrackerStub.getCurrentBlock = noop; + _blockTrackerStub.getLatestBlock = noop; const _txController = new TransactionController({ provider: _provider, getGasPrice() { - return '0xee6b2800' + return '0xee6b2800'; }, networkStore: new ObservableStore(currentNetworkId), txHistoryLimit: 10, blockTracker: _blockTrackerStub, signTransaction: (ethTx) => new Promise((resolve) => { - ethTx.sign(_fromAccount.key) - resolve() + ethTx.sign(_fromAccount.key); + resolve(); }), getParticipateInMetrics: () => false, - }) + }); const result = await _txController._determineTransactionCategory({ to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9', data: 'abd', - }) + }); assert.deepEqual(result, { transactionCategory: TRANSACTION_CATEGORIES.CONTRACT_INTERACTION, getCodeResponse: '0x0a', - }) - }) + }); + }); it('should return a contract interaction transactionCategory with the correct getCodeResponse when to is a contract address and data is falsy', async function () { const _providerResultStub = { @@ -885,39 +885,39 @@ describe('Transaction Controller', function () { eth_gasPrice: '0x0de0b6b3a7640000', // by default, all accounts are external accounts (not contracts) eth_getCode: '0xa', - } + }; const _provider = createTestProviderTools({ scaffold: _providerResultStub, - }).provider - const _fromAccount = getTestAccounts()[0] - const _blockTrackerStub = new EventEmitter() - _blockTrackerStub.getCurrentBlock = noop - _blockTrackerStub.getLatestBlock = noop + }).provider; + const _fromAccount = getTestAccounts()[0]; + const _blockTrackerStub = new EventEmitter(); + _blockTrackerStub.getCurrentBlock = noop; + _blockTrackerStub.getLatestBlock = noop; const _txController = new TransactionController({ provider: _provider, getGasPrice() { - return '0xee6b2800' + return '0xee6b2800'; }, networkStore: new ObservableStore(currentNetworkId), txHistoryLimit: 10, blockTracker: _blockTrackerStub, signTransaction: (ethTx) => new Promise((resolve) => { - ethTx.sign(_fromAccount.key) - resolve() + ethTx.sign(_fromAccount.key); + resolve(); }), getParticipateInMetrics: () => false, - }) + }); const result = await _txController._determineTransactionCategory({ to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9', data: '', - }) + }); assert.deepEqual(result, { transactionCategory: TRANSACTION_CATEGORIES.CONTRACT_INTERACTION, getCodeResponse: '0x0a', - }) - }) - }) + }); + }); + }); describe('#getPendingTransactions', function () { it('should show only submitted and approved transactions as pending transaction', function () { @@ -970,23 +970,23 @@ describe('Transaction Controller', function () { txParams: {}, history: [{}], }, - ]) + ]); assert.equal( txController.pendingTxTracker.getPendingTransactions().length, 2, - ) + ); const states = txController.pendingTxTracker .getPendingTransactions() - .map((tx) => tx.status) + .map((tx) => tx.status); assert.ok( states.includes(TRANSACTION_STATUSES.APPROVED), 'includes approved', - ) + ); assert.ok( states.includes(TRANSACTION_STATUSES.SUBMITTED), 'includes submitted', - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/test/unit/app/controllers/transactions/tx-gas-util-test.js b/test/unit/app/controllers/transactions/tx-gas-util-test.js index c08b705206..d3e9cfddff 100644 --- a/test/unit/app/controllers/transactions/tx-gas-util-test.js +++ b/test/unit/app/controllers/transactions/tx-gas-util-test.js @@ -1,10 +1,10 @@ -import { strict as assert } from 'assert' -import Transaction from 'ethereumjs-tx' -import { hexToBn, bnToHex } from '../../../../../app/scripts/lib/util' -import TxUtils from '../../../../../app/scripts/controllers/transactions/tx-gas-utils' +import { strict as assert } from 'assert'; +import Transaction from 'ethereumjs-tx'; +import { hexToBn, bnToHex } from '../../../../../app/scripts/lib/util'; +import TxUtils from '../../../../../app/scripts/controllers/transactions/tx-gas-utils'; describe('txUtils', function () { - let txUtils + let txUtils; before(function () { txUtils = new TxUtils( @@ -12,12 +12,12 @@ describe('txUtils', function () { {}, { get: () => { - return () => undefined + return () => undefined; }, }, ), - ) - }) + ); + }); describe('chain Id', function () { it('prepares a transaction with the provided chainId', function () { @@ -30,56 +30,56 @@ describe('txUtils', function () { data: '0x', nonce: '0x3', chainId: 42, - } - const ethTx = new Transaction(txParams) - assert.equal(ethTx.getChainId(), 42, 'chainId is set from tx params') - }) - }) + }; + const ethTx = new Transaction(txParams); + assert.equal(ethTx.getChainId(), 42, 'chainId is set from tx params'); + }); + }); describe('addGasBuffer', function () { it('multiplies by 1.5, when within block gas limit', function () { // naive estimatedGas: 0x16e360 (1.5 mil) - const inputHex = '0x16e360' + const inputHex = '0x16e360'; // dummy gas limit: 0x3d4c52 (4 mil) - const blockGasLimitHex = '0x3d4c52' - const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex) - const inputBn = hexToBn(inputHex) - const outputBn = hexToBn(output) - const expectedBn = inputBn.muln(1.5) - assert.ok(outputBn.eq(expectedBn), 'returns 1.5 the input value') - }) + const blockGasLimitHex = '0x3d4c52'; + const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex); + const inputBn = hexToBn(inputHex); + const outputBn = hexToBn(output); + const expectedBn = inputBn.muln(1.5); + assert.ok(outputBn.eq(expectedBn), 'returns 1.5 the input value'); + }); it('uses original estimatedGas, when above block gas limit', function () { // naive estimatedGas: 0x16e360 (1.5 mil) - const inputHex = '0x16e360' + const inputHex = '0x16e360'; // dummy gas limit: 0x0f4240 (1 mil) - const blockGasLimitHex = '0x0f4240' - const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex) + const blockGasLimitHex = '0x0f4240'; + const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex); // const inputBn = hexToBn(inputHex) - const outputBn = hexToBn(output) - const expectedBn = hexToBn(inputHex) + const outputBn = hexToBn(output); + const expectedBn = hexToBn(inputHex); assert.ok( outputBn.eq(expectedBn), 'returns the original estimatedGas value', - ) - }) + ); + }); it('buffers up to recommend gas limit recommended ceiling', function () { // naive estimatedGas: 0x16e360 (1.5 mil) - const inputHex = '0x16e360' + const inputHex = '0x16e360'; // dummy gas limit: 0x1e8480 (2 mil) - const blockGasLimitHex = '0x1e8480' - const blockGasLimitBn = hexToBn(blockGasLimitHex) - const ceilGasLimitBn = blockGasLimitBn.muln(0.9) - const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex) + const blockGasLimitHex = '0x1e8480'; + const blockGasLimitBn = hexToBn(blockGasLimitHex); + const ceilGasLimitBn = blockGasLimitBn.muln(0.9); + const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex); // const inputBn = hexToBn(inputHex) // const outputBn = hexToBn(output) - const expectedHex = bnToHex(ceilGasLimitBn) + const expectedHex = bnToHex(ceilGasLimitBn); assert.equal( output, expectedHex, 'returns the gas limit recommended ceiling value', - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/test/unit/app/controllers/transactions/tx-helper-test.js b/test/unit/app/controllers/transactions/tx-helper-test.js index 0330e77243..c2b13af4c6 100644 --- a/test/unit/app/controllers/transactions/tx-helper-test.js +++ b/test/unit/app/controllers/transactions/tx-helper-test.js @@ -1,17 +1,17 @@ -import { strict as assert } from 'assert' -import txHelper from '../../../../../ui/lib/tx-helper' +import { strict as assert } from 'assert'; +import txHelper from '../../../../../ui/lib/tx-helper'; describe('txHelper', function () { it('always shows the oldest tx first', function () { - const metamaskNetworkId = '1' + const metamaskNetworkId = '1'; const txs = { a: { metamaskNetworkId, time: 3 }, b: { metamaskNetworkId, time: 1 }, c: { metamaskNetworkId, time: 2 }, - } + }; - const sorted = txHelper(txs, null, null, metamaskNetworkId) - assert.equal(sorted[0].time, 1, 'oldest tx first') - assert.equal(sorted[2].time, 3, 'newest tx last') - }) -}) + const sorted = txHelper(txs, null, null, metamaskNetworkId); + assert.equal(sorted[0].time, 1, 'oldest tx first'); + assert.equal(sorted[2].time, 3, 'newest tx last'); + }); +}); diff --git a/test/unit/app/controllers/transactions/tx-state-history-helpers-test.js b/test/unit/app/controllers/transactions/tx-state-history-helpers-test.js index c11cb17e06..6ff852baee 100644 --- a/test/unit/app/controllers/transactions/tx-state-history-helpers-test.js +++ b/test/unit/app/controllers/transactions/tx-state-history-helpers-test.js @@ -1,11 +1,11 @@ -import { strict as assert } from 'assert' +import { strict as assert } from 'assert'; import { snapshotFromTxMeta, migrateFromSnapshotsToDiffs, replayHistory, generateHistoryEntry, -} from '../../../../../app/scripts/controllers/transactions/lib/tx-state-history-helpers' -import testData from '../../../../data/mock-tx-history.json' +} from '../../../../../app/scripts/controllers/transactions/lib/tx-state-history-helpers'; +import testData from '../../../../data/mock-tx-history.json'; describe('Transaction state history helper', function () { describe('#snapshotFromTxMeta', function () { @@ -16,86 +16,86 @@ describe('Transaction state history helper', function () { bam: 'baz', }, }, - } - const output = snapshotFromTxMeta(input) - assert.ok('foo' in output, 'has a foo key') - assert.ok('bar' in output.foo, 'has a bar key') - assert.ok('bam' in output.foo.bar, 'has a bar key') - assert.equal(output.foo.bar.bam, 'baz', 'has a baz value') - }) + }; + const output = snapshotFromTxMeta(input); + assert.ok('foo' in output, 'has a foo key'); + assert.ok('bar' in output.foo, 'has a bar key'); + assert.ok('bam' in output.foo.bar, 'has a bar key'); + assert.equal(output.foo.bar.bam, 'baz', 'has a baz value'); + }); it('should remove the history key', function () { - const input = { foo: 'bar', history: 'remembered' } - const output = snapshotFromTxMeta(input) - assert.equal(typeof output.history, 'undefined', 'should remove history') - }) - }) + const input = { foo: 'bar', history: 'remembered' }; + const output = snapshotFromTxMeta(input); + assert.equal(typeof output.history, 'undefined', 'should remove history'); + }); + }); describe('#migrateFromSnapshotsToDiffs', function () { it('migrates history to diffs and can recover original values', function () { testData.TransactionsController.transactions.forEach((tx) => { - const newHistory = migrateFromSnapshotsToDiffs(tx.history) + const newHistory = migrateFromSnapshotsToDiffs(tx.history); newHistory.forEach((newEntry, index) => { if (index === 0) { assert.equal( Array.isArray(newEntry), false, 'initial history item IS NOT a json patch obj', - ) + ); } else { assert.equal( Array.isArray(newEntry), true, 'non-initial history entry IS a json patch obj', - ) + ); } - const oldEntry = tx.history[index] - const historySubset = newHistory.slice(0, index + 1) - const reconstructedValue = replayHistory(historySubset) + const oldEntry = tx.history[index]; + const historySubset = newHistory.slice(0, index + 1); + const reconstructedValue = replayHistory(historySubset); assert.deepEqual( oldEntry, reconstructedValue, 'was able to reconstruct old entry from diffs', - ) - }) - }) - }) - }) + ); + }); + }); + }); + }); describe('#replayHistory', function () { it('replaying history does not mutate the original object', function () { - const initialState = { test: true, message: 'hello', value: 1 } + const initialState = { test: true, message: 'hello', value: 1 }; const diff1 = [ { op: 'replace', path: '/message', value: 'haay', }, - ] + ]; const diff2 = [ { op: 'replace', path: '/value', value: 2, }, - ] - const history = [initialState, diff1, diff2] + ]; + const history = [initialState, diff1, diff2]; - const beforeStateSnapshot = JSON.stringify(initialState) - const latestState = replayHistory(history) - const afterStateSnapshot = JSON.stringify(initialState) + const beforeStateSnapshot = JSON.stringify(initialState); + const latestState = replayHistory(history); + const afterStateSnapshot = JSON.stringify(initialState); assert.notEqual( initialState, latestState, 'initial state is not the same obj as the latest state', - ) + ); assert.equal( beforeStateSnapshot, afterStateSnapshot, 'initial state is not modified during run', - ) - }) - }) + ); + }); + }); describe('#generateHistoryEntry', function () { function generateHistoryEntryTest(note) { @@ -106,7 +106,7 @@ describe('Transaction state history helper', function () { bam: 'baz', }, }, - } + }; const nextState = { newPropRoot: 'new property - root', @@ -117,46 +117,46 @@ describe('Transaction state history helper', function () { bam: 'baz', }, }, - } + }; - const before = new Date().getTime() - const result = generateHistoryEntry(prevState, nextState, note) - const after = new Date().getTime() - assert.ok(Array.isArray(result)) - assert.equal(result.length, 3) + const before = new Date().getTime(); + const result = generateHistoryEntry(prevState, nextState, note); + const after = new Date().getTime(); + assert.ok(Array.isArray(result)); + assert.equal(result.length, 3); const expectedEntry1 = { op: 'add', path: '/foo/newPropFirstLevel', value: 'new property - first level', - } - assert.equal(result[0].op, expectedEntry1.op) - assert.equal(result[0].path, expectedEntry1.path) - assert.equal(result[0].value, expectedEntry1.value) - assert.equal(result[0].note, note) - assert.ok(result[0].timestamp >= before && result[0].timestamp <= after) + }; + assert.equal(result[0].op, expectedEntry1.op); + assert.equal(result[0].path, expectedEntry1.path); + assert.equal(result[0].value, expectedEntry1.value); + assert.equal(result[0].note, note); + assert.ok(result[0].timestamp >= before && result[0].timestamp <= after); const expectedEntry2 = { op: 'replace', path: '/someValue', value: 'value 2', - } - assert.deepEqual(result[1], expectedEntry2) + }; + assert.deepEqual(result[1], expectedEntry2); const expectedEntry3 = { op: 'add', path: '/newPropRoot', value: 'new property - root', - } - assert.deepEqual(result[2], expectedEntry3) + }; + assert.deepEqual(result[2], expectedEntry3); } it('should generate history entries', function () { - generateHistoryEntryTest() - }) + generateHistoryEntryTest(); + }); it('should add note to first entry', function () { - generateHistoryEntryTest('custom note') - }) - }) -}) + generateHistoryEntryTest('custom note'); + }); + }); +}); diff --git a/test/unit/app/controllers/transactions/tx-state-manager-test.js b/test/unit/app/controllers/transactions/tx-state-manager-test.js index 0b32e7e6fc..6efafb6932 100644 --- a/test/unit/app/controllers/transactions/tx-state-manager-test.js +++ b/test/unit/app/controllers/transactions/tx-state-manager-test.js @@ -1,15 +1,15 @@ -import { strict as assert } from 'assert' -import sinon from 'sinon' -import TxStateManager from '../../../../../app/scripts/controllers/transactions/tx-state-manager' -import { snapshotFromTxMeta } from '../../../../../app/scripts/controllers/transactions/lib/tx-state-history-helpers' -import { TRANSACTION_STATUSES } from '../../../../../shared/constants/transaction' +import { strict as assert } from 'assert'; +import sinon from 'sinon'; +import TxStateManager from '../../../../../app/scripts/controllers/transactions/tx-state-manager'; +import { snapshotFromTxMeta } from '../../../../../app/scripts/controllers/transactions/lib/tx-state-history-helpers'; +import { TRANSACTION_STATUSES } from '../../../../../shared/constants/transaction'; -const noop = () => true +const noop = () => true; describe('TransactionStateManager', function () { - let txStateManager - const currentNetworkId = '42' - const otherNetworkId = '2' + let txStateManager; + const currentNetworkId = '42'; + const otherNetworkId = '2'; beforeEach(function () { txStateManager = new TxStateManager({ @@ -18,8 +18,8 @@ describe('TransactionStateManager', function () { }, txHistoryLimit: 10, getNetwork: () => currentNetworkId, - }) - }) + }); + }); describe('#setTxStatusSigned', function () { it('sets the tx status to signed', function () { @@ -28,14 +28,14 @@ describe('TransactionStateManager', function () { status: TRANSACTION_STATUSES.UNAPPROVED, metamaskNetworkId: currentNetworkId, txParams: {}, - } - txStateManager.addTx(tx, noop) - txStateManager.setTxStatusSigned(1) - const result = txStateManager.getTxList() - assert.ok(Array.isArray(result)) - assert.equal(result.length, 1) - assert.equal(result[0].status, TRANSACTION_STATUSES.SIGNED) - }) + }; + txStateManager.addTx(tx, noop); + txStateManager.setTxStatusSigned(1); + const result = txStateManager.getTxList(); + assert.ok(Array.isArray(result)); + assert.equal(result.length, 1); + assert.equal(result[0].status, TRANSACTION_STATUSES.SIGNED); + }); it('should emit a signed event to signal the execution of callback', function () { const tx = { @@ -43,19 +43,19 @@ describe('TransactionStateManager', function () { status: TRANSACTION_STATUSES.UNAPPROVED, metamaskNetworkId: currentNetworkId, txParams: {}, - } - const clock = sinon.useFakeTimers() - const onSigned = sinon.spy() + }; + const clock = sinon.useFakeTimers(); + const onSigned = sinon.spy(); - txStateManager.addTx(tx) - txStateManager.on('1:signed', onSigned) - txStateManager.setTxStatusSigned(1) - clock.runAll() - clock.restore() + txStateManager.addTx(tx); + txStateManager.on('1:signed', onSigned); + txStateManager.setTxStatusSigned(1); + clock.runAll(); + clock.restore(); - assert.ok(onSigned.calledOnce) - }) - }) + assert.ok(onSigned.calledOnce); + }); + }); describe('#setTxStatusRejected', function () { it('sets the tx status to rejected and removes it from history', function () { @@ -64,13 +64,13 @@ describe('TransactionStateManager', function () { status: TRANSACTION_STATUSES.UNAPPROVED, metamaskNetworkId: currentNetworkId, txParams: {}, - } - txStateManager.addTx(tx) - txStateManager.setTxStatusRejected(1) - const result = txStateManager.getTxList() - assert.ok(Array.isArray(result)) - assert.equal(result.length, 0) - }) + }; + txStateManager.addTx(tx); + txStateManager.setTxStatusRejected(1); + const result = txStateManager.getTxList(); + assert.ok(Array.isArray(result)); + assert.equal(result.length, 0); + }); it('should emit a rejected event to signal the execution of callback', function () { const tx = { @@ -78,34 +78,34 @@ describe('TransactionStateManager', function () { status: TRANSACTION_STATUSES.UNAPPROVED, metamaskNetworkId: currentNetworkId, txParams: {}, - } - const clock = sinon.useFakeTimers() - const onSigned = sinon.spy() + }; + const clock = sinon.useFakeTimers(); + const onSigned = sinon.spy(); - txStateManager.addTx(tx) - txStateManager.on('1:rejected', onSigned) - txStateManager.setTxStatusRejected(1) - clock.runAll() - clock.restore() + txStateManager.addTx(tx); + txStateManager.on('1:rejected', onSigned); + txStateManager.setTxStatusRejected(1); + clock.runAll(); + clock.restore(); - assert.ok(onSigned.calledOnce) - }) - }) + assert.ok(onSigned.calledOnce); + }); + }); describe('#getFullTxList', function () { it('when new should return empty array', function () { - const result = txStateManager.getTxList() - assert.ok(Array.isArray(result)) - assert.equal(result.length, 0) - }) - }) + const result = txStateManager.getTxList(); + assert.ok(Array.isArray(result)); + assert.equal(result.length, 0); + }); + }); describe('#getTxList', function () { it('when new should return empty array', function () { - const result = txStateManager.getTxList() - assert.ok(Array.isArray(result)) - assert.equal(result.length, 0) - }) + const result = txStateManager.getTxList(); + assert.ok(Array.isArray(result)); + assert.equal(result.length, 0); + }); it('should return a full list of transactions', function () { const submittedTx = { @@ -118,7 +118,7 @@ describe('TransactionStateManager', function () { nonce: '0x0', }, status: TRANSACTION_STATUSES.SUBMITTED, - } + }; const confirmedTx = { id: 3, @@ -130,17 +130,17 @@ describe('TransactionStateManager', function () { nonce: '0x3', }, status: TRANSACTION_STATUSES.CONFIRMED, - } + }; const txm = new TxStateManager({ initState: { transactions: [submittedTx, confirmedTx], }, getNetwork: () => currentNetworkId, - }) + }); - assert.deepEqual(txm.getTxList(), [submittedTx, confirmedTx]) - }) + assert.deepEqual(txm.getTxList(), [submittedTx, confirmedTx]); + }); it('should return a list of transactions, limited by N unique nonces when there are NO duplicates', function () { const submittedTx0 = { @@ -153,7 +153,7 @@ describe('TransactionStateManager', function () { nonce: '0x0', }, status: TRANSACTION_STATUSES.SUBMITTED, - } + }; const unapprovedTx1 = { id: 1, @@ -165,7 +165,7 @@ describe('TransactionStateManager', function () { nonce: '0x1', }, status: TRANSACTION_STATUSES.UNAPPROVED, - } + }; const approvedTx2 = { id: 2, @@ -177,7 +177,7 @@ describe('TransactionStateManager', function () { nonce: '0x2', }, status: TRANSACTION_STATUSES.APPROVED, - } + }; const confirmedTx3 = { id: 3, @@ -189,7 +189,7 @@ describe('TransactionStateManager', function () { nonce: '0x3', }, status: TRANSACTION_STATUSES.CONFIRMED, - } + }; const txm = new TxStateManager({ initState: { @@ -201,10 +201,10 @@ describe('TransactionStateManager', function () { ], }, getNetwork: () => currentNetworkId, - }) + }); - assert.deepEqual(txm.getTxList(2), [approvedTx2, confirmedTx3]) - }) + assert.deepEqual(txm.getTxList(2), [approvedTx2, confirmedTx3]); + }); it('should return a list of transactions, limited by N unique nonces when there ARE duplicates', function () { const submittedTx0s = [ @@ -230,7 +230,7 @@ describe('TransactionStateManager', function () { }, status: TRANSACTION_STATUSES.SUBMITTED, }, - ] + ]; const unapprovedTx1 = { id: 1, @@ -242,7 +242,7 @@ describe('TransactionStateManager', function () { nonce: '0x1', }, status: TRANSACTION_STATUSES.UNAPPROVED, - } + }; const approvedTx2s = [ { @@ -267,7 +267,7 @@ describe('TransactionStateManager', function () { }, status: TRANSACTION_STATUSES.APPROVED, }, - ] + ]; const failedTx3s = [ { @@ -292,7 +292,7 @@ describe('TransactionStateManager', function () { }, status: TRANSACTION_STATUSES.FAILED, }, - ] + ]; const txm = new TxStateManager({ initState: { @@ -304,11 +304,11 @@ describe('TransactionStateManager', function () { ], }, getNetwork: () => currentNetworkId, - }) + }); - assert.deepEqual(txm.getTxList(2), [...approvedTx2s, ...failedTx3s]) - }) - }) + assert.deepEqual(txm.getTxList(2), [...approvedTx2s, ...failedTx3s]); + }); + }); describe('#addTx', function () { it('adds a tx returned in getTxList', function () { @@ -317,13 +317,13 @@ describe('TransactionStateManager', function () { status: TRANSACTION_STATUSES.CONFIRMED, metamaskNetworkId: currentNetworkId, txParams: {}, - } - txStateManager.addTx(tx, noop) - const result = txStateManager.getTxList() - assert.ok(Array.isArray(result)) - assert.equal(result.length, 1) - assert.equal(result[0].id, 1) - }) + }; + txStateManager.addTx(tx, noop); + const result = txStateManager.getTxList(); + assert.ok(Array.isArray(result)); + assert.equal(result.length, 1); + assert.equal(result[0].id, 1); + }); it('throws error and does not add tx if txParams are invalid', function () { const validTxParams = { @@ -334,8 +334,8 @@ describe('TransactionStateManager', function () { gasPrice: '0x77359400', value: '0x0', data: '0x0', - } - const invalidValues = [1, true, {}, Symbol('1')] + }; + const invalidValues = [1, true, {}, Symbol('1')]; Object.keys(validTxParams).forEach((key) => { for (const value of invalidValues) { @@ -347,17 +347,17 @@ describe('TransactionStateManager', function () { ...validTxParams, [key]: value, }, - } + }; assert.throws( txStateManager.addTx.bind(txStateManager, tx), 'addTx should throw error', - ) - const result = txStateManager.getTxList() - assert.ok(Array.isArray(result), 'txList should be an array') - assert.equal(result.length, 0, 'txList should be empty') + ); + const result = txStateManager.getTxList(); + assert.ok(Array.isArray(result), 'txList should be an array'); + assert.equal(result.length, 0, 'txList should be empty'); } - }) - }) + }); + }); it('does not override txs from other networks', function () { const tx = { @@ -365,23 +365,23 @@ describe('TransactionStateManager', function () { status: TRANSACTION_STATUSES.CONFIRMED, metamaskNetworkId: currentNetworkId, txParams: {}, - } + }; const tx2 = { id: 2, status: TRANSACTION_STATUSES.CONFIRMED, metamaskNetworkId: otherNetworkId, txParams: {}, - } - txStateManager.addTx(tx, noop) - txStateManager.addTx(tx2, noop) - const result = txStateManager.getFullTxList() - const result2 = txStateManager.getTxList() - assert.equal(result.length, 2, 'txs were deleted') - assert.equal(result2.length, 1, 'incorrect number of txs on network.') - }) + }; + txStateManager.addTx(tx, noop); + txStateManager.addTx(tx2, noop); + const result = txStateManager.getFullTxList(); + const result2 = txStateManager.getTxList(); + assert.equal(result.length, 2, 'txs were deleted'); + assert.equal(result2.length, 1, 'incorrect number of txs on network.'); + }); it('cuts off early txs beyond a limit', function () { - const limit = txStateManager.txHistoryLimit + const limit = txStateManager.txHistoryLimit; for (let i = 0; i < limit + 1; i++) { const tx = { id: i, @@ -389,16 +389,16 @@ describe('TransactionStateManager', function () { status: TRANSACTION_STATUSES.CONFIRMED, metamaskNetworkId: currentNetworkId, txParams: {}, - } - txStateManager.addTx(tx, noop) + }; + txStateManager.addTx(tx, noop); } - const result = txStateManager.getTxList() - assert.equal(result.length, limit, `limit of ${limit} txs enforced`) - assert.equal(result[0].id, 1, 'early txs truncated') - }) + const result = txStateManager.getTxList(); + assert.equal(result.length, limit, `limit of ${limit} txs enforced`); + assert.equal(result[0].id, 1, 'early txs truncated'); + }); it('cuts off early txs beyond a limit whether or not it is confirmed or rejected', function () { - const limit = txStateManager.txHistoryLimit + const limit = txStateManager.txHistoryLimit; for (let i = 0; i < limit + 1; i++) { const tx = { id: i, @@ -406,13 +406,13 @@ describe('TransactionStateManager', function () { status: TRANSACTION_STATUSES.REJECTED, metamaskNetworkId: currentNetworkId, txParams: {}, - } - txStateManager.addTx(tx, noop) + }; + txStateManager.addTx(tx, noop); } - const result = txStateManager.getTxList() - assert.equal(result.length, limit, `limit of ${limit} txs enforced`) - assert.equal(result[0].id, 1, 'early txs truncated') - }) + const result = txStateManager.getTxList(); + assert.equal(result.length, limit, `limit of ${limit} txs enforced`); + assert.equal(result[0].id, 1, 'early txs truncated'); + }); it('cuts off early txs beyond a limit but does not cut unapproved txs', function () { const unconfirmedTx = { @@ -421,9 +421,9 @@ describe('TransactionStateManager', function () { status: TRANSACTION_STATUSES.UNAPPROVED, metamaskNetworkId: currentNetworkId, txParams: {}, - } - txStateManager.addTx(unconfirmedTx, noop) - const limit = txStateManager.txHistoryLimit + }; + txStateManager.addTx(unconfirmedTx, noop); + const limit = txStateManager.txHistoryLimit; for (let i = 1; i < limit + 1; i++) { const tx = { id: i, @@ -431,20 +431,20 @@ describe('TransactionStateManager', function () { status: TRANSACTION_STATUSES.CONFIRMED, metamaskNetworkId: currentNetworkId, txParams: {}, - } - txStateManager.addTx(tx, noop) + }; + txStateManager.addTx(tx, noop); } - const result = txStateManager.getTxList() - assert.equal(result.length, limit, `limit of ${limit} txs enforced`) - assert.equal(result[0].id, 0, 'first tx should still be there') + const result = txStateManager.getTxList(); + assert.equal(result.length, limit, `limit of ${limit} txs enforced`); + assert.equal(result[0].id, 0, 'first tx should still be there'); assert.equal( result[0].status, TRANSACTION_STATUSES.UNAPPROVED, 'first tx should be unapproved', - ) - assert.equal(result[1].id, 2, 'early txs truncated') - }) - }) + ); + assert.equal(result[1].id, 2, 'early txs truncated'); + }); + }); describe('#updateTx', function () { it('replaces the tx with the same id', function () { @@ -456,7 +456,7 @@ describe('TransactionStateManager', function () { txParams: {}, }, noop, - ) + ); txStateManager.addTx( { id: '2', @@ -465,13 +465,13 @@ describe('TransactionStateManager', function () { txParams: {}, }, noop, - ) - const txMeta = txStateManager.getTx('1') - txMeta.hash = 'foo' - txStateManager.updateTx(txMeta) - const result = txStateManager.getTx('1') - assert.equal(result.hash, 'foo') - }) + ); + const txMeta = txStateManager.getTx('1'); + txMeta.hash = 'foo'; + txStateManager.updateTx(txMeta); + const result = txStateManager.getTx('1'); + assert.equal(result.hash, 'foo'); + }); it('throws error and does not update tx if txParams are invalid', function () { const validTxParams = { @@ -482,39 +482,39 @@ describe('TransactionStateManager', function () { gasPrice: '0x77359400', value: '0x0', data: '0x0', - } - const invalidValues = [1, true, {}, Symbol('1')] + }; + const invalidValues = [1, true, {}, Symbol('1')]; txStateManager.addTx({ id: 1, status: TRANSACTION_STATUSES.UNAPPROVED, metamaskNetworkId: currentNetworkId, txParams: validTxParams, - }) + }); Object.keys(validTxParams).forEach((key) => { for (const value of invalidValues) { - const originalTx = txStateManager.getTx(1) + const originalTx = txStateManager.getTx(1); const newTx = { ...originalTx, txParams: { ...originalTx.txParams, [key]: value, }, - } + }; assert.throws( txStateManager.updateTx.bind(txStateManager, newTx), 'updateTx should throw an error', - ) - const result = txStateManager.getTx(1) - assert.deepEqual(result, originalTx, 'tx should not be updated') + ); + const result = txStateManager.getTx(1); + assert.deepEqual(result, originalTx, 'tx should not be updated'); } - }) - }) + }); + }); it('updates gas price and adds history items', function () { - const originalGasPrice = '0x01' - const desiredGasPrice = '0x02' + const originalGasPrice = '0x01'; + const desiredGasPrice = '0x02'; const txMeta = { id: '1', @@ -523,71 +523,71 @@ describe('TransactionStateManager', function () { txParams: { gasPrice: originalGasPrice, }, - } + }; - txStateManager.addTx(txMeta) - const updatedTx = txStateManager.getTx('1') + txStateManager.addTx(txMeta); + const updatedTx = txStateManager.getTx('1'); // verify tx was initialized correctly - assert.equal(updatedTx.history.length, 1, 'one history item (initial)') + assert.equal(updatedTx.history.length, 1, 'one history item (initial)'); assert.equal( Array.isArray(updatedTx.history[0]), false, 'first history item is initial state', - ) + ); assert.deepEqual( updatedTx.history[0], snapshotFromTxMeta(updatedTx), 'first history item is initial state', - ) + ); // modify value and updateTx - updatedTx.txParams.gasPrice = desiredGasPrice - const before = new Date().getTime() - txStateManager.updateTx(updatedTx) - const after = new Date().getTime() + updatedTx.txParams.gasPrice = desiredGasPrice; + const before = new Date().getTime(); + txStateManager.updateTx(updatedTx); + const after = new Date().getTime(); // check updated value - const result = txStateManager.getTx('1') + const result = txStateManager.getTx('1'); assert.equal( result.txParams.gasPrice, desiredGasPrice, 'gas price updated', - ) + ); // validate history was updated assert.equal( result.history.length, 2, 'two history items (initial + diff)', - ) + ); assert.equal( result.history[1].length, 1, 'two history state items (initial + diff)', - ) + ); const expectedEntry = { op: 'replace', path: '/txParams/gasPrice', value: desiredGasPrice, - } + }; assert.deepEqual( result.history[1][0].op, expectedEntry.op, 'two history items (initial + diff) operation', - ) + ); assert.deepEqual( result.history[1][0].path, expectedEntry.path, 'two history items (initial + diff) path', - ) + ); assert.deepEqual( result.history[1][0].value, expectedEntry.value, 'two history items (initial + diff) value', - ) + ); assert.ok( result.history[1][0].timestamp >= before && result.history[1][0].timestamp <= after, - ) - }) + ); + }); it('does NOT add empty history items', function () { const txMeta = { @@ -597,15 +597,15 @@ describe('TransactionStateManager', function () { txParams: { gasPrice: '0x01', }, - } + }; - txStateManager.addTx(txMeta) - txStateManager.updateTx(txMeta) + txStateManager.addTx(txMeta); + txStateManager.updateTx(txMeta); - const { history } = txStateManager.getTx('1') - assert.equal(history.length, 1, 'two history items (initial + diff)') - }) - }) + const { history } = txStateManager.getTx('1'); + assert.equal(history.length, 1, 'two history items (initial + diff)'); + }); + }); describe('#getUnapprovedTxList', function () { it('returns unapproved txs in a hash', function () { @@ -617,7 +617,7 @@ describe('TransactionStateManager', function () { txParams: {}, }, noop, - ) + ); txStateManager.addTx( { id: '2', @@ -626,13 +626,13 @@ describe('TransactionStateManager', function () { txParams: {}, }, noop, - ) - const result = txStateManager.getUnapprovedTxList() - assert.equal(typeof result, 'object') - assert.equal(result['1'].status, TRANSACTION_STATUSES.UNAPPROVED) - assert.equal(result['2'], undefined) - }) - }) + ); + const result = txStateManager.getUnapprovedTxList(); + assert.equal(typeof result, 'object'); + assert.equal(result['1'].status, TRANSACTION_STATUSES.UNAPPROVED); + assert.equal(result['2'], undefined); + }); + }); describe('#getTx', function () { it('returns a tx with the requested id', function () { @@ -644,7 +644,7 @@ describe('TransactionStateManager', function () { txParams: {}, }, noop, - ) + ); txStateManager.addTx( { id: '2', @@ -653,17 +653,17 @@ describe('TransactionStateManager', function () { txParams: {}, }, noop, - ) + ); assert.equal( txStateManager.getTx('1').status, TRANSACTION_STATUSES.UNAPPROVED, - ) + ); assert.equal( txStateManager.getTx('2').status, TRANSACTION_STATUSES.CONFIRMED, - ) - }) - }) + ); + }); + }); describe('#getFilteredTxList', function () { it('returns a tx with the requested data', function () { @@ -728,60 +728,60 @@ describe('TransactionStateManager', function () { txParams: { from: '0xbb', to: '0xaa' }, metamaskNetworkId: currentNetworkId, }, - ] - txMetas.forEach((txMeta) => txStateManager.addTx(txMeta, noop)) - let filterParams + ]; + txMetas.forEach((txMeta) => txStateManager.addTx(txMeta, noop)); + let filterParams; - filterParams = { status: TRANSACTION_STATUSES.UNAPPROVED, from: '0xaa' } + filterParams = { status: TRANSACTION_STATUSES.UNAPPROVED, from: '0xaa' }; assert.equal( txStateManager.getFilteredTxList(filterParams).length, 3, `getFilteredTxList - ${JSON.stringify(filterParams)}`, - ) - filterParams = { status: TRANSACTION_STATUSES.UNAPPROVED, to: '0xaa' } + ); + filterParams = { status: TRANSACTION_STATUSES.UNAPPROVED, to: '0xaa' }; assert.equal( txStateManager.getFilteredTxList(filterParams).length, 2, `getFilteredTxList - ${JSON.stringify(filterParams)}`, - ) - filterParams = { status: TRANSACTION_STATUSES.CONFIRMED, from: '0xbb' } + ); + filterParams = { status: TRANSACTION_STATUSES.CONFIRMED, from: '0xbb' }; assert.equal( txStateManager.getFilteredTxList(filterParams).length, 3, `getFilteredTxList - ${JSON.stringify(filterParams)}`, - ) - filterParams = { status: TRANSACTION_STATUSES.CONFIRMED } + ); + filterParams = { status: TRANSACTION_STATUSES.CONFIRMED }; assert.equal( txStateManager.getFilteredTxList(filterParams).length, 5, `getFilteredTxList - ${JSON.stringify(filterParams)}`, - ) - filterParams = { from: '0xaa' } + ); + filterParams = { from: '0xaa' }; assert.equal( txStateManager.getFilteredTxList(filterParams).length, 5, `getFilteredTxList - ${JSON.stringify(filterParams)}`, - ) - filterParams = { to: '0xaa' } + ); + filterParams = { to: '0xaa' }; assert.equal( txStateManager.getFilteredTxList(filterParams).length, 5, `getFilteredTxList - ${JSON.stringify(filterParams)}`, - ) + ); filterParams = { status: (status) => status !== TRANSACTION_STATUSES.CONFIRMED, - } + }; assert.equal( txStateManager.getFilteredTxList(filterParams).length, 5, `getFilteredTxList - ${JSON.stringify(filterParams)}`, - ) - }) - }) + ); + }); + }); describe('#wipeTransactions', function () { - const specificAddress = '0xaa' - const otherAddress = '0xbb' + const specificAddress = '0xaa'; + const otherAddress = '0xbb'; it('should remove only the transactions from a specific address', function () { const txMetas = [ @@ -803,21 +803,21 @@ describe('TransactionStateManager', function () { txParams: { from: otherAddress, to: specificAddress }, metamaskNetworkId: currentNetworkId, }, - ] - txMetas.forEach((txMeta) => txStateManager.addTx(txMeta, noop)) + ]; + txMetas.forEach((txMeta) => txStateManager.addTx(txMeta, noop)); - txStateManager.wipeTransactions(specificAddress) + txStateManager.wipeTransactions(specificAddress); const transactionsFromCurrentAddress = txStateManager .getTxList() - .filter((txMeta) => txMeta.txParams.from === specificAddress) + .filter((txMeta) => txMeta.txParams.from === specificAddress); const transactionsFromOtherAddresses = txStateManager .getTxList() - .filter((txMeta) => txMeta.txParams.from !== specificAddress) + .filter((txMeta) => txMeta.txParams.from !== specificAddress); - assert.equal(transactionsFromCurrentAddress.length, 0) - assert.equal(transactionsFromOtherAddresses.length, 2) - }) + assert.equal(transactionsFromCurrentAddress.length, 0); + assert.equal(transactionsFromOtherAddresses.length, 2); + }); it('should not remove the transactions from other networks', function () { const txMetas = [ @@ -839,44 +839,44 @@ describe('TransactionStateManager', function () { txParams: { from: specificAddress, to: otherAddress }, metamaskNetworkId: otherNetworkId, }, - ] + ]; - txMetas.forEach((txMeta) => txStateManager.addTx(txMeta, noop)) + txMetas.forEach((txMeta) => txStateManager.addTx(txMeta, noop)); - txStateManager.wipeTransactions(specificAddress) + txStateManager.wipeTransactions(specificAddress); const txsFromCurrentNetworkAndAddress = txStateManager .getTxList() - .filter((txMeta) => txMeta.txParams.from === specificAddress) + .filter((txMeta) => txMeta.txParams.from === specificAddress); const txFromOtherNetworks = txStateManager .getFullTxList() - .filter((txMeta) => txMeta.metamaskNetworkId === otherNetworkId) + .filter((txMeta) => txMeta.metamaskNetworkId === otherNetworkId); - assert.equal(txsFromCurrentNetworkAndAddress.length, 0) - assert.equal(txFromOtherNetworks.length, 2) - }) - }) + assert.equal(txsFromCurrentNetworkAndAddress.length, 0); + assert.equal(txFromOtherNetworks.length, 2); + }); + }); describe('#_removeTx', function () { it('should remove the transaction from the storage', function () { - txStateManager._saveTxList([{ id: 1 }]) - txStateManager._removeTx(1) + txStateManager._saveTxList([{ id: 1 }]); + txStateManager._removeTx(1); assert.ok( !txStateManager.getFullTxList().length, 'txList should be empty', - ) - }) + ); + }); it('should only remove the transaction with ID 1 from the storage', function () { - txStateManager._saveTxList([{ id: 1 }, { id: 2 }]) - txStateManager._removeTx(1) + txStateManager._saveTxList([{ id: 1 }, { id: 2 }]); + txStateManager._removeTx(1); assert.equal( txStateManager.getFullTxList()[0].id, 2, 'txList should have a id of 2', - ) - }) - }) + ); + }); + }); describe('#clearUnapprovedTxs', function () { it('removes unapproved transactions', function () { @@ -905,17 +905,17 @@ describe('TransactionStateManager', function () { txParams: { from: '0xaa', to: '0xbb' }, metamaskNetworkId: otherNetworkId, }, - ] + ]; - txMetas.forEach((txMeta) => txStateManager.addTx(txMeta, noop)) + txMetas.forEach((txMeta) => txStateManager.addTx(txMeta, noop)); - txStateManager.clearUnapprovedTxs() + txStateManager.clearUnapprovedTxs(); const unapprovedTxList = txStateManager .getFullTxList() - .filter((tx) => tx.status === TRANSACTION_STATUSES.UNAPPROVED) + .filter((tx) => tx.status === TRANSACTION_STATUSES.UNAPPROVED); - assert.equal(unapprovedTxList.length, 0) - }) - }) -}) + assert.equal(unapprovedTxList.length, 0); + }); + }); +}); diff --git a/test/unit/app/controllers/transactions/tx-utils-test.js b/test/unit/app/controllers/transactions/tx-utils-test.js index 77add3f627..a643d9deae 100644 --- a/test/unit/app/controllers/transactions/tx-utils-test.js +++ b/test/unit/app/controllers/transactions/tx-utils-test.js @@ -1,5 +1,5 @@ -import { strict as assert } from 'assert' -import * as txUtils from '../../../../../app/scripts/controllers/transactions/lib/util' +import { strict as assert } from 'assert'; +import * as txUtils from '../../../../../app/scripts/controllers/transactions/lib/util'; describe('txUtils', function () { describe('#validateTxParams', function () { @@ -8,47 +8,47 @@ describe('txUtils', function () { from: '0x1678a085c290ebd122dc42cba69373b5953b831d', to: '0xc42edfcc21ed14dda456aa0756c153f7985d8813', value: '0x01', - } - txUtils.validateTxParams(sample) - }) + }; + txUtils.validateTxParams(sample); + }); it('throws for invalid params value', function () { assert.throws(() => txUtils.validateTxParams(), { message: 'Invalid transaction params: must be an object.', - }) + }); assert.throws(() => txUtils.validateTxParams(null), { message: 'Invalid transaction params: must be an object.', - }) + }); assert.throws(() => txUtils.validateTxParams(true), { message: 'Invalid transaction params: must be an object.', - }) + }); assert.throws(() => txUtils.validateTxParams([]), { message: 'Invalid transaction params: must be an object.', - }) - }) + }); + }); it('throws for missing "to" and "data"', function () { const sample = { from: '0x1678a085c290ebd122dc42cba69373b5953b831d', value: '0x01', - } + }; assert.throws(() => txUtils.validateTxParams(sample), { message: 'Invalid transaction params: must specify "data" for contract deployments, or "to" (and optionally "data") for all other types of transactions.', - }) - }) + }); + }); it('throws for negative values', function () { const sample = { from: '0x1678a085c290ebd122dc42cba69373b5953b831d', to: '0xc42edfcc21ed14dda456aa0756c153f7985d8813', value: '-0x01', - } + }; assert.throws(() => txUtils.validateTxParams(sample), { message: 'Invalid transaction value "-0x01": not a positive number.', - }) - }) - }) + }); + }); + }); describe('#normalizeTxParams', function () { it('should normalize txParams', function () { @@ -58,36 +58,39 @@ describe('txUtils', function () { to: null, data: '68656c6c6f20776f726c64', random: 'hello world', - } + }; - let normalizedTxParams = txUtils.normalizeTxParams(txParams) + let normalizedTxParams = txUtils.normalizeTxParams(txParams); - assert.ok(!normalizedTxParams.chainId, 'there should be no chainId') - assert.ok(!normalizedTxParams.to, 'there should be no to address if null') + assert.ok(!normalizedTxParams.chainId, 'there should be no chainId'); + assert.ok( + !normalizedTxParams.to, + 'there should be no to address if null', + ); assert.equal( normalizedTxParams.from.slice(0, 2), '0x', 'from should be hex-prefixed', - ) + ); assert.equal( normalizedTxParams.data.slice(0, 2), '0x', 'data should be hex-prefixed', - ) + ); assert.ok( !('random' in normalizedTxParams), 'there should be no random key in normalizedTxParams', - ) + ); - txParams.to = 'a7df1beDBF813f57096dF77FCd515f0B3900e402' - normalizedTxParams = txUtils.normalizeTxParams(txParams) + txParams.to = 'a7df1beDBF813f57096dF77FCd515f0B3900e402'; + normalizedTxParams = txUtils.normalizeTxParams(txParams); assert.equal( normalizedTxParams.to.slice(0, 2), '0x', 'to should be hex-prefixed', - ) - }) - }) + ); + }); + }); describe('#validateRecipient', function () { it('removes recipient for txParams with 0x when contract data is provided', function () { @@ -95,10 +98,10 @@ describe('txUtils', function () { from: '0x1678a085c290ebd122dc42cba69373b5953b831d', to: '0x', data: 'bytecode', - } + }; const sanitizedTxParams = txUtils.validateRecipient( zeroRecipientDataTxParams, - ) + ); assert.deepEqual( sanitizedTxParams, { @@ -106,69 +109,69 @@ describe('txUtils', function () { data: 'bytecode', }, 'no recipient with 0x', - ) - }) + ); + }); it('should error when recipient is 0x', function () { const zeroRecipientTxParams = { from: '0x1678a085c290ebd122dc42cba69373b5953b831d', to: '0x', - } + }; assert.throws( () => { - txUtils.validateRecipient(zeroRecipientTxParams) + txUtils.validateRecipient(zeroRecipientTxParams); }, Error, 'Invalid recipient address', - ) - }) - }) + ); + }); + }); describe('#validateFrom', function () { it('should error when from is not a hex string', function () { // where from is undefined - const txParams = {} + const txParams = {}; assert.throws( () => { - txUtils.validateFrom(txParams) + txUtils.validateFrom(txParams); }, Error, `Invalid from address ${txParams.from} not a string`, - ) + ); // where from is array - txParams.from = [] + txParams.from = []; assert.throws( () => { - txUtils.validateFrom(txParams) + txUtils.validateFrom(txParams); }, Error, `Invalid from address ${txParams.from} not a string`, - ) + ); // where from is a object - txParams.from = {} + txParams.from = {}; assert.throws( () => { - txUtils.validateFrom(txParams) + txUtils.validateFrom(txParams); }, Error, `Invalid from address ${txParams.from} not a string`, - ) + ); // where from is a invalid address - txParams.from = 'im going to fail' + txParams.from = 'im going to fail'; assert.throws( () => { - txUtils.validateFrom(txParams) + txUtils.validateFrom(txParams); }, Error, `Invalid from address`, - ) + ); // should run - txParams.from = '0x1678a085c290ebd122dc42cba69373b5953b831d' - txUtils.validateFrom(txParams) - }) - }) -}) + txParams.from = '0x1678a085c290ebd122dc42cba69373b5953b831d'; + txUtils.validateFrom(txParams); + }); + }); +}); diff --git a/test/unit/app/fetch-with-timeout.test.js b/test/unit/app/fetch-with-timeout.test.js index dd91ff58b8..9a8aae4033 100644 --- a/test/unit/app/fetch-with-timeout.test.js +++ b/test/unit/app/fetch-with-timeout.test.js @@ -1,57 +1,61 @@ -import assert from 'assert' -import nock from 'nock' +import assert from 'assert'; +import nock from 'nock'; -import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout' +import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout'; describe('getFetchWithTimeout', function () { it('fetches a url', async function () { - nock('https://api.infura.io').get('/money').reply(200, '{"hodl": false}') + nock('https://api.infura.io').get('/money').reply(200, '{"hodl": false}'); - const fetchWithTimeout = getFetchWithTimeout(30000) + const fetchWithTimeout = getFetchWithTimeout(30000); const response = await ( await fetchWithTimeout('https://api.infura.io/money') - ).json() + ).json(); assert.deepEqual(response, { hodl: false, - }) - }) + }); + }); it('throws when the request hits a custom timeout', async function () { nock('https://api.infura.io') .get('/moon') .delay(2000) - .reply(200, '{"moon": "2012-12-21T11:11:11Z"}') + .reply(200, '{"moon": "2012-12-21T11:11:11Z"}'); - const fetchWithTimeout = getFetchWithTimeout(123) + const fetchWithTimeout = getFetchWithTimeout(123); try { - await fetchWithTimeout('https://api.infura.io/moon').then((r) => r.json()) - assert.fail('Request should throw') + await fetchWithTimeout('https://api.infura.io/moon').then((r) => + r.json(), + ); + assert.fail('Request should throw'); } catch (e) { - assert.ok(e) + assert.ok(e); } - }) + }); it('should abort the request when the custom timeout is hit', async function () { nock('https://api.infura.io') .get('/moon') .delay(2000) - .reply(200, '{"moon": "2012-12-21T11:11:11Z"}') + .reply(200, '{"moon": "2012-12-21T11:11:11Z"}'); - const fetchWithTimeout = getFetchWithTimeout(123) + const fetchWithTimeout = getFetchWithTimeout(123); try { - await fetchWithTimeout('https://api.infura.io/moon').then((r) => r.json()) - assert.fail('Request should be aborted') + await fetchWithTimeout('https://api.infura.io/moon').then((r) => + r.json(), + ); + assert.fail('Request should be aborted'); } catch (e) { - assert.deepEqual(e.message, 'Aborted') + assert.deepEqual(e.message, 'Aborted'); } - }) + }); it('throws on invalid timeout', async function () { - assert.throws(() => getFetchWithTimeout(), 'should throw') - assert.throws(() => getFetchWithTimeout(-1), 'should throw') - assert.throws(() => getFetchWithTimeout({}), 'should throw') - assert.throws(() => getFetchWithTimeout(true), 'should throw') - }) -}) + assert.throws(() => getFetchWithTimeout(), 'should throw'); + assert.throws(() => getFetchWithTimeout(-1), 'should throw'); + assert.throws(() => getFetchWithTimeout({}), 'should throw'); + assert.throws(() => getFetchWithTimeout(true), 'should throw'); + }); +}); diff --git a/test/unit/app/message-manager-test.js b/test/unit/app/message-manager-test.js index cd1769cda2..2c0589e631 100644 --- a/test/unit/app/message-manager-test.js +++ b/test/unit/app/message-manager-test.js @@ -1,21 +1,21 @@ -import assert from 'assert' -import MessageManager from '../../../app/scripts/lib/message-manager' -import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' +import assert from 'assert'; +import MessageManager from '../../../app/scripts/lib/message-manager'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; describe('Message Manager', function () { - let messageManager + let messageManager; beforeEach(function () { - messageManager = new MessageManager() - }) + messageManager = new MessageManager(); + }); describe('#getMsgList', function () { it('when new should return empty array', function () { - const result = messageManager.messages - assert.ok(Array.isArray(result)) - assert.equal(result.length, 0) - }) - }) + const result = messageManager.messages; + assert.ok(Array.isArray(result)); + assert.equal(result.length, 0); + }); + }); describe('#addMsg', function () { it('adds a Msg returned in getMsgList', function () { @@ -23,14 +23,14 @@ describe('Message Manager', function () { id: 1, status: TRANSACTION_STATUSES.APPROVED, metamaskNetworkId: 'unit test', - } - messageManager.addMsg(Msg) - const result = messageManager.messages - assert.ok(Array.isArray(result)) - assert.equal(result.length, 1) - assert.equal(result[0].id, 1) - }) - }) + }; + messageManager.addMsg(Msg); + const result = messageManager.messages; + assert.ok(Array.isArray(result)); + assert.equal(result.length, 1); + assert.equal(result[0].id, 1); + }); + }); describe('#setMsgStatusApproved', function () { it('sets the Msg status to approved', function () { @@ -38,15 +38,15 @@ describe('Message Manager', function () { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test', - } - messageManager.addMsg(Msg) - messageManager.setMsgStatusApproved(1) - const result = messageManager.messages - assert.ok(Array.isArray(result)) - assert.equal(result.length, 1) - assert.equal(result[0].status, TRANSACTION_STATUSES.APPROVED) - }) - }) + }; + messageManager.addMsg(Msg); + messageManager.setMsgStatusApproved(1); + const result = messageManager.messages; + assert.ok(Array.isArray(result)); + assert.equal(result.length, 1); + assert.equal(result[0].status, TRANSACTION_STATUSES.APPROVED); + }); + }); describe('#rejectMsg', function () { it('sets the Msg status to rejected', function () { @@ -54,15 +54,15 @@ describe('Message Manager', function () { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test', - } - messageManager.addMsg(Msg) - messageManager.rejectMsg(1) - const result = messageManager.messages - assert.ok(Array.isArray(result)) - assert.equal(result.length, 1) - assert.equal(result[0].status, TRANSACTION_STATUSES.REJECTED) - }) - }) + }; + messageManager.addMsg(Msg); + messageManager.rejectMsg(1); + const result = messageManager.messages; + assert.ok(Array.isArray(result)); + assert.equal(result.length, 1); + assert.equal(result[0].status, TRANSACTION_STATUSES.REJECTED); + }); + }); describe('#_updateMsg', function () { it('replaces the Msg with the same id', function () { @@ -70,22 +70,22 @@ describe('Message Manager', function () { id: '1', status: 'unapproved', metamaskNetworkId: 'unit test', - }) + }); messageManager.addMsg({ id: '2', status: TRANSACTION_STATUSES.APPROVED, metamaskNetworkId: 'unit test', - }) + }); messageManager._updateMsg({ id: '1', status: 'blah', hash: 'foo', metamaskNetworkId: 'unit test', - }) - const result = messageManager.getMsg('1') - assert.equal(result.hash, 'foo') - }) - }) + }); + const result = messageManager.getMsg('1'); + assert.equal(result.hash, 'foo'); + }); + }); describe('#getUnapprovedMsgs', function () { it('returns unapproved Msgs in a hash', function () { @@ -93,18 +93,18 @@ describe('Message Manager', function () { id: '1', status: 'unapproved', metamaskNetworkId: 'unit test', - }) + }); messageManager.addMsg({ id: '2', status: TRANSACTION_STATUSES.APPROVED, metamaskNetworkId: 'unit test', - }) - const result = messageManager.getUnapprovedMsgs() - assert.equal(typeof result, 'object') - assert.equal(result['1'].status, 'unapproved') - assert.equal(result['2'], undefined) - }) - }) + }); + const result = messageManager.getUnapprovedMsgs(); + assert.equal(typeof result, 'object'); + assert.equal(result['1'].status, 'unapproved'); + assert.equal(result['2'], undefined); + }); + }); describe('#getMsg', function () { it('returns a Msg with the requested id', function () { @@ -112,17 +112,17 @@ describe('Message Manager', function () { id: '1', status: 'unapproved', metamaskNetworkId: 'unit test', - }) + }); messageManager.addMsg({ id: '2', status: TRANSACTION_STATUSES.APPROVED, metamaskNetworkId: 'unit test', - }) - assert.equal(messageManager.getMsg('1').status, 'unapproved') + }); + assert.equal(messageManager.getMsg('1').status, 'unapproved'); assert.equal( messageManager.getMsg('2').status, TRANSACTION_STATUSES.APPROVED, - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/test/unit/app/nodeify-test.js b/test/unit/app/nodeify-test.js index 050553e610..2418f40bce 100644 --- a/test/unit/app/nodeify-test.js +++ b/test/unit/app/nodeify-test.js @@ -1,74 +1,74 @@ -import assert from 'assert' -import nodeify from '../../../app/scripts/lib/nodeify' +import assert from 'assert'; +import nodeify from '../../../app/scripts/lib/nodeify'; describe('nodeify', function () { const obj = { foo: 'bar', promiseFunc(a) { - const solution = this.foo + a - return Promise.resolve(solution) + const solution = this.foo + a; + return Promise.resolve(solution); }, - } + }; it('should retain original context', function (done) { - const nodified = nodeify(obj.promiseFunc, obj) + const nodified = nodeify(obj.promiseFunc, obj); nodified('baz', (err, res) => { if (!err) { - assert.equal(res, 'barbaz') - done() - return + assert.equal(res, 'barbaz'); + done(); + return; } - done(new Error(err.toString())) - }) - }) + done(new Error(err.toString())); + }); + }); it('no callback - should allow the last argument to not be a function', function (done) { - const nodified = nodeify(obj.promiseFunc, obj) + const nodified = nodeify(obj.promiseFunc, obj); try { - nodified('baz') - done() + nodified('baz'); + done(); } catch (err) { done( new Error( 'should not have thrown if the last argument is not a function', ), - ) + ); } - }) + }); it('sync functions - returns value', function (done) { - const nodified = nodeify(() => 42) + const nodified = nodeify(() => 42); try { nodified((err, result) => { if (err) { - done(new Error(`should not have thrown any error: ${err.message}`)) - return + done(new Error(`should not have thrown any error: ${err.message}`)); + return; } - assert.equal(42, result, 'got expected result') - }) - done() + assert.equal(42, result, 'got expected result'); + }); + done(); } catch (err) { - done(new Error(`should not have thrown any error: ${err.message}`)) + done(new Error(`should not have thrown any error: ${err.message}`)); } - }) + }); it('sync functions - handles errors', function (done) { const nodified = nodeify(() => { - throw new Error('boom!') - }) + throw new Error('boom!'); + }); try { nodified((err, result) => { if (result) { - done(new Error('should not have returned any result')) - return + done(new Error('should not have returned any result')); + return; } - assert.ok(err, 'got expected error') - assert.ok(err.message.includes('boom!'), 'got expected error message') - }) - done() + assert.ok(err, 'got expected error'); + assert.ok(err.message.includes('boom!'), 'got expected error message'); + }); + done(); } catch (err) { - done(new Error(`should not have thrown any error: ${err.message}`)) + done(new Error(`should not have thrown any error: ${err.message}`)); } - }) -}) + }); +}); diff --git a/test/unit/app/personal-message-manager-test.js b/test/unit/app/personal-message-manager-test.js index fd1aa91640..15035a111f 100644 --- a/test/unit/app/personal-message-manager-test.js +++ b/test/unit/app/personal-message-manager-test.js @@ -1,21 +1,21 @@ -import assert from 'assert' -import PersonalMessageManager from '../../../app/scripts/lib/personal-message-manager' -import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' +import assert from 'assert'; +import PersonalMessageManager from '../../../app/scripts/lib/personal-message-manager'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; describe('Personal Message Manager', function () { - let messageManager + let messageManager; beforeEach(function () { - messageManager = new PersonalMessageManager() - }) + messageManager = new PersonalMessageManager(); + }); describe('#getMsgList', function () { it('when new should return empty array', function () { - const result = messageManager.messages - assert.ok(Array.isArray(result)) - assert.equal(result.length, 0) - }) - }) + const result = messageManager.messages; + assert.ok(Array.isArray(result)); + assert.equal(result.length, 0); + }); + }); describe('#addMsg', function () { it('adds a Msg returned in getMsgList', function () { @@ -23,14 +23,14 @@ describe('Personal Message Manager', function () { id: 1, status: TRANSACTION_STATUSES.APPROVED, metamaskNetworkId: 'unit test', - } - messageManager.addMsg(Msg) - const result = messageManager.messages - assert.ok(Array.isArray(result)) - assert.equal(result.length, 1) - assert.equal(result[0].id, 1) - }) - }) + }; + messageManager.addMsg(Msg); + const result = messageManager.messages; + assert.ok(Array.isArray(result)); + assert.equal(result.length, 1); + assert.equal(result[0].id, 1); + }); + }); describe('#setMsgStatusApproved', function () { it('sets the Msg status to approved', function () { @@ -38,15 +38,15 @@ describe('Personal Message Manager', function () { id: 1, status: TRANSACTION_STATUSES.UNAPPROVED, metamaskNetworkId: 'unit test', - } - messageManager.addMsg(Msg) - messageManager.setMsgStatusApproved(1) - const result = messageManager.messages - assert.ok(Array.isArray(result)) - assert.equal(result.length, 1) - assert.equal(result[0].status, TRANSACTION_STATUSES.APPROVED) - }) - }) + }; + messageManager.addMsg(Msg); + messageManager.setMsgStatusApproved(1); + const result = messageManager.messages; + assert.ok(Array.isArray(result)); + assert.equal(result.length, 1); + assert.equal(result[0].status, TRANSACTION_STATUSES.APPROVED); + }); + }); describe('#rejectMsg', function () { it('sets the Msg status to rejected', function () { @@ -54,15 +54,15 @@ describe('Personal Message Manager', function () { id: 1, status: TRANSACTION_STATUSES.UNAPPROVED, metamaskNetworkId: 'unit test', - } - messageManager.addMsg(Msg) - messageManager.rejectMsg(1) - const result = messageManager.messages - assert.ok(Array.isArray(result)) - assert.equal(result.length, 1) - assert.equal(result[0].status, TRANSACTION_STATUSES.REJECTED) - }) - }) + }; + messageManager.addMsg(Msg); + messageManager.rejectMsg(1); + const result = messageManager.messages; + assert.ok(Array.isArray(result)); + assert.equal(result.length, 1); + assert.equal(result[0].status, TRANSACTION_STATUSES.REJECTED); + }); + }); describe('#_updateMsg', function () { it('replaces the Msg with the same id', function () { @@ -70,22 +70,22 @@ describe('Personal Message Manager', function () { id: '1', status: TRANSACTION_STATUSES.UNAPPROVED, metamaskNetworkId: 'unit test', - }) + }); messageManager.addMsg({ id: '2', status: TRANSACTION_STATUSES.APPROVED, metamaskNetworkId: 'unit test', - }) + }); messageManager._updateMsg({ id: '1', status: 'blah', hash: 'foo', metamaskNetworkId: 'unit test', - }) - const result = messageManager.getMsg('1') - assert.equal(result.hash, 'foo') - }) - }) + }); + const result = messageManager.getMsg('1'); + assert.equal(result.hash, 'foo'); + }); + }); describe('#getUnapprovedMsgs', function () { it('returns unapproved Msgs in a hash', function () { @@ -93,18 +93,18 @@ describe('Personal Message Manager', function () { id: '1', status: TRANSACTION_STATUSES.UNAPPROVED, metamaskNetworkId: 'unit test', - }) + }); messageManager.addMsg({ id: '2', status: TRANSACTION_STATUSES.APPROVED, metamaskNetworkId: 'unit test', - }) - const result = messageManager.getUnapprovedMsgs() - assert.equal(typeof result, 'object') - assert.equal(result['1'].status, TRANSACTION_STATUSES.UNAPPROVED) - assert.equal(result['2'], undefined) - }) - }) + }); + const result = messageManager.getUnapprovedMsgs(); + assert.equal(typeof result, 'object'); + assert.equal(result['1'].status, TRANSACTION_STATUSES.UNAPPROVED); + assert.equal(result['2'], undefined); + }); + }); describe('#getMsg', function () { it('returns a Msg with the requested id', function () { @@ -112,40 +112,40 @@ describe('Personal Message Manager', function () { id: '1', status: TRANSACTION_STATUSES.UNAPPROVED, metamaskNetworkId: 'unit test', - }) + }); messageManager.addMsg({ id: '2', status: TRANSACTION_STATUSES.APPROVED, metamaskNetworkId: 'unit test', - }) + }); assert.equal( messageManager.getMsg('1').status, TRANSACTION_STATUSES.UNAPPROVED, - ) + ); assert.equal( messageManager.getMsg('2').status, TRANSACTION_STATUSES.APPROVED, - ) - }) - }) + ); + }); + }); describe('#normalizeMsgData', function () { it('converts text to a utf8 hex string', function () { - const input = 'hello' - const output = messageManager.normalizeMsgData(input) - assert.equal(output, '0x68656c6c6f', 'predictably hex encoded') - }) + const input = 'hello'; + const output = messageManager.normalizeMsgData(input); + assert.equal(output, '0x68656c6c6f', 'predictably hex encoded'); + }); it('tolerates a hex prefix', function () { - const input = '0x12' - const output = messageManager.normalizeMsgData(input) - assert.equal(output, '0x12', 'un modified') - }) + const input = '0x12'; + const output = messageManager.normalizeMsgData(input); + assert.equal(output, '0x12', 'un modified'); + }); it('tolerates normal hex', function () { - const input = '12' - const output = messageManager.normalizeMsgData(input) - assert.equal(output, '0x12', 'adds prefix') - }) - }) -}) + const input = '12'; + const output = messageManager.normalizeMsgData(input); + assert.equal(output, '0x12', 'adds prefix'); + }); + }); +}); diff --git a/test/unit/app/seed-phrase-verifier-test.js b/test/unit/app/seed-phrase-verifier-test.js index 9f569c556b..650f97eb3d 100644 --- a/test/unit/app/seed-phrase-verifier-test.js +++ b/test/unit/app/seed-phrase-verifier-test.js @@ -1,129 +1,129 @@ -import assert from 'assert' -import { cloneDeep } from 'lodash' -import KeyringController from 'eth-keyring-controller' -import firstTimeState from '../../../app/scripts/first-time-state' -import seedPhraseVerifier from '../../../app/scripts/lib/seed-phrase-verifier' -import mockEncryptor from '../../lib/mock-encryptor' +import assert from 'assert'; +import { cloneDeep } from 'lodash'; +import KeyringController from 'eth-keyring-controller'; +import firstTimeState from '../../../app/scripts/first-time-state'; +import seedPhraseVerifier from '../../../app/scripts/lib/seed-phrase-verifier'; +import mockEncryptor from '../../lib/mock-encryptor'; describe('SeedPhraseVerifier', function () { describe('verifyAccounts', function () { - const password = 'passw0rd1' - const hdKeyTree = 'HD Key Tree' + const password = 'passw0rd1'; + const hdKeyTree = 'HD Key Tree'; - let keyringController - let primaryKeyring + let keyringController; + let primaryKeyring; beforeEach(async function () { keyringController = new KeyringController({ initState: cloneDeep(firstTimeState), encryptor: mockEncryptor, - }) + }); - assert(keyringController) + assert(keyringController); - await keyringController.createNewVaultAndKeychain(password) - primaryKeyring = keyringController.getKeyringsByType(hdKeyTree)[0] - }) + await keyringController.createNewVaultAndKeychain(password); + primaryKeyring = keyringController.getKeyringsByType(hdKeyTree)[0]; + }); it('should be able to verify created account with seed words', async function () { - const createdAccounts = await primaryKeyring.getAccounts() - assert.equal(createdAccounts.length, 1) + const createdAccounts = await primaryKeyring.getAccounts(); + assert.equal(createdAccounts.length, 1); - const serialized = await primaryKeyring.serialize() - const seedWords = serialized.mnemonic - assert.notEqual(seedWords.length, 0) + const serialized = await primaryKeyring.serialize(); + const seedWords = serialized.mnemonic; + assert.notEqual(seedWords.length, 0); - await seedPhraseVerifier.verifyAccounts(createdAccounts, seedWords) - }) + await seedPhraseVerifier.verifyAccounts(createdAccounts, seedWords); + }); it('should be able to verify created account (upper case) with seed words', async function () { - const createdAccounts = await primaryKeyring.getAccounts() - assert.equal(createdAccounts.length, 1) + const createdAccounts = await primaryKeyring.getAccounts(); + assert.equal(createdAccounts.length, 1); - const upperCaseAccounts = [createdAccounts[0].toUpperCase()] + const upperCaseAccounts = [createdAccounts[0].toUpperCase()]; - const serialized = await primaryKeyring.serialize() - const seedWords = serialized.mnemonic - assert.notEqual(seedWords.length, 0) + const serialized = await primaryKeyring.serialize(); + const seedWords = serialized.mnemonic; + assert.notEqual(seedWords.length, 0); - await seedPhraseVerifier.verifyAccounts(upperCaseAccounts, seedWords) - }) + await seedPhraseVerifier.verifyAccounts(upperCaseAccounts, seedWords); + }); it('should be able to verify created account (lower case) with seed words', async function () { - const createdAccounts = await primaryKeyring.getAccounts() - assert.equal(createdAccounts.length, 1) - const lowerCaseAccounts = [createdAccounts[0].toLowerCase()] + const createdAccounts = await primaryKeyring.getAccounts(); + assert.equal(createdAccounts.length, 1); + const lowerCaseAccounts = [createdAccounts[0].toLowerCase()]; - const serialized = await primaryKeyring.serialize() - const seedWords = serialized.mnemonic - assert.notEqual(seedWords.length, 0) + const serialized = await primaryKeyring.serialize(); + const seedWords = serialized.mnemonic; + assert.notEqual(seedWords.length, 0); - await seedPhraseVerifier.verifyAccounts(lowerCaseAccounts, seedWords) - }) + await seedPhraseVerifier.verifyAccounts(lowerCaseAccounts, seedWords); + }); it('should return error with good but different seed words', async function () { - const createdAccounts = await primaryKeyring.getAccounts() - assert.equal(createdAccounts.length, 1) + const createdAccounts = await primaryKeyring.getAccounts(); + assert.equal(createdAccounts.length, 1); - await primaryKeyring.serialize() + await primaryKeyring.serialize(); const seedWords = - 'debris dizzy just program just float decrease vacant alarm reduce speak stadium' + 'debris dizzy just program just float decrease vacant alarm reduce speak stadium'; try { - await seedPhraseVerifier.verifyAccounts(createdAccounts, seedWords) - assert.fail('Should reject') + await seedPhraseVerifier.verifyAccounts(createdAccounts, seedWords); + assert.fail('Should reject'); } catch (err) { assert.ok( err.message.indexOf('Not identical accounts!') >= 0, 'Wrong error message', - ) + ); } - }) + }); it('should return error with undefined existing accounts', async function () { - const createdAccounts = await primaryKeyring.getAccounts() - assert.equal(createdAccounts.length, 1) + const createdAccounts = await primaryKeyring.getAccounts(); + assert.equal(createdAccounts.length, 1); - await primaryKeyring.serialize() + await primaryKeyring.serialize(); const seedWords = - 'debris dizzy just program just float decrease vacant alarm reduce speak stadium' + 'debris dizzy just program just float decrease vacant alarm reduce speak stadium'; try { - await seedPhraseVerifier.verifyAccounts(undefined, seedWords) - assert.fail('Should reject') + await seedPhraseVerifier.verifyAccounts(undefined, seedWords); + assert.fail('Should reject'); } catch (err) { - assert.equal(err.message, 'No created accounts defined.') + assert.equal(err.message, 'No created accounts defined.'); } - }) + }); it('should return error with empty accounts array', async function () { - const createdAccounts = await primaryKeyring.getAccounts() - assert.equal(createdAccounts.length, 1) + const createdAccounts = await primaryKeyring.getAccounts(); + assert.equal(createdAccounts.length, 1); - await primaryKeyring.serialize() + await primaryKeyring.serialize(); const seedWords = - 'debris dizzy just program just float decrease vacant alarm reduce speak stadium' + 'debris dizzy just program just float decrease vacant alarm reduce speak stadium'; try { - await seedPhraseVerifier.verifyAccounts([], seedWords) - assert.fail('Should reject') + await seedPhraseVerifier.verifyAccounts([], seedWords); + assert.fail('Should reject'); } catch (err) { - assert.equal(err.message, 'No created accounts defined.') + assert.equal(err.message, 'No created accounts defined.'); } - }) + }); it('should be able to verify more than one created account with seed words', async function () { - await keyringController.addNewAccount(primaryKeyring) - await keyringController.addNewAccount(primaryKeyring) + await keyringController.addNewAccount(primaryKeyring); + await keyringController.addNewAccount(primaryKeyring); - const createdAccounts = await primaryKeyring.getAccounts() - assert.equal(createdAccounts.length, 3) + const createdAccounts = await primaryKeyring.getAccounts(); + assert.equal(createdAccounts.length, 3); - const serialized = await primaryKeyring.serialize() - const seedWords = serialized.mnemonic - assert.notEqual(seedWords.length, 0) + const serialized = await primaryKeyring.serialize(); + const seedWords = serialized.mnemonic; + assert.notEqual(seedWords.length, 0); - await seedPhraseVerifier.verifyAccounts(createdAccounts, seedWords) - }) - }) -}) + await seedPhraseVerifier.verifyAccounts(createdAccounts, seedWords); + }); + }); +}); diff --git a/test/unit/app/typed-message-manager.spec.js b/test/unit/app/typed-message-manager.spec.js index b396b0c22c..5d7333688a 100644 --- a/test/unit/app/typed-message-manager.spec.js +++ b/test/unit/app/typed-message-manager.spec.js @@ -1,7 +1,7 @@ -import assert from 'assert' -import sinon from 'sinon' -import TypedMessageManager from '../../../app/scripts/lib/typed-message-manager' -import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' +import assert from 'assert'; +import sinon from 'sinon'; +import TypedMessageManager from '../../../app/scripts/lib/typed-message-manager'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; describe('Typed Message Manager', function () { let typedMessageManager, @@ -10,14 +10,14 @@ describe('Typed Message Manager', function () { typedMsgs, messages, msgId, - numberMsgId + numberMsgId; - const address = '0xc42edfcc21ed14dda456aa0756c153f7985d8813' + const address = '0xc42edfcc21ed14dda456aa0756c153f7985d8813'; beforeEach(async function () { typedMessageManager = new TypedMessageManager({ getCurrentChainId: sinon.fake.returns('0x1'), - }) + }); msgParamsV1 = { from: address, @@ -29,7 +29,7 @@ describe('Typed Message Manager', function () { value: '$$$', }, ], - } + }; msgParamsV3 = { from: address, @@ -70,54 +70,57 @@ describe('Typed Message Manager', function () { contents: 'Hello, Bob!', }, }), - } + }; - await typedMessageManager.addUnapprovedMessage(msgParamsV3, null, 'V3') - typedMsgs = typedMessageManager.getUnapprovedMsgs() - messages = typedMessageManager.messages - msgId = Object.keys(typedMsgs)[0] - messages[0].msgParams.metamaskId = parseInt(msgId, 10) - numberMsgId = parseInt(msgId, 10) - }) + await typedMessageManager.addUnapprovedMessage(msgParamsV3, null, 'V3'); + typedMsgs = typedMessageManager.getUnapprovedMsgs(); + messages = typedMessageManager.messages; + msgId = Object.keys(typedMsgs)[0]; + messages[0].msgParams.metamaskId = parseInt(msgId, 10); + numberMsgId = parseInt(msgId, 10); + }); it('supports version 1 of signedTypedData', function () { - typedMessageManager.addUnapprovedMessage(msgParamsV1, null, 'V1') - assert.equal(messages[messages.length - 1].msgParams.data, msgParamsV1.data) - }) + typedMessageManager.addUnapprovedMessage(msgParamsV1, null, 'V1'); + assert.equal( + messages[messages.length - 1].msgParams.data, + msgParamsV1.data, + ); + }); it('has params address', function () { - assert.equal(typedMsgs[msgId].msgParams.from, address) - }) + assert.equal(typedMsgs[msgId].msgParams.from, address); + }); it('adds to unapproved messages and sets status to unapproved', function () { - assert.equal(typedMsgs[msgId].status, TRANSACTION_STATUSES.UNAPPROVED) - }) + assert.equal(typedMsgs[msgId].status, TRANSACTION_STATUSES.UNAPPROVED); + }); it('validates params', function () { assert.doesNotThrow(() => { - typedMessageManager.validateParams(messages[0].msgParams) - }, 'Does not throw with valid parameters') - }) + typedMessageManager.validateParams(messages[0].msgParams); + }, 'Does not throw with valid parameters'); + }); it('gets unapproved by id', function () { - const getMsg = typedMessageManager.getMsg(numberMsgId) - assert.equal(getMsg.id, numberMsgId) - }) + const getMsg = typedMessageManager.getMsg(numberMsgId); + assert.equal(getMsg.id, numberMsgId); + }); it('approves messages', async function () { - const messageMetaMaskId = messages[0].msgParams - typedMessageManager.approveMessage(messageMetaMaskId) - assert.equal(messages[0].status, TRANSACTION_STATUSES.APPROVED) - }) + const messageMetaMaskId = messages[0].msgParams; + typedMessageManager.approveMessage(messageMetaMaskId); + assert.equal(messages[0].status, TRANSACTION_STATUSES.APPROVED); + }); it('sets msg status to signed and adds a raw sig to message details', function () { - typedMessageManager.setMsgStatusSigned(numberMsgId, 'raw sig') - assert.equal(messages[0].status, TRANSACTION_STATUSES.SIGNED) - assert.equal(messages[0].rawSig, 'raw sig') - }) + typedMessageManager.setMsgStatusSigned(numberMsgId, 'raw sig'); + assert.equal(messages[0].status, TRANSACTION_STATUSES.SIGNED); + assert.equal(messages[0].rawSig, 'raw sig'); + }); it('rejects message', function () { - typedMessageManager.rejectMsg(numberMsgId) - assert.equal(messages[0].status, TRANSACTION_STATUSES.REJECTED) - }) -}) + typedMessageManager.rejectMsg(numberMsgId); + assert.equal(messages[0].status, TRANSACTION_STATUSES.REJECTED); + }); +}); diff --git a/test/unit/app/util-test.js b/test/unit/app/util-test.js index ca58f11189..a6d2783f1c 100644 --- a/test/unit/app/util-test.js +++ b/test/unit/app/util-test.js @@ -1,75 +1,75 @@ -import { strict as assert } from 'assert' +import { strict as assert } from 'assert'; import { getEnvironmentType, sufficientBalance, -} from '../../../app/scripts/lib/util' -import { isPrefixedFormattedHexString } from '../../../shared/modules/utils' +} from '../../../app/scripts/lib/util'; +import { isPrefixedFormattedHexString } from '../../../shared/modules/utils'; import { ENVIRONMENT_TYPE_POPUP, ENVIRONMENT_TYPE_NOTIFICATION, ENVIRONMENT_TYPE_FULLSCREEN, ENVIRONMENT_TYPE_BACKGROUND, -} from '../../../shared/constants/app' +} from '../../../shared/constants/app'; describe('app utils', function () { describe('getEnvironmentType', function () { it('should return popup type', function () { const environmentType = getEnvironmentType( 'http://extension-id/popup.html', - ) - assert.equal(environmentType, ENVIRONMENT_TYPE_POPUP) - }) + ); + assert.equal(environmentType, ENVIRONMENT_TYPE_POPUP); + }); it('should return notification type', function () { const environmentType = getEnvironmentType( 'http://extension-id/notification.html', - ) - assert.equal(environmentType, ENVIRONMENT_TYPE_NOTIFICATION) - }) + ); + assert.equal(environmentType, ENVIRONMENT_TYPE_NOTIFICATION); + }); it('should return fullscreen type for home.html', function () { const environmentType = getEnvironmentType( 'http://extension-id/home.html', - ) - assert.equal(environmentType, ENVIRONMENT_TYPE_FULLSCREEN) - }) + ); + assert.equal(environmentType, ENVIRONMENT_TYPE_FULLSCREEN); + }); it('should return fullscreen type for phishing.html', function () { const environmentType = getEnvironmentType( 'http://extension-id/phishing.html', - ) - assert.equal(environmentType, ENVIRONMENT_TYPE_FULLSCREEN) - }) + ); + assert.equal(environmentType, ENVIRONMENT_TYPE_FULLSCREEN); + }); it('should return background type', function () { const environmentType = getEnvironmentType( 'http://extension-id/_generated_background_page.html', - ) - assert.equal(environmentType, ENVIRONMENT_TYPE_BACKGROUND) - }) + ); + assert.equal(environmentType, ENVIRONMENT_TYPE_BACKGROUND); + }); it('should return the correct type for a URL with a hash fragment', function () { const environmentType = getEnvironmentType( 'http://extension-id/popup.html#hash', - ) - assert.equal(environmentType, ENVIRONMENT_TYPE_POPUP) - }) + ); + assert.equal(environmentType, ENVIRONMENT_TYPE_POPUP); + }); it('should return the correct type for a URL with query parameters', function () { const environmentType = getEnvironmentType( 'http://extension-id/popup.html?param=foo', - ) - assert.equal(environmentType, ENVIRONMENT_TYPE_POPUP) - }) + ); + assert.equal(environmentType, ENVIRONMENT_TYPE_POPUP); + }); it('should return the correct type for a URL with query parameters and a hash fragment', function () { const environmentType = getEnvironmentType( 'http://extension-id/popup.html?param=foo#hash', - ) - assert.equal(environmentType, ENVIRONMENT_TYPE_POPUP) - }) - }) + ); + assert.equal(environmentType, ENVIRONMENT_TYPE_POPUP); + }); + }); describe('SufficientBalance', function () { it('returns true if max tx cost is equal to balance.', function () { @@ -77,37 +77,37 @@ describe('app utils', function () { value: '0x1', gas: '0x2', gasPrice: '0x3', - } - const balance = '0x8' + }; + const balance = '0x8'; - const result = sufficientBalance(tx, balance) - assert.ok(result, 'sufficient balance found.') - }) + const result = sufficientBalance(tx, balance); + assert.ok(result, 'sufficient balance found.'); + }); it('returns true if max tx cost is less than balance.', function () { const tx = { value: '0x1', gas: '0x2', gasPrice: '0x3', - } - const balance = '0x9' + }; + const balance = '0x9'; - const result = sufficientBalance(tx, balance) - assert.ok(result, 'sufficient balance found.') - }) + const result = sufficientBalance(tx, balance); + assert.ok(result, 'sufficient balance found.'); + }); it('returns false if max tx cost is more than balance.', function () { const tx = { value: '0x1', gas: '0x2', gasPrice: '0x3', - } - const balance = '0x6' + }; + const balance = '0x6'; - const result = sufficientBalance(tx, balance) - assert.ok(!result, 'insufficient balance found.') - }) - }) + const result = sufficientBalance(tx, balance); + assert.ok(!result, 'insufficient balance found.'); + }); + }); describe('isPrefixedFormattedHexString', function () { it('should return true for valid hex strings', function () { @@ -115,77 +115,81 @@ describe('app utils', function () { isPrefixedFormattedHexString('0x1'), true, 'should return true', - ) + ); assert.equal( isPrefixedFormattedHexString('0xa'), true, 'should return true', - ) + ); assert.equal( isPrefixedFormattedHexString('0xabcd1123fae909aad87452'), true, 'should return true', - ) - }) + ); + }); it('should return false for invalid hex strings', function () { assert.equal( isPrefixedFormattedHexString('0x'), false, 'should return false', - ) + ); assert.equal( isPrefixedFormattedHexString('0x0'), false, 'should return false', - ) + ); assert.equal( isPrefixedFormattedHexString('0x01'), false, 'should return false', - ) + ); assert.equal( isPrefixedFormattedHexString(' 0x1'), false, 'should return false', - ) + ); assert.equal( isPrefixedFormattedHexString('0x1 '), false, 'should return false', - ) + ); assert.equal( isPrefixedFormattedHexString('0x1afz'), false, 'should return false', - ) + ); assert.equal( isPrefixedFormattedHexString('z'), false, 'should return false', - ) + ); assert.equal( isPrefixedFormattedHexString(2), false, 'should return false', - ) + ); assert.equal( isPrefixedFormattedHexString(['0x1']), false, 'should return false', - ) + ); - assert.equal(isPrefixedFormattedHexString(), false, 'should return false') - }) - }) -}) + assert.equal( + isPrefixedFormattedHexString(), + false, + 'should return false', + ); + }); + }); +}); diff --git a/test/unit/balance-formatter-test.js b/test/unit/balance-formatter-test.js index 74df60faac..cd63ee68ff 100644 --- a/test/unit/balance-formatter-test.js +++ b/test/unit/balance-formatter-test.js @@ -1,27 +1,27 @@ -import assert from 'assert' -import currencyFormatter from 'currency-formatter' -import availableCurrencies from '../../ui/app/helpers/constants/available-conversions.json' +import assert from 'assert'; +import currencyFormatter from 'currency-formatter'; +import availableCurrencies from '../../ui/app/helpers/constants/available-conversions.json'; describe('currencyFormatting', function () { it('be able to format any infura currency', function (done) { - const number = 10000 + const number = 10000; availableCurrencies.forEach((conversion) => { - const code = conversion.code.toUpperCase() - const result = currencyFormatter.format(number, { code }) + const code = conversion.code.toUpperCase(); + const result = currencyFormatter.format(number, { code }); switch (code) { case 'USD': - assert.equal(result, '$10,000.00') - break + assert.equal(result, '$10,000.00'); + break; case 'JPY': - assert.equal(result, '¥10,000') - break + assert.equal(result, '¥10,000'); + break; default: - assert.ok(result, `Currency ${code} formatted as ${result}`) + assert.ok(result, `Currency ${code} formatted as ${result}`); } - }) + }); - done() - }) -}) + done(); + }); +}); diff --git a/test/unit/lib/account-link.test.js b/test/unit/lib/account-link.test.js index 8ba9404e4d..a8a25ee31d 100644 --- a/test/unit/lib/account-link.test.js +++ b/test/unit/lib/account-link.test.js @@ -1,5 +1,5 @@ -import assert from 'assert' -import getAccountLink from '../../../ui/lib/account-link' +import assert from 'assert'; +import getAccountLink from '../../../ui/lib/account-link'; describe('Account link', function () { describe('getAccountLink', function () { @@ -34,11 +34,11 @@ describe('Account link', function () { blockExplorerUrl: 'https://another.block.explorer/', }, }, - ] + ]; tests.forEach(({ expected, address, network, rpcPrefs }) => { - assert.equal(getAccountLink(address, network, rpcPrefs), expected) - }) - }) - }) -}) + assert.equal(getAccountLink(address, network, rpcPrefs), expected); + }); + }); + }); +}); diff --git a/test/unit/localhostState.js b/test/unit/localhostState.js index 069ac0b78a..b758b9120d 100644 --- a/test/unit/localhostState.js +++ b/test/unit/localhostState.js @@ -1,4 +1,4 @@ -import { NETWORK_TYPE_RPC } from '../../shared/constants/network' +import { NETWORK_TYPE_RPC } from '../../shared/constants/network'; /** * @typedef {Object} FirstTimeState @@ -18,6 +18,6 @@ const initialState = { chainId: '0x539', }, }, -} +}; -export default initialState +export default initialState; diff --git a/test/unit/migrations/021-test.js b/test/unit/migrations/021-test.js index 028e0e99d3..d17615713c 100644 --- a/test/unit/migrations/021-test.js +++ b/test/unit/migrations/021-test.js @@ -1,17 +1,17 @@ -import assert from 'assert' -import wallet2 from '../../lib/migrations/002.json' -import migration21 from '../../../app/scripts/migrations/021' +import assert from 'assert'; +import wallet2 from '../../lib/migrations/002.json'; +import migration21 from '../../../app/scripts/migrations/021'; describe('wallet2 is migrated successfully with out the BlacklistController', function () { it('should delete BlacklistController key', function (done) { migration21 .migrate(wallet2) .then((migratedData) => { - assert.equal(migratedData.meta.version, 21) - assert(!migratedData.data.BlacklistController) - assert(!migratedData.data.RecentBlocks) - done() + assert.equal(migratedData.meta.version, 21); + assert(!migratedData.data.BlacklistController); + assert(!migratedData.data.RecentBlocks); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/migrations/022-test.js b/test/unit/migrations/022-test.js index 347edf99a5..537a2ba419 100644 --- a/test/unit/migrations/022-test.js +++ b/test/unit/migrations/022-test.js @@ -1,8 +1,8 @@ -import assert from 'assert' -import migration22 from '../../../app/scripts/migrations/022' -import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' +import assert from 'assert'; +import migration22 from '../../../app/scripts/migrations/022'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; -const properTime = new Date().getTime() +const properTime = new Date().getTime(); const storage = { meta: {}, data: { @@ -14,7 +14,7 @@ const storage = { ], }, }, -} +}; describe('storage is migrated successfully where transactions that are submitted have submittedTimes', function () { it('should add submittedTime key on the txMeta if appropriate', function (done) { @@ -25,16 +25,16 @@ describe('storage is migrated successfully where transactions that are submitted txMeta1, txMeta2, txMeta3, - ] = migratedData.data.TransactionController.transactions - assert.equal(migratedData.meta.version, 22) + ] = migratedData.data.TransactionController.transactions; + assert.equal(migratedData.meta.version, 22); // should have written a submitted time - assert(txMeta1.submittedTime) + assert(txMeta1.submittedTime); // should not have written a submitted time because it already has one - assert.equal(txMeta2.submittedTime, properTime) + assert.equal(txMeta2.submittedTime, properTime); // should not have written a submitted time - assert(!txMeta3.submittedTime) - done() + assert(!txMeta3.submittedTime); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/migrations/023-test.js b/test/unit/migrations/023-test.js index a0cc09f307..d1eb7109bc 100644 --- a/test/unit/migrations/023-test.js +++ b/test/unit/migrations/023-test.js @@ -1,6 +1,6 @@ -import assert from 'assert' -import migration23 from '../../../app/scripts/migrations/023' -import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' +import assert from 'assert'; +import migration23 from '../../../app/scripts/migrations/023'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; const storage = { meta: {}, @@ -9,107 +9,110 @@ const storage = { transactions: [], }, }, -} +}; -const transactions = [] -const transactions40 = [] -const transactions20 = [] +const transactions = []; +const transactions40 = []; +const transactions20 = []; -const txStates = Object.values(TRANSACTION_STATUSES) +const txStates = Object.values(TRANSACTION_STATUSES); const deletableTxStates = [ TRANSACTION_STATUSES.CONFIRMED, TRANSACTION_STATUSES.REJECTED, TRANSACTION_STATUSES.FAILED, TRANSACTION_STATUSES.DROPPED, -] +]; -let nonDeletableCount = 0 +let nonDeletableCount = 0; -let status +let status; while (transactions.length <= 100) { - status = txStates[Math.floor(Math.random() * Math.floor(txStates.length - 1))] + status = + txStates[Math.floor(Math.random() * Math.floor(txStates.length - 1))]; // This is an old migration, let's allow it // eslint-disable-next-line no-loop-func if (!deletableTxStates.find((s) => s === status)) { - nonDeletableCount += 1 + nonDeletableCount += 1; } - transactions.push({ status }) + transactions.push({ status }); } while (transactions40.length < 40) { - status = txStates[Math.floor(Math.random() * Math.floor(txStates.length - 1))] - transactions40.push({ status }) + status = + txStates[Math.floor(Math.random() * Math.floor(txStates.length - 1))]; + transactions40.push({ status }); } while (transactions20.length < 20) { - status = txStates[Math.floor(Math.random() * Math.floor(txStates.length - 1))] - transactions20.push({ status }) + status = + txStates[Math.floor(Math.random() * Math.floor(txStates.length - 1))]; + transactions20.push({ status }); } -storage.data.TransactionController.transactions = transactions +storage.data.TransactionController.transactions = transactions; describe('storage is migrated successfully and the proper transactions are remove from state', function () { it('should remove transactions that are unneeded', function (done) { migration23 .migrate(storage) .then((migratedData) => { - let leftoverNonDeletableTxCount = 0 + let leftoverNonDeletableTxCount = 0; const migratedTransactions = - migratedData.data.TransactionController.transactions + migratedData.data.TransactionController.transactions; migratedTransactions.forEach((tx) => { if (!deletableTxStates.find((s) => s === tx.status)) { - leftoverNonDeletableTxCount += 1 + leftoverNonDeletableTxCount += 1; } - }) + }); assert.equal( leftoverNonDeletableTxCount, nonDeletableCount, "migration shouldn't delete transactions we want to keep", - ) + ); assert( migratedTransactions.length >= 40, `should be equal or greater to 40 if they are non deletable states got ${migratedTransactions.length} transactions`, - ) - done() + ); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should not remove any transactions because 40 is the expected limit', function (done) { - storage.meta.version = 22 - storage.data.TransactionController.transactions = transactions40 + storage.meta.version = 22; + storage.data.TransactionController.transactions = transactions40; migration23 .migrate(storage) .then((migratedData) => { const migratedTransactions = - migratedData.data.TransactionController.transactions + migratedData.data.TransactionController.transactions; assert.equal( migratedTransactions.length, 40, "migration shouldn't delete when at limit", - ) - done() + ); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should not remove any transactions because 20 txs is under the expected limit', function (done) { - storage.meta.version = 22 - storage.data.TransactionController.transactions = transactions20 + storage.meta.version = 22; + storage.data.TransactionController.transactions = transactions20; migration23 .migrate(storage) .then((migratedData) => { const migratedTransactions = - migratedData.data.TransactionController.transactions + migratedData.data.TransactionController.transactions; assert.equal( migratedTransactions.length, 20, "migration shouldn't delete when under limit", - ) - done() + ); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/migrations/024-test.js b/test/unit/migrations/024-test.js index b753c4d06e..a90729c5d5 100644 --- a/test/unit/migrations/024-test.js +++ b/test/unit/migrations/024-test.js @@ -1,12 +1,12 @@ -import assert from 'assert' -import migration24 from '../../../app/scripts/migrations/024' -import data from '../../../app/scripts/first-time-state' -import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' +import assert from 'assert'; +import migration24 from '../../../app/scripts/migrations/024'; +import data from '../../../app/scripts/first-time-state'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; const firstTimeState = { meta: {}, data, -} +}; const storage = { meta: {}, data: { @@ -14,22 +14,22 @@ const storage = { transactions: [], }, }, -} +}; -const transactions = [] +const transactions = []; while (transactions.length <= 10) { transactions.push({ txParams: { from: '0x8aCce2391c0d510a6c5E5d8f819a678f79b7e675' }, status: TRANSACTION_STATUSES.UNAPPROVED, - }) + }); transactions.push({ txParams: { from: '0x8aCce2391c0d510a6c5E5d8f819a678f79b7e675' }, status: TRANSACTION_STATUSES.CONFIRMED, - }) + }); } -storage.data.TransactionController.transactions = transactions +storage.data.TransactionController.transactions = transactions; describe('storage is migrated successfully and the txParams.from are lowercase', function () { it('should lowercase the from for unapproved txs', function (done) { @@ -37,32 +37,32 @@ describe('storage is migrated successfully and the txParams.from are lowercase', .migrate(storage) .then((migratedData) => { const migratedTransactions = - migratedData.data.TransactionController.transactions + migratedData.data.TransactionController.transactions; migratedTransactions.forEach((tx) => { if (tx.status === TRANSACTION_STATUSES.UNAPPROVED) { assert.equal( tx.txParams.from, '0x8acce2391c0d510a6c5e5d8f819a678f79b7e675', - ) + ); } else { assert.equal( tx.txParams.from, '0x8aCce2391c0d510a6c5E5d8f819a678f79b7e675', - ) + ); } - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should migrate first time state', function (done) { migration24 .migrate(firstTimeState) .then((migratedData) => { - assert.equal(migratedData.meta.version, 24) - done() + assert.equal(migratedData.meta.version, 24); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/migrations/025-test.js b/test/unit/migrations/025-test.js index 811cbaef72..f99db50108 100644 --- a/test/unit/migrations/025-test.js +++ b/test/unit/migrations/025-test.js @@ -1,12 +1,12 @@ -import assert from 'assert' -import migration25 from '../../../app/scripts/migrations/025' -import data from '../../../app/scripts/first-time-state' -import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' +import assert from 'assert'; +import migration25 from '../../../app/scripts/migrations/025'; +import data from '../../../app/scripts/first-time-state'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; const firstTimeState = { meta: {}, data, -} +}; const storage = { meta: {}, @@ -15,9 +15,9 @@ const storage = { transactions: [], }, }, -} +}; -const transactions = [] +const transactions = []; while (transactions.length <= 10) { transactions.push({ @@ -27,14 +27,14 @@ while (transactions.length <= 10) { chainId: 2, }, status: TRANSACTION_STATUSES.UNAPPROVED, - }) + }); transactions.push({ txParams: { from: '0x8aCce2391c0d510a6c5E5d8f819a678f79b7e675' }, status: TRANSACTION_STATUSES.CONFIRMED, - }) + }); } -storage.data.TransactionController.transactions = transactions +storage.data.TransactionController.transactions = transactions; describe('storage is migrated successfully and the txParams.from are lowercase', function () { it('should lowercase the from for unapproved txs', function (done) { @@ -42,27 +42,27 @@ describe('storage is migrated successfully and the txParams.from are lowercase', .migrate(storage) .then((migratedData) => { const migratedTransactions = - migratedData.data.TransactionController.transactions + migratedData.data.TransactionController.transactions; migratedTransactions.forEach((tx) => { if (tx.status === TRANSACTION_STATUSES.UNAPPROVED) { - assert(!tx.txParams.random) + assert(!tx.txParams.random); } if (tx.status === TRANSACTION_STATUSES.UNAPPROVED) { - assert(!tx.txParams.chainId) + assert(!tx.txParams.chainId); } - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should migrate first time state', function (done) { migration25 .migrate(firstTimeState) .then((migratedData) => { - assert.equal(migratedData.meta.version, 25) - done() + assert.equal(migratedData.meta.version, 25); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/migrations/026-test.js b/test/unit/migrations/026-test.js index 9168ea493c..684300ba50 100644 --- a/test/unit/migrations/026-test.js +++ b/test/unit/migrations/026-test.js @@ -1,6 +1,6 @@ -import assert from 'assert' -import firstTimeState from '../../../app/scripts/first-time-state' -import migration26 from '../../../app/scripts/migrations/026' +import assert from 'assert'; +import firstTimeState from '../../../app/scripts/first-time-state'; +import migration26 from '../../../app/scripts/migrations/026'; const oldStorage = { meta: { version: 25 }, @@ -13,26 +13,26 @@ const oldStorage = { }, }, }, -} +}; describe('migration #26', function () { it('should move the identities from KeyringController', function (done) { migration26 .migrate(oldStorage) .then((newStorage) => { - const { identities } = newStorage.data.PreferencesController + const { identities } = newStorage.data.PreferencesController; assert.deepEqual(identities, { '0x1e77e2': { name: 'Test Account 1', address: '0x1e77e2' }, '0x7e57e2': { name: 'Test Account 2', address: '0x7e57e2' }, - }) + }); assert.strictEqual( newStorage.data.KeyringController.walletNicknames, undefined, - ) - done() + ); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should successfully migrate first time state', function (done) { migration26 @@ -41,9 +41,9 @@ describe('migration #26', function () { data: firstTimeState, }) .then((migratedData) => { - assert.equal(migratedData.meta.version, migration26.version) - done() + assert.equal(migratedData.meta.version, migration26.version); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/migrations/027-test.js b/test/unit/migrations/027-test.js index 18a19107a8..c6d2ada97f 100644 --- a/test/unit/migrations/027-test.js +++ b/test/unit/migrations/027-test.js @@ -1,7 +1,7 @@ -import assert from 'assert' -import firstTimeState from '../../../app/scripts/first-time-state' -import migration27 from '../../../app/scripts/migrations/027' -import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' +import assert from 'assert'; +import firstTimeState from '../../../app/scripts/first-time-state'; +import migration27 from '../../../app/scripts/migrations/027'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; const oldStorage = { meta: {}, @@ -10,17 +10,17 @@ const oldStorage = { transactions: [], }, }, -} +}; -const transactions = [] +const transactions = []; while (transactions.length < 9) { - transactions.push({ status: TRANSACTION_STATUSES.REJECTED }) - transactions.push({ status: TRANSACTION_STATUSES.UNAPPROVED }) - transactions.push({ status: TRANSACTION_STATUSES.APPROVED }) + transactions.push({ status: TRANSACTION_STATUSES.REJECTED }); + transactions.push({ status: TRANSACTION_STATUSES.UNAPPROVED }); + transactions.push({ status: TRANSACTION_STATUSES.APPROVED }); } -oldStorage.data.TransactionController.transactions = transactions +oldStorage.data.TransactionController.transactions = transactions; describe('migration #27', function () { it('should remove rejected transactions', function (done) { @@ -28,21 +28,21 @@ describe('migration #27', function () { .migrate(oldStorage) .then((newStorage) => { const newTransactions = - newStorage.data.TransactionController.transactions + newStorage.data.TransactionController.transactions; assert.equal( newTransactions.length, 6, 'transactions is expected to have the length of 6', - ) + ); newTransactions.forEach((txMeta) => { if (txMeta.status === TRANSACTION_STATUSES.REJECTED) { - done(new Error('transaction was found with a status of rejected')) + done(new Error('transaction was found with a status of rejected')); } - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should successfully migrate first time state', function (done) { migration27 @@ -51,9 +51,9 @@ describe('migration #27', function () { data: firstTimeState, }) .then((migratedData) => { - assert.equal(migratedData.meta.version, migration27.version) - done() + assert.equal(migratedData.meta.version, migration27.version); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/migrations/028-test.js b/test/unit/migrations/028-test.js index caa8c86bfc..d7483d116d 100644 --- a/test/unit/migrations/028-test.js +++ b/test/unit/migrations/028-test.js @@ -1,6 +1,6 @@ -import assert from 'assert' -import firstTimeState from '../../../app/scripts/first-time-state' -import migration28 from '../../../app/scripts/migrations/028' +import assert from 'assert'; +import firstTimeState from '../../../app/scripts/first-time-state'; +import migration28 from '../../../app/scripts/migrations/028'; const oldStorage = { meta: {}, @@ -16,55 +16,55 @@ const oldStorage = { }, }, }, -} +}; describe('migration #28', function () { it('should add corresponding tokens to accountTokens', function (done) { migration28 .migrate(oldStorage) .then((newStorage) => { - const newTokens = newStorage.data.PreferencesController.tokens + const newTokens = newStorage.data.PreferencesController.tokens; const newAccountTokens = - newStorage.data.PreferencesController.accountTokens + newStorage.data.PreferencesController.accountTokens; const testTokens = [ { address: '0xa', symbol: 'A', decimals: 4 }, { address: '0xb', symbol: 'B', decimals: 4 }, - ] + ]; assert.equal( newTokens.length, 0, 'tokens is expected to have the length of 0', - ) + ); assert.equal( newAccountTokens['0x6d14'].mainnet.length, 2, 'tokens for address is expected to have the length of 2', - ) + ); assert.equal( newAccountTokens['0x3695'].mainnet.length, 2, 'tokens for address is expected to have the length of 2', - ) + ); assert.equal( Object.keys(newAccountTokens).length, 2, 'account tokens should be created for all identities', - ) + ); assert.deepEqual( newAccountTokens['0x6d14'].mainnet, testTokens, 'tokens for address should be the same than before', - ) + ); assert.deepEqual( newAccountTokens['0x3695'].mainnet, testTokens, 'tokens for address should be the same than before', - ) - done() + ); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should successfully migrate first time state', function (done) { migration28 @@ -73,9 +73,9 @@ describe('migration #28', function () { data: firstTimeState, }) .then((migratedData) => { - assert.equal(migratedData.meta.version, migration28.version) - done() + assert.equal(migratedData.meta.version, migration28.version); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/migrations/029-test.js b/test/unit/migrations/029-test.js index 4e37a48f47..2eb97c128e 100644 --- a/test/unit/migrations/029-test.js +++ b/test/unit/migrations/029-test.js @@ -1,8 +1,8 @@ -import assert from 'assert' -import migration29 from '../../../app/scripts/migrations/029' -import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' +import assert from 'assert'; +import migration29 from '../../../app/scripts/migrations/029'; +import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; -const properTime = new Date().getTime() +const properTime = new Date().getTime(); const storage = { meta: {}, data: { @@ -28,40 +28,40 @@ const storage = { ], }, }, -} +}; describe('storage is migrated successfully where transactions that are submitted have submittedTimes', function () { it('should auto fail transactions more than 12 hours old', function (done) { migration29 .migrate(storage) .then((migratedData) => { - const txs = migratedData.data.TransactionController.transactions - const [txMeta1] = txs - assert.equal(migratedData.meta.version, 29) + const txs = migratedData.data.TransactionController.transactions; + const [txMeta1] = txs; + assert.equal(migratedData.meta.version, 29); assert.equal( txMeta1.status, TRANSACTION_STATUSES.FAILED, 'old tx is auto failed', - ) + ); assert( txMeta1.err.message.includes('too long'), 'error message assigned', - ) + ); txs.forEach((tx) => { if (tx.id === 1) { - return + return; } assert.notEqual( tx.status, TRANSACTION_STATUSES.FAILED, 'other tx is not auto failed', - ) - }) + ); + }); - done() + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/migrations/030-test.js b/test/unit/migrations/030-test.js index 24acbfba25..3610a72b05 100644 --- a/test/unit/migrations/030-test.js +++ b/test/unit/migrations/030-test.js @@ -1,5 +1,5 @@ -import assert from 'assert' -import migrationTemplate from '../../../app/scripts/migrations/030' +import assert from 'assert'; +import migrationTemplate from '../../../app/scripts/migrations/030'; const storage = { meta: {}, @@ -31,31 +31,31 @@ const storage = { ], }, }, -} +}; describe('storage is migrated successfully', function () { it('should work', function (done) { migrationTemplate .migrate(storage) .then((migratedData) => { - assert.equal(migratedData.meta.version, 30) + assert.equal(migratedData.meta.version, 30); assert.equal( migratedData.data.PreferencesController.frequentRpcListDetail[0] .chainId, undefined, - ) + ); assert.equal( migratedData.data.PreferencesController.frequentRpcListDetail[1] .chainId, '1', - ) + ); assert.equal( migratedData.data.NetworkController.provider.chainId, undefined, - ) - assert.equal(migratedData.data.NetworkController.network, undefined) - done() + ); + assert.equal(migratedData.data.NetworkController.network, undefined); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/migrations/031-test.js b/test/unit/migrations/031-test.js index 2110fc373e..57159176bc 100644 --- a/test/unit/migrations/031-test.js +++ b/test/unit/migrations/031-test.js @@ -1,5 +1,5 @@ -import assert from 'assert' -import migration31 from '../../../app/scripts/migrations/031' +import assert from 'assert'; +import migration31 from '../../../app/scripts/migrations/031'; describe('migration #31', function () { it('should set completedOnboarding to true if vault exists', function (done) { @@ -24,7 +24,7 @@ describe('migration #31', function () { }, }, }, - } + }; migration31 .migrate(oldStorage) @@ -32,11 +32,11 @@ describe('migration #31', function () { assert.equal( newStorage.data.PreferencesController.completedOnboarding, true, - ) - done() + ); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should set completedOnboarding to false if vault does not exist', function (done) { const oldStorage = { @@ -54,7 +54,7 @@ describe('migration #31', function () { }, KeyringController: {}, }, - } + }; migration31 .migrate(oldStorage) @@ -62,9 +62,9 @@ describe('migration #31', function () { assert.equal( newStorage.data.PreferencesController.completedOnboarding, false, - ) - done() + ); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/migrations/033-test.js b/test/unit/migrations/033-test.js index b09846f0fe..ca8018460f 100644 --- a/test/unit/migrations/033-test.js +++ b/test/unit/migrations/033-test.js @@ -1,5 +1,5 @@ -import assert from 'assert' -import migration33 from '../../../app/scripts/migrations/033' +import assert from 'assert'; +import migration33 from '../../../app/scripts/migrations/033'; describe('Migration to delete notice controller', function () { const oldStorage = { @@ -29,11 +29,11 @@ describe('Migration to delete notice controller', function () { ], }, }, - } + }; it('removes notice controller from state', function () { migration33.migrate(oldStorage).then((newStorage) => { - assert.equal(newStorage.data.NoticeController, undefined) - }) - }) -}) + assert.equal(newStorage.data.NoticeController, undefined); + }); + }); +}); diff --git a/test/unit/migrations/034-test.js b/test/unit/migrations/034-test.js index 74de274cf5..e9554793d5 100644 --- a/test/unit/migrations/034-test.js +++ b/test/unit/migrations/034-test.js @@ -1,5 +1,5 @@ -import assert from 'assert' -import migration34 from '../../../app/scripts/migrations/034' +import assert from 'assert'; +import migration34 from '../../../app/scripts/migrations/034'; describe('migration #34', function () { it('should update the version metadata', function (done) { @@ -8,18 +8,18 @@ describe('migration #34', function () { version: 33, }, data: {}, - } + }; migration34 .migrate(oldStorage) .then((newStorage) => { assert.deepEqual(newStorage.meta, { version: 34, - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should set migratedPrivacyMode & privacyMode if featureFlags.privacyMode was false', function (done) { const oldStorage = { @@ -31,7 +31,7 @@ describe('migration #34', function () { }, }, }, - } + }; migration34 .migrate(oldStorage) @@ -41,11 +41,11 @@ describe('migration #34', function () { featureFlags: { privacyMode: true, }, - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should NOT change any state if migratedPrivacyMode is already set to true', function (done) { const oldStorage = { @@ -58,16 +58,16 @@ describe('migration #34', function () { }, }, }, - } + }; migration34 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data, oldStorage.data) - done() + assert.deepEqual(newStorage.data, oldStorage.data); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should NOT change any state if migratedPrivacyMode is already set to false', function (done) { const oldStorage = { @@ -80,31 +80,31 @@ describe('migration #34', function () { }, }, }, - } + }; migration34 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data, oldStorage.data) - done() + assert.deepEqual(newStorage.data, oldStorage.data); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should NOT change any state if PreferencesController is missing', function (done) { const oldStorage = { meta: {}, data: {}, - } + }; migration34 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data, oldStorage.data) - done() + assert.deepEqual(newStorage.data, oldStorage.data); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should NOT change any state if featureFlags.privacyMode is already true', function (done) { const oldStorage = { @@ -116,14 +116,14 @@ describe('migration #34', function () { }, }, }, - } + }; migration34 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data, oldStorage.data) - done() + assert.deepEqual(newStorage.data, oldStorage.data); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/migrations/035-test.js b/test/unit/migrations/035-test.js index 263b2e2df5..f3e600df2f 100644 --- a/test/unit/migrations/035-test.js +++ b/test/unit/migrations/035-test.js @@ -1,5 +1,5 @@ -import assert from 'assert' -import migration35 from '../../../app/scripts/migrations/035' +import assert from 'assert'; +import migration35 from '../../../app/scripts/migrations/035'; describe('migration #35', function () { it('should update the version metadata', function (done) { @@ -8,18 +8,18 @@ describe('migration #35', function () { version: 34, }, data: {}, - } + }; migration35 .migrate(oldStorage) .then((newStorage) => { assert.deepEqual(newStorage.meta, { version: 35, - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should delete seedWords', function (done) { const oldStorage = { @@ -29,16 +29,16 @@ describe('migration #35', function () { seedWords: 'seed words', }, }, - } + }; migration35 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data.PreferencesController, {}) - done() + assert.deepEqual(newStorage.data.PreferencesController, {}); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should delete falsy seedWords', function (done) { const oldStorage = { @@ -48,16 +48,16 @@ describe('migration #35', function () { seedWords: '', }, }, - } + }; migration35 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data.PreferencesController, {}) - done() + assert.deepEqual(newStorage.data.PreferencesController, {}); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should leave state without seedWords unchanged', function (done) { const oldStorage = { @@ -86,14 +86,14 @@ describe('migration #35', function () { metaMetricsSendCount: 0, }, }, - } + }; migration35 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data, oldStorage.data) - done() + assert.deepEqual(newStorage.data, oldStorage.data); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/migrations/036-test.js b/test/unit/migrations/036-test.js index 380de627b5..679fc8a3b0 100644 --- a/test/unit/migrations/036-test.js +++ b/test/unit/migrations/036-test.js @@ -1,5 +1,5 @@ -import assert from 'assert' -import migration36 from '../../../app/scripts/migrations/036' +import assert from 'assert'; +import migration36 from '../../../app/scripts/migrations/036'; describe('migration #36', function () { it('should update the version metadata', function (done) { @@ -8,18 +8,18 @@ describe('migration #36', function () { version: 35, }, data: {}, - } + }; migration36 .migrate(oldStorage) .then((newStorage) => { assert.deepEqual(newStorage.meta, { version: 36, - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should remove privacyMode if featureFlags.privacyMode was false', function (done) { const oldStorage = { @@ -31,18 +31,18 @@ describe('migration #36', function () { }, }, }, - } + }; migration36 .migrate(oldStorage) .then((newStorage) => { assert.deepEqual(newStorage.data.PreferencesController, { featureFlags: {}, - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should remove privacyMode if featureFlags.privacyMode was true', function (done) { const oldStorage = { @@ -54,18 +54,18 @@ describe('migration #36', function () { }, }, }, - } + }; migration36 .migrate(oldStorage) .then((newStorage) => { assert.deepEqual(newStorage.data.PreferencesController, { featureFlags: {}, - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should NOT change any state if privacyMode does not exist', function (done) { const oldStorage = { @@ -76,31 +76,31 @@ describe('migration #36', function () { featureFlags: {}, }, }, - } + }; migration36 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data, oldStorage.data) - done() + assert.deepEqual(newStorage.data, oldStorage.data); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should NOT change any state if PreferencesController is missing', function (done) { const oldStorage = { meta: {}, data: {}, - } + }; migration36 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data, oldStorage.data) - done() + assert.deepEqual(newStorage.data, oldStorage.data); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should NOT change any state if featureFlags is missing', function (done) { const oldStorage = { @@ -108,14 +108,14 @@ describe('migration #36', function () { data: { PreferencesController: {}, }, - } + }; migration36 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data, oldStorage.data) - done() + assert.deepEqual(newStorage.data, oldStorage.data); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/migrations/037-test.js b/test/unit/migrations/037-test.js index 861ab4cd1c..78fe85cb58 100644 --- a/test/unit/migrations/037-test.js +++ b/test/unit/migrations/037-test.js @@ -1,5 +1,5 @@ -import assert from 'assert' -import migration37 from '../../../app/scripts/migrations/037' +import assert from 'assert'; +import migration37 from '../../../app/scripts/migrations/037'; describe('migration #37', function () { it('should update the version metadata', function (done) { @@ -8,18 +8,18 @@ describe('migration #37', function () { version: 36, }, data: {}, - } + }; migration37 .migrate(oldStorage) .then((newStorage) => { assert.deepEqual(newStorage.meta, { version: 37, - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should transform old state to new format', function (done) { const oldStorage = { @@ -49,7 +49,7 @@ describe('migration #37', function () { }, }, }, - } + }; migration37 .migrate(oldStorage) @@ -80,11 +80,11 @@ describe('migration #37', function () { name: 'account 2', }, }, - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('ens validation test', function (done) { const oldStorage = { @@ -101,7 +101,7 @@ describe('migration #37', function () { }, }, }, - } + }; migration37 .migrate(oldStorage) @@ -116,9 +116,9 @@ describe('migration #37', function () { name: 'metamask.eth', }, }, - }) - done() + }); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/migrations/038-test.js b/test/unit/migrations/038-test.js index 2c727a352b..c1e8e2a1e8 100644 --- a/test/unit/migrations/038-test.js +++ b/test/unit/migrations/038-test.js @@ -1,5 +1,5 @@ -import { strict as assert } from 'assert' -import migration38 from '../../../app/scripts/migrations/038' +import { strict as assert } from 'assert'; +import migration38 from '../../../app/scripts/migrations/038'; describe('migration #38', function () { it('should update the version metadata', function (done) { @@ -8,24 +8,24 @@ describe('migration #38', function () { version: 37, }, data: {}, - } + }; migration38 .migrate(oldStorage) .then((newStorage) => { assert.deepEqual(newStorage.meta, { version: 38, - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should add a fullScreenVsPopup property set to either "control" or "fullScreen"', function (done) { const oldStorage = { meta: {}, data: {}, - } + }; migration38 .migrate(oldStorage) @@ -33,11 +33,11 @@ describe('migration #38', function () { assert.equal( newStorage.data.ABTestController.abTests.fullScreenVsPopup, 'control', - ) - done() + ); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should leave the fullScreenVsPopup property unchanged if it exists', function (done) { const oldStorage = { @@ -49,7 +49,7 @@ describe('migration #38', function () { }, }, }, - } + }; migration38 .migrate(oldStorage) @@ -58,9 +58,9 @@ describe('migration #38', function () { abTests: { fullScreenVsPopup: 'fullScreen', }, - }) - done() + }); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/migrations/039-test.js b/test/unit/migrations/039-test.js index 70b00da5f2..8cfc3e0b1e 100644 --- a/test/unit/migrations/039-test.js +++ b/test/unit/migrations/039-test.js @@ -1,5 +1,5 @@ -import assert from 'assert' -import migration39 from '../../../app/scripts/migrations/039' +import assert from 'assert'; +import migration39 from '../../../app/scripts/migrations/039'; describe('migration #39', function () { it('should update the version metadata', function (done) { @@ -8,18 +8,18 @@ describe('migration #39', function () { version: 38, }, data: {}, - } + }; migration39 .migrate(oldStorage) .then((newStorage) => { assert.deepEqual(newStorage.meta, { version: 39, - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should update old DAI token symbol to SAI in tokens', function (done) { const oldStorage = { @@ -45,7 +45,7 @@ describe('migration #39', function () { ], }, }, - } + }; migration39 .migrate(oldStorage) @@ -68,11 +68,11 @@ describe('migration #39', function () { decimals: 18, }, ], - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should update old DAI token symbol to SAI in accountTokens', function (done) { const oldStorage = { @@ -116,7 +116,7 @@ describe('migration #39', function () { }, }, }, - } + }; migration39 .migrate(oldStorage) @@ -157,11 +157,11 @@ describe('migration #39', function () { ], }, }, - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should NOT change any state if accountTokens is not an object', function (done) { const oldStorage = { @@ -171,16 +171,16 @@ describe('migration #39', function () { accountTokens: [], }, }, - } + }; migration39 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data, oldStorage.data) - done() + assert.deepEqual(newStorage.data, oldStorage.data); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should NOT change any state if accountTokens is an object with invalid values', function (done) { const oldStorage = { @@ -203,16 +203,16 @@ describe('migration #39', function () { }, }, }, - } + }; migration39 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data, oldStorage.data) - done() + assert.deepEqual(newStorage.data, oldStorage.data); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should NOT change any state if accountTokens includes the new DAI token', function (done) { const oldStorage = { @@ -256,16 +256,16 @@ describe('migration #39', function () { }, }, }, - } + }; migration39 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data, oldStorage.data) - done() + assert.deepEqual(newStorage.data, oldStorage.data); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should NOT change any state if tokens includes the new DAI token', function (done) { const oldStorage = { @@ -286,16 +286,16 @@ describe('migration #39', function () { ], }, }, - } + }; migration39 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data, oldStorage.data) - done() + assert.deepEqual(newStorage.data, oldStorage.data); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should NOT change any state if tokens does not include DAI', function (done) { const oldStorage = { @@ -316,16 +316,16 @@ describe('migration #39', function () { ], }, }, - } + }; migration39 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data, oldStorage.data) - done() + assert.deepEqual(newStorage.data, oldStorage.data); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should NOT change any state if a tokens property has invalid entries', function (done) { const oldStorage = { @@ -335,16 +335,16 @@ describe('migration #39', function () { tokens: [null, [], undefined, 42], }, }, - } + }; migration39 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data, oldStorage.data) - done() + assert.deepEqual(newStorage.data, oldStorage.data); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should NOT change any state if a tokens property is not an array', function (done) { const oldStorage = { @@ -354,16 +354,16 @@ describe('migration #39', function () { tokens: {}, }, }, - } + }; migration39 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data, oldStorage.data) - done() + assert.deepEqual(newStorage.data, oldStorage.data); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should NOT change any state if a tokens property is null', function (done) { const oldStorage = { @@ -373,16 +373,16 @@ describe('migration #39', function () { tokens: null, }, }, - } + }; migration39 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data, oldStorage.data) - done() + assert.deepEqual(newStorage.data, oldStorage.data); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should NOT change any state if a tokens property is missing', function (done) { const oldStorage = { @@ -390,16 +390,16 @@ describe('migration #39', function () { data: { PreferencesController: {}, }, - } + }; migration39 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data, oldStorage.data) - done() + assert.deepEqual(newStorage.data, oldStorage.data); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should NOT change any state if a accountTokens property is missing', function (done) { const oldStorage = { @@ -407,29 +407,29 @@ describe('migration #39', function () { data: { PreferencesController: {}, }, - } + }; migration39 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data, oldStorage.data) - done() + assert.deepEqual(newStorage.data, oldStorage.data); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should NOT change any state if PreferencesController is missing', function (done) { const oldStorage = { meta: {}, data: {}, - } + }; migration39 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data, oldStorage.data) - done() + assert.deepEqual(newStorage.data, oldStorage.data); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/migrations/040-test.js b/test/unit/migrations/040-test.js index fd4f481938..98fce305b3 100644 --- a/test/unit/migrations/040-test.js +++ b/test/unit/migrations/040-test.js @@ -1,5 +1,5 @@ -import assert from 'assert' -import migration40 from '../../../app/scripts/migrations/040' +import assert from 'assert'; +import migration40 from '../../../app/scripts/migrations/040'; describe('migration #40', function () { it('should update the version metadata', function (done) { @@ -8,18 +8,18 @@ describe('migration #40', function () { version: 39, }, data: {}, - } + }; migration40 .migrate(oldStorage) .then((newStorage) => { assert.deepEqual(newStorage.meta, { version: 40, - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should delete ProviderApprovalController storage key', function (done) { const oldStorage = { @@ -28,29 +28,29 @@ describe('migration #40', function () { ProviderApprovalController: {}, foo: 'bar', }, - } + }; migration40 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data, { foo: 'bar' }) - done() + assert.deepEqual(newStorage.data, { foo: 'bar' }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should do nothing if no ProviderApprovalController storage key', function (done) { const oldStorage = { meta: {}, data: { foo: 'bar' }, - } + }; migration40 .migrate(oldStorage) .then((newStorage) => { - assert.deepEqual(newStorage.data, { foo: 'bar' }) - done() + assert.deepEqual(newStorage.data, { foo: 'bar' }); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/migrations/041-test.js b/test/unit/migrations/041-test.js index 7b95dfa3fa..e61ce66e2a 100644 --- a/test/unit/migrations/041-test.js +++ b/test/unit/migrations/041-test.js @@ -1,5 +1,5 @@ -import assert from 'assert' -import migration41 from '../../../app/scripts/migrations/041' +import assert from 'assert'; +import migration41 from '../../../app/scripts/migrations/041'; describe('migration #41', function () { it('should update the version metadata', function (done) { @@ -8,18 +8,18 @@ describe('migration #41', function () { version: 40, }, data: {}, - } + }; migration41 .migrate(oldStorage) .then((newStorage) => { assert.deepEqual(newStorage.meta, { version: 41, - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should rename autoLogoutTimeLimit storage key', function (done) { const oldStorage = { @@ -34,7 +34,7 @@ describe('migration #41', function () { }, foo: 'bar', }, - } + }; migration41 .migrate(oldStorage) @@ -48,11 +48,11 @@ describe('migration #41', function () { bar: 'baz', }, foo: 'bar', - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should do nothing if no PreferencesController key', function (done) { const oldStorage = { @@ -60,18 +60,18 @@ describe('migration #41', function () { data: { foo: 'bar', }, - } + }; migration41 .migrate(oldStorage) .then((newStorage) => { assert.deepEqual(newStorage.data, { foo: 'bar', - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should do nothing if no preferences key', function (done) { const oldStorage = { @@ -82,7 +82,7 @@ describe('migration #41', function () { }, foo: 'bar', }, - } + }; migration41 .migrate(oldStorage) @@ -92,9 +92,9 @@ describe('migration #41', function () { bar: 'baz', }, foo: 'bar', - }) - done() + }); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/migrations/042-test.js b/test/unit/migrations/042-test.js index 0c2cbf01a2..9159fb7563 100644 --- a/test/unit/migrations/042-test.js +++ b/test/unit/migrations/042-test.js @@ -1,5 +1,5 @@ -import assert from 'assert' -import migration42 from '../../../app/scripts/migrations/042' +import assert from 'assert'; +import migration42 from '../../../app/scripts/migrations/042'; describe('migration #42', function () { it('should update the version metadata', function (done) { @@ -8,18 +8,18 @@ describe('migration #42', function () { version: 41, }, data: {}, - } + }; migration42 .migrate(oldStorage) .then((newStorage) => { assert.deepEqual(newStorage.meta, { version: 42, - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should set connectedStatusPopoverHasBeenShown to false', function (done) { const oldStorage = { @@ -31,7 +31,7 @@ describe('migration #42', function () { }, foo: 'bar', }, - } + }; migration42 .migrate(oldStorage) @@ -42,11 +42,11 @@ describe('migration #42', function () { bar: 'baz', }, foo: 'bar', - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should initialize AppStateController if it does not exist', function (done) { const oldStorage = { @@ -54,7 +54,7 @@ describe('migration #42', function () { data: { foo: 'bar', }, - } + }; migration42 .migrate(oldStorage) @@ -64,9 +64,9 @@ describe('migration #42', function () { AppStateController: { connectedStatusPopoverHasBeenShown: false, }, - }) - done() + }); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/migrations/043-test.js b/test/unit/migrations/043-test.js index 5a25e676ca..25ac0336db 100644 --- a/test/unit/migrations/043-test.js +++ b/test/unit/migrations/043-test.js @@ -1,5 +1,5 @@ -import { strict as assert } from 'assert' -import migration43 from '../../../app/scripts/migrations/043' +import { strict as assert } from 'assert'; +import migration43 from '../../../app/scripts/migrations/043'; describe('migration #43', function () { it('should update the version metadata', async function () { @@ -8,13 +8,13 @@ describe('migration #43', function () { version: 42, }, data: {}, - } + }; - const newStorage = await migration43.migrate(oldStorage) + const newStorage = await migration43.migrate(oldStorage); assert.deepEqual(newStorage.meta, { version: 43, - }) - }) + }); + }); it('should delete currentAccountTab state', async function () { const oldStorage = { @@ -26,16 +26,16 @@ describe('migration #43', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration43.migrate(oldStorage) + const newStorage = await migration43.migrate(oldStorage); assert.deepEqual(newStorage.data, { PreferencesController: { bar: 'baz', }, foo: 'bar', - }) - }) + }); + }); it('should do nothing if currentAccountTab state does not exist', async function () { const oldStorage = { @@ -46,9 +46,9 @@ describe('migration #43', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration43.migrate(oldStorage) - assert.deepEqual(oldStorage.data, newStorage.data) - }) -}) + const newStorage = await migration43.migrate(oldStorage); + assert.deepEqual(oldStorage.data, newStorage.data); + }); +}); diff --git a/test/unit/migrations/044-test.js b/test/unit/migrations/044-test.js index 0fe8a96489..0b53b506b9 100644 --- a/test/unit/migrations/044-test.js +++ b/test/unit/migrations/044-test.js @@ -1,5 +1,5 @@ -import { strict as assert } from 'assert' -import migration44 from '../../../app/scripts/migrations/044' +import { strict as assert } from 'assert'; +import migration44 from '../../../app/scripts/migrations/044'; describe('migration #44', function () { it('should update the version metadata', async function () { @@ -8,13 +8,13 @@ describe('migration #44', function () { version: 43, }, data: {}, - } + }; - const newStorage = await migration44.migrate(oldStorage) + const newStorage = await migration44.migrate(oldStorage); assert.deepEqual(newStorage.meta, { version: 44, - }) - }) + }); + }); it('should delete mkrMigrationReminderTimestamp state', async function () { const oldStorage = { @@ -26,16 +26,16 @@ describe('migration #44', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration44.migrate(oldStorage) + const newStorage = await migration44.migrate(oldStorage); assert.deepEqual(newStorage.data, { AppStateController: { bar: 'baz', }, foo: 'bar', - }) - }) + }); + }); it('should delete mkrMigrationReminderTimestamp state if it is null', async function () { const oldStorage = { @@ -47,16 +47,16 @@ describe('migration #44', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration44.migrate(oldStorage) + const newStorage = await migration44.migrate(oldStorage); assert.deepEqual(newStorage.data, { AppStateController: { bar: 'baz', }, foo: 'bar', - }) - }) + }); + }); it('should do nothing if mkrMigrationReminderTimestamp state does not exist', async function () { const oldStorage = { @@ -67,9 +67,9 @@ describe('migration #44', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration44.migrate(oldStorage) - assert.deepEqual(oldStorage.data, newStorage.data) - }) -}) + const newStorage = await migration44.migrate(oldStorage); + assert.deepEqual(oldStorage.data, newStorage.data); + }); +}); diff --git a/test/unit/migrations/045-test.js b/test/unit/migrations/045-test.js index 6547203daa..bd102a9279 100644 --- a/test/unit/migrations/045-test.js +++ b/test/unit/migrations/045-test.js @@ -1,5 +1,5 @@ -import assert from 'assert' -import migration45 from '../../../app/scripts/migrations/045' +import assert from 'assert'; +import migration45 from '../../../app/scripts/migrations/045'; describe('migration #45', function () { it('should update the version metadata', function (done) { @@ -8,18 +8,18 @@ describe('migration #45', function () { version: 44, }, data: {}, - } + }; migration45 .migrate(oldStorage) .then((newStorage) => { assert.deepEqual(newStorage.meta, { version: 45, - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should update ipfsGateway value if outdated', function (done) { const oldStorage = { @@ -31,7 +31,7 @@ describe('migration #45', function () { }, foo: 'bar', }, - } + }; migration45 .migrate(oldStorage) @@ -42,11 +42,11 @@ describe('migration #45', function () { bar: 'baz', }, foo: 'bar', - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should not update ipfsGateway value if custom set', function (done) { const oldStorage = { @@ -58,7 +58,7 @@ describe('migration #45', function () { }, foo: 'bar', }, - } + }; migration45 .migrate(oldStorage) @@ -69,11 +69,11 @@ describe('migration #45', function () { bar: 'baz', }, foo: 'bar', - }) - done() + }); + done(); }) - .catch(done) - }) + .catch(done); + }); it('should do nothing if no PreferencesController key', function (done) { const oldStorage = { @@ -81,16 +81,16 @@ describe('migration #45', function () { data: { foo: 'bar', }, - } + }; migration45 .migrate(oldStorage) .then((newStorage) => { assert.deepEqual(newStorage.data, { foo: 'bar', - }) - done() + }); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/migrations/046-test.js b/test/unit/migrations/046-test.js index 0c327eb8ac..43a79da946 100644 --- a/test/unit/migrations/046-test.js +++ b/test/unit/migrations/046-test.js @@ -1,5 +1,5 @@ -import { strict as assert } from 'assert' -import migration46 from '../../../app/scripts/migrations/046' +import { strict as assert } from 'assert'; +import migration46 from '../../../app/scripts/migrations/046'; describe('migration #46', function () { it('should update the version metadata', async function () { @@ -8,13 +8,13 @@ describe('migration #46', function () { version: 45, }, data: {}, - } + }; - const newStorage = await migration46.migrate(oldStorage) + const newStorage = await migration46.migrate(oldStorage); assert.deepEqual(newStorage.meta, { version: 46, - }) - }) + }); + }); it('should delete ABTestController state', async function () { const oldStorage = { @@ -27,13 +27,13 @@ describe('migration #46', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration46.migrate(oldStorage) + const newStorage = await migration46.migrate(oldStorage); assert.deepEqual(newStorage.data, { foo: 'bar', - }) - }) + }); + }); it('should do nothing if ABTestController state does not exist', async function () { const oldStorage = { @@ -44,9 +44,9 @@ describe('migration #46', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration46.migrate(oldStorage) - assert.deepEqual(oldStorage.data, newStorage.data) - }) -}) + const newStorage = await migration46.migrate(oldStorage); + assert.deepEqual(oldStorage.data, newStorage.data); + }); +}); diff --git a/test/unit/migrations/047-test.js b/test/unit/migrations/047-test.js index bdaf66175c..12dc35fdfa 100644 --- a/test/unit/migrations/047-test.js +++ b/test/unit/migrations/047-test.js @@ -1,5 +1,5 @@ -import { strict as assert } from 'assert' -import migration47 from '../../../app/scripts/migrations/047' +import { strict as assert } from 'assert'; +import migration47 from '../../../app/scripts/migrations/047'; describe('migration #47', function () { it('should update the version metadata', async function () { @@ -8,13 +8,13 @@ describe('migration #47', function () { version: 46, }, data: {}, - } + }; - const newStorage = await migration47.migrate(oldStorage) + const newStorage = await migration47.migrate(oldStorage); assert.deepEqual(newStorage.meta, { version: 47, - }) - }) + }); + }); it('should stringify transactions metamaskNetworkId values', async function () { const oldStorage = { @@ -30,9 +30,9 @@ describe('migration #47', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration47.migrate(oldStorage) + const newStorage = await migration47.migrate(oldStorage); assert.deepEqual(newStorage.data, { TransactionController: { transactions: [ @@ -43,8 +43,8 @@ describe('migration #47', function () { ], }, foo: 'bar', - }) - }) + }); + }); it('should do nothing if transactions metamaskNetworkId values are already strings', async function () { const oldStorage = { @@ -60,11 +60,11 @@ describe('migration #47', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration47.migrate(oldStorage) - assert.deepEqual(oldStorage.data, newStorage.data) - }) + const newStorage = await migration47.migrate(oldStorage); + assert.deepEqual(oldStorage.data, newStorage.data); + }); it('should do nothing if transactions state does not exist', async function () { const oldStorage = { @@ -75,11 +75,11 @@ describe('migration #47', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration47.migrate(oldStorage) - assert.deepEqual(oldStorage.data, newStorage.data) - }) + const newStorage = await migration47.migrate(oldStorage); + assert.deepEqual(oldStorage.data, newStorage.data); + }); it('should do nothing if transactions state is empty', async function () { const oldStorage = { @@ -91,19 +91,19 @@ describe('migration #47', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration47.migrate(oldStorage) - assert.deepEqual(oldStorage.data, newStorage.data) - }) + const newStorage = await migration47.migrate(oldStorage); + assert.deepEqual(oldStorage.data, newStorage.data); + }); it('should do nothing if state is empty', async function () { const oldStorage = { meta: {}, data: {}, - } + }; - const newStorage = await migration47.migrate(oldStorage) - assert.deepEqual(oldStorage.data, newStorage.data) - }) -}) + const newStorage = await migration47.migrate(oldStorage); + assert.deepEqual(oldStorage.data, newStorage.data); + }); +}); diff --git a/test/unit/migrations/048-test.js b/test/unit/migrations/048-test.js index bf96a07151..cd731c38eb 100644 --- a/test/unit/migrations/048-test.js +++ b/test/unit/migrations/048-test.js @@ -1,5 +1,5 @@ -import { strict as assert } from 'assert' -import migration48 from '../../../app/scripts/migrations/048' +import { strict as assert } from 'assert'; +import migration48 from '../../../app/scripts/migrations/048'; const localhostNetwork = { rpcUrl: 'http://localhost:8545', @@ -7,7 +7,7 @@ const localhostNetwork = { ticker: 'ETH', nickname: 'Localhost 8545', rpcPrefs: {}, -} +}; const expectedPreferencesState = { PreferencesController: { frequentRpcListDetail: [ @@ -16,7 +16,7 @@ const expectedPreferencesState = { }, ], }, -} +}; describe('migration #48', function () { it('should update the version metadata', async function () { @@ -25,13 +25,13 @@ describe('migration #48', function () { version: 47, }, data: {}, - } + }; - const newStorage = await migration48.migrate(oldStorage) + const newStorage = await migration48.migrate(oldStorage); assert.deepEqual(newStorage.meta, { version: 48, - }) - }) + }); + }); it('should delete NetworkController.settings', async function () { const oldStorage = { @@ -47,9 +47,9 @@ describe('migration #48', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration48.migrate(oldStorage) + const newStorage = await migration48.migrate(oldStorage); assert.deepEqual(newStorage.data, { ...expectedPreferencesState, NetworkController: { @@ -58,8 +58,8 @@ describe('migration #48', function () { }, }, foo: 'bar', - }) - }) + }); + }); it('should migrate NetworkController.provider to Rinkeby if the type is "rpc" and the chainId is invalid (1)', async function () { const oldStorage = { @@ -75,9 +75,9 @@ describe('migration #48', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration48.migrate(oldStorage) + const newStorage = await migration48.migrate(oldStorage); assert.deepEqual(newStorage.data, { ...expectedPreferencesState, NetworkController: { @@ -92,8 +92,8 @@ describe('migration #48', function () { foo: 'bar', }, foo: 'bar', - }) - }) + }); + }); it('should migrate NetworkController.provider to Rinkeby if the type is "rpc" and the chainId is invalid (2)', async function () { const oldStorage = { @@ -109,9 +109,9 @@ describe('migration #48', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration48.migrate(oldStorage) + const newStorage = await migration48.migrate(oldStorage); assert.deepEqual(newStorage.data, { ...expectedPreferencesState, NetworkController: { @@ -126,8 +126,8 @@ describe('migration #48', function () { foo: 'bar', }, foo: 'bar', - }) - }) + }); + }); it('should not migrate NetworkController.provider to Rinkeby if the type is "rpc" and the chainId is valid', async function () { const oldStorage = { @@ -143,9 +143,9 @@ describe('migration #48', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration48.migrate(oldStorage) + const newStorage = await migration48.migrate(oldStorage); assert.deepEqual(newStorage.data, { ...expectedPreferencesState, NetworkController: { @@ -157,8 +157,8 @@ describe('migration #48', function () { foo: 'bar', }, foo: 'bar', - }) - }) + }); + }); it('should migrate NetworkController.provider to Rinkeby if the type is "localhost"', async function () { const oldStorage = { @@ -173,9 +173,9 @@ describe('migration #48', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration48.migrate(oldStorage) + const newStorage = await migration48.migrate(oldStorage); assert.deepEqual(newStorage.data, { ...expectedPreferencesState, NetworkController: { @@ -190,8 +190,8 @@ describe('migration #48', function () { foo: 'bar', }, foo: 'bar', - }) - }) + }); + }); it('should re-key NetworkController.provider.rpcTarget to rpcUrl if the type is not "rpc" or "localhost"', async function () { const oldStorage = { @@ -207,9 +207,9 @@ describe('migration #48', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration48.migrate(oldStorage) + const newStorage = await migration48.migrate(oldStorage); assert.deepEqual(newStorage.data, { ...expectedPreferencesState, NetworkController: { @@ -221,8 +221,8 @@ describe('migration #48', function () { }, }, foo: 'bar', - }) - }) + }); + }); it('should do nothing to NetworkController if affected state does not exist', async function () { const oldStorage = { @@ -235,20 +235,20 @@ describe('migration #48', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration48.migrate(oldStorage) + const newStorage = await migration48.migrate(oldStorage); assert.deepEqual( { ...expectedPreferencesState, ...oldStorage.data }, { ...expectedPreferencesState, ...newStorage.data }, - ) - }) + ); + }); it('should add frequentRpcListDetail item to beginning of list', async function () { const existingList = [ { rpcUrl: 'foo', chainId: '0x1' }, { rpcUrl: 'bar', chainId: '0x2' }, - ] + ]; const oldStorage = { meta: {}, @@ -258,16 +258,16 @@ describe('migration #48', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration48.migrate(oldStorage) + const newStorage = await migration48.migrate(oldStorage); assert.deepEqual(newStorage.data, { PreferencesController: { frequentRpcListDetail: [{ ...localhostNetwork }, ...existingList], }, foo: 'bar', - }) - }) + }); + }); it('should delete CachedBalancesController.cachedBalances', async function () { const oldStorage = { @@ -283,9 +283,9 @@ describe('migration #48', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration48.migrate(oldStorage) + const newStorage = await migration48.migrate(oldStorage); assert.deepEqual(newStorage.data, { ...expectedPreferencesState, CachedBalancesController: { @@ -294,8 +294,8 @@ describe('migration #48', function () { }, }, foo: 'bar', - }) - }) + }); + }); it('should convert hex transaction metamaskNetworkId values to decimal', async function () { const oldStorage = { @@ -320,9 +320,9 @@ describe('migration #48', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration48.migrate(oldStorage) + const newStorage = await migration48.migrate(oldStorage); assert.deepEqual(newStorage.data, { ...expectedPreferencesState, TransactionController: { @@ -343,8 +343,8 @@ describe('migration #48', function () { }, }, foo: 'bar', - }) - }) + }); + }); it('should migrate the address book', async function () { const oldStorage = { @@ -377,9 +377,9 @@ describe('migration #48', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration48.migrate(oldStorage) + const newStorage = await migration48.migrate(oldStorage); assert.deepEqual(newStorage.data, { ...expectedPreferencesState, AddressBookController: { @@ -408,8 +408,8 @@ describe('migration #48', function () { }, }, foo: 'bar', - }) - }) + }); + }); it('should migrate the address book and merge entries', async function () { const oldStorage = { @@ -449,9 +449,9 @@ describe('migration #48', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration48.migrate(oldStorage) + const newStorage = await migration48.migrate(oldStorage); assert.deepEqual(newStorage.data, { ...expectedPreferencesState, AddressBookController: { @@ -480,8 +480,8 @@ describe('migration #48', function () { }, }, foo: 'bar', - }) - }) + }); + }); it('should not modify address book if all entries are valid or un-parseable', async function () { const oldStorage = { @@ -498,9 +498,9 @@ describe('migration #48', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration48.migrate(oldStorage) + const newStorage = await migration48.migrate(oldStorage); assert.deepEqual(newStorage.data, { ...expectedPreferencesState, AddressBookController: { @@ -513,8 +513,8 @@ describe('migration #48', function () { }, }, foo: 'bar', - }) - }) + }); + }); it('should delete localhost key in IncomingTransactionsController', async function () { const oldStorage = { @@ -529,9 +529,9 @@ describe('migration #48', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration48.migrate(oldStorage) + const newStorage = await migration48.migrate(oldStorage); assert.deepEqual(newStorage.data, { ...expectedPreferencesState, IncomingTransactionsController: { @@ -541,8 +541,8 @@ describe('migration #48', function () { bar: 'baz', }, foo: 'bar', - }) - }) + }); + }); it('should not modify IncomingTransactionsController state if affected key is missing', async function () { const oldStorage = { @@ -557,9 +557,9 @@ describe('migration #48', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration48.migrate(oldStorage) + const newStorage = await migration48.migrate(oldStorage); assert.deepEqual(newStorage.data, { ...expectedPreferencesState, IncomingTransactionsController: { @@ -570,8 +570,8 @@ describe('migration #48', function () { bar: 'baz', }, foo: 'bar', - }) - }) + }); + }); it('should merge localhost token list into rpc token list', async function () { const oldStorage = { @@ -601,9 +601,9 @@ describe('migration #48', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration48.migrate(oldStorage) + const newStorage = await migration48.migrate(oldStorage); assert.deepEqual(newStorage.data, { PreferencesController: { accountTokens: { @@ -630,6 +630,6 @@ describe('migration #48', function () { ], }, foo: 'bar', - }) - }) -}) + }); + }); +}); diff --git a/test/unit/migrations/049-test.js b/test/unit/migrations/049-test.js index f720a47235..df441a47a6 100644 --- a/test/unit/migrations/049-test.js +++ b/test/unit/migrations/049-test.js @@ -1,5 +1,5 @@ -import assert from 'assert' -import migration49 from '../../../app/scripts/migrations/049' +import assert from 'assert'; +import migration49 from '../../../app/scripts/migrations/049'; describe('migration #49', function () { it('should update the version metadata', async function () { @@ -8,13 +8,13 @@ describe('migration #49', function () { version: 48, }, data: {}, - } + }; - const newStorage = await migration49.migrate(oldStorage) + const newStorage = await migration49.migrate(oldStorage); assert.deepStrictEqual(newStorage.meta, { version: 49, - }) - }) + }); + }); it('should move metaMetricsId to MetaMetricsController', async function () { const oldStorage = { @@ -26,9 +26,9 @@ describe('migration #49', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration49.migrate(oldStorage) + const newStorage = await migration49.migrate(oldStorage); assert.deepStrictEqual(newStorage.data, { PreferencesController: { bar: 'baz', @@ -37,8 +37,8 @@ describe('migration #49', function () { metaMetricsId: '0xaab', }, foo: 'bar', - }) - }) + }); + }); it('should move participateInMetaMetrics to MetaMetricsController', async function () { const oldStorage = { @@ -50,9 +50,9 @@ describe('migration #49', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration49.migrate(oldStorage) + const newStorage = await migration49.migrate(oldStorage); assert.deepStrictEqual(newStorage.data, { PreferencesController: { bar: 'baz', @@ -61,8 +61,8 @@ describe('migration #49', function () { participateInMetaMetrics: false, }, foo: 'bar', - }) - }) + }); + }); it('should move metaMetricsSendCount to MetaMetricsController', async function () { const oldStorage = { @@ -74,9 +74,9 @@ describe('migration #49', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration49.migrate(oldStorage) + const newStorage = await migration49.migrate(oldStorage); assert.deepStrictEqual(newStorage.data, { PreferencesController: { bar: 'baz', @@ -85,8 +85,8 @@ describe('migration #49', function () { metaMetricsSendCount: 1, }, foo: 'bar', - }) - }) + }); + }); it('should move all metaMetrics fields to MetaMetricsController', async function () { const oldStorage = { @@ -100,9 +100,9 @@ describe('migration #49', function () { }, foo: 'bar', }, - } + }; - const newStorage = await migration49.migrate(oldStorage) + const newStorage = await migration49.migrate(oldStorage); assert.deepStrictEqual(newStorage.data, { PreferencesController: { bar: 'baz', @@ -113,8 +113,8 @@ describe('migration #49', function () { participateInMetaMetrics: true, }, foo: 'bar', - }) - }) + }); + }); it('should do nothing if no PreferencesController key', async function () { const oldStorage = { @@ -122,11 +122,11 @@ describe('migration #49', function () { data: { foo: 'bar', }, - } + }; - const newStorage = await migration49.migrate(oldStorage) + const newStorage = await migration49.migrate(oldStorage); assert.deepStrictEqual(newStorage.data, { foo: 'bar', - }) - }) -}) + }); + }); +}); diff --git a/test/unit/migrations/050-test.js b/test/unit/migrations/050-test.js index fea2f1b060..05aa735aeb 100644 --- a/test/unit/migrations/050-test.js +++ b/test/unit/migrations/050-test.js @@ -1,6 +1,6 @@ -import { strict as assert } from 'assert' -import sinon from 'sinon' -import migration50 from '../../../app/scripts/migrations/050' +import { strict as assert } from 'assert'; +import sinon from 'sinon'; +import migration50 from '../../../app/scripts/migrations/050'; const LEGACY_LOCAL_STORAGE_KEYS = [ 'METASWAP_GAS_PRICE_ESTIMATES_LAST_RETRIEVED', @@ -12,18 +12,18 @@ const LEGACY_LOCAL_STORAGE_KEYS = [ 'BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED', 'GAS_API_ESTIMATES_LAST_RETRIEVED', 'GAS_API_ESTIMATES', -] +]; describe('migration #50', function () { - let mockLocalStorageRemoveItem + let mockLocalStorageRemoveItem; beforeEach(function () { - mockLocalStorageRemoveItem = sinon.stub(window.localStorage, 'removeItem') - }) + mockLocalStorageRemoveItem = sinon.stub(window.localStorage, 'removeItem'); + }); afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('should update the version metadata', async function () { const oldStorage = { @@ -31,13 +31,13 @@ describe('migration #50', function () { version: 49, }, data: {}, - } + }; - const newStorage = await migration50.migrate(oldStorage) + const newStorage = await migration50.migrate(oldStorage); assert.deepEqual(newStorage.meta, { version: 50, - }) - }) + }); + }); it('should call window.localStorage.removeItem for each legacy key', async function () { const oldStorage = { @@ -45,45 +45,45 @@ describe('migration #50', function () { version: 49, }, data: {}, - } + }; - await migration50.migrate(oldStorage) - assert.equal(mockLocalStorageRemoveItem.callCount, 9) + await migration50.migrate(oldStorage); + assert.equal(mockLocalStorageRemoveItem.callCount, 9); assert.equal( mockLocalStorageRemoveItem.getCall(0).args[0], LEGACY_LOCAL_STORAGE_KEYS[0], - ) + ); assert.equal( mockLocalStorageRemoveItem.getCall(1).args[0], LEGACY_LOCAL_STORAGE_KEYS[1], - ) + ); assert.equal( mockLocalStorageRemoveItem.getCall(2).args[0], LEGACY_LOCAL_STORAGE_KEYS[2], - ) + ); assert.equal( mockLocalStorageRemoveItem.getCall(3).args[0], LEGACY_LOCAL_STORAGE_KEYS[3], - ) + ); assert.equal( mockLocalStorageRemoveItem.getCall(4).args[0], LEGACY_LOCAL_STORAGE_KEYS[4], - ) + ); assert.equal( mockLocalStorageRemoveItem.getCall(5).args[0], LEGACY_LOCAL_STORAGE_KEYS[5], - ) + ); assert.equal( mockLocalStorageRemoveItem.getCall(6).args[0], LEGACY_LOCAL_STORAGE_KEYS[6], - ) + ); assert.equal( mockLocalStorageRemoveItem.getCall(7).args[0], LEGACY_LOCAL_STORAGE_KEYS[7], - ) + ); assert.equal( mockLocalStorageRemoveItem.getCall(8).args[0], LEGACY_LOCAL_STORAGE_KEYS[8], - ) - }) -}) + ); + }); +}); diff --git a/test/unit/migrations/051-test.js b/test/unit/migrations/051-test.js index ae0a78afe0..4d1428a87f 100644 --- a/test/unit/migrations/051-test.js +++ b/test/unit/migrations/051-test.js @@ -1,9 +1,9 @@ -import { strict as assert } from 'assert' -import migration51 from '../../../app/scripts/migrations/051' +import { strict as assert } from 'assert'; +import migration51 from '../../../app/scripts/migrations/051'; import { INFURA_PROVIDER_TYPES, NETWORK_TYPE_TO_ID_MAP, -} from '../../../shared/constants/network' +} from '../../../shared/constants/network'; describe('migration #51', function () { it('should update the version metadata', async function () { @@ -12,13 +12,13 @@ describe('migration #51', function () { version: 50, }, data: {}, - } + }; - const newStorage = await migration51.migrate(oldStorage) + const newStorage = await migration51.migrate(oldStorage); assert.deepEqual(newStorage.meta, { version: 51, - }) - }) + }); + }); describe('setting chainId', function () { INFURA_PROVIDER_TYPES.forEach(function (type) { @@ -36,8 +36,8 @@ describe('migration #51', function () { }, foo: 'bar', }, - } - const newStorage = await migration51.migrate(oldStorage) + }; + const newStorage = await migration51.migrate(oldStorage); assert.deepEqual(newStorage.data, { NetworkController: { settings: { @@ -49,8 +49,8 @@ describe('migration #51', function () { }, }, foo: 'bar', - }) - }) + }); + }); it(`should correctly set the chainId for the Infura network "${type}", if an incorrect chainId is set`, async function () { const oldStorage = { @@ -67,8 +67,8 @@ describe('migration #51', function () { }, foo: 'bar', }, - } - const newStorage = await migration51.migrate(oldStorage) + }; + const newStorage = await migration51.migrate(oldStorage); assert.deepEqual(newStorage.data, { NetworkController: { settings: { @@ -80,9 +80,9 @@ describe('migration #51', function () { }, }, foo: 'bar', - }) - }) - }) + }); + }); + }); it('should not set the chainId for a non-Infura network that does not have chainId set', async function () { const oldStorage = { @@ -97,10 +97,10 @@ describe('migration #51', function () { }, }, }, - } - const newStorage = await migration51.migrate(oldStorage) - assert.deepEqual(newStorage.data, oldStorage.data) - }) + }; + const newStorage = await migration51.migrate(oldStorage); + assert.deepEqual(newStorage.data, oldStorage.data); + }); it('should not set the chainId for a non-Infura network that does have chainId set', async function () { const oldStorage = { @@ -116,9 +116,9 @@ describe('migration #51', function () { }, }, }, - } - const newStorage = await migration51.migrate(oldStorage) - assert.deepEqual(newStorage.data, oldStorage.data) - }) - }) -}) + }; + const newStorage = await migration51.migrate(oldStorage); + assert.deepEqual(newStorage.data, oldStorage.data); + }); + }); +}); diff --git a/test/unit/migrations/migrations-test.js b/test/unit/migrations/migrations-test.js index a61376145d..d5fcd6bdc3 100644 --- a/test/unit/migrations/migrations-test.js +++ b/test/unit/migrations/migrations-test.js @@ -1,91 +1,91 @@ -import assert from 'assert' -import wallet1 from '../../lib/migrations/001.json' -import vault4 from '../../lib/migrations/004.json' -import migration2 from '../../../app/scripts/migrations/002' -import migration3 from '../../../app/scripts/migrations/003' -import migration4 from '../../../app/scripts/migrations/004' -import migration5 from '../../../app/scripts/migrations/005' -import migration6 from '../../../app/scripts/migrations/006' -import migration7 from '../../../app/scripts/migrations/007' -import migration8 from '../../../app/scripts/migrations/008' -import migration9 from '../../../app/scripts/migrations/009' -import migration10 from '../../../app/scripts/migrations/010' -import migration11 from '../../../app/scripts/migrations/011' -import migration12 from '../../../app/scripts/migrations/012' -import migration13 from '../../../app/scripts/migrations/013' +import assert from 'assert'; +import wallet1 from '../../lib/migrations/001.json'; +import vault4 from '../../lib/migrations/004.json'; +import migration2 from '../../../app/scripts/migrations/002'; +import migration3 from '../../../app/scripts/migrations/003'; +import migration4 from '../../../app/scripts/migrations/004'; +import migration5 from '../../../app/scripts/migrations/005'; +import migration6 from '../../../app/scripts/migrations/006'; +import migration7 from '../../../app/scripts/migrations/007'; +import migration8 from '../../../app/scripts/migrations/008'; +import migration9 from '../../../app/scripts/migrations/009'; +import migration10 from '../../../app/scripts/migrations/010'; +import migration11 from '../../../app/scripts/migrations/011'; +import migration12 from '../../../app/scripts/migrations/012'; +import migration13 from '../../../app/scripts/migrations/013'; -let vault5, vault6, vault7, vault8, vault9 // vault10, vault11 +let vault5, vault6, vault7, vault8, vault9; // vault10, vault11 -const oldTestRpc = 'https://rawtestrpc.metamask.io/' -const newTestRpc = 'https://testrpc.metamask.io/' +const oldTestRpc = 'https://rawtestrpc.metamask.io/'; +const newTestRpc = 'https://testrpc.metamask.io/'; describe('wallet1 is migrated successfully', function () { it('should convert providers', function () { - wallet1.data.config.provider = { type: 'etherscan', rpcTarget: null } + wallet1.data.config.provider = { type: 'etherscan', rpcTarget: null }; return migration2 .migrate(wallet1) .then((secondResult) => { - const secondData = secondResult.data + const secondData = secondResult.data; assert.equal( secondData.config.provider.type, 'rpc', 'provider should be rpc', - ) + ); assert.equal( secondData.config.provider.rpcTarget, 'https://rpc.metamask.io/', 'main provider should be our rpc', - ) - secondResult.data.config.provider.rpcTarget = oldTestRpc - return migration3.migrate(secondResult) + ); + secondResult.data.config.provider.rpcTarget = oldTestRpc; + return migration3.migrate(secondResult); }) .then((thirdResult) => { assert.equal( thirdResult.data.config.provider.rpcTarget, newTestRpc, 'config.provider.rpcTarget should be set to the proper testrpc url.', - ) - return migration4.migrate(thirdResult) + ); + return migration4.migrate(thirdResult); }) .then((fourthResult) => { - const fourthData = fourthResult.data + const fourthData = fourthResult.data; assert.equal( fourthData.config.provider.rpcTarget, null, 'old rpcTarget should not exist.', - ) + ); assert.equal( fourthData.config.provider.type, 'testnet', 'config.provider should be set to testnet.', - ) + ); - return migration5.migrate(vault4) + return migration5.migrate(vault4); }) .then((fifthResult) => { - const fifthData = fifthResult.data - assert.equal(fifthData.vault, null, 'old vault should not exist') + const fifthData = fifthResult.data; + assert.equal(fifthData.vault, null, 'old vault should not exist'); assert.equal( fifthData.walletNicknames, null, 'old walletNicknames should not exist', - ) + ); assert.equal( fifthData.config.selectedAccount, null, 'old config.selectedAccount should not exist', - ) + ); assert.equal( fifthData.KeyringController.vault, vault4.data.vault, 'KeyringController.vault should exist', - ) + ); assert.equal( fifthData.KeyringController.selectedAccount, vault4.data.config.selectedAccount, 'KeyringController.selectedAccount should have moved', - ) + ); assert.equal( fifthData.KeyringController.walletNicknames[ '0x0beb674745816b125fbc07285d39fd373e64895c' @@ -94,159 +94,159 @@ describe('wallet1 is migrated successfully', function () { '0x0beb674745816b125fbc07285d39fd373e64895c' ], 'KeyringController.walletNicknames should have moved', - ) + ); - vault5 = fifthResult - return migration6.migrate(fifthResult) + vault5 = fifthResult; + return migration6.migrate(fifthResult); }) .then((sixthResult) => { assert.equal( sixthResult.data.KeyringController.selectedAccount, null, 'old selectedAccount should not exist', - ) + ); assert.equal( sixthResult.data.PreferencesController.selectedAddress, vault5.data.KeyringController.selectedAccount, 'selectedAccount should have moved', - ) + ); - vault6 = sixthResult - return migration7.migrate(sixthResult) + vault6 = sixthResult; + return migration7.migrate(sixthResult); }) .then((seventhResult) => { assert.equal( seventhResult.data.transactions, null, 'old transactions should not exist', - ) + ); assert.equal( seventhResult.data.gasMultiplier, null, 'old gasMultiplier should not exist', - ) + ); assert.equal( seventhResult.data.TransactionManager.transactions[0].id, vault6.data.transactions[0].id, 'transactions should have moved', - ) + ); assert.equal( seventhResult.data.TransactionManager.gasMultiplier, vault6.data.gasMultiplier, 'gasMultiplier should have moved', - ) + ); - vault7 = seventhResult - return migration8.migrate(seventhResult) + vault7 = seventhResult; + return migration8.migrate(seventhResult); }) .then((eighthResult) => { assert.equal( eighthResult.data.noticesList, null, 'old noticesList should not exist', - ) + ); assert.equal( eighthResult.data.NoticeController.noticesList[0].title, vault7.data.noticesList[0].title, 'noticesList should have moved', - ) + ); - vault8 = eighthResult - return migration9.migrate(eighthResult) + vault8 = eighthResult; + return migration9.migrate(eighthResult); }) .then((ninthResult) => { assert.equal( ninthResult.data.currentFiat, null, 'old currentFiat should not exist', - ) + ); assert.equal( ninthResult.data.fiatCurrency, null, 'old fiatCurrency should not exist', - ) + ); assert.equal( ninthResult.data.conversionRate, null, 'old conversionRate should not exist', - ) + ); assert.equal( ninthResult.data.conversionDate, null, 'old conversionDate should not exist', - ) + ); assert.equal( ninthResult.data.CurrencyController.currentCurrency, vault8.data.fiatCurrency, 'currentFiat should have moved', - ) + ); assert.equal( ninthResult.data.CurrencyController.conversionRate, vault8.data.conversionRate, 'conversionRate should have moved', - ) + ); assert.equal( ninthResult.data.CurrencyController.conversionDate, vault8.data.conversionDate, 'conversionDate should have moved', - ) + ); - vault9 = ninthResult - return migration10.migrate(ninthResult) + vault9 = ninthResult; + return migration10.migrate(ninthResult); }) .then((tenthResult) => { assert.equal( tenthResult.data.shapeShiftTxList, null, 'old shapeShiftTxList should not exist', - ) + ); assert.equal( tenthResult.data.ShapeShiftController.shapeShiftTxList[0].transaction, vault9.data.shapeShiftTxList[0].transaction, - ) + ); - return migration11.migrate(tenthResult) + return migration11.migrate(tenthResult); }) .then((eleventhResult) => { assert.equal( eleventhResult.data.isDisclaimerConfirmed, null, 'isDisclaimerConfirmed should not exist', - ) + ); assert.equal( eleventhResult.data.TOSHash, null, 'TOSHash should not exist', - ) + ); - return migration12.migrate(eleventhResult) + return migration12.migrate(eleventhResult); }) .then((twelfthResult) => { assert.equal( twelfthResult.data.NoticeController.noticesList[0].body, '', 'notices that have been read should have an empty body.', - ) + ); assert.equal( twelfthResult.data.NoticeController.noticesList[1].body, 'nonempty', 'notices that have not been read should not have an empty body.', - ) + ); assert.equal( twelfthResult.data.config.provider.type, 'testnet', 'network is originally testnet.', - ) - return migration13.migrate(twelfthResult) + ); + return migration13.migrate(twelfthResult); }) .then((thirteenthResult) => { assert.equal( thirteenthResult.data.config.provider.type, 'ropsten', 'network has been changed to ropsten.', - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/test/unit/migrations/migrator-test.js b/test/unit/migrations/migrator-test.js index 7c50015968..ee20cc7a63 100644 --- a/test/unit/migrations/migrator-test.js +++ b/test/unit/migrations/migrator-test.js @@ -1,107 +1,107 @@ -import fs from 'fs' -import assert from 'assert' -import { cloneDeep } from 'lodash' -import Migrator from '../../../app/scripts/lib/migrator' -import liveMigrations from '../../../app/scripts/migrations' -import data from '../../../app/scripts/first-time-state' +import fs from 'fs'; +import assert from 'assert'; +import { cloneDeep } from 'lodash'; +import Migrator from '../../../app/scripts/lib/migrator'; +import liveMigrations from '../../../app/scripts/migrations'; +import data from '../../../app/scripts/first-time-state'; const stubMigrations = [ { version: 1, migrate: (state) => { // clone the data just like we do in migrations - const clonedData = cloneDeep(state) - clonedData.meta.version = 1 - return Promise.resolve(clonedData) + const clonedData = cloneDeep(state); + clonedData.meta.version = 1; + return Promise.resolve(clonedData); }, }, { version: 2, migrate: (state) => { - const clonedData = cloneDeep(state) - clonedData.meta.version = 2 - return Promise.resolve(clonedData) + const clonedData = cloneDeep(state); + clonedData.meta.version = 2; + return Promise.resolve(clonedData); }, }, { version: 3, migrate: (state) => { - const clonedData = cloneDeep(state) - clonedData.meta.version = 3 - return Promise.resolve(clonedData) + const clonedData = cloneDeep(state); + clonedData.meta.version = 3; + return Promise.resolve(clonedData); }, }, -] -const versionedData = { meta: { version: 0 }, data: { hello: 'world' } } +]; +const versionedData = { meta: { version: 0 }, data: { hello: 'world' } }; const firstTimeState = { meta: { version: 0 }, data, -} +}; describe('migrations', function () { describe('liveMigrations require list', function () { - let migrationNumbers + let migrationNumbers; before(function () { - const fileNames = fs.readdirSync('./app/scripts/migrations/') + const fileNames = fs.readdirSync('./app/scripts/migrations/'); migrationNumbers = fileNames .reduce((acc, filename) => { - const name = filename.split('.')[0] + const name = filename.split('.')[0]; if (/^\d+$/u.test(name)) { - acc.push(name) + acc.push(name); } - return acc + return acc; }, []) - .map((num) => parseInt(num, 10)) - }) + .map((num) => parseInt(num, 10)); + }); it('should include all migrations', function () { migrationNumbers.forEach((num) => { - const migration = liveMigrations.find((m) => m.version === num) + const migration = liveMigrations.find((m) => m.version === num); assert( migration, `migration not included in 'migrations/index.js': ${num}`, - ) - }) - }) + ); + }); + }); it('should have tests for all migrations', function () { - const fileNames = fs.readdirSync('./test/unit/migrations/') + const fileNames = fs.readdirSync('./test/unit/migrations/'); const testNumbers = fileNames .reduce((acc, filename) => { - const name = filename.split('-test.')[0] + const name = filename.split('-test.')[0]; if (/^\d+$/u.test(name)) { - acc.push(name) + acc.push(name); } - return acc + return acc; }, []) - .map((num) => parseInt(num, 10)) + .map((num) => parseInt(num, 10)); migrationNumbers.forEach((num) => { if (num >= 33) { assert.ok( testNumbers.includes(num), `no test found for migration: ${num}`, - ) + ); } - }) - }) - }) + }); + }); + }); describe('Migrator', function () { it('migratedData version should be version 3', async function () { - const migrator = new Migrator({ migrations: stubMigrations }) - const migratedData = await migrator.migrateData(versionedData) - assert.equal(migratedData.meta.version, stubMigrations[2].version) - }) + const migrator = new Migrator({ migrations: stubMigrations }); + const migratedData = await migrator.migrateData(versionedData); + assert.equal(migratedData.meta.version, stubMigrations[2].version); + }); it('should match the last version in live migrations', async function () { - const migrator = new Migrator({ migrations: liveMigrations }) - const migratedData = await migrator.migrateData(firstTimeState) - const last = liveMigrations.length - 1 - assert.equal(migratedData.meta.version, liveMigrations[last].version) - }) + const migrator = new Migrator({ migrations: liveMigrations }); + const migratedData = await migrator.migrateData(firstTimeState); + const last = liveMigrations.length - 1; + assert.equal(migratedData.meta.version, liveMigrations[last].version); + }); it('should emit an error', async function () { const migrator = new Migrator({ @@ -109,12 +109,12 @@ describe('migrations', function () { { version: 1, async migrate() { - throw new Error('test') + throw new Error('test'); }, }, ], - }) - await assert.rejects(migrator.migrateData({ meta: { version: 0 } })) - }) - }) -}) + }); + await assert.rejects(migrator.migrateData({ meta: { version: 0 } })); + }); + }); +}); diff --git a/test/unit/migrations/template-test.js b/test/unit/migrations/template-test.js index ca74b30f0b..79b127ed98 100644 --- a/test/unit/migrations/template-test.js +++ b/test/unit/migrations/template-test.js @@ -1,19 +1,19 @@ -import assert from 'assert' -import migrationTemplate from '../../../app/scripts/migrations/template' +import assert from 'assert'; +import migrationTemplate from '../../../app/scripts/migrations/template'; const storage = { meta: {}, data: {}, -} +}; describe('storage is migrated successfully', function () { it('should work', function (done) { migrationTemplate .migrate(storage) .then((migratedData) => { - assert.equal(migratedData.meta.version, 0) - done() + assert.equal(migratedData.meta.version, 0); + done(); }) - .catch(done) - }) -}) + .catch(done); + }); +}); diff --git a/test/unit/responsive/components/dropdown-test.js b/test/unit/responsive/components/dropdown-test.js index fc550a6fd6..a7f83b07d7 100644 --- a/test/unit/responsive/components/dropdown-test.js +++ b/test/unit/responsive/components/dropdown-test.js @@ -1,15 +1,15 @@ -import assert from 'assert' -import React from 'react' -import configureMockStore from 'redux-mock-store' -import { fireEvent } from '@testing-library/react' -import sinon from 'sinon' -import { renderWithProvider } from '../../../lib/render-helpers' -import { Dropdown } from '../../../../ui/app/components/app/dropdowns/components/dropdown' +import assert from 'assert'; +import React from 'react'; +import configureMockStore from 'redux-mock-store'; +import { fireEvent } from '@testing-library/react'; +import sinon from 'sinon'; +import { renderWithProvider } from '../../../lib/render-helpers'; +import { Dropdown } from '../../../../ui/app/components/app/dropdowns/components/dropdown'; describe('Dropdown components', function () { const mockState = { metamask: {}, - } + }; const props = { isOpen: true, @@ -21,12 +21,12 @@ describe('Dropdown components', function () { top: '36px', }, innerStyle: {}, - } + }; it('invokes click handler when item clicked', function () { - const store = configureMockStore()(mockState) + const store = configureMockStore()(mockState); - const onClickSpy = sinon.spy() + const onClickSpy = sinon.spy(); const { getByText } = renderWithProvider( @@ -34,11 +34,11 @@ describe('Dropdown components', function () {
  • Item 2
  • , store, - ) + ); - const item1 = getByText(/Item 1/u) - fireEvent.click(item1) + const item1 = getByText(/Item 1/u); + fireEvent.click(item1); - assert.ok(onClickSpy.calledOnce) - }) -}) + assert.ok(onClickSpy.calledOnce); + }); +}); diff --git a/test/unit/ui/app/actions.spec.js b/test/unit/ui/app/actions.spec.js index 6a02830a89..5cb2484346 100644 --- a/test/unit/ui/app/actions.spec.js +++ b/test/unit/ui/app/actions.spec.js @@ -1,30 +1,30 @@ -import assert from 'assert' -import sinon from 'sinon' -import configureStore from 'redux-mock-store' -import thunk from 'redux-thunk' -import EthQuery from 'eth-query' -import Eth from 'ethjs' -import { createTestProviderTools } from '../../../stub/provider' -import enLocale from '../../../../app/_locales/en/messages.json' -import * as actions from '../../../../ui/app/store/actions' -import MetaMaskController from '../../../../app/scripts/metamask-controller' -import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction' - -const { provider } = createTestProviderTools({ scaffold: {} }) -const middleware = [thunk] +import assert from 'assert'; +import sinon from 'sinon'; +import configureStore from 'redux-mock-store'; +import thunk from 'redux-thunk'; +import EthQuery from 'eth-query'; +import Eth from 'ethjs'; +import { createTestProviderTools } from '../../../stub/provider'; +import enLocale from '../../../../app/_locales/en/messages.json'; +import * as actions from '../../../../ui/app/store/actions'; +import MetaMaskController from '../../../../app/scripts/metamask-controller'; +import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'; + +const { provider } = createTestProviderTools({ scaffold: {} }); +const middleware = [thunk]; const defaultState = { metamask: { currentLocale: 'test', selectedAddress: '0xFirstAddress', provider: { chainId: '0x1' }, }, -} -const mockStore = (state = defaultState) => configureStore(middleware)(state) +}; +const mockStore = (state = defaultState) => configureStore(middleware)(state); describe('Actions', function () { - let background + let background; - const currentNetworkId = '42' + const currentNetworkId = '42'; beforeEach(async function () { background = sinon.createStubInstance(MetaMaskController, { @@ -34,28 +34,28 @@ describe('Actions', function () { selectedAddress: '0xFirstAddress', }), ), - }) + }); - global.ethQuery = new EthQuery(provider) - }) + global.ethQuery = new EthQuery(provider); + }); describe('#tryUnlockMetamask', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls submitPassword and verifySeedPhrase', async function () { - const store = mockStore() + const store = mockStore(); const submitPassword = background.submitPassword.callsFake((_, cb) => cb(), - ) + ); const verifySeedPhrase = background.verifySeedPhrase.callsFake((cb) => cb(), - ) + ); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, @@ -69,95 +69,95 @@ describe('Actions', function () { }, }, { type: 'HIDE_LOADING_INDICATION' }, - ] + ]; - await store.dispatch(actions.tryUnlockMetamask()) + await store.dispatch(actions.tryUnlockMetamask()); - assert(submitPassword.calledOnce) - assert(verifySeedPhrase.calledOnce) + assert(submitPassword.calledOnce); + assert(verifySeedPhrase.calledOnce); - assert.deepStrictEqual(store.getActions(), expectedActions) - }) + assert.deepStrictEqual(store.getActions(), expectedActions); + }); it('errors on submitPassword will fail', async function () { - const store = mockStore() + const store = mockStore(); - background.submitPassword.callsFake((_, cb) => cb(new Error('error'))) + background.submitPassword.callsFake((_, cb) => cb(new Error('error'))); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'UNLOCK_IN_PROGRESS' }, { type: 'UNLOCK_FAILED', value: 'error' }, { type: 'HIDE_LOADING_INDICATION' }, - ] + ]; try { - await store.dispatch(actions.tryUnlockMetamask('test')) - assert.fail('Should have thrown error') + await store.dispatch(actions.tryUnlockMetamask('test')); + assert.fail('Should have thrown error'); } catch (_) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) + }); it('displays warning error and unlock failed when verifySeed fails', async function () { - const store = mockStore() + const store = mockStore(); - background.submitPassword.callsFake((_, cb) => cb()) + background.submitPassword.callsFake((_, cb) => cb()); background.verifySeedPhrase.callsFake((cb) => { - cb(new Error('error')) - }) + cb(new Error('error')); + }); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); - const displayWarningError = [{ type: 'DISPLAY_WARNING', value: 'error' }] - const unlockFailedError = [{ type: 'UNLOCK_FAILED', value: 'error' }] + const displayWarningError = [{ type: 'DISPLAY_WARNING', value: 'error' }]; + const unlockFailedError = [{ type: 'UNLOCK_FAILED', value: 'error' }]; try { - await store.dispatch(actions.tryUnlockMetamask('test')) - assert.fail('Should have thrown error') + await store.dispatch(actions.tryUnlockMetamask('test')); + assert.fail('Should have thrown error'); } catch (_) { - const actions1 = store.getActions() + const actions1 = store.getActions(); const warning = actions1.filter( (action) => action.type === 'DISPLAY_WARNING', - ) + ); const unlockFailed = actions1.filter( (action) => action.type === 'UNLOCK_FAILED', - ) - assert.deepStrictEqual(warning, displayWarningError) - assert.deepStrictEqual(unlockFailed, unlockFailedError) + ); + assert.deepStrictEqual(warning, displayWarningError); + assert.deepStrictEqual(unlockFailed, unlockFailedError); } - }) - }) + }); + }); describe('#createNewVaultAndRestore', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls createNewVaultAndRestore', async function () { - const store = mockStore() + const store = mockStore(); const createNewVaultAndRestore = background.createNewVaultAndRestore.callsFake( (_, __, cb) => cb(), - ) + ); - background.unMarkPasswordForgotten.callsFake((cb) => cb()) + background.unMarkPasswordForgotten.callsFake((cb) => cb()); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); - await store.dispatch(actions.createNewVaultAndRestore()) - assert(createNewVaultAndRestore.calledOnce) - }) + await store.dispatch(actions.createNewVaultAndRestore()); + assert(createNewVaultAndRestore.calledOnce); + }); it('calls the expected actions', async function () { - const store = mockStore() + const store = mockStore(); - background.createNewVaultAndRestore.callsFake((_, __, cb) => cb()) - background.unMarkPasswordForgotten.callsFake((cb) => cb()) + background.createNewVaultAndRestore.callsFake((_, __, cb) => cb()); + background.unMarkPasswordForgotten.callsFake((cb) => cb()); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, @@ -171,102 +171,102 @@ describe('Actions', function () { }, { type: 'SHOW_ACCOUNTS_PAGE' }, { type: 'HIDE_LOADING_INDICATION' }, - ] + ]; - await store.dispatch(actions.createNewVaultAndRestore()) + await store.dispatch(actions.createNewVaultAndRestore()); - assert.deepStrictEqual(store.getActions(), expectedActions) - }) + assert.deepStrictEqual(store.getActions(), expectedActions); + }); it('errors when callback in createNewVaultAndRestore throws', async function () { - const store = mockStore() + const store = mockStore(); background.createNewVaultAndRestore.callsFake((_, __, cb) => cb(new Error('error')), - ) + ); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'DISPLAY_WARNING', value: 'error' }, { type: 'HIDE_LOADING_INDICATION' }, - ] + ]; try { - await store.dispatch(actions.createNewVaultAndRestore()) - assert.fail('Should have thrown error') + await store.dispatch(actions.createNewVaultAndRestore()); + assert.fail('Should have thrown error'); } catch (_) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) - }) + }); + }); describe('#requestRevealSeedWords', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls verifyPassword in background', async function () { - const store = mockStore() + const store = mockStore(); const verifyPassword = background.verifyPassword.callsFake((_, cb) => cb(), - ) + ); const verifySeedPhrase = background.verifySeedPhrase.callsFake((cb) => cb(), - ) + ); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); - await store.dispatch(actions.requestRevealSeedWords()) - assert(verifyPassword.calledOnce) - assert(verifySeedPhrase.calledOnce) - }) + await store.dispatch(actions.requestRevealSeedWords()); + assert(verifyPassword.calledOnce); + assert(verifySeedPhrase.calledOnce); + }); it('displays warning error message then callback in background errors', async function () { - const store = mockStore() + const store = mockStore(); - background.verifyPassword.callsFake((_, cb) => cb()) + background.verifyPassword.callsFake((_, cb) => cb()); background.verifySeedPhrase.callsFake((cb) => { - cb(new Error('error')) - }) + cb(new Error('error')); + }); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'DISPLAY_WARNING', value: 'error' }, { type: 'HIDE_LOADING_INDICATION' }, - ] + ]; try { - await store.dispatch(actions.requestRevealSeedWords()) - assert.fail('Should have thrown error') + await store.dispatch(actions.requestRevealSeedWords()); + assert.fail('Should have thrown error'); } catch (_) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) - }) + }); + }); describe('#removeAccount', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls removeAccount in background and expect actions to show account', async function () { - const store = mockStore() + const store = mockStore(); background.getState.callsFake((cb) => cb(null, { currentLocale: 'test', selectedAddress: '0xAnotherAddress', }), - ) + ); - const removeAccount = background.removeAccount.callsFake((_, cb) => cb()) + const removeAccount = background.removeAccount.callsFake((_, cb) => cb()); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ 'SHOW_LOADING_INDICATION', @@ -274,122 +274,122 @@ describe('Actions', function () { 'UPDATE_METAMASK_STATE', 'HIDE_LOADING_INDICATION', 'SHOW_ACCOUNTS_PAGE', - ] + ]; await store.dispatch( actions.removeAccount('0xe18035bf8712672935fdb4e5e431b1a0183d2dfc'), - ) - assert(removeAccount.calledOnce) - const actionTypes = store.getActions().map((action) => action.type) - assert.deepStrictEqual(actionTypes, expectedActions) - }) + ); + assert(removeAccount.calledOnce); + const actionTypes = store.getActions().map((action) => action.type); + assert.deepStrictEqual(actionTypes, expectedActions); + }); it('displays warning error message when removeAccount callback errors', async function () { - const store = mockStore() + const store = mockStore(); background.removeAccount.callsFake((_, cb) => { - cb(new Error('error')) - }) + cb(new Error('error')); + }); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ 'SHOW_LOADING_INDICATION', 'DISPLAY_WARNING', 'HIDE_LOADING_INDICATION', - ] + ]; try { await store.dispatch( actions.removeAccount('0xe18035bf8712672935fdb4e5e431b1a0183d2dfc'), - ) - assert.fail('Should have thrown error') + ); + assert.fail('Should have thrown error'); } catch (_) { - const actionTypes = store.getActions().map((action) => action.type) - assert.deepStrictEqual(actionTypes, expectedActions) + const actionTypes = store.getActions().map((action) => action.type); + assert.deepStrictEqual(actionTypes, expectedActions); } - }) - }) + }); + }); describe('#resetAccount', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('resets account', async function () { - const store = mockStore() + const store = mockStore(); - const resetAccount = background.resetAccount.callsFake((cb) => cb()) + const resetAccount = background.resetAccount.callsFake((cb) => cb()); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'HIDE_LOADING_INDICATION' }, { type: 'SHOW_ACCOUNTS_PAGE' }, - ] + ]; - await store.dispatch(actions.resetAccount()) - assert(resetAccount.calledOnce) - assert.deepStrictEqual(store.getActions(), expectedActions) - }) + await store.dispatch(actions.resetAccount()); + assert(resetAccount.calledOnce); + assert.deepStrictEqual(store.getActions(), expectedActions); + }); it('throws if resetAccount throws', async function () { - const store = mockStore() + const store = mockStore(); background.resetAccount.callsFake((cb) => { - cb(new Error('error')) - }) + cb(new Error('error')); + }); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'HIDE_LOADING_INDICATION' }, { type: 'DISPLAY_WARNING', value: 'error' }, - ] + ]; try { - await store.dispatch(actions.resetAccount()) - assert.fail('Should have thrown error') + await store.dispatch(actions.resetAccount()); + assert.fail('Should have thrown error'); } catch (_) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) - }) + }); + }); describe('#importNewAccount', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls importAccountWithStrategies in background', async function () { - const store = mockStore() + const store = mockStore(); const importAccountWithStrategy = background.importAccountWithStrategy.callsFake( (_, __, cb) => { - cb() + cb(); }, - ) + ); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); await store.dispatch( actions.importNewAccount('Private Key', [ 'c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3', ]), - ) - assert(importAccountWithStrategy.calledOnce) - }) + ); + assert(importAccountWithStrategy.calledOnce); + }); it('displays warning error message when importAccount in background callback errors', async function () { - const store = mockStore() + const store = mockStore(); background.importAccountWithStrategy.callsFake((_, __, cb) => cb(new Error('error')), - ) + ); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { @@ -398,169 +398,169 @@ describe('Actions', function () { }, { type: 'DISPLAY_WARNING', value: 'error' }, { type: 'HIDE_LOADING_INDICATION' }, - ] + ]; try { - await store.dispatch(actions.importNewAccount()) - assert.fail('Should have thrown error') + await store.dispatch(actions.importNewAccount()); + assert.fail('Should have thrown error'); } catch (_) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) - }) + }); + }); describe('#addNewAccount', function () { it('Adds a new account', async function () { - const store = mockStore({ metamask: { identities: {} } }) + const store = mockStore({ metamask: { identities: {} } }); const addNewAccount = background.addNewAccount.callsFake((cb) => cb(null, { identities: {}, }), - ) + ); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); - await store.dispatch(actions.addNewAccount()) - assert(addNewAccount.calledOnce) - }) + await store.dispatch(actions.addNewAccount()); + assert(addNewAccount.calledOnce); + }); it('displays warning error message when addNewAccount in background callback errors', async function () { - const store = mockStore() + const store = mockStore(); background.addNewAccount.callsFake((cb) => { - cb(new Error('error')) - }) + cb(new Error('error')); + }); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'DISPLAY_WARNING', value: 'error' }, { type: 'HIDE_LOADING_INDICATION' }, - ] + ]; try { - await store.dispatch(actions.addNewAccount()) - assert.fail('Should have thrown error') + await store.dispatch(actions.addNewAccount()); + assert.fail('Should have thrown error'); } catch (_) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) - }) + }); + }); describe('#checkHardwareStatus', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls checkHardwareStatus in background', async function () { - const store = mockStore() + const store = mockStore(); const checkHardwareStatus = background.checkHardwareStatus.callsFake( (_, __, cb) => { - cb() + cb(); }, - ) + ); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); await store.dispatch( actions.checkHardwareStatus('ledger', `m/44'/60'/0'/0`), - ) - assert.strictEqual(checkHardwareStatus.calledOnce, true) - }) + ); + assert.strictEqual(checkHardwareStatus.calledOnce, true); + }); it('shows loading indicator and displays error', async function () { - const store = mockStore() + const store = mockStore(); background.checkHardwareStatus.callsFake((_, __, cb) => cb(new Error('error')), - ) + ); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'DISPLAY_WARNING', value: 'error' }, { type: 'HIDE_LOADING_INDICATION' }, - ] + ]; try { - await store.dispatch(actions.checkHardwareStatus()) - assert.fail('Should have thrown error') + await store.dispatch(actions.checkHardwareStatus()); + assert.fail('Should have thrown error'); } catch (_) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) - }) + }); + }); describe('#forgetDevice', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls forgetDevice in background', async function () { - const store = mockStore() + const store = mockStore(); - const forgetDevice = background.forgetDevice.callsFake((_, cb) => cb()) + const forgetDevice = background.forgetDevice.callsFake((_, cb) => cb()); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); - await store.dispatch(actions.forgetDevice('ledger')) - assert(forgetDevice.calledOnce) - }) + await store.dispatch(actions.forgetDevice('ledger')); + assert(forgetDevice.calledOnce); + }); it('shows loading indicator and displays error', async function () { - const store = mockStore() + const store = mockStore(); - background.forgetDevice.callsFake((_, cb) => cb(new Error('error'))) + background.forgetDevice.callsFake((_, cb) => cb(new Error('error'))); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'DISPLAY_WARNING', value: 'error' }, { type: 'HIDE_LOADING_INDICATION' }, - ] + ]; try { - await store.dispatch(actions.forgetDevice()) - assert.fail('Should have thrown error') + await store.dispatch(actions.forgetDevice()); + assert.fail('Should have thrown error'); } catch (_) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) - }) + }); + }); describe('#connectHardware', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls connectHardware in background', async function () { - const store = mockStore() + const store = mockStore(); const connectHardware = background.connectHardware.callsFake( (_, __, ___, cb) => cb(), - ) + ); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); await store.dispatch( actions.connectHardware('ledger', 0, `m/44'/60'/0'/0`), - ) - assert(connectHardware.calledOnce) - }) + ); + assert(connectHardware.calledOnce); + }); it('shows loading indicator and displays error', async function () { - const store = mockStore() + const store = mockStore(); background.connectHardware.callsFake((_, __, ___, cb) => cb(new Error('error')), - ) + ); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { @@ -569,67 +569,67 @@ describe('Actions', function () { }, { type: 'DISPLAY_WARNING', value: 'error' }, { type: 'HIDE_LOADING_INDICATION' }, - ] + ]; try { - await store.dispatch(actions.connectHardware('ledger')) - assert.fail('Should have thrown error') + await store.dispatch(actions.connectHardware('ledger')); + assert.fail('Should have thrown error'); } catch (_) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) - }) + }); + }); describe('#unlockHardwareWalletAccount', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls unlockHardwareWalletAccount in background', async function () { - const store = mockStore() + const store = mockStore(); const unlockHardwareWalletAccount = background.unlockHardwareWalletAccount.callsFake( (_, __, ___, cb) => cb(), - ) + ); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); await store.dispatch( actions.unlockHardwareWalletAccount('ledger', 0, `m/44'/60'/0'/0`), - ) - assert(unlockHardwareWalletAccount.calledOnce) - }) + ); + assert(unlockHardwareWalletAccount.calledOnce); + }); it('shows loading indicator and displays error', async function () { - const store = mockStore() + const store = mockStore(); background.unlockHardwareWalletAccount.callsFake((_, __, ___, cb) => cb(new Error('error')), - ) + ); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'HIDE_LOADING_INDICATION' }, { type: 'DISPLAY_WARNING', value: 'error' }, - ] + ]; try { - await store.dispatch(actions.unlockHardwareWalletAccount()) - assert.fail('Should have thrown error') + await store.dispatch(actions.unlockHardwareWalletAccount()); + assert.fail('Should have thrown error'); } catch (error) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) - }) + }); + }); describe('#setCurrentCurrency', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls setCurrentCurrency', async function () { - const store = mockStore() + const store = mockStore(); const setCurrentCurrency = background.setCurrentCurrency.callsFake( (_, cb) => cb(null, { @@ -637,31 +637,33 @@ describe('Actions', function () { conversionRate: 100, conversionDate: 1611839083653, }), - ) + ); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); - await store.dispatch(actions.setCurrentCurrency('jpy')) - assert(setCurrentCurrency.calledOnce) - }) + await store.dispatch(actions.setCurrentCurrency('jpy')); + assert(setCurrentCurrency.calledOnce); + }); it('throws if setCurrentCurrency throws', async function () { - const store = mockStore() + const store = mockStore(); - background.setCurrentCurrency.callsFake((_, cb) => cb(new Error('error'))) + background.setCurrentCurrency.callsFake((_, cb) => + cb(new Error('error')), + ); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'DISPLAY_WARNING', value: 'error' }, { type: 'HIDE_LOADING_INDICATION' }, - ] + ]; - await store.dispatch(actions.setCurrentCurrency()) - assert.deepStrictEqual(store.getActions(), expectedActions) - }) - }) + await store.dispatch(actions.setCurrentCurrency()); + assert.deepStrictEqual(store.getActions(), expectedActions); + }); + }); describe('#signMsg', function () { const msgParams = { @@ -669,94 +671,94 @@ describe('Actions', function () { from: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', data: '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0', - } + }; afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls signMsg in background', async function () { - const store = mockStore() + const store = mockStore(); const signMessage = background.signMessage.callsFake((_, cb) => cb(null, defaultState), - ) + ); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); - await store.dispatch(actions.signMsg(msgParams)) - assert(signMessage.calledOnce) - }) + await store.dispatch(actions.signMsg(msgParams)); + assert(signMessage.calledOnce); + }); it('errors when signMessage in background throws', async function () { - const store = mockStore() + const store = mockStore(); - background.signMessage.callsFake((_, cb) => cb(new Error('error'))) + background.signMessage.callsFake((_, cb) => cb(new Error('error'))); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'DISPLAY_WARNING', value: 'error' }, { type: 'HIDE_LOADING_INDICATION' }, - ] + ]; try { - await store.dispatch(actions.signMsg(msgParams)) - assert.fail('Should have thrown error') + await store.dispatch(actions.signMsg(msgParams)); + assert.fail('Should have thrown error'); } catch (_) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) - }) + }); + }); describe('#signPersonalMsg', function () { const msgParams = { from: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', data: '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0', - } + }; afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls signPersonalMessage', async function () { - const store = mockStore() + const store = mockStore(); const signPersonalMessage = background.signPersonalMessage.callsFake( (_, cb) => cb(null, defaultState), - ) + ); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); - await store.dispatch(actions.signPersonalMsg(msgParams)) - assert(signPersonalMessage.calledOnce) - }) + await store.dispatch(actions.signPersonalMsg(msgParams)); + assert(signPersonalMessage.calledOnce); + }); it('throws if signPersonalMessage throws', async function () { - const store = mockStore() + const store = mockStore(); background.signPersonalMessage.callsFake((_, cb) => { - cb(new Error('error')) - }) + cb(new Error('error')); + }); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'DISPLAY_WARNING', value: 'error' }, { type: 'HIDE_LOADING_INDICATION' }, - ] + ]; try { - await store.dispatch(actions.signPersonalMsg(msgParams)) - assert.fail('Should have thrown error') + await store.dispatch(actions.signPersonalMsg(msgParams)); + assert.fail('Should have thrown error'); } catch (_) { - assert.deepEqual(store.getActions(), expectedActions) + assert.deepEqual(store.getActions(), expectedActions); } - }) - }) + }); + }); describe('#signTypedMsg', function () { const msgParamsV3 = { @@ -797,83 +799,83 @@ describe('Actions', function () { contents: 'Hello, Bob!', }, }), - } + }; afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls signTypedMsg in background with no error', async function () { - const store = mockStore() + const store = mockStore(); const signTypedMsg = background.signTypedMessage.callsFake((_, cb) => cb(null, defaultState), - ) + ); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); - await store.dispatch(actions.signTypedMsg(msgParamsV3)) - assert(signTypedMsg.calledOnce) - }) + await store.dispatch(actions.signTypedMsg(msgParamsV3)); + assert(signTypedMsg.calledOnce); + }); it('returns expected actions with error', async function () { - const store = mockStore() + const store = mockStore(); - background.signTypedMessage.callsFake((_, cb) => cb(new Error('error'))) + background.signTypedMessage.callsFake((_, cb) => cb(new Error('error'))); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'DISPLAY_WARNING', value: 'error' }, { type: 'HIDE_LOADING_INDICATION' }, - ] + ]; try { - await store.dispatch(actions.signTypedMsg()) - assert.fail('Should have thrown error') + await store.dispatch(actions.signTypedMsg()); + assert.fail('Should have thrown error'); } catch (_) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) - }) + }); + }); describe('#signTx', function () { - let sendTransaction + let sendTransaction; beforeEach(function () { - sendTransaction = sinon.stub(global.ethQuery, 'sendTransaction') - }) + sendTransaction = sinon.stub(global.ethQuery, 'sendTransaction'); + }); afterEach(function () { - sendTransaction.restore() - }) + sendTransaction.restore(); + }); it('calls sendTransaction in global ethQuery', function () { - const store = mockStore() + const store = mockStore(); - store.dispatch(actions.signTx()) - assert(sendTransaction.calledOnce) - }) + store.dispatch(actions.signTx()); + assert(sendTransaction.calledOnce); + }); it('errors in when sendTransaction throws', function () { - const store = mockStore() + const store = mockStore(); const expectedActions = [ { type: 'DISPLAY_WARNING', value: 'error' }, { type: 'SHOW_CONF_TX_PAGE', id: undefined }, - ] + ]; sendTransaction.callsFake((_, callback) => { - callback(new Error('error')) - }) + callback(new Error('error')); + }); - store.dispatch(actions.signTx()) - assert.deepStrictEqual(store.getActions(), expectedActions) - }) - }) + store.dispatch(actions.signTx()); + assert.deepStrictEqual(store.getActions(), expectedActions); + }); + }); describe('#updatedGasData', function () { it('errors when get code does not return', async function () { - const store = mockStore() + const store = mockStore(); const expectedActions = [ { type: 'GAS_LOADING_STARTED' }, @@ -882,7 +884,7 @@ describe('Actions', function () { value: { gasLoadingError: 'gasLoadingError' }, }, { type: 'GAS_LOADING_FINISHED' }, - ] + ]; const mockData = { gasPrice: '0x3b9aca00', // @@ -890,15 +892,15 @@ describe('Actions', function () { selectedAddress: '0x0DCD5D886577d5081B0c52e242Ef29E70Be3E7bc', to: '0xEC1Adf982415D2Ef5ec55899b9Bfb8BC0f29251B', value: '0xde0b6b3a7640000', // 1000000000000000000 - } + }; try { - await store.dispatch(actions.updateGasData(mockData)) - assert.fail('Should have thrown error') + await store.dispatch(actions.updateGasData(mockData)); + assert.fail('Should have thrown error'); } catch (error) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) + }); it('returns default gas limit for basic eth transaction', async function () { const mockData = { @@ -907,12 +909,12 @@ describe('Actions', function () { selectedAddress: '0x0DCD5D886577d5081B0c52e242Ef29E70Be3E7bc', to: '0xEC1Adf982415D2Ef5ec55899b9Bfb8BC0f29251B', value: '0xde0b6b3a7640000', // 1000000000000000000 - } + }; global.eth = { getCode: sinon.stub().returns('0x'), - } - const store = mockStore() + }; + const store = mockStore(); const expectedActions = [ { type: 'GAS_LOADING_STARTED' }, @@ -920,24 +922,24 @@ describe('Actions', function () { { type: 'metamask/gas/SET_CUSTOM_GAS_LIMIT', value: '0x5208' }, { type: 'UPDATE_SEND_ERRORS', value: { gasLoadingError: null } }, { type: 'GAS_LOADING_FINISHED' }, - ] + ]; - await store.dispatch(actions.updateGasData(mockData)) - assert.deepStrictEqual(store.getActions(), expectedActions) - global.eth.getCode.reset() - }) - }) + await store.dispatch(actions.updateGasData(mockData)); + assert.deepStrictEqual(store.getActions(), expectedActions); + global.eth.getCode.reset(); + }); + }); describe('#signTokenTx', function () { it('calls eth.contract', function () { - global.eth = new Eth(provider) - const tokenSpy = sinon.spy(global.eth, 'contract') - const store = mockStore() - store.dispatch(actions.signTokenTx()) - assert(tokenSpy.calledOnce) - tokenSpy.restore() - }) - }) + global.eth = new Eth(provider); + const tokenSpy = sinon.spy(global.eth, 'contract'); + const store = mockStore(); + store.dispatch(actions.signTokenTx()); + assert(tokenSpy.calledOnce); + tokenSpy.restore(); + }); + }); describe('#updateTransaction', function () { const txParams = { @@ -946,23 +948,23 @@ describe('Actions', function () { gasPrice: '0x3b9aca00', to: '0x2', value: '0x0', - } + }; const txData = { id: '1', status: TRANSACTION_STATUSES.UNAPPROVED, metamaskNetworkId: currentNetworkId, txParams, - } + }; afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('updates transaction', async function () { - const store = mockStore() + const store = mockStore(); - const updateTransactionStub = sinon.stub().callsFake((_, cb) => cb()) + const updateTransactionStub = sinon.stub().callsFake((_, cb) => cb()); background.getApi.returns({ updateTransaction: updateTransactionStub, @@ -972,27 +974,27 @@ describe('Actions', function () { selectedAddress: '0xFirstAddress', }), ), - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); - await store.dispatch(actions.updateTransaction(txData)) + await store.dispatch(actions.updateTransaction(txData)); - const resultantActions = store.getActions() - assert(updateTransactionStub.calledOnce) + const resultantActions = store.getActions(); + assert(updateTransactionStub.calledOnce); assert.deepStrictEqual(resultantActions[1], { type: 'UPDATE_TRANSACTION_PARAMS', id: txData.id, value: txParams, - }) - }) + }); + }); it('rejects with error message', async function () { - const store = mockStore() + const store = mockStore(); background.getApi.returns({ updateTransaction: (_, callback) => { - callback(new Error('error')) + callback(new Error('error')); }, getState: sinon.stub().callsFake((cb) => cb(null, { @@ -1000,198 +1002,198 @@ describe('Actions', function () { selectedAddress: '0xFirstAddress', }), ), - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); try { - await store.dispatch(actions.updateTransaction(txData)) - assert.fail('Should have thrown error') + await store.dispatch(actions.updateTransaction(txData)); + assert.fail('Should have thrown error'); } catch (error) { - assert.strictEqual(error.message, 'error') + assert.strictEqual(error.message, 'error'); } - }) - }) + }); + }); describe('#lockMetamask', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls setLocked', async function () { - const store = mockStore() + const store = mockStore(); - const backgroundSetLocked = background.setLocked.callsFake((cb) => cb()) + const backgroundSetLocked = background.setLocked.callsFake((cb) => cb()); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); - await store.dispatch(actions.lockMetamask()) - assert(backgroundSetLocked.calledOnce) - }) + await store.dispatch(actions.lockMetamask()); + assert(backgroundSetLocked.calledOnce); + }); it('returns display warning error with value when setLocked in background callback errors', async function () { - const store = mockStore() + const store = mockStore(); background.setLocked.callsFake((cb) => { - cb(new Error('error')) - }) + cb(new Error('error')); + }); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'DISPLAY_WARNING', value: 'error' }, { type: 'HIDE_LOADING_INDICATION' }, { type: 'LOCK_METAMASK' }, - ] + ]; try { - await store.dispatch(actions.lockMetamask()) - assert.fail('Should have thrown error') + await store.dispatch(actions.lockMetamask()); + assert.fail('Should have thrown error'); } catch (error) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) - }) + }); + }); describe('#setSelectedAddress', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls setSelectedAddress in background', async function () { - const store = mockStore() + const store = mockStore(); - const setSelectedAddressSpy = sinon.stub().callsFake((_, cb) => cb()) + const setSelectedAddressSpy = sinon.stub().callsFake((_, cb) => cb()); background.getApi.returns({ setSelectedAddress: setSelectedAddressSpy, - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); await store.dispatch( actions.setSelectedAddress( '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', ), - ) - assert(setSelectedAddressSpy.calledOnce) - }) + ); + assert(setSelectedAddressSpy.calledOnce); + }); it('errors when setSelectedAddress throws', async function () { - const store = mockStore() + const store = mockStore(); const setSelectedAddressSpy = sinon .stub() - .callsFake((_, cb) => cb(new Error('error'))) + .callsFake((_, cb) => cb(new Error('error'))); background.getApi.returns({ setSelectedAddress: setSelectedAddressSpy, - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'DISPLAY_WARNING', value: 'error' }, { type: 'HIDE_LOADING_INDICATION' }, - ] + ]; - await store.dispatch(actions.setSelectedAddress()) - assert.deepStrictEqual(store.getActions(), expectedActions) - }) - }) + await store.dispatch(actions.setSelectedAddress()); + assert.deepStrictEqual(store.getActions(), expectedActions); + }); + }); describe('#showAccountDetail', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('#showAccountDetail', async function () { const store = mockStore({ activeTab: {}, metamask: { alertEnabledness: {}, selectedAddress: '0x123' }, - }) + }); - const setSelectedAddressSpy = sinon.stub().callsFake((_, cb) => cb()) + const setSelectedAddressSpy = sinon.stub().callsFake((_, cb) => cb()); background.getApi.returns({ setSelectedAddress: setSelectedAddressSpy, - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); - await store.dispatch(actions.showAccountDetail()) - assert(setSelectedAddressSpy.calledOnce) - }) + await store.dispatch(actions.showAccountDetail()); + assert(setSelectedAddressSpy.calledOnce); + }); it('displays warning if setSelectedAddress throws', async function () { const store = mockStore({ activeTab: {}, metamask: { alertEnabledness: {}, selectedAddress: '0x123' }, - }) + }); const setSelectedAddressSpy = sinon .stub() - .callsFake((_, cb) => cb(new Error('error'))) + .callsFake((_, cb) => cb(new Error('error'))); background.getApi.returns({ setSelectedAddress: setSelectedAddressSpy, - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'DISPLAY_WARNING', value: 'error' }, { type: 'HIDE_LOADING_INDICATION' }, - ] + ]; - await store.dispatch(actions.showAccountDetail()) - assert.deepStrictEqual(store.getActions(), expectedActions) - }) - }) + await store.dispatch(actions.showAccountDetail()); + assert.deepStrictEqual(store.getActions(), expectedActions); + }); + }); describe('#addToken', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls addToken in background', async function () { - const store = mockStore() + const store = mockStore(); const addTokenStub = sinon .stub() - .callsFake((_, __, ___, ____, cb) => cb()) + .callsFake((_, __, ___, ____, cb) => cb()); background.getApi.returns({ addToken: addTokenStub, - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); - await store.dispatch(actions.addToken()) - assert(addTokenStub.calledOnce) - }) + await store.dispatch(actions.addToken()); + assert(addTokenStub.calledOnce); + }); it('expected actions', async function () { - const store = mockStore() + const store = mockStore(); const tokenDetails = { address: 'tokenAddress', symbol: 'token', decimal: 18, - } + }; const addTokenStub = sinon .stub() - .callsFake((_, __, ___, ____, cb) => cb(null, tokenDetails)) + .callsFake((_, __, ___, ____, cb) => cb(null, tokenDetails)); background.getApi.returns({ addToken: addTokenStub, - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, @@ -1200,201 +1202,201 @@ describe('Actions', function () { type: 'UPDATE_TOKENS', newTokens: tokenDetails, }, - ] + ]; - await store.dispatch(actions.addToken()) + await store.dispatch(actions.addToken()); - assert.deepStrictEqual(store.getActions(), expectedActions) - }) + assert.deepStrictEqual(store.getActions(), expectedActions); + }); it('errors when addToken in background throws', async function () { - const store = mockStore() + const store = mockStore(); const addTokenStub = sinon .stub() - .callsFake((_, __, ___, ____, cb) => cb(new Error('error'))) + .callsFake((_, __, ___, ____, cb) => cb(new Error('error'))); background.getApi.returns({ addToken: addTokenStub, - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'HIDE_LOADING_INDICATION' }, { type: 'DISPLAY_WARNING', value: 'error' }, - ] + ]; try { - await store.dispatch(actions.addToken()) - assert.fail('Should have thrown error') + await store.dispatch(actions.addToken()); + assert.fail('Should have thrown error'); } catch (_) { - assert.deepEqual(store.getActions(), expectedActions) + assert.deepEqual(store.getActions(), expectedActions); } - }) - }) + }); + }); describe('#removeToken', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls removeToken in background', async function () { - const store = mockStore() + const store = mockStore(); - const removeTokenStub = sinon.stub().callsFake((_, cb) => cb()) + const removeTokenStub = sinon.stub().callsFake((_, cb) => cb()); background.getApi.returns({ removeToken: removeTokenStub, - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); - await store.dispatch(actions.removeToken()) - assert(removeTokenStub.calledOnce) - }) + await store.dispatch(actions.removeToken()); + assert(removeTokenStub.calledOnce); + }); it('errors when removeToken in background fails', async function () { - const store = mockStore() + const store = mockStore(); background.getApi.returns({ removeToken: sinon.stub().callsFake((_, cb) => cb(new Error('error'))), - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'HIDE_LOADING_INDICATION' }, { type: 'DISPLAY_WARNING', value: 'error' }, - ] + ]; try { - await store.dispatch(actions.removeToken()) - assert.fail('Should have thrown error') + await store.dispatch(actions.removeToken()); + assert.fail('Should have thrown error'); } catch (_) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) - }) + }); + }); describe('#setProviderType', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls setProviderType', async function () { - const store = mockStore() + const store = mockStore(); - const setProviderTypeStub = sinon.stub().callsFake((_, cb) => cb()) + const setProviderTypeStub = sinon.stub().callsFake((_, cb) => cb()); background.getApi.returns({ setProviderType: setProviderTypeStub, - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); - await store.dispatch(actions.setProviderType()) - assert(setProviderTypeStub.calledOnce) - }) + await store.dispatch(actions.setProviderType()); + assert(setProviderTypeStub.calledOnce); + }); it('displays warning when setProviderType throws', async function () { - const store = mockStore() + const store = mockStore(); background.getApi.returns({ setProviderType: sinon .stub() .callsFake((_, cb) => cb(new Error('error'))), - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); const expectedActions = [ { type: 'DISPLAY_WARNING', value: 'Had a problem changing networks!' }, - ] + ]; - await store.dispatch(actions.setProviderType()) - assert.deepStrictEqual(store.getActions(), expectedActions) - }) - }) + await store.dispatch(actions.setProviderType()); + assert.deepStrictEqual(store.getActions(), expectedActions); + }); + }); describe('#setRpcTarget', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls setRpcTarget', async function () { - const store = mockStore() + const store = mockStore(); - background.setCustomRpc.callsFake((_, __, ___, ____, cb) => cb()) + background.setCustomRpc.callsFake((_, __, ___, ____, cb) => cb()); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); - await store.dispatch(actions.setRpcTarget('http://localhost:8545')) - assert(background.setCustomRpc.calledOnce) - }) + await store.dispatch(actions.setRpcTarget('http://localhost:8545')); + assert(background.setCustomRpc.calledOnce); + }); it('displays warning when setRpcTarget throws', async function () { - const store = mockStore() + const store = mockStore(); background.setCustomRpc.callsFake((_, __, ___, ____, cb) => cb(new Error('error')), - ) + ); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { type: 'DISPLAY_WARNING', value: 'Had a problem changing networks!' }, - ] + ]; - await store.dispatch(actions.setRpcTarget()) - assert.deepStrictEqual(store.getActions(), expectedActions) - }) - }) + await store.dispatch(actions.setRpcTarget()); + assert.deepStrictEqual(store.getActions(), expectedActions); + }); + }); describe('#addToAddressBook', function () { it('calls setAddressBook', async function () { - const store = mockStore() + const store = mockStore(); const setAddressBookStub = sinon .stub() - .callsFake((_, __, ___, ____, cb) => cb()) + .callsFake((_, __, ___, ____, cb) => cb()); background.getApi.returns({ setAddressBook: setAddressBookStub, - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); - await store.dispatch(actions.addToAddressBook('test')) - assert(setAddressBookStub.calledOnce) - sinon.restore() - }) - }) + await store.dispatch(actions.addToAddressBook('test')); + assert(setAddressBookStub.calledOnce); + sinon.restore(); + }); + }); describe('#exportAccount', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('returns expected actions for successful action', async function () { - const store = mockStore() + const store = mockStore(); - const testPrivKey = 'a-test-priv-key' + const testPrivKey = 'a-test-priv-key'; - const verifyPasswordStub = sinon.stub().callsFake((_, cb) => cb()) + const verifyPasswordStub = sinon.stub().callsFake((_, cb) => cb()); const exportAccountStub = sinon .stub() - .callsFake((_, cb) => cb(null, testPrivKey)) + .callsFake((_, cb) => cb(null, testPrivKey)); background.getApi.returns({ verifyPassword: verifyPasswordStub, exportAccount: exportAccountStub, - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, @@ -1403,60 +1405,60 @@ describe('Actions', function () { type: 'SHOW_PRIVATE_KEY', value: testPrivKey, }, - ] + ]; await store.dispatch( actions.exportAccount('a-test-password', '0xAddress'), - ) - assert(verifyPasswordStub.calledOnce) - assert(exportAccountStub.calledOnce) - assert.deepStrictEqual(store.getActions(), expectedActions) - }) + ); + assert(verifyPasswordStub.calledOnce); + assert(exportAccountStub.calledOnce); + assert.deepStrictEqual(store.getActions(), expectedActions); + }); it('returns action errors when first func callback errors', async function () { - const store = mockStore() + const store = mockStore(); const verifyPasswordStub = sinon .stub() - .callsFake((_, cb) => cb(new Error('error'))) + .callsFake((_, cb) => cb(new Error('error'))); background.getApi.returns({ verifyPassword: verifyPasswordStub, - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'HIDE_LOADING_INDICATION' }, { type: 'DISPLAY_WARNING', value: 'Incorrect Password.' }, - ] + ]; try { await store.dispatch( actions.exportAccount('a-test-password', '0xAddress'), - ) - assert.fail('Should have thrown error') + ); + assert.fail('Should have thrown error'); } catch (_) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) + }); it('returns action errors when second func callback errors', async function () { - const store = mockStore() + const store = mockStore(); - const verifyPasswordStub = sinon.stub().callsFake((_, cb) => cb()) + const verifyPasswordStub = sinon.stub().callsFake((_, cb) => cb()); const exportAccountStub = sinon .stub() - .callsFake((_, cb) => cb(new Error('error'))) + .callsFake((_, cb) => cb(new Error('error'))); background.getApi.returns({ verifyPassword: verifyPasswordStub, exportAccount: exportAccountStub, - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, @@ -1465,60 +1467,60 @@ describe('Actions', function () { type: 'DISPLAY_WARNING', value: 'Had a problem exporting the account.', }, - ] + ]; try { await store.dispatch( actions.exportAccount('a-test-password', '0xAddress'), - ) - assert.fail('Should have thrown error') + ); + assert.fail('Should have thrown error'); } catch (_) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) - }) + }); + }); describe('#setAccountLabel', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls setAccountLabel', async function () { - const store = mockStore() + const store = mockStore(); - const setAccountLabelStub = sinon.stub().callsFake((_, __, cb) => cb()) + const setAccountLabelStub = sinon.stub().callsFake((_, __, cb) => cb()); background.getApi.returns({ setAccountLabel: setAccountLabelStub, - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); await store.dispatch( actions.setAccountLabel( '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', 'test', ), - ) - assert(setAccountLabelStub.calledOnce) - }) + ); + assert(setAccountLabelStub.calledOnce); + }); it('returns action errors when func callback errors', async function () { - const store = mockStore() + const store = mockStore(); background.getApi.returns({ setAccountLabel: sinon .stub() .callsFake((_, __, cb) => cb(new Error('error'))), - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'HIDE_LOADING_INDICATION' }, { type: 'DISPLAY_WARNING', value: 'error' }, - ] + ]; try { await store.dispatch( @@ -1526,159 +1528,159 @@ describe('Actions', function () { '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', 'test', ), - ) - assert.fail('Should have thrown error') + ); + assert.fail('Should have thrown error'); } catch (error) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) - }) + }); + }); describe('#setFeatureFlag', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls setFeatureFlag in the background', async function () { - const store = mockStore() + const store = mockStore(); - const setFeatureFlagStub = sinon.stub().callsFake((_, __, cb) => cb()) + const setFeatureFlagStub = sinon.stub().callsFake((_, __, cb) => cb()); background.getApi.returns({ setFeatureFlag: setFeatureFlagStub, - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); - await store.dispatch(actions.setFeatureFlag()) - assert(setFeatureFlagStub.calledOnce) - }) + await store.dispatch(actions.setFeatureFlag()); + assert(setFeatureFlagStub.calledOnce); + }); it('errors when setFeatureFlag in background throws', async function () { - const store = mockStore() + const store = mockStore(); background.getApi.returns({ setFeatureFlag: sinon .stub() .callsFake((_, __, cb) => cb(new Error('error'))), - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'HIDE_LOADING_INDICATION' }, { type: 'DISPLAY_WARNING', value: 'error' }, - ] + ]; try { - await store.dispatch(actions.setFeatureFlag()) - assert.fail('Should have thrown error') + await store.dispatch(actions.setFeatureFlag()); + assert.fail('Should have thrown error'); } catch (_) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) - }) + }); + }); describe('#setCompletedOnboarding', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('completes onboarding', async function () { - const store = mockStore() - const completeOnboardingStub = sinon.stub().callsFake((cb) => cb()) + const store = mockStore(); + const completeOnboardingStub = sinon.stub().callsFake((cb) => cb()); background.getApi.returns({ completeOnboarding: completeOnboardingStub, - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); - await store.dispatch(actions.setCompletedOnboarding()) - assert(completeOnboardingStub.calledOnce) - }) + await store.dispatch(actions.setCompletedOnboarding()); + assert(completeOnboardingStub.calledOnce); + }); it('errors when setCompletedOnboarding in background throws', async function () { - const store = mockStore() + const store = mockStore(); background.getApi.returns({ completeOnboarding: sinon .stub() .callsFake((cb) => cb(new Error('error'))), - }) + }); - actions._setBackgroundConnection(background.getApi()) + actions._setBackgroundConnection(background.getApi()); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'DISPLAY_WARNING', value: 'error' }, { type: 'HIDE_LOADING_INDICATION' }, - ] + ]; try { - await store.dispatch(actions.setCompletedOnboarding()) - assert.fail('Should have thrown error') + await store.dispatch(actions.setCompletedOnboarding()); + assert.fail('Should have thrown error'); } catch (_) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) - }) + }); + }); describe('#setUseBlockie', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls setUseBlockie in background', async function () { - const store = mockStore() + const store = mockStore(); const setUseBlockStub = background.setUseBlockie.callsFake((_, cb) => cb(), - ) + ); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); - await store.dispatch(actions.setUseBlockie()) - assert(setUseBlockStub.calledOnce) - }) + await store.dispatch(actions.setUseBlockie()); + assert(setUseBlockStub.calledOnce); + }); it('errors when setUseBlockie in background throws', async function () { - const store = mockStore() + const store = mockStore(); - background.setUseBlockie.callsFake((_, cb) => cb(new Error('error'))) + background.setUseBlockie.callsFake((_, cb) => cb(new Error('error'))); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'HIDE_LOADING_INDICATION' }, { type: 'DISPLAY_WARNING', value: 'error' }, { type: 'SET_USE_BLOCKIE', value: undefined }, - ] + ]; - await store.dispatch(actions.setUseBlockie()) - assert.deepStrictEqual(store.getActions(), expectedActions) - }) - }) + await store.dispatch(actions.setUseBlockie()); + assert.deepStrictEqual(store.getActions(), expectedActions); + }); + }); describe('#updateCurrentLocale', function () { beforeEach(function () { sinon.stub(window, 'fetch').resolves({ json: async () => enLocale, - }) - }) + }); + }); afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls expected actions', async function () { - const store = mockStore() + const store = mockStore(); - background.setCurrentLocale.callsFake((_, cb) => cb()) + background.setCurrentLocale.callsFake((_, cb) => cb()); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, @@ -1687,63 +1689,65 @@ describe('Actions', function () { value: { locale: 'test', messages: enLocale }, }, { type: 'HIDE_LOADING_INDICATION' }, - ] + ]; - await store.dispatch(actions.updateCurrentLocale('test')) - assert(background.setCurrentLocale.calledOnce) - assert.deepStrictEqual(store.getActions(), expectedActions) - }) + await store.dispatch(actions.updateCurrentLocale('test')); + assert(background.setCurrentLocale.calledOnce); + assert.deepStrictEqual(store.getActions(), expectedActions); + }); it('errors when setCurrentLocale throws', async function () { - const store = mockStore() + const store = mockStore(); - background.setCurrentLocale.callsFake((_, cb) => cb(new Error('error'))) + background.setCurrentLocale.callsFake((_, cb) => cb(new Error('error'))); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { type: 'SHOW_LOADING_INDICATION', value: undefined }, { type: 'DISPLAY_WARNING', value: 'error' }, { type: 'HIDE_LOADING_INDICATION' }, - ] + ]; try { - await store.dispatch(actions.updateCurrentLocale('test')) - assert.fail('Should have thrown error') + await store.dispatch(actions.updateCurrentLocale('test')); + assert.fail('Should have thrown error'); } catch (_) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) - }) + }); + }); describe('#markPasswordForgotten', function () { afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('calls markPasswordForgotten', async function () { - const store = mockStore() + const store = mockStore(); - background.markPasswordForgotten.callsFake((cb) => cb()) + background.markPasswordForgotten.callsFake((cb) => cb()); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); - await store.dispatch(actions.markPasswordForgotten()) + await store.dispatch(actions.markPasswordForgotten()); - const resultantActions = store.getActions() + const resultantActions = store.getActions(); assert.deepStrictEqual(resultantActions[1], { type: 'FORGOT_PASSWORD', value: true, - }) - assert(background.markPasswordForgotten.calledOnce) - }) + }); + assert(background.markPasswordForgotten.calledOnce); + }); it('errors when markPasswordForgotten throws', async function () { - const store = mockStore() + const store = mockStore(); - background.markPasswordForgotten.callsFake((cb) => cb(new Error('error'))) + background.markPasswordForgotten.callsFake((cb) => + cb(new Error('error')), + ); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); const expectedActions = [ { type: 'HIDE_LOADING_INDICATION' }, @@ -1755,33 +1759,33 @@ describe('Actions', function () { selectedAddress: '0xFirstAddress', }, }, - ] + ]; try { - await store.dispatch(actions.markPasswordForgotten('test')) - assert.fail('Should have thrown error') + await store.dispatch(actions.markPasswordForgotten('test')); + assert.fail('Should have thrown error'); } catch (_) { - assert.deepStrictEqual(store.getActions(), expectedActions) + assert.deepStrictEqual(store.getActions(), expectedActions); } - }) - }) + }); + }); describe('#unMarkPasswordForgotten', function () { it('calls unMarkPasswordForgotten', async function () { - const store = mockStore() + const store = mockStore(); - background.unMarkPasswordForgotten.callsFake((cb) => cb()) + background.unMarkPasswordForgotten.callsFake((cb) => cb()); - actions._setBackgroundConnection(background) + actions._setBackgroundConnection(background); - await store.dispatch(actions.unMarkPasswordForgotten()) + await store.dispatch(actions.unMarkPasswordForgotten()); - const resultantActions = store.getActions() + const resultantActions = store.getActions(); assert.deepStrictEqual(resultantActions[0], { type: 'FORGOT_PASSWORD', value: false, - }) - assert(background.unMarkPasswordForgotten.calledOnce) - }) - }) -}) + }); + assert(background.unMarkPasswordForgotten.calledOnce); + }); + }); +}); diff --git a/test/unit/ui/app/reducers/app.spec.js b/test/unit/ui/app/reducers/app.spec.js index 3cf350b7f5..f95060e32a 100644 --- a/test/unit/ui/app/reducers/app.spec.js +++ b/test/unit/ui/app/reducers/app.spec.js @@ -1,8 +1,8 @@ -import assert from 'assert' -import reduceApp from '../../../../../ui/app/ducks/app/app' -import * as actionConstants from '../../../../../ui/app/store/actionConstants' +import assert from 'assert'; +import reduceApp from '../../../../../ui/app/ducks/app/app'; +import * as actionConstants from '../../../../../ui/app/store/actionConstants'; -const actions = actionConstants +const actions = actionConstants; describe('App State', function () { const metamaskState = { @@ -13,86 +13,86 @@ describe('App State', function () { address: '0xAddress', }, }, - } + }; it('App init state', function () { - const initState = reduceApp(metamaskState, {}) + const initState = reduceApp(metamaskState, {}); - assert(initState) - }) + assert(initState); + }); it('sets networkDropdownOpen dropdown to true', function () { const state = reduceApp(metamaskState, { type: actions.NETWORK_DROPDOWN_OPEN, - }) + }); - assert.equal(state.networkDropdownOpen, true) - }) + assert.equal(state.networkDropdownOpen, true); + }); it('sets networkDropdownOpen dropdown to false', function () { - const dropdown = { networkDropdowopen: true } - const state = { ...metamaskState, ...dropdown } + const dropdown = { networkDropdowopen: true }; + const state = { ...metamaskState, ...dropdown }; const newState = reduceApp(state, { type: actions.NETWORK_DROPDOWN_CLOSE, - }) + }); - assert.equal(newState.networkDropdownOpen, false) - }) + assert.equal(newState.networkDropdownOpen, false); + }); it('opens sidebar', function () { const value = { transitionName: 'sidebar-right', type: 'wallet-view', isOpen: true, - } + }; const state = reduceApp(metamaskState, { type: actions.SIDEBAR_OPEN, value, - }) + }); - assert.deepEqual(state.sidebar, value) - }) + assert.deepEqual(state.sidebar, value); + }); it('closes sidebar', function () { - const openSidebar = { sidebar: { isOpen: true } } - const state = { ...metamaskState, ...openSidebar } + const openSidebar = { sidebar: { isOpen: true } }; + const state = { ...metamaskState, ...openSidebar }; const newState = reduceApp(state, { type: actions.SIDEBAR_CLOSE, - }) + }); - assert.equal(newState.sidebar.isOpen, false) - }) + assert.equal(newState.sidebar.isOpen, false); + }); it('opens alert', function () { const state = reduceApp(metamaskState, { type: actions.ALERT_OPEN, value: 'test message', - }) + }); - assert.equal(state.alertOpen, true) - assert.equal(state.alertMessage, 'test message') - }) + assert.equal(state.alertOpen, true); + assert.equal(state.alertMessage, 'test message'); + }); it('closes alert', function () { - const alert = { alertOpen: true, alertMessage: 'test message' } - const state = { ...metamaskState, ...alert } + const alert = { alertOpen: true, alertMessage: 'test message' }; + const state = { ...metamaskState, ...alert }; const newState = reduceApp(state, { type: actions.ALERT_CLOSE, - }) + }); - assert.equal(newState.alertOpen, false) - assert.equal(newState.alertMessage, null) - }) + assert.equal(newState.alertOpen, false); + assert.equal(newState.alertMessage, null); + }); it('detects qr code data', function () { const state = reduceApp(metamaskState, { type: actions.QR_CODE_DETECTED, value: 'qr data', - }) + }); - assert.equal(state.qrCodeData, 'qr data') - }) + assert.equal(state.qrCodeData, 'qr data'); + }); it('opens modal', function () { const state = reduceApp(metamaskState, { @@ -100,11 +100,11 @@ describe('App State', function () { payload: { name: 'test', }, - }) + }); - assert.equal(state.modal.open, true) - assert.equal(state.modal.modalState.name, 'test') - }) + assert.equal(state.modal.open, true); + assert.equal(state.modal.modalState.name, 'test'); + }); it('closes modal, but moves open modal state to previous modal state', function () { const opensModal = { @@ -114,54 +114,54 @@ describe('App State', function () { name: 'test', }, }, - } + }; - const state = { ...metamaskState, appState: { ...opensModal } } + const state = { ...metamaskState, appState: { ...opensModal } }; const newState = reduceApp(state, { type: actions.MODAL_CLOSE, - }) + }); - assert.equal(newState.modal.open, false) - assert.equal(newState.modal.modalState.name, null) - }) + assert.equal(newState.modal.open, false); + assert.equal(newState.modal.modalState.name, null); + }); it('shows send token page', function () { const state = reduceApp(metamaskState, { type: actions.SHOW_SEND_TOKEN_PAGE, - }) + }); - assert.equal(state.warning, null) - }) + assert.equal(state.warning, null); + }); it('locks Metamask', function () { const state = reduceApp(metamaskState, { type: actions.LOCK_METAMASK, - }) + }); - assert.equal(state.warning, null) - }) + assert.equal(state.warning, null); + }); it('goes home', function () { const state = reduceApp(metamaskState, { type: actions.GO_HOME, - }) + }); - assert.equal(state.accountDetail.subview, 'transactions') - assert.equal(state.accountDetail.accountExport, 'none') - assert.equal(state.accountDetail.privateKey, '') - assert.equal(state.warning, null) - }) + assert.equal(state.accountDetail.subview, 'transactions'); + assert.equal(state.accountDetail.accountExport, 'none'); + assert.equal(state.accountDetail.privateKey, ''); + assert.equal(state.warning, null); + }); it('shows account detail', function () { const state = reduceApp(metamaskState, { type: actions.SHOW_ACCOUNT_DETAIL, value: 'context address', - }) - assert.equal(state.forgottenPassword, null) // default - assert.equal(state.accountDetail.subview, 'transactions') // default - assert.equal(state.accountDetail.accountExport, 'none') // default - assert.equal(state.accountDetail.privateKey, '') // default - }) + }); + assert.equal(state.forgottenPassword, null); // default + assert.equal(state.accountDetail.subview, 'transactions'); // default + assert.equal(state.accountDetail.accountExport, 'none'); // default + assert.equal(state.accountDetail.privateKey, ''); // default + }); it('clears account details', function () { const exportPrivKeyModal = { @@ -170,26 +170,26 @@ describe('App State', function () { accountExport: 'completed', privateKey: 'a-priv-key', }, - } + }; - const state = { ...metamaskState, appState: { ...exportPrivKeyModal } } + const state = { ...metamaskState, appState: { ...exportPrivKeyModal } }; const newState = reduceApp(state, { type: actions.CLEAR_ACCOUNT_DETAILS, - }) + }); - assert.deepStrictEqual(newState.accountDetail, {}) - }) + assert.deepStrictEqual(newState.accountDetail, {}); + }); it('shoes account page', function () { const state = reduceApp(metamaskState, { type: actions.SHOW_ACCOUNTS_PAGE, - }) + }); - assert.equal(state.isLoading, false) - assert.equal(state.warning, null) - assert.equal(state.scrollToBottom, false) - assert.equal(state.forgottenPassword, false) - }) + assert.equal(state.isLoading, false); + assert.equal(state.warning, null); + assert.equal(state.scrollToBottom, false); + assert.equal(state.forgottenPassword, false); + }); it('shows confirm tx page', function () { const txs = { @@ -201,17 +201,17 @@ describe('App State', function () { id: 2, }, }, - } - const oldState = { ...metamaskState, ...txs } + }; + const oldState = { ...metamaskState, ...txs }; const state = reduceApp(oldState, { type: actions.SHOW_CONF_TX_PAGE, id: 2, - }) + }); - assert.equal(state.txId, 2) - assert.equal(state.warning, null) - assert.equal(state.isLoading, false) - }) + assert.equal(state.txId, 2); + assert.equal(state.warning, null); + assert.equal(state.isLoading, false); + }); it('completes tx continues to show pending txs current view context', function () { const txs = { @@ -223,20 +223,20 @@ describe('App State', function () { id: 2, }, }, - } + }; - const oldState = { ...metamaskState, ...txs } + const oldState = { ...metamaskState, ...txs }; const state = reduceApp(oldState, { type: actions.COMPLETED_TX, value: { id: 1, }, - }) + }); - assert.equal(state.txId, null) - assert.equal(state.warning, null) - }) + assert.equal(state.txId, null); + assert.equal(state.warning, null); + }); it('returns to account detail page when no unconf actions completed tx', function () { const state = reduceApp(metamaskState, { @@ -244,131 +244,131 @@ describe('App State', function () { value: { unconfirmedActionsCount: 0, }, - }) + }); - assert.equal(state.warning, null) - assert.equal(state.accountDetail.subview, 'transactions') - }) + assert.equal(state.warning, null); + assert.equal(state.accountDetail.subview, 'transactions'); + }); it('sets default warning when unlock fails', function () { const state = reduceApp(metamaskState, { type: actions.UNLOCK_FAILED, - }) + }); - assert.equal(state.warning, 'Incorrect password. Try again.') - }) + assert.equal(state.warning, 'Incorrect password. Try again.'); + }); it('sets errors when unlock fails', function () { const state = reduceApp(metamaskState, { type: actions.UNLOCK_FAILED, value: 'errors', - }) + }); - assert.equal(state.warning, 'errors') - }) + assert.equal(state.warning, 'errors'); + }); it('sets warning to empty string when unlock succeeds', function () { - const errorState = { warning: 'errors' } - const oldState = { ...metamaskState, ...errorState } + const errorState = { warning: 'errors' }; + const oldState = { ...metamaskState, ...errorState }; const state = reduceApp(oldState, { type: actions.UNLOCK_SUCCEEDED, - }) + }); - assert.equal(state.warning, '') - }) + assert.equal(state.warning, ''); + }); it('sets hardware wallet default hd path', function () { const hdPaths = { trezor: "m/44'/60'/0'/0", ledger: "m/44'/60'/0'", - } + }; const state = reduceApp(metamaskState, { type: actions.SET_HARDWARE_WALLET_DEFAULT_HD_PATH, value: { device: 'ledger', path: "m/44'/60'/0'", }, - }) + }); - assert.deepEqual(state.defaultHdPaths, hdPaths) - }) + assert.deepEqual(state.defaultHdPaths, hdPaths); + }); it('shows loading message', function () { const state = reduceApp(metamaskState, { type: actions.SHOW_LOADING, value: 'loading', - }) + }); - assert.equal(state.isLoading, true) - assert.equal(state.loadingMessage, 'loading') - }) + assert.equal(state.isLoading, true); + assert.equal(state.loadingMessage, 'loading'); + }); it('hides loading message', function () { - const loadingState = { isLoading: true } - const oldState = { ...metamaskState, ...loadingState } + const loadingState = { isLoading: true }; + const oldState = { ...metamaskState, ...loadingState }; const state = reduceApp(oldState, { type: actions.HIDE_LOADING, - }) + }); - assert.equal(state.isLoading, false) - }) + assert.equal(state.isLoading, false); + }); it('displays warning', function () { const state = reduceApp(metamaskState, { type: actions.DISPLAY_WARNING, value: 'warning', - }) + }); - assert.equal(state.isLoading, false) - assert.equal(state.warning, 'warning') - }) + assert.equal(state.isLoading, false); + assert.equal(state.warning, 'warning'); + }); it('hides warning', function () { - const displayWarningState = { warning: 'warning' } - const oldState = { ...metamaskState, ...displayWarningState } + const displayWarningState = { warning: 'warning' }; + const oldState = { ...metamaskState, ...displayWarningState }; const state = reduceApp(oldState, { type: actions.HIDE_WARNING, - }) + }); - assert.equal(state.warning, undefined) - }) + assert.equal(state.warning, undefined); + }); it('shows private key', function () { const state = reduceApp(metamaskState, { type: actions.SHOW_PRIVATE_KEY, value: 'private key', - }) + }); - assert.equal(state.accountDetail.subview, 'export') - assert.equal(state.accountDetail.accountExport, 'completed') - assert.equal(state.accountDetail.privateKey, 'private key') - }) + assert.equal(state.accountDetail.subview, 'export'); + assert.equal(state.accountDetail.accountExport, 'completed'); + assert.equal(state.accountDetail.privateKey, 'private key'); + }); it('set mouse user state', function () { const state = reduceApp(metamaskState, { type: actions.SET_MOUSE_USER_STATE, value: true, - }) + }); - assert.equal(state.isMouseUser, true) - }) + assert.equal(state.isMouseUser, true); + }); it('sets gas loading', function () { const state = reduceApp(metamaskState, { type: actions.GAS_LOADING_STARTED, - }) + }); - assert.equal(state.gasIsLoading, true) - }) + assert.equal(state.gasIsLoading, true); + }); it('unsets gas loading', function () { - const gasLoadingState = { gasIsLoading: true } - const oldState = { ...metamaskState, ...gasLoadingState } + const gasLoadingState = { gasIsLoading: true }; + const oldState = { ...metamaskState, ...gasLoadingState }; const state = reduceApp(oldState, { type: actions.GAS_LOADING_FINISHED, - }) + }); - assert.equal(state.gasIsLoading, false) - }) -}) + assert.equal(state.gasIsLoading, false); + }); +}); diff --git a/test/unit/ui/app/reducers/metamask.spec.js b/test/unit/ui/app/reducers/metamask.spec.js index c36ad1bb9d..faf765b868 100644 --- a/test/unit/ui/app/reducers/metamask.spec.js +++ b/test/unit/ui/app/reducers/metamask.spec.js @@ -1,24 +1,24 @@ -import assert from 'assert' -import reduceMetamask from '../../../../../ui/app/ducks/metamask/metamask' -import * as actionConstants from '../../../../../ui/app/store/actionConstants' +import assert from 'assert'; +import reduceMetamask from '../../../../../ui/app/ducks/metamask/metamask'; +import * as actionConstants from '../../../../../ui/app/store/actionConstants'; describe('MetaMask Reducers', function () { it('init state', function () { - const initState = reduceMetamask(undefined, {}) - assert(initState) - }) + const initState = reduceMetamask(undefined, {}); + assert(initState); + }); it('locks MetaMask', function () { const unlockMetaMaskState = { isUnlocked: true, selectedAddress: 'test address', - } + }; const lockMetaMask = reduceMetamask(unlockMetaMaskState, { type: actionConstants.LOCK_METAMASK, - }) + }); - assert.equal(lockMetaMask.isUnlocked, false) - }) + assert.equal(lockMetaMask.isUnlocked, false); + }); it('sets rpc target', function () { const state = reduceMetamask( @@ -27,10 +27,10 @@ describe('MetaMask Reducers', function () { type: actionConstants.SET_RPC_TARGET, value: 'https://custom.rpc', }, - ) + ); - assert.equal(state.provider.rpcUrl, 'https://custom.rpc') - }) + assert.equal(state.provider.rpcUrl, 'https://custom.rpc'); + }); it('sets provider type', function () { const state = reduceMetamask( @@ -39,10 +39,10 @@ describe('MetaMask Reducers', function () { type: actionConstants.SET_PROVIDER_TYPE, value: 'provider type', }, - ) + ); - assert.equal(state.provider.type, 'provider type') - }) + assert.equal(state.provider.type, 'provider type'); + }); it('shows account detail', function () { const state = reduceMetamask( @@ -51,12 +51,12 @@ describe('MetaMask Reducers', function () { type: actionConstants.SHOW_ACCOUNT_DETAIL, value: 'test address', }, - ) + ); - assert.equal(state.isUnlocked, true) - assert.equal(state.isInitialized, true) - assert.equal(state.selectedAddress, 'test address') - }) + assert.equal(state.isUnlocked, true); + assert.equal(state.isInitialized, true); + assert.equal(state.selectedAddress, 'test address'); + }); it('sets account label', function () { const state = reduceMetamask( @@ -68,19 +68,19 @@ describe('MetaMask Reducers', function () { label: 'test label', }, }, - ) + ); assert.deepEqual(state.identities, { 'test account': { name: 'test label' }, - }) - }) + }); + }); it('sets current fiat', function () { const value = { currentCurrency: 'yen', conversionRate: 3.14, conversionDate: new Date(2018, 9), - } + }; const state = reduceMetamask( {}, @@ -88,19 +88,19 @@ describe('MetaMask Reducers', function () { type: actionConstants.SET_CURRENT_FIAT, value, }, - ) + ); - assert.equal(state.currentCurrency, value.currentCurrency) - assert.equal(state.conversionRate, value.conversionRate) - assert.equal(state.conversionDate, value.conversionDate) - }) + assert.equal(state.currentCurrency, value.currentCurrency); + assert.equal(state.conversionRate, value.conversionRate); + assert.equal(state.conversionDate, value.conversionDate); + }); it('updates tokens', function () { const newTokens = { address: '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4', decimals: 18, symbol: 'META', - } + }; const state = reduceMetamask( {}, @@ -108,10 +108,10 @@ describe('MetaMask Reducers', function () { type: actionConstants.UPDATE_TOKENS, newTokens, }, - ) + ); - assert.deepEqual(state.tokens, newTokens) - }) + assert.deepEqual(state.tokens, newTokens); + }); it('updates send gas limit', function () { const state = reduceMetamask( @@ -120,10 +120,10 @@ describe('MetaMask Reducers', function () { type: actionConstants.UPDATE_GAS_LIMIT, value: '0xGasLimit', }, - ) + ); - assert.equal(state.send.gasLimit, '0xGasLimit') - }) + assert.equal(state.send.gasLimit, '0xGasLimit'); + }); it('updates send gas price', function () { const state = reduceMetamask( @@ -132,10 +132,10 @@ describe('MetaMask Reducers', function () { type: actionConstants.UPDATE_GAS_PRICE, value: '0xGasPrice', }, - ) + ); - assert.equal(state.send.gasPrice, '0xGasPrice') - }) + assert.equal(state.send.gasPrice, '0xGasPrice'); + }); it('toggles account menu ', function () { const state = reduceMetamask( @@ -143,10 +143,10 @@ describe('MetaMask Reducers', function () { { type: actionConstants.TOGGLE_ACCOUNT_MENU, }, - ) + ); - assert.equal(state.isAccountMenuOpen, true) - }) + assert.equal(state.isAccountMenuOpen, true); + }); it('updates gas total', function () { const state = reduceMetamask( @@ -155,10 +155,10 @@ describe('MetaMask Reducers', function () { type: actionConstants.UPDATE_GAS_TOTAL, value: '0xGasTotal', }, - ) + ); - assert.equal(state.send.gasTotal, '0xGasTotal') - }) + assert.equal(state.send.gasTotal, '0xGasTotal'); + }); it('updates send token balance', function () { const state = reduceMetamask( @@ -167,10 +167,10 @@ describe('MetaMask Reducers', function () { type: actionConstants.UPDATE_SEND_TOKEN_BALANCE, value: '0xTokenBalance', }, - ) + ); - assert.equal(state.send.tokenBalance, '0xTokenBalance') - }) + assert.equal(state.send.tokenBalance, '0xTokenBalance'); + }); it('updates data', function () { const state = reduceMetamask( @@ -179,10 +179,10 @@ describe('MetaMask Reducers', function () { type: actionConstants.UPDATE_SEND_HEX_DATA, value: '0xData', }, - ) + ); - assert.equal(state.send.data, '0xData') - }) + assert.equal(state.send.data, '0xData'); + }); it('updates send to', function () { const state = reduceMetamask( @@ -194,11 +194,11 @@ describe('MetaMask Reducers', function () { nickname: 'nickname', }, }, - ) + ); - assert.equal(state.send.to, '0xAddress') - assert.equal(state.send.toNickname, 'nickname') - }) + assert.equal(state.send.to, '0xAddress'); + assert.equal(state.send.toNickname, 'nickname'); + }); it('update send amount', function () { const state = reduceMetamask( @@ -207,10 +207,10 @@ describe('MetaMask Reducers', function () { type: actionConstants.UPDATE_SEND_AMOUNT, value: '0xAmount', }, - ) + ); - assert.equal(state.send.amount, '0xAmount') - }) + assert.equal(state.send.amount, '0xAmount'); + }); it('updates max mode', function () { const state = reduceMetamask( @@ -219,10 +219,10 @@ describe('MetaMask Reducers', function () { type: actionConstants.UPDATE_MAX_MODE, value: true, }, - ) + ); - assert.equal(state.send.maxModeOn, true) - }) + assert.equal(state.send.maxModeOn, true); + }); it('update send', function () { const value = { @@ -240,7 +240,7 @@ describe('MetaMask Reducers', function () { editingTransactionId: 22, ensResolution: null, ensResolutionError: '', - } + }; const sendState = reduceMetamask( {}, @@ -248,10 +248,10 @@ describe('MetaMask Reducers', function () { type: actionConstants.UPDATE_SEND, value, }, - ) + ); - assert.deepEqual(sendState.send, value) - }) + assert.deepEqual(sendState.send, value); + }); it('clears send', function () { const initStateSend = { @@ -269,7 +269,7 @@ describe('MetaMask Reducers', function () { editingTransactionId: null, toNickname: '', }, - } + }; const sendState = { send: { @@ -286,14 +286,14 @@ describe('MetaMask Reducers', function () { errors: {}, editingTransactionId: 22, }, - } + }; const state = reduceMetamask(sendState, { type: actionConstants.CLEAR_SEND, - }) + }); - assert.deepEqual(state.send, initStateSend.send) - }) + assert.deepEqual(state.send, initStateSend.send); + }); it('updates value of tx by id', function () { const oldState = { @@ -303,16 +303,16 @@ describe('MetaMask Reducers', function () { txParams: 'foo', }, ], - } + }; const state = reduceMetamask(oldState, { type: actionConstants.UPDATE_TRANSACTION_PARAMS, id: 1, value: 'bar', - }) + }); - assert.equal(state.currentNetworkTxList[0].txParams, 'bar') - }) + assert.equal(state.currentNetworkTxList[0].txParams, 'bar'); + }); it('sets blockies', function () { const state = reduceMetamask( @@ -321,10 +321,10 @@ describe('MetaMask Reducers', function () { type: actionConstants.SET_USE_BLOCKIE, value: true, }, - ) + ); - assert.equal(state.useBlockie, true) - }) + assert.equal(state.useBlockie, true); + }); it('updates an arbitrary feature flag', function () { const state = reduceMetamask( @@ -335,10 +335,10 @@ describe('MetaMask Reducers', function () { foo: true, }, }, - ) + ); - assert.equal(state.featureFlags.foo, true) - }) + assert.equal(state.featureFlags.foo, true); + }); it('close welcome screen', function () { const state = reduceMetamask( @@ -346,10 +346,10 @@ describe('MetaMask Reducers', function () { { type: actionConstants.CLOSE_WELCOME_SCREEN, }, - ) + ); - assert.equal(state.welcomeScreenSeen, true) - }) + assert.equal(state.welcomeScreenSeen, true); + }); it('sets current locale', function () { const state = reduceMetamask( @@ -358,17 +358,17 @@ describe('MetaMask Reducers', function () { type: actionConstants.SET_CURRENT_LOCALE, value: { locale: 'ge' }, }, - ) + ); - assert.equal(state.currentLocale, 'ge') - }) + assert.equal(state.currentLocale, 'ge'); + }); it('sets pending tokens ', function () { const payload = { address: '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4', decimals: 18, symbol: 'META', - } + }; const pendingTokensState = reduceMetamask( {}, @@ -376,28 +376,28 @@ describe('MetaMask Reducers', function () { type: actionConstants.SET_PENDING_TOKENS, payload, }, - ) + ); - assert.deepEqual(pendingTokensState.pendingTokens, payload) - }) + assert.deepEqual(pendingTokensState.pendingTokens, payload); + }); it('clears pending tokens', function () { const payload = { address: '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4', decimals: 18, symbol: 'META', - } + }; const pendingTokensState = { pendingTokens: payload, - } + }; const state = reduceMetamask(pendingTokensState, { type: actionConstants.CLEAR_PENDING_TOKENS, - }) + }); - assert.deepEqual(state.pendingTokens, {}) - }) + assert.deepEqual(state.pendingTokens, {}); + }); it('update ensResolution', function () { const state = reduceMetamask( @@ -406,11 +406,11 @@ describe('MetaMask Reducers', function () { type: actionConstants.UPDATE_SEND_ENS_RESOLUTION, payload: '0x1337', }, - ) + ); - assert.deepEqual(state.send.ensResolution, '0x1337') - assert.deepEqual(state.send.ensResolutionError, '') - }) + assert.deepEqual(state.send.ensResolution, '0x1337'); + assert.deepEqual(state.send.ensResolutionError, ''); + }); it('update ensResolutionError', function () { const state = reduceMetamask( @@ -419,9 +419,9 @@ describe('MetaMask Reducers', function () { type: actionConstants.UPDATE_SEND_ENS_RESOLUTION_ERROR, payload: 'ens name not found', }, - ) + ); - assert.deepEqual(state.send.ensResolutionError, 'ens name not found') - assert.deepEqual(state.send.ensResolution, null) - }) -}) + assert.deepEqual(state.send.ensResolutionError, 'ens name not found'); + assert.deepEqual(state.send.ensResolution, null); + }); +}); diff --git a/test/unit/ui/etherscan-prefix-for-network.spec.js b/test/unit/ui/etherscan-prefix-for-network.spec.js index 1b3ce7b34e..e53c32e5e5 100644 --- a/test/unit/ui/etherscan-prefix-for-network.spec.js +++ b/test/unit/ui/etherscan-prefix-for-network.spec.js @@ -1,28 +1,28 @@ -import assert from 'assert' -import { getEtherscanNetworkPrefix } from '../../../ui/lib/etherscan-prefix-for-network' +import assert from 'assert'; +import { getEtherscanNetworkPrefix } from '../../../ui/lib/etherscan-prefix-for-network'; describe('Etherscan Network Prefix', function () { it('returns empty string as default value', function () { - assert.equal(getEtherscanNetworkPrefix(), '') - }) + assert.equal(getEtherscanNetworkPrefix(), ''); + }); it('returns empty string as a prefix for networkId of 1', function () { - assert.equal(getEtherscanNetworkPrefix('1'), '') - }) + assert.equal(getEtherscanNetworkPrefix('1'), ''); + }); it('returns ropsten as prefix for networkId of 3', function () { - assert.equal(getEtherscanNetworkPrefix('3'), 'ropsten.') - }) + assert.equal(getEtherscanNetworkPrefix('3'), 'ropsten.'); + }); it('returns rinkeby as prefix for networkId of 4', function () { - assert.equal(getEtherscanNetworkPrefix('4'), 'rinkeby.') - }) + assert.equal(getEtherscanNetworkPrefix('4'), 'rinkeby.'); + }); it('returs kovan as prefix for networkId of 42', function () { - assert.equal(getEtherscanNetworkPrefix('42'), 'kovan.') - }) + assert.equal(getEtherscanNetworkPrefix('42'), 'kovan.'); + }); it('returs goerli as prefix for networkId of 5', function () { - assert.equal(getEtherscanNetworkPrefix('5'), 'goerli.') - }) -}) + assert.equal(getEtherscanNetworkPrefix('5'), 'goerli.'); + }); +}); diff --git a/ui/app/components/app/account-list-item/account-list-item.js b/ui/app/components/app/account-list-item/account-list-item.js index 362c740d00..9b0c0e38f4 100644 --- a/ui/app/components/app/account-list-item/account-list-item.js +++ b/ui/app/components/app/account-list-item/account-list-item.js @@ -1,8 +1,8 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { checksumAddress } from '../../../helpers/utils/util' -import Identicon from '../../ui/identicon' -import AccountMismatchWarning from '../../ui/account-mismatch-warning/account-mismatch-warning.component' +import React from 'react'; +import PropTypes from 'prop-types'; +import { checksumAddress } from '../../../helpers/utils/util'; +import Identicon from '../../ui/identicon'; +import AccountMismatchWarning from '../../ui/account-mismatch-warning/account-mismatch-warning.component'; export default function AccountListItem({ account, @@ -11,7 +11,7 @@ export default function AccountListItem({ handleClick, icon = null, }) { - const { name, address, balance } = account || {} + const { name, address, balance } = account || {}; return (
    )}
    - ) + ); } AccountListItem.propTypes = { @@ -47,4 +47,4 @@ AccountListItem.propTypes = { displayAddress: PropTypes.bool, handleClick: PropTypes.func, icon: PropTypes.node, -} +}; diff --git a/ui/app/components/app/account-list-item/index.js b/ui/app/components/app/account-list-item/index.js index 1759f6597e..a129d450c8 100644 --- a/ui/app/components/app/account-list-item/index.js +++ b/ui/app/components/app/account-list-item/index.js @@ -1 +1 @@ -export { default } from './account-list-item' +export { default } from './account-list-item'; diff --git a/ui/app/components/app/account-list-item/tests/account-list-item-component.test.js b/ui/app/components/app/account-list-item/tests/account-list-item-component.test.js index 5b329d1acd..558f9cebe2 100644 --- a/ui/app/components/app/account-list-item/tests/account-list-item-component.test.js +++ b/ui/app/components/app/account-list-item/tests/account-list-item-component.test.js @@ -1,23 +1,23 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import sinon from 'sinon' -import * as utils from '../../../../helpers/utils/util' -import Identicon from '../../../ui/identicon' -import AccountListItem from '../account-list-item' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import * as utils from '../../../../helpers/utils/util'; +import Identicon from '../../../ui/identicon'; +import AccountListItem from '../account-list-item'; describe('AccountListItem Component', function () { - let wrapper, propsMethodSpies, checksumAddressStub + let wrapper, propsMethodSpies, checksumAddressStub; describe('render', function () { before(function () { checksumAddressStub = sinon .stub(utils, 'checksumAddress') - .returns('mockCheckSumAddress') + .returns('mockCheckSumAddress'); propsMethodSpies = { handleClick: sinon.spy(), - } - }) + }; + }); beforeEach(function () { wrapper = shallow( } />, { context: { t: (str) => `${str}_t` } }, - ) - }) + ); + }); afterEach(function () { - propsMethodSpies.handleClick.resetHistory() - checksumAddressStub.resetHistory() - }) + propsMethodSpies.handleClick.resetHistory(); + checksumAddressStub.resetHistory(); + }); after(function () { - sinon.restore() - }) + sinon.restore(); + }); it('should render a div with the passed className', function () { - assert.strictEqual(wrapper.find('.mockClassName').length, 1) - assert(wrapper.find('.mockClassName').is('div')) - assert(wrapper.find('.mockClassName').hasClass('account-list-item')) - }) + assert.strictEqual(wrapper.find('.mockClassName').length, 1); + assert(wrapper.find('.mockClassName').is('div')); + assert(wrapper.find('.mockClassName').hasClass('account-list-item')); + }); it('should call handleClick with the expected props when the root div is clicked', function () { - const { onClick } = wrapper.find('.mockClassName').props() - assert.strictEqual(propsMethodSpies.handleClick.callCount, 0) - onClick() - assert.strictEqual(propsMethodSpies.handleClick.callCount, 1) + const { onClick } = wrapper.find('.mockClassName').props(); + assert.strictEqual(propsMethodSpies.handleClick.callCount, 0); + onClick(); + assert.strictEqual(propsMethodSpies.handleClick.callCount, 1); assert.deepStrictEqual(propsMethodSpies.handleClick.getCall(0).args, [ { address: 'mockAddress', name: 'mockName', balance: 'mockBalance' }, - ]) - }) + ]); + }); it('should have a top row div', function () { assert.strictEqual( wrapper.find('.mockClassName > .account-list-item__top-row').length, 1, - ) + ); assert( wrapper.find('.mockClassName > .account-list-item__top-row').is('div'), - ) - }) + ); + }); it('should have an identicon, name and icon in the top row', function () { const topRow = wrapper.find( '.mockClassName > .account-list-item__top-row', - ) - assert.strictEqual(topRow.find(Identicon).length, 1) + ); + assert.strictEqual(topRow.find(Identicon).length, 1); assert.strictEqual( topRow.find('.account-list-item__account-name').length, 1, - ) - assert.strictEqual(topRow.find('.account-list-item__icon').length, 1) - }) + ); + assert.strictEqual(topRow.find('.account-list-item__icon').length, 1); + }); it('should show the account name if it exists', function () { const topRow = wrapper.find( '.mockClassName > .account-list-item__top-row', - ) + ); assert.strictEqual( topRow.find('.account-list-item__account-name').text(), 'mockName', - ) - }) + ); + }); it('should show the account address if there is no name', function () { - wrapper.setProps({ account: { address: 'addressButNoName' } }) + wrapper.setProps({ account: { address: 'addressButNoName' } }); const topRow = wrapper.find( '.mockClassName > .account-list-item__top-row', - ) + ); assert.strictEqual( topRow.find('.account-list-item__account-name').text(), 'addressButNoName', - ) - }) + ); + }); it('should render the passed icon', function () { const topRow = wrapper.find( '.mockClassName > .account-list-item__top-row', - ) - assert(topRow.find('.account-list-item__icon').childAt(0).is('i')) + ); + assert(topRow.find('.account-list-item__icon').childAt(0).is('i')); assert( topRow.find('.account-list-item__icon').childAt(0).hasClass('mockIcon'), - ) - }) + ); + }); it('should not render an icon if none is passed', function () { - wrapper.setProps({ icon: null }) + wrapper.setProps({ icon: null }); const topRow = wrapper.find( '.mockClassName > .account-list-item__top-row', - ) - assert.strictEqual(topRow.find('.account-list-item__icon').length, 0) - }) + ); + assert.strictEqual(topRow.find('.account-list-item__icon').length, 0); + }); it('should render the account address as a checksumAddress if displayAddress is true and name is provided', function () { - wrapper.setProps({ displayAddress: true }) + wrapper.setProps({ displayAddress: true }); assert.strictEqual( wrapper.find('.account-list-item__account-address').length, 1, - ) + ); assert.strictEqual( wrapper.find('.account-list-item__account-address').text(), 'mockCheckSumAddress', - ) + ); assert.deepStrictEqual(checksumAddressStub.getCall(0).args, [ 'mockAddress', - ]) - }) + ]); + }); it('should not render the account address as a checksumAddress if displayAddress is false', function () { - wrapper.setProps({ displayAddress: false }) + wrapper.setProps({ displayAddress: false }); assert.strictEqual( wrapper.find('.account-list-item__account-address').length, 0, - ) - }) + ); + }); it('should not render the account address as a checksumAddress if name is not provided', function () { - wrapper.setProps({ account: { address: 'someAddressButNoName' } }) + wrapper.setProps({ account: { address: 'someAddressButNoName' } }); assert.strictEqual( wrapper.find('.account-list-item__account-address').length, 0, - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/ui/app/components/app/account-menu/account-menu.component.js b/ui/app/components/app/account-menu/account-menu.component.js index f16cb41a48..4c57f4c8da 100644 --- a/ui/app/components/app/account-menu/account-menu.component.js +++ b/ui/app/components/app/account-menu/account-menu.component.js @@ -1,15 +1,15 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import { debounce } from 'lodash' -import Fuse from 'fuse.js' -import InputAdornment from '@material-ui/core/InputAdornment' -import classnames from 'classnames' -import { ENVIRONMENT_TYPE_POPUP } from '../../../../../shared/constants/app' -import { getEnvironmentType } from '../../../../../app/scripts/lib/util' -import Identicon from '../../ui/identicon' -import SiteIcon from '../../ui/site-icon' -import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display' -import { PRIMARY } from '../../../helpers/constants/common' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { debounce } from 'lodash'; +import Fuse from 'fuse.js'; +import InputAdornment from '@material-ui/core/InputAdornment'; +import classnames from 'classnames'; +import { ENVIRONMENT_TYPE_POPUP } from '../../../../../shared/constants/app'; +import { getEnvironmentType } from '../../../../../app/scripts/lib/util'; +import Identicon from '../../ui/identicon'; +import SiteIcon from '../../ui/site-icon'; +import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display'; +import { PRIMARY } from '../../../helpers/constants/common'; import { SETTINGS_ROUTE, ABOUT_US_ROUTE, @@ -17,16 +17,16 @@ import { IMPORT_ACCOUNT_ROUTE, CONNECT_HARDWARE_ROUTE, DEFAULT_ROUTE, -} from '../../../helpers/constants/routes' -import TextField from '../../ui/text-field' -import SearchIcon from '../../ui/search-icon' +} from '../../../helpers/constants/routes'; +import TextField from '../../ui/text-field'; +import SearchIcon from '../../ui/search-icon'; export function AccountMenuItem(props) { - const { icon, children, text, subText, className, onClick } = props + const { icon, children, text, subText, className, onClick } = props; const itemClassName = classnames('account-menu__item', className, { 'account-menu__item--clickable': Boolean(onClick), - }) + }); return children ? (
    {children} @@ -39,7 +39,7 @@ export function AccountMenuItem(props) {
    {subText}
    ) : null}
    - ) + ); } AccountMenuItem.propTypes = { @@ -49,13 +49,13 @@ AccountMenuItem.propTypes = { subText: PropTypes.node, onClick: PropTypes.func, className: PropTypes.string, -} +}; export default class AccountMenu extends Component { static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; static propTypes = { shouldShowAccountsSearch: PropTypes.bool, @@ -69,14 +69,14 @@ export default class AccountMenu extends Component { toggleAccountMenu: PropTypes.func, addressConnectedDomainMap: PropTypes.object, originOfCurrentTab: PropTypes.string, - } + }; - accountsRef + accountsRef; state = { shouldShowScrollButton: false, searchQuery: '', - } + }; addressFuse = new Fuse([], { shouldSort: false, @@ -89,23 +89,23 @@ export default class AccountMenu extends Component { { name: 'name', weight: 0.5 }, { name: 'address', weight: 0.5 }, ], - }) + }); componentDidUpdate(prevProps, prevState) { - const { isAccountMenuOpen: prevIsAccountMenuOpen } = prevProps - const { searchQuery: prevSearchQuery } = prevState - const { isAccountMenuOpen } = this.props - const { searchQuery } = this.state + const { isAccountMenuOpen: prevIsAccountMenuOpen } = prevProps; + const { searchQuery: prevSearchQuery } = prevState; + const { isAccountMenuOpen } = this.props; + const { searchQuery } = this.state; if (!prevIsAccountMenuOpen && isAccountMenuOpen) { - this.setShouldShowScrollButton() - this.resetSearchQuery() + this.setShouldShowScrollButton(); + this.resetSearchQuery(); } // recalculate on each search query change // whether we can show scroll down button if (isAccountMenuOpen && prevSearchQuery !== searchQuery) { - this.setShouldShowScrollButton() + this.setShouldShowScrollButton(); } } @@ -121,7 +121,7 @@ export default class AccountMenu extends Component { > - ) + ); return [ ,
    , - ] + ]; } renderAccounts() { @@ -147,13 +147,13 @@ export default class AccountMenu extends Component { showAccountDetail, addressConnectedDomainMap, originOfCurrentTab, - } = this.props - const { searchQuery } = this.state + } = this.props; + const { searchQuery } = this.state; - let filteredIdentities = accounts + let filteredIdentities = accounts; if (searchQuery) { - this.addressFuse.setCollection(accounts) - filteredIdentities = this.addressFuse.search(searchQuery) + this.addressFuse.setCollection(accounts); + filteredIdentities = this.addressFuse.search(searchQuery); } if (filteredIdentities.length === 0) { @@ -161,22 +161,22 @@ export default class AccountMenu extends Component {

    {this.context.t('noAccountsFound')}

    - ) + ); } return filteredIdentities.map((identity) => { - const isSelected = identity.address === selectedAddress + const isSelected = identity.address === selectedAddress; - const simpleAddress = identity.address.substring(2).toLowerCase() + const simpleAddress = identity.address.substring(2).toLowerCase(); const keyring = keyrings.find((kr) => { return ( kr.accounts.includes(simpleAddress) || kr.accounts.includes(identity.address) - ) - }) - const addressDomains = addressConnectedDomainMap[identity.address] || {} - const iconAndNameForOpenDomain = addressDomains[originOfCurrentTab] + ); + }); + const addressDomains = addressConnectedDomainMap[identity.address] || {}; + const iconAndNameForOpenDomain = addressDomains[originOfCurrentTab]; return (
    @@ -216,70 +216,70 @@ export default class AccountMenu extends Component {
    ) : null}
    - ) - }) + ); + }); } renderKeyringType(keyring) { - const { t } = this.context + const { t } = this.context; // Sometimes keyrings aren't loaded yet if (!keyring) { - return null + return null; } - const { type } = keyring - let label + const { type } = keyring; + let label; switch (type) { case 'Trezor Hardware': case 'Ledger Hardware': - label = t('hardware') - break + label = t('hardware'); + break; case 'Simple Key Pair': - label = t('imported') - break + label = t('imported'); + break; default: - return null + return null; } - return
    {label}
    + return
    {label}
    ; } resetSearchQuery() { - this.setSearchQuery('') + this.setSearchQuery(''); } setSearchQuery(searchQuery) { - this.setState({ searchQuery }) + this.setState({ searchQuery }); } setShouldShowScrollButton = () => { - const { scrollTop, offsetHeight, scrollHeight } = this.accountsRef + const { scrollTop, offsetHeight, scrollHeight } = this.accountsRef; - const canScroll = scrollHeight > offsetHeight + const canScroll = scrollHeight > offsetHeight; - const atAccountListBottom = scrollTop + offsetHeight >= scrollHeight + const atAccountListBottom = scrollTop + offsetHeight >= scrollHeight; - const shouldShowScrollButton = canScroll && !atAccountListBottom + const shouldShowScrollButton = canScroll && !atAccountListBottom; - this.setState({ shouldShowScrollButton }) - } + this.setState({ shouldShowScrollButton }); + }; - onScroll = debounce(this.setShouldShowScrollButton, 25) + onScroll = debounce(this.setShouldShowScrollButton, 25); handleScrollDown = (e) => { - e.stopPropagation() + e.stopPropagation(); - const { scrollHeight } = this.accountsRef - this.accountsRef.scroll({ left: 0, top: scrollHeight, behavior: 'smooth' }) + const { scrollHeight } = this.accountsRef; + this.accountsRef.scroll({ left: 0, top: scrollHeight, behavior: 'smooth' }); - this.setShouldShowScrollButton() - } + this.setShouldShowScrollButton(); + }; renderScrollButton() { if (!this.state.shouldShowScrollButton) { - return null + return null; } return ( @@ -294,21 +294,21 @@ export default class AccountMenu extends Component { alt={this.context.t('scrollDown')} /> - ) + ); } render() { - const { t, metricsEvent } = this.context + const { t, metricsEvent } = this.context; const { shouldShowAccountsSearch, isAccountMenuOpen, toggleAccountMenu, lockMetamask, history, - } = this.props + } = this.props; if (!isAccountMenuOpen) { - return null + return null; } return ( @@ -319,8 +319,8 @@ export default class AccountMenu extends Component { - ) + ); } diff --git a/ui/app/components/app/add-token-button/index.js b/ui/app/components/app/add-token-button/index.js index 15c4fe6ca5..0534cd39f5 100644 --- a/ui/app/components/app/add-token-button/index.js +++ b/ui/app/components/app/add-token-button/index.js @@ -1 +1 @@ -export { default } from './add-token-button.component' +export { default } from './add-token-button.component'; diff --git a/ui/app/components/app/alerts/alerts.js b/ui/app/components/app/alerts/alerts.js index f5034073d0..382c0a55e8 100644 --- a/ui/app/components/app/alerts/alerts.js +++ b/ui/app/components/app/alerts/alerts.js @@ -1,32 +1,32 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import PropTypes from 'prop-types' +import React from 'react'; +import { useSelector } from 'react-redux'; +import PropTypes from 'prop-types'; -import { alertIsOpen as unconnectedAccountAlertIsOpen } from '../../../ducks/alerts/unconnected-account' -import { alertIsOpen as invalidCustomNetworkAlertIsOpen } from '../../../ducks/alerts/invalid-custom-network' -import InvalidCustomNetworkAlert from './invalid-custom-network-alert' -import UnconnectedAccountAlert from './unconnected-account-alert' +import { alertIsOpen as unconnectedAccountAlertIsOpen } from '../../../ducks/alerts/unconnected-account'; +import { alertIsOpen as invalidCustomNetworkAlertIsOpen } from '../../../ducks/alerts/invalid-custom-network'; +import InvalidCustomNetworkAlert from './invalid-custom-network-alert'; +import UnconnectedAccountAlert from './unconnected-account-alert'; const Alerts = ({ history }) => { const _invalidCustomNetworkAlertIsOpen = useSelector( invalidCustomNetworkAlertIsOpen, - ) + ); const _unconnectedAccountAlertIsOpen = useSelector( unconnectedAccountAlertIsOpen, - ) + ); if (_invalidCustomNetworkAlertIsOpen) { - return + return ; } if (_unconnectedAccountAlertIsOpen) { - return + return ; } - return null -} + return null; +}; Alerts.propTypes = { history: PropTypes.object.isRequired, -} +}; -export default Alerts +export default Alerts; diff --git a/ui/app/components/app/alerts/index.js b/ui/app/components/app/alerts/index.js index b52e5d6502..9b5497e58d 100644 --- a/ui/app/components/app/alerts/index.js +++ b/ui/app/components/app/alerts/index.js @@ -1 +1 @@ -export { default } from './alerts' +export { default } from './alerts'; diff --git a/ui/app/components/app/alerts/invalid-custom-network-alert/index.js b/ui/app/components/app/alerts/invalid-custom-network-alert/index.js index 9227a2172b..5c9fc683d4 100644 --- a/ui/app/components/app/alerts/invalid-custom-network-alert/index.js +++ b/ui/app/components/app/alerts/invalid-custom-network-alert/index.js @@ -1 +1 @@ -export { default } from './invalid-custom-network-alert' +export { default } from './invalid-custom-network-alert'; diff --git a/ui/app/components/app/alerts/invalid-custom-network-alert/invalid-custom-network-alert.js b/ui/app/components/app/alerts/invalid-custom-network-alert/invalid-custom-network-alert.js index 40cad2a0fa..e5c7ab8c0c 100644 --- a/ui/app/components/app/alerts/invalid-custom-network-alert/invalid-custom-network-alert.js +++ b/ui/app/components/app/alerts/invalid-custom-network-alert/invalid-custom-network-alert.js @@ -1,27 +1,27 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import PropTypes from 'prop-types' +import React from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import PropTypes from 'prop-types'; -import { ALERT_STATE } from '../../../../ducks/alerts' +import { ALERT_STATE } from '../../../../ducks/alerts'; import { dismissAlert, getAlertState, getNetworkName, -} from '../../../../ducks/alerts/invalid-custom-network' -import Popover from '../../../ui/popover' -import Button from '../../../ui/button' -import { useI18nContext } from '../../../../hooks/useI18nContext' -import { NETWORKS_ROUTE } from '../../../../helpers/constants/routes' +} from '../../../../ducks/alerts/invalid-custom-network'; +import Popover from '../../../ui/popover'; +import Button from '../../../ui/button'; +import { useI18nContext } from '../../../../hooks/useI18nContext'; +import { NETWORKS_ROUTE } from '../../../../helpers/constants/routes'; -const { ERROR, LOADING } = ALERT_STATE +const { ERROR, LOADING } = ALERT_STATE; const InvalidCustomNetworkAlert = ({ history }) => { - const t = useI18nContext() - const dispatch = useDispatch() - const alertState = useSelector(getAlertState) - const networkName = useSelector(getNetworkName) + const t = useI18nContext(); + const dispatch = useDispatch(); + const alertState = useSelector(getAlertState); + const networkName = useSelector(getNetworkName); - const onClose = () => dispatch(dismissAlert()) + const onClose = () => dispatch(dismissAlert()); const footer = ( <> @@ -42,8 +42,8 @@ const InvalidCustomNetworkAlert = ({ history }) => { - ) + ); return ( { ])}

    - ) -} + ); +}; InvalidCustomNetworkAlert.propTypes = { history: PropTypes.object.isRequired, -} +}; -export default InvalidCustomNetworkAlert +export default InvalidCustomNetworkAlert; diff --git a/ui/app/components/app/alerts/unconnected-account-alert/index.js b/ui/app/components/app/alerts/unconnected-account-alert/index.js index 495f14c333..bfa1b93621 100644 --- a/ui/app/components/app/alerts/unconnected-account-alert/index.js +++ b/ui/app/components/app/alerts/unconnected-account-alert/index.js @@ -1 +1 @@ -export { default } from './unconnected-account-alert' +export { default } from './unconnected-account-alert'; diff --git a/ui/app/components/app/alerts/unconnected-account-alert/tests/unconnected-account-alert.test.js b/ui/app/components/app/alerts/unconnected-account-alert/tests/unconnected-account-alert.test.js index d16ec36c07..701ffa1639 100644 --- a/ui/app/components/app/alerts/unconnected-account-alert/tests/unconnected-account-alert.test.js +++ b/ui/app/components/app/alerts/unconnected-account-alert/tests/unconnected-account-alert.test.js @@ -1,21 +1,21 @@ -import assert from 'assert' -import React from 'react' +import assert from 'assert'; +import React from 'react'; -import sinon from 'sinon' -import thunk from 'redux-thunk' +import sinon from 'sinon'; +import thunk from 'redux-thunk'; -import { fireEvent } from '@testing-library/react' -import configureMockStore from 'redux-mock-store' +import { fireEvent } from '@testing-library/react'; +import configureMockStore from 'redux-mock-store'; -import { renderWithProvider } from '../../../../../../../test/lib/render-helpers' +import { renderWithProvider } from '../../../../../../../test/lib/render-helpers'; -import * as actions from '../../../../../store/actions' -import UnconnectedAccountAlert from '..' +import * as actions from '../../../../../store/actions'; +import UnconnectedAccountAlert from '..'; describe('Unconnected Account Alert', function () { - const network = '123' + const network = '123'; - const selectedAddress = '0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b' + const selectedAddress = '0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b'; const identities = { '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc': { @@ -26,7 +26,7 @@ describe('Unconnected Account Alert', function () { address: '0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b', name: 'Account 2', }, - } + }; const accounts = { '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc': { @@ -37,14 +37,14 @@ describe('Unconnected Account Alert', function () { address: '0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b', balance: '0x0', }, - } + }; const cachedBalances = { 123: { '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc': '0x0', '0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b': '0x0', }, - } + }; const keyrings = [ { @@ -54,7 +54,7 @@ describe('Unconnected Account Alert', function () { '0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b', ], }, - ] + ]; const mockState = { metamask: { @@ -102,63 +102,69 @@ describe('Unconnected Account Alert', function () { unconnectedAccount: { state: 'OPEN', }, - } + }; afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('checks that checkbox is checked', function () { - const store = configureMockStore()(mockState) + const store = configureMockStore()(mockState); - const { getByRole } = renderWithProvider(, store) + const { getByRole } = renderWithProvider( + , + store, + ); - const dontShowCheckbox = getByRole('checkbox') + const dontShowCheckbox = getByRole('checkbox'); - assert.strictEqual(dontShowCheckbox.checked, false) - fireEvent.click(dontShowCheckbox) - assert.strictEqual(dontShowCheckbox.checked, true) - }) + assert.strictEqual(dontShowCheckbox.checked, false); + fireEvent.click(dontShowCheckbox); + assert.strictEqual(dontShowCheckbox.checked, true); + }); it('clicks dismiss button and calls dismissAlert action', function () { - const store = configureMockStore()(mockState) + const store = configureMockStore()(mockState); - const { getByText } = renderWithProvider(, store) + const { getByText } = renderWithProvider( + , + store, + ); - const dismissButton = getByText(/dismiss/u) - fireEvent.click(dismissButton) + const dismissButton = getByText(/dismiss/u); + fireEvent.click(dismissButton); assert.strictEqual( store.getActions()[0].type, 'unconnectedAccount/dismissAlert', - ) - }) + ); + }); it('clicks Dont Show checkbox and dismiss to call disable alert request action', async function () { - sinon.stub(actions, 'setAlertEnabledness').returns(() => Promise.resolve()) + sinon.stub(actions, 'setAlertEnabledness').returns(() => Promise.resolve()); - const store = configureMockStore([thunk])(mockState) + const store = configureMockStore([thunk])(mockState); const { getByText, getByRole } = renderWithProvider( , store, - ) + ); - const dismissButton = getByText(/dismiss/u) - const dontShowCheckbox = getByRole('checkbox') + const dismissButton = getByText(/dismiss/u); + const dontShowCheckbox = getByRole('checkbox'); - fireEvent.click(dontShowCheckbox) - fireEvent.click(dismissButton) + fireEvent.click(dontShowCheckbox); + fireEvent.click(dismissButton); setImmediate(() => { assert.strictEqual( store.getActions()[0].type, 'unconnectedAccount/disableAlertRequested', - ) + ); assert.strictEqual( store.getActions()[1].type, 'unconnectedAccount/disableAlertSucceeded', - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/ui/app/components/app/alerts/unconnected-account-alert/unconnected-account-alert.js b/ui/app/components/app/alerts/unconnected-account-alert/unconnected-account-alert.js index ce6e236aa9..c73de3f84f 100644 --- a/ui/app/components/app/alerts/unconnected-account-alert/unconnected-account-alert.js +++ b/ui/app/components/app/alerts/unconnected-account-alert/unconnected-account-alert.js @@ -1,45 +1,47 @@ -import React, { useState } from 'react' -import { useDispatch, useSelector } from 'react-redux' +import React, { useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; -import { ALERT_STATE } from '../../../../ducks/alerts' +import { ALERT_STATE } from '../../../../ducks/alerts'; import { connectAccount, dismissAlert, dismissAndDisableAlert, getAlertState, switchToAccount, -} from '../../../../ducks/alerts/unconnected-account' +} from '../../../../ducks/alerts/unconnected-account'; import { getOriginOfCurrentTab, getOrderedConnectedAccountsForActiveTab, getSelectedAddress, getSelectedIdentity, -} from '../../../../selectors' -import { isExtensionUrl } from '../../../../helpers/utils/util' -import Popover from '../../../ui/popover' -import Button from '../../../ui/button' -import Checkbox from '../../../ui/check-box' -import Tooltip from '../../../ui/tooltip' -import ConnectedAccountsList from '../../connected-accounts-list' -import { useI18nContext } from '../../../../hooks/useI18nContext' +} from '../../../../selectors'; +import { isExtensionUrl } from '../../../../helpers/utils/util'; +import Popover from '../../../ui/popover'; +import Button from '../../../ui/button'; +import Checkbox from '../../../ui/check-box'; +import Tooltip from '../../../ui/tooltip'; +import ConnectedAccountsList from '../../connected-accounts-list'; +import { useI18nContext } from '../../../../hooks/useI18nContext'; -const { ERROR, LOADING } = ALERT_STATE +const { ERROR, LOADING } = ALERT_STATE; const UnconnectedAccountAlert = () => { - const t = useI18nContext() - const dispatch = useDispatch() - const alertState = useSelector(getAlertState) - const connectedAccounts = useSelector(getOrderedConnectedAccountsForActiveTab) - const origin = useSelector(getOriginOfCurrentTab) - const selectedIdentity = useSelector(getSelectedIdentity) - const selectedAddress = useSelector(getSelectedAddress) - const [dontShowThisAgain, setDontShowThisAgain] = useState(false) + const t = useI18nContext(); + const dispatch = useDispatch(); + const alertState = useSelector(getAlertState); + const connectedAccounts = useSelector( + getOrderedConnectedAccountsForActiveTab, + ); + const origin = useSelector(getOriginOfCurrentTab); + const selectedIdentity = useSelector(getSelectedIdentity); + const selectedAddress = useSelector(getSelectedAddress); + const [dontShowThisAgain, setDontShowThisAgain] = useState(false); const onClose = async () => { return dontShowThisAgain ? await dispatch(dismissAndDisableAlert()) - : dispatch(dismissAlert()) - } + : dispatch(dismissAlert()); + }; const footer = ( <> @@ -81,7 +83,7 @@ const UnconnectedAccountAlert = () => { - ) + ); return ( { shouldRenderListOptions={false} /> - ) -} + ); +}; -export default UnconnectedAccountAlert +export default UnconnectedAccountAlert; diff --git a/ui/app/components/app/app-header/app-header.component.js b/ui/app/components/app/app-header/app-header.component.js index c8e388880c..1694362c6b 100644 --- a/ui/app/components/app/app-header/app-header.component.js +++ b/ui/app/components/app/app-header/app-header.component.js @@ -1,10 +1,10 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import Identicon from '../../ui/identicon' -import MetaFoxLogo from '../../ui/metafox-logo' -import { DEFAULT_ROUTE } from '../../../helpers/constants/routes' -import NetworkDisplay from '../network-display' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import Identicon from '../../ui/identicon'; +import MetaFoxLogo from '../../ui/metafox-logo'; +import { DEFAULT_ROUTE } from '../../../helpers/constants/routes'; +import NetworkDisplay from '../network-display'; export default class AppHeader extends PureComponent { static propTypes = { @@ -20,16 +20,16 @@ export default class AppHeader extends PureComponent { disableNetworkIndicator: PropTypes.bool, isAccountMenuOpen: PropTypes.bool, onClick: PropTypes.func, - } + }; static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; handleNetworkIndicatorClick(event) { - event.preventDefault() - event.stopPropagation() + event.preventDefault(); + event.stopPropagation(); const { networkDropdownOpen, @@ -37,10 +37,10 @@ export default class AppHeader extends PureComponent { hideNetworkDropdown, disabled, disableNetworkIndicator, - } = this.props + } = this.props; if (disabled || disableNetworkIndicator) { - return + return; } if (networkDropdownOpen === false) { @@ -50,10 +50,10 @@ export default class AppHeader extends PureComponent { action: 'Home', name: 'Opened Network Menu', }, - }) - showNetworkDropdown() + }); + showNetworkDropdown(); } else { - hideNetworkDropdown() + hideNetworkDropdown(); } } @@ -64,7 +64,7 @@ export default class AppHeader extends PureComponent { selectedAddress, disabled, isAccountMenuOpen, - } = this.props + } = this.props; return ( isUnlocked && ( @@ -81,15 +81,15 @@ export default class AppHeader extends PureComponent { action: 'Home', name: 'Opened Main Menu', }, - }) - toggleAccountMenu() + }); + toggleAccountMenu(); } }} > ) - ) + ); } render() { @@ -100,7 +100,7 @@ export default class AppHeader extends PureComponent { disableNetworkIndicator, disabled, onClick, - } = this.props + } = this.props; return (
    { if (onClick) { - await onClick() + await onClick(); } - history.push(DEFAULT_ROUTE) + history.push(DEFAULT_ROUTE); }} />
    @@ -134,6 +134,6 @@ export default class AppHeader extends PureComponent {
    - ) + ); } } diff --git a/ui/app/components/app/app-header/app-header.container.js b/ui/app/components/app/app-header/app-header.container.js index 955f2f3202..d1751c67a8 100644 --- a/ui/app/components/app/app-header/app-header.container.js +++ b/ui/app/components/app/app-header/app-header.container.js @@ -1,20 +1,20 @@ -import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom' -import { compose } from 'redux' +import { connect } from 'react-redux'; +import { withRouter } from 'react-router-dom'; +import { compose } from 'redux'; -import * as actions from '../../../store/actions' -import AppHeader from './app-header.component' +import * as actions from '../../../store/actions'; +import AppHeader from './app-header.component'; const mapStateToProps = (state) => { - const { appState, metamask } = state - const { networkDropdownOpen } = appState + const { appState, metamask } = state; + const { networkDropdownOpen } = appState; const { network, provider, selectedAddress, isUnlocked, isAccountMenuOpen, - } = metamask + } = metamask; return { networkDropdownOpen, @@ -23,18 +23,18 @@ const mapStateToProps = (state) => { selectedAddress, isUnlocked, isAccountMenuOpen, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { showNetworkDropdown: () => dispatch(actions.showNetworkDropdown()), hideNetworkDropdown: () => dispatch(actions.hideNetworkDropdown()), toggleAccountMenu: () => dispatch(actions.toggleAccountMenu()), - } -} + }; +}; export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps), -)(AppHeader) +)(AppHeader); diff --git a/ui/app/components/app/app-header/index.js b/ui/app/components/app/app-header/index.js index 6de2f9c786..4fbba4306f 100644 --- a/ui/app/components/app/app-header/index.js +++ b/ui/app/components/app/app-header/index.js @@ -1 +1 @@ -export { default } from './app-header.container' +export { default } from './app-header.container'; diff --git a/ui/app/components/app/app-header/tests/app-header.test.js b/ui/app/components/app/app-header/tests/app-header.test.js index c736d6549e..40045defc1 100644 --- a/ui/app/components/app/app-header/tests/app-header.test.js +++ b/ui/app/components/app/app-header/tests/app-header.test.js @@ -1,13 +1,13 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import { shallow } from 'enzyme' -import MetaFoxLogo from '../../../ui/metafox-logo' -import AppHeader from '..' -import NetworkDisplay from '../../network-display' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import { shallow } from 'enzyme'; +import MetaFoxLogo from '../../../ui/metafox-logo'; +import AppHeader from '..'; +import NetworkDisplay from '../../network-display'; describe('App Header', function () { - let wrapper + let wrapper; const props = { hideNetworkDropdown: sinon.spy(), @@ -24,7 +24,7 @@ describe('App Header', function () { networkDropdownOpen: false, isAccountMenuOpen: false, isUnlocked: true, - } + }; beforeEach(function () { wrapper = shallow(, { @@ -32,65 +32,65 @@ describe('App Header', function () { t: (str) => str, metricsEvent: () => undefined, }, - }) - }) + }); + }); afterEach(function () { - props.toggleAccountMenu.resetHistory() - }) + props.toggleAccountMenu.resetHistory(); + }); describe('App Header Logo', function () { it('routes to default route when logo is clicked', function () { - const appLogo = wrapper.find(MetaFoxLogo) - appLogo.simulate('click') - assert(props.history.push.calledOnce) - assert.strictEqual(props.history.push.getCall(0).args[0], '/') - }) - }) + const appLogo = wrapper.find(MetaFoxLogo); + appLogo.simulate('click'); + assert(props.history.push.calledOnce); + assert.strictEqual(props.history.push.getCall(0).args[0], '/'); + }); + }); describe('Network', function () { it('shows network dropdown when networkDropdownOpen is false', function () { - const network = wrapper.find(NetworkDisplay) + const network = wrapper.find(NetworkDisplay); network.simulate('click', { preventDefault: () => undefined, stopPropagation: () => undefined, - }) + }); - assert(props.showNetworkDropdown.calledOnce) - }) + assert(props.showNetworkDropdown.calledOnce); + }); it('hides network dropdown when networkDropdownOpen is true', function () { - wrapper.setProps({ networkDropdownOpen: true }) - const network = wrapper.find(NetworkDisplay) + wrapper.setProps({ networkDropdownOpen: true }); + const network = wrapper.find(NetworkDisplay); network.simulate('click', { preventDefault: () => undefined, stopPropagation: () => undefined, - }) + }); - assert(props.hideNetworkDropdown.calledOnce) - }) + assert(props.hideNetworkDropdown.calledOnce); + }); it('hides network indicator', function () { - wrapper.setProps({ hideNetworkIndicator: true }) - const network = wrapper.find({ network: 'test' }) - assert.strictEqual(network.length, 0) - }) - }) + wrapper.setProps({ hideNetworkIndicator: true }); + const network = wrapper.find({ network: 'test' }); + assert.strictEqual(network.length, 0); + }); + }); describe('Account Menu', function () { it('toggles account menu', function () { - const accountMenu = wrapper.find('.account-menu__icon') - accountMenu.simulate('click') - assert(props.toggleAccountMenu.calledOnce) - }) + const accountMenu = wrapper.find('.account-menu__icon'); + accountMenu.simulate('click'); + assert(props.toggleAccountMenu.calledOnce); + }); it('does not toggle account menu when disabled', function () { - wrapper.setProps({ disabled: true }) - const accountMenu = wrapper.find('.account-menu__icon') - accountMenu.simulate('click') - assert(props.toggleAccountMenu.notCalled) - }) - }) -}) + wrapper.setProps({ disabled: true }); + const accountMenu = wrapper.find('.account-menu__icon'); + accountMenu.simulate('click'); + assert(props.toggleAccountMenu.notCalled); + }); + }); +}); diff --git a/ui/app/components/app/asset-list-item/asset-list-item.js b/ui/app/components/app/asset-list-item/asset-list-item.js index b09fb3c3f9..8672a8c8e8 100644 --- a/ui/app/components/app/asset-list-item/asset-list-item.js +++ b/ui/app/components/app/asset-list-item/asset-list-item.js @@ -1,18 +1,18 @@ -import React, { useMemo } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { useDispatch } from 'react-redux' -import { useHistory } from 'react-router-dom' -import Identicon from '../../ui/identicon' -import ListItem from '../../ui/list-item' -import Tooltip from '../../ui/tooltip' -import InfoIcon from '../../ui/icon/info-icon.component' -import Button from '../../ui/button' -import { useI18nContext } from '../../../hooks/useI18nContext' -import { useMetricEvent } from '../../../hooks/useMetricEvent' -import { updateSendToken } from '../../../store/actions' -import { SEND_ROUTE } from '../../../helpers/constants/routes' -import { SEVERITIES } from '../../../helpers/constants/design-system' +import React, { useMemo } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import { useDispatch } from 'react-redux'; +import { useHistory } from 'react-router-dom'; +import Identicon from '../../ui/identicon'; +import ListItem from '../../ui/list-item'; +import Tooltip from '../../ui/tooltip'; +import InfoIcon from '../../ui/icon/info-icon.component'; +import Button from '../../ui/button'; +import { useI18nContext } from '../../../hooks/useI18nContext'; +import { useMetricEvent } from '../../../hooks/useMetricEvent'; +import { updateSendToken } from '../../../store/actions'; +import { SEND_ROUTE } from '../../../helpers/constants/routes'; +import { SEVERITIES } from '../../../helpers/constants/design-system'; const AssetListItem = ({ className, @@ -27,16 +27,16 @@ const AssetListItem = ({ primary, secondary, }) => { - const t = useI18nContext() - const dispatch = useDispatch() - const history = useHistory() + const t = useI18nContext(); + const dispatch = useDispatch(); + const history = useHistory(); const sendTokenEvent = useMetricEvent({ eventOpts: { category: 'Navigation', action: 'Home', name: 'Clicked Send: Token', }, - }) + }); const titleIcon = warning ? ( - ) : null + ) : null; const midContent = warning ? ( <>
    {warning}
    - ) : null + ) : null; const sendTokenButton = useMemo(() => { if (tokenAddress === null || tokenAddress === undefined) { - return null + return null; } return ( - ) + ); }, [ tokenSymbol, sendTokenEvent, @@ -87,7 +87,7 @@ const AssetListItem = ({ history, t, dispatch, - ]) + ]); return ( } /> - ) -} + ); +}; AssetListItem.propTypes = { className: PropTypes.string, @@ -140,7 +140,7 @@ AssetListItem.propTypes = { warning: PropTypes.node, primary: PropTypes.string, secondary: PropTypes.string, -} +}; AssetListItem.defaultProps = { className: undefined, @@ -149,6 +149,6 @@ AssetListItem.defaultProps = { tokenAddress: undefined, tokenImage: undefined, warning: undefined, -} +}; -export default AssetListItem +export default AssetListItem; diff --git a/ui/app/components/app/asset-list-item/index.js b/ui/app/components/app/asset-list-item/index.js index 48b7de3d28..9e8c6dcf2d 100644 --- a/ui/app/components/app/asset-list-item/index.js +++ b/ui/app/components/app/asset-list-item/index.js @@ -1 +1 @@ -export { default } from './asset-list-item' +export { default } from './asset-list-item'; diff --git a/ui/app/components/app/asset-list/asset-list.js b/ui/app/components/app/asset-list/asset-list.js index b576e0bf3f..7a817d1cb7 100644 --- a/ui/app/components/app/asset-list/asset-list.js +++ b/ui/app/components/app/asset-list/asset-list.js @@ -1,51 +1,51 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { useSelector } from 'react-redux' -import { useHistory } from 'react-router-dom' -import AddTokenButton from '../add-token-button' -import TokenList from '../token-list' -import { ADD_TOKEN_ROUTE } from '../../../helpers/constants/routes' -import AssetListItem from '../asset-list-item' -import { PRIMARY, SECONDARY } from '../../../helpers/constants/common' -import { useMetricEvent } from '../../../hooks/useMetricEvent' -import { useUserPreferencedCurrency } from '../../../hooks/useUserPreferencedCurrency' +import React from 'react'; +import PropTypes from 'prop-types'; +import { useSelector } from 'react-redux'; +import { useHistory } from 'react-router-dom'; +import AddTokenButton from '../add-token-button'; +import TokenList from '../token-list'; +import { ADD_TOKEN_ROUTE } from '../../../helpers/constants/routes'; +import AssetListItem from '../asset-list-item'; +import { PRIMARY, SECONDARY } from '../../../helpers/constants/common'; +import { useMetricEvent } from '../../../hooks/useMetricEvent'; +import { useUserPreferencedCurrency } from '../../../hooks/useUserPreferencedCurrency'; import { getCurrentAccountWithSendEtherInfo, getNativeCurrency, getShouldShowFiat, -} from '../../../selectors' -import { useCurrencyDisplay } from '../../../hooks/useCurrencyDisplay' +} from '../../../selectors'; +import { useCurrencyDisplay } from '../../../hooks/useCurrencyDisplay'; const AssetList = ({ onClickAsset }) => { - const history = useHistory() + const history = useHistory(); const selectedAccountBalance = useSelector( (state) => getCurrentAccountWithSendEtherInfo(state).balance, - ) - const nativeCurrency = useSelector(getNativeCurrency) - const showFiat = useSelector(getShouldShowFiat) + ); + const nativeCurrency = useSelector(getNativeCurrency); + const showFiat = useSelector(getShouldShowFiat); const selectTokenEvent = useMetricEvent({ eventOpts: { category: 'Navigation', action: 'Token Menu', name: 'Clicked Token', }, - }) + }); const addTokenEvent = useMetricEvent({ eventOpts: { category: 'Navigation', action: 'Token Menu', name: 'Clicked "Add Token"', }, - }) + }); const { currency: primaryCurrency, numberOfDecimals: primaryNumberOfDecimals, - } = useUserPreferencedCurrency(PRIMARY, { ethNumberOfDecimals: 4 }) + } = useUserPreferencedCurrency(PRIMARY, { ethNumberOfDecimals: 4 }); const { currency: secondaryCurrency, numberOfDecimals: secondaryNumberOfDecimals, - } = useUserPreferencedCurrency(SECONDARY, { ethNumberOfDecimals: 4 }) + } = useUserPreferencedCurrency(SECONDARY, { ethNumberOfDecimals: 4 }); const [, primaryCurrencyProperties] = useCurrencyDisplay( selectedAccountBalance, @@ -53,7 +53,7 @@ const AssetList = ({ onClickAsset }) => { numberOfDecimals: primaryNumberOfDecimals, currency: primaryCurrency, }, - ) + ); const [secondaryCurrencyDisplay] = useCurrencyDisplay( selectedAccountBalance, @@ -61,7 +61,7 @@ const AssetList = ({ onClickAsset }) => { numberOfDecimals: secondaryNumberOfDecimals, currency: secondaryCurrency, }, - ) + ); return ( <> @@ -74,22 +74,22 @@ const AssetList = ({ onClickAsset }) => { /> { - onClickAsset(tokenAddress) - selectTokenEvent() + onClickAsset(tokenAddress); + selectTokenEvent(); }} /> { - history.push(ADD_TOKEN_ROUTE) - addTokenEvent() + history.push(ADD_TOKEN_ROUTE); + addTokenEvent(); }} /> - ) -} + ); +}; AssetList.propTypes = { onClickAsset: PropTypes.func.isRequired, -} +}; -export default AssetList +export default AssetList; diff --git a/ui/app/components/app/asset-list/index.js b/ui/app/components/app/asset-list/index.js index 47ee5ce9fe..7906ebe8ef 100644 --- a/ui/app/components/app/asset-list/index.js +++ b/ui/app/components/app/asset-list/index.js @@ -1 +1 @@ -export { default } from './asset-list' +export { default } from './asset-list'; diff --git a/ui/app/components/app/confirm-page-container/confirm-detail-row/confirm-detail-row.component.js b/ui/app/components/app/confirm-page-container/confirm-detail-row/confirm-detail-row.component.js index 280c5662f9..4ee4ecbd47 100644 --- a/ui/app/components/app/confirm-page-container/confirm-detail-row/confirm-detail-row.component.js +++ b/ui/app/components/app/confirm-page-container/confirm-detail-row/confirm-detail-row.component.js @@ -1,8 +1,8 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import UserPreferencedCurrencyDisplay from '../../user-preferenced-currency-display' -import { PRIMARY, SECONDARY } from '../../../../helpers/constants/common' +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import UserPreferencedCurrencyDisplay from '../../user-preferenced-currency-display'; +import { PRIMARY, SECONDARY } from '../../../../helpers/constants/common'; const ConfirmDetailRow = (props) => { const { @@ -14,7 +14,7 @@ const ConfirmDetailRow = (props) => { headerText, headerTextClassName, value, - } = props + } = props; return (
    @@ -62,8 +62,8 @@ const ConfirmDetailRow = (props) => { )}
    - ) -} + ); +}; ConfirmDetailRow.propTypes = { headerText: PropTypes.string, @@ -74,6 +74,6 @@ ConfirmDetailRow.propTypes = { primaryText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), secondaryText: PropTypes.string, value: PropTypes.string, -} +}; -export default ConfirmDetailRow +export default ConfirmDetailRow; diff --git a/ui/app/components/app/confirm-page-container/confirm-detail-row/index.js b/ui/app/components/app/confirm-page-container/confirm-detail-row/index.js index 056afff04e..18e6082719 100644 --- a/ui/app/components/app/confirm-page-container/confirm-detail-row/index.js +++ b/ui/app/components/app/confirm-page-container/confirm-detail-row/index.js @@ -1 +1 @@ -export { default } from './confirm-detail-row.component' +export { default } from './confirm-detail-row.component'; diff --git a/ui/app/components/app/confirm-page-container/confirm-detail-row/tests/confirm-detail-row.component.test.js b/ui/app/components/app/confirm-page-container/confirm-detail-row/tests/confirm-detail-row.component.test.js index ed6ac21f83..c019f3a5b7 100644 --- a/ui/app/components/app/confirm-page-container/confirm-detail-row/tests/confirm-detail-row.component.test.js +++ b/ui/app/components/app/confirm-page-container/confirm-detail-row/tests/confirm-detail-row.component.test.js @@ -1,16 +1,16 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import sinon from 'sinon' -import ConfirmDetailRow from '../confirm-detail-row.component' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import ConfirmDetailRow from '../confirm-detail-row.component'; const propsMethodSpies = { onHeaderClick: sinon.spy(), -} +}; describe('Confirm Detail Row Component', function () { describe('render', function () { - let wrapper + let wrapper; beforeEach(function () { wrapper = shallow( @@ -25,12 +25,12 @@ describe('Confirm Detail Row Component', function () { headerText="mockHeaderText" headerTextClassName="mockHeaderClass" />, - ) - }) + ); + }); it('should render a div with a confirm-detail-row class', function () { - assert.strictEqual(wrapper.find('div.confirm-detail-row').length, 1) - }) + assert.strictEqual(wrapper.find('div.confirm-detail-row').length, 1); + }); it('should render the label as a child of the confirm-detail-row__label', function () { assert.strictEqual( @@ -39,8 +39,8 @@ describe('Confirm Detail Row Component', function () { .childAt(0) .text(), 'mockLabel', - ) - }) + ); + }); it('should render the headerText as a child of the confirm-detail-row__header-text', function () { assert.strictEqual( @@ -51,8 +51,8 @@ describe('Confirm Detail Row Component', function () { .childAt(0) .text(), 'mockHeaderText', - ) - }) + ); + }); it('should render the primaryText as a child of the confirm-detail-row__primary', function () { assert.strictEqual( @@ -61,8 +61,8 @@ describe('Confirm Detail Row Component', function () { .childAt(0) .text(), 'mockFiatText', - ) - }) + ); + }); it('should render the ethText as a child of the confirm-detail-row__secondary', function () { assert.strictEqual( @@ -71,26 +71,26 @@ describe('Confirm Detail Row Component', function () { .childAt(0) .text(), 'mockEthText', - ) - }) + ); + }); it('should set the fiatTextColor on confirm-detail-row__primary', function () { assert.strictEqual( wrapper.find('.confirm-detail-row__primary').props().style.color, 'mockColor', - ) - }) + ); + }); it('should assure the confirm-detail-row__header-text classname is correct', function () { assert.strictEqual( wrapper.find('.confirm-detail-row__header-text').props().className, 'confirm-detail-row__header-text mockHeaderClass', - ) - }) + ); + }); it('should call onHeaderClick when headerText div gets clicked', function () { - wrapper.find('.confirm-detail-row__header-text').props().onClick() - assert.ok(propsMethodSpies.onHeaderClick.calledOnce) - }) - }) -}) + wrapper.find('.confirm-detail-row__header-text').props().onClick(); + assert.ok(propsMethodSpies.onHeaderClick.calledOnce); + }); + }); +}); diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-content.component.js b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-content.component.js index d3542345ee..9009f9feba 100644 --- a/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-content.component.js +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-content.component.js @@ -1,10 +1,10 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { Tabs, Tab } from '../../../ui/tabs' -import ErrorMessage from '../../../ui/error-message' -import { PageContainerFooter } from '../../../ui/page-container' -import { ConfirmPageContainerSummary, ConfirmPageContainerWarning } from '.' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import { Tabs, Tab } from '../../../ui/tabs'; +import ErrorMessage from '../../../ui/error-message'; +import { PageContainerFooter } from '../../../ui/page-container'; +import { ConfirmPageContainerSummary, ConfirmPageContainerWarning } from '.'; export default class ConfirmPageContainerContent extends Component { static propTypes = { @@ -31,19 +31,19 @@ export default class ConfirmPageContainerContent extends Component { disabled: PropTypes.bool, unapprovedTxCount: PropTypes.number, rejectNText: PropTypes.string, - } + }; renderContent() { - const { detailsComponent, dataComponent } = this.props + const { detailsComponent, dataComponent } = this.props; if (detailsComponent && dataComponent) { - return this.renderTabs() + return this.renderTabs(); } - return detailsComponent || dataComponent + return detailsComponent || dataComponent; } renderTabs() { - const { detailsComponent, dataComponent } = this.props + const { detailsComponent, dataComponent } = this.props; return ( @@ -54,7 +54,7 @@ export default class ConfirmPageContainerContent extends Component { {dataComponent} - ) + ); } render() { @@ -81,7 +81,7 @@ export default class ConfirmPageContainerContent extends Component { unapprovedTxCount, rejectNText, origin, - } = this.props + } = this.props; return (
    @@ -118,6 +118,6 @@ export default class ConfirmPageContainerContent extends Component { {unapprovedTxCount > 1 && {rejectNText}}
    - ) + ); } } diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/confirm-page-container-summary.component.js b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/confirm-page-container-summary.component.js index 49efb86e54..cd33ee3577 100644 --- a/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/confirm-page-container-summary.component.js +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/confirm-page-container-summary.component.js @@ -1,7 +1,7 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import Identicon from '../../../../ui/identicon' +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import Identicon from '../../../../ui/identicon'; const ConfirmPageContainerSummary = (props) => { const { @@ -15,7 +15,7 @@ const ConfirmPageContainerSummary = (props) => { nonce, assetImage, origin, - } = props + } = props; return (
    @@ -49,8 +49,8 @@ const ConfirmPageContainerSummary = (props) => {
    )} - ) -} + ); +}; ConfirmPageContainerSummary.propTypes = { action: PropTypes.string, @@ -63,6 +63,6 @@ ConfirmPageContainerSummary.propTypes = { nonce: PropTypes.string, assetImage: PropTypes.string, origin: PropTypes.string.isRequired, -} +}; -export default ConfirmPageContainerSummary +export default ConfirmPageContainerSummary; diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/index.js b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/index.js index ed1b28cf23..a5ddf1cdf2 100644 --- a/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/index.js +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/index.js @@ -1 +1 @@ -export { default } from './confirm-page-container-summary.component' +export { default } from './confirm-page-container-summary.component'; diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/confirm-page-container-warning.component.js b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/confirm-page-container-warning.component.js index a79cabcd65..eef1ed09e5 100644 --- a/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/confirm-page-container-warning.component.js +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/confirm-page-container-warning.component.js @@ -1,5 +1,5 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; const ConfirmPageContainerWarning = (props) => { return ( @@ -13,11 +13,11 @@ const ConfirmPageContainerWarning = (props) => { {props.warning} - ) -} + ); +}; ConfirmPageContainerWarning.propTypes = { warning: PropTypes.string, -} +}; -export default ConfirmPageContainerWarning +export default ConfirmPageContainerWarning; diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/index.js b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/index.js index 6e48bd1446..dce2fb7a91 100644 --- a/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/index.js +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/index.js @@ -1 +1 @@ -export { default } from './confirm-page-container-warning.component' +export { default } from './confirm-page-container-warning.component'; diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-content/index.js b/ui/app/components/app/confirm-page-container/confirm-page-container-content/index.js index 4dfd89d929..15f290dbac 100644 --- a/ui/app/components/app/confirm-page-container/confirm-page-container-content/index.js +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-content/index.js @@ -1,3 +1,3 @@ -export { default } from './confirm-page-container-content.component' -export { default as ConfirmPageContainerSummary } from './confirm-page-container-summary' -export { default as ConfirmPageContainerWarning } from './confirm-page-container-warning' +export { default } from './confirm-page-container-content.component'; +export { default as ConfirmPageContainerSummary } from './confirm-page-container-summary'; +export { default as ConfirmPageContainerWarning } from './confirm-page-container-warning'; diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-header/confirm-page-container-header.component.js b/ui/app/components/app/confirm-page-container/confirm-page-container-header/confirm-page-container-header.component.js index bdc6295d6e..0c17f41fa6 100644 --- a/ui/app/components/app/confirm-page-container/confirm-page-container-header/confirm-page-container-header.component.js +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-header/confirm-page-container-header.component.js @@ -1,15 +1,15 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; import { ENVIRONMENT_TYPE_POPUP, ENVIRONMENT_TYPE_NOTIFICATION, -} from '../../../../../../shared/constants/app' -import { getEnvironmentType } from '../../../../../../app/scripts/lib/util' -import NetworkDisplay from '../../network-display' -import Identicon from '../../../ui/identicon' -import { shortenAddress } from '../../../../helpers/utils/util' -import AccountMismatchWarning from '../../../ui/account-mismatch-warning/account-mismatch-warning.component' -import { useI18nContext } from '../../../../hooks/useI18nContext' +} from '../../../../../../shared/constants/app'; +import { getEnvironmentType } from '../../../../../../app/scripts/lib/util'; +import NetworkDisplay from '../../network-display'; +import Identicon from '../../../ui/identicon'; +import { shortenAddress } from '../../../../helpers/utils/util'; +import AccountMismatchWarning from '../../../ui/account-mismatch-warning/account-mismatch-warning.component'; +import { useI18nContext } from '../../../../hooks/useI18nContext'; export default function ConfirmPageContainerHeader({ onEdit, @@ -18,14 +18,14 @@ export default function ConfirmPageContainerHeader({ showAccountInHeader, children, }) { - const t = useI18nContext() - const windowType = getEnvironmentType() + const t = useI18nContext(); + const windowType = getEnvironmentType(); const isFullScreen = windowType !== ENVIRONMENT_TYPE_NOTIFICATION && - windowType !== ENVIRONMENT_TYPE_POPUP + windowType !== ENVIRONMENT_TYPE_POPUP; if (!showEdit && isFullScreen) { - return null + return null; } return (
    @@ -60,7 +60,7 @@ export default function ConfirmPageContainerHeader({
    {children} - ) + ); } ConfirmPageContainerHeader.propTypes = { @@ -69,4 +69,4 @@ ConfirmPageContainerHeader.propTypes = { showEdit: PropTypes.bool, onEdit: PropTypes.func, children: PropTypes.node, -} +}; diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-header/index.js b/ui/app/components/app/confirm-page-container/confirm-page-container-header/index.js index 71feb69316..b8c53f3b0c 100644 --- a/ui/app/components/app/confirm-page-container/confirm-page-container-header/index.js +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-header/index.js @@ -1 +1 @@ -export { default } from './confirm-page-container-header.component' +export { default } from './confirm-page-container-header.component'; diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-navigation/confirm-page-container-navigation.component.js b/ui/app/components/app/confirm-page-container/confirm-page-container-navigation/confirm-page-container-navigation.component.js index 010262b528..20e9c0ce55 100755 --- a/ui/app/components/app/confirm-page-container/confirm-page-container-navigation/confirm-page-container-navigation.component.js +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-navigation/confirm-page-container-navigation.component.js @@ -1,5 +1,5 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; const ConfirmPageContainerNavigation = (props) => { const { @@ -13,7 +13,7 @@ const ConfirmPageContainerNavigation = (props) => { lastTx, ofText, requestsWaitingText, - } = props + } = props; return (
    {
    - ) -} + ); +}; ConfirmPageContainerNavigation.propTypes = { totalTx: PropTypes.number, @@ -95,6 +95,6 @@ ConfirmPageContainerNavigation.propTypes = { lastTx: PropTypes.string, ofText: PropTypes.string, requestsWaitingText: PropTypes.string, -} +}; -export default ConfirmPageContainerNavigation +export default ConfirmPageContainerNavigation; diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-navigation/index.js b/ui/app/components/app/confirm-page-container/confirm-page-container-navigation/index.js index d97c1b447f..133d52557c 100755 --- a/ui/app/components/app/confirm-page-container/confirm-page-container-navigation/index.js +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-navigation/index.js @@ -1 +1 @@ -export { default } from './confirm-page-container-navigation.component' +export { default } from './confirm-page-container-navigation.component'; diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container.component.js b/ui/app/components/app/confirm-page-container/confirm-page-container.component.js index 623b31102c..c713935f9f 100644 --- a/ui/app/components/app/confirm-page-container/confirm-page-container.component.js +++ b/ui/app/components/app/confirm-page-container/confirm-page-container.component.js @@ -1,17 +1,17 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import SenderToRecipient from '../../ui/sender-to-recipient' -import { PageContainerFooter } from '../../ui/page-container' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import SenderToRecipient from '../../ui/sender-to-recipient'; +import { PageContainerFooter } from '../../ui/page-container'; import { ConfirmPageContainerHeader, ConfirmPageContainerContent, ConfirmPageContainerNavigation, -} from '.' +} from '.'; export default class ConfirmPageContainer extends Component { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { // Header @@ -59,7 +59,7 @@ export default class ConfirmPageContainer extends Component { onCancel: PropTypes.func, onSubmit: PropTypes.func, disabled: PropTypes.bool, - } + }; render() { const { @@ -103,9 +103,9 @@ export default class ConfirmPageContainer extends Component { hideSenderToRecipient, showAccountInHeader, origin, - } = this.props + } = this.props; const renderAssetImage = - contentComponent || (!contentComponent && !identiconAddress) + contentComponent || (!contentComponent && !identiconAddress); return (
    @@ -182,6 +182,6 @@ export default class ConfirmPageContainer extends Component { )}
    - ) + ); } } diff --git a/ui/app/components/app/confirm-page-container/index.js b/ui/app/components/app/confirm-page-container/index.js index 62fc9cedc0..d9bc6f5a89 100644 --- a/ui/app/components/app/confirm-page-container/index.js +++ b/ui/app/components/app/confirm-page-container/index.js @@ -1,9 +1,9 @@ -export { default } from './confirm-page-container.component' -export { default as ConfirmPageContainerHeader } from './confirm-page-container-header' -export { default as ConfirmDetailRow } from './confirm-detail-row' -export { default as ConfirmPageContainerNavigation } from './confirm-page-container-navigation' +export { default } from './confirm-page-container.component'; +export { default as ConfirmPageContainerHeader } from './confirm-page-container-header'; +export { default as ConfirmDetailRow } from './confirm-detail-row'; +export { default as ConfirmPageContainerNavigation } from './confirm-page-container-navigation'; export { default as ConfirmPageContainerContent, ConfirmPageContainerSummary, -} from './confirm-page-container-content' +} from './confirm-page-container-content'; diff --git a/ui/app/components/app/connected-accounts-list/connected-accounts-list-item/connected-accounts-list-item.component.js b/ui/app/components/app/connected-accounts-list/connected-accounts-list-item/connected-accounts-list-item.component.js index 8a1fc08521..4ec24a7b48 100644 --- a/ui/app/components/app/connected-accounts-list/connected-accounts-list-item/connected-accounts-list-item.component.js +++ b/ui/app/components/app/connected-accounts-list/connected-accounts-list-item/connected-accounts-list-item.component.js @@ -1,12 +1,12 @@ -import classnames from 'classnames' -import PropTypes from 'prop-types' -import React, { PureComponent } from 'react' -import Identicon from '../../../ui/identicon' +import classnames from 'classnames'; +import PropTypes from 'prop-types'; +import React, { PureComponent } from 'react'; +import Identicon from '../../../ui/identicon'; export default class ConnectedAccountsListItem extends PureComponent { static contextTypes = { t: PropTypes.func.isRequired, - } + }; static propTypes = { address: PropTypes.string.isRequired, @@ -15,16 +15,16 @@ export default class ConnectedAccountsListItem extends PureComponent { status: PropTypes.string, action: PropTypes.node, options: PropTypes.node, - } + }; static defaultProps = { className: null, options: null, action: null, - } + }; render() { - const { address, className, name, status, action, options } = this.props + const { address, className, name, status, action, options } = this.props; return (
    @@ -49,6 +49,6 @@ export default class ConnectedAccountsListItem extends PureComponent {
    {options} - ) + ); } } diff --git a/ui/app/components/app/connected-accounts-list/connected-accounts-list-item/index.js b/ui/app/components/app/connected-accounts-list/connected-accounts-list-item/index.js index 3fb33c23ee..7543d6dc10 100644 --- a/ui/app/components/app/connected-accounts-list/connected-accounts-list-item/index.js +++ b/ui/app/components/app/connected-accounts-list/connected-accounts-list-item/index.js @@ -1 +1 @@ -export { default } from './connected-accounts-list-item.component' +export { default } from './connected-accounts-list-item.component'; diff --git a/ui/app/components/app/connected-accounts-list/connected-accounts-list-options/connected-accounts-list-options.component.js b/ui/app/components/app/connected-accounts-list/connected-accounts-list-options/connected-accounts-list-options.component.js index c647bca40d..1850b11d79 100644 --- a/ui/app/components/app/connected-accounts-list/connected-accounts-list-options/connected-accounts-list-options.component.js +++ b/ui/app/components/app/connected-accounts-list/connected-accounts-list-options/connected-accounts-list-options.component.js @@ -1,6 +1,6 @@ -import PropTypes from 'prop-types' -import React, { useState } from 'react' -import { Menu } from '../../../ui/menu' +import PropTypes from 'prop-types'; +import React, { useState } from 'react'; +import { Menu } from '../../../ui/menu'; const ConnectedAccountsListOptions = ({ children, @@ -8,7 +8,7 @@ const ConnectedAccountsListOptions = ({ onHideOptions, show, }) => { - const [optionsButtonElement, setOptionsButtonElement] = useState(null) + const [optionsButtonElement, setOptionsButtonElement] = useState(null); return ( <> @@ -31,14 +31,14 @@ const ConnectedAccountsListOptions = ({ ) : null} - ) -} + ); +}; ConnectedAccountsListOptions.propTypes = { children: PropTypes.node.isRequired, onHideOptions: PropTypes.func.isRequired, onShowOptions: PropTypes.func.isRequired, show: PropTypes.bool.isRequired, -} +}; -export default ConnectedAccountsListOptions +export default ConnectedAccountsListOptions; diff --git a/ui/app/components/app/connected-accounts-list/connected-accounts-list-options/index.js b/ui/app/components/app/connected-accounts-list/connected-accounts-list-options/index.js index 6e4db34466..c876378ebc 100644 --- a/ui/app/components/app/connected-accounts-list/connected-accounts-list-options/index.js +++ b/ui/app/components/app/connected-accounts-list/connected-accounts-list-options/index.js @@ -1 +1 @@ -export { default } from './connected-accounts-list-options.component' +export { default } from './connected-accounts-list-options.component'; diff --git a/ui/app/components/app/connected-accounts-list/connected-accounts-list.component.js b/ui/app/components/app/connected-accounts-list/connected-accounts-list.component.js index 501af81959..cb1fa58614 100644 --- a/ui/app/components/app/connected-accounts-list/connected-accounts-list.component.js +++ b/ui/app/components/app/connected-accounts-list/connected-accounts-list.component.js @@ -1,17 +1,17 @@ -import PropTypes from 'prop-types' -import React, { PureComponent } from 'react' -import { MenuItem } from '../../ui/menu' -import ConnectedAccountsListItem from './connected-accounts-list-item' -import ConnectedAccountsListOptions from './connected-accounts-list-options' +import PropTypes from 'prop-types'; +import React, { PureComponent } from 'react'; +import { MenuItem } from '../../ui/menu'; +import ConnectedAccountsListItem from './connected-accounts-list-item'; +import ConnectedAccountsListOptions from './connected-accounts-list-options'; export default class ConnectedAccountsList extends PureComponent { static contextTypes = { t: PropTypes.func.isRequired, - } + }; static defaultProps = { accountToConnect: null, - } + }; static propTypes = { accountToConnect: PropTypes.shape({ @@ -35,47 +35,47 @@ export default class ConnectedAccountsList extends PureComponent { `Warning: Failed prop type: '${propName}' of component '${componentName}' must be a boolean. Received: ${typeof props[ propName ]}`, - ) + ); } else if (props[propName] && !props.removePermittedAccount) { return new Error( `Warning: Failed prop type: '${propName}' of component '${componentName}' requires prop 'removePermittedAccount'.`, - ) + ); } - return undefined + return undefined; }, - } + }; state = { accountWithOptionsShown: null, - } + }; disconnectAccount = () => { - this.hideAccountOptions() - this.props.removePermittedAccount(this.state.accountWithOptionsShown) - } + this.hideAccountOptions(); + this.props.removePermittedAccount(this.state.accountWithOptionsShown); + }; switchAccount = (address) => { - this.hideAccountOptions() - this.props.setSelectedAddress(address) - } + this.hideAccountOptions(); + this.props.setSelectedAddress(address); + }; hideAccountOptions = () => { - this.setState({ accountWithOptionsShown: null }) - } + this.setState({ accountWithOptionsShown: null }); + }; showAccountOptions = (address) => { - this.setState({ accountWithOptionsShown: address }) - } + this.setState({ accountWithOptionsShown: address }); + }; renderUnconnectedAccount() { - const { accountToConnect, connectAccount } = this.props - const { t } = this.context + const { accountToConnect, connectAccount } = this.props; + const { t } = this.context; if (!accountToConnect) { - return null + return null; } - const { address, name } = accountToConnect + const { address, name } = accountToConnect; return ( } /> - ) + ); } renderListItemOptions(address) { - const { accountWithOptionsShown } = this.state - const { t } = this.context + const { accountWithOptionsShown } = this.state; + const { t } = this.context; return ( - ) + ); } renderListItemAction(address) { - const { t } = this.context + const { t } = this.context; return ( {t('switchToThisAccount')} - ) + ); } render() { @@ -132,8 +132,8 @@ export default class ConnectedAccountsList extends PureComponent { connectedAccounts, selectedAddress, shouldRenderListOptions, - } = this.props - const { t } = this.context + } = this.props; + const { t } = this.context; return ( <> @@ -157,10 +157,10 @@ export default class ConnectedAccountsList extends PureComponent { : this.renderListItemAction(address) } /> - ) + ); })} - ) + ); } } diff --git a/ui/app/components/app/connected-accounts-list/index.js b/ui/app/components/app/connected-accounts-list/index.js index ee436f58ab..1df443c461 100644 --- a/ui/app/components/app/connected-accounts-list/index.js +++ b/ui/app/components/app/connected-accounts-list/index.js @@ -1 +1 @@ -export { default } from './connected-accounts-list.component' +export { default } from './connected-accounts-list.component'; diff --git a/ui/app/components/app/connected-accounts-permissions/connected-accounts-permissions.component.js b/ui/app/components/app/connected-accounts-permissions/connected-accounts-permissions.component.js index 4b6e21678b..11e521c556 100644 --- a/ui/app/components/app/connected-accounts-permissions/connected-accounts-permissions.component.js +++ b/ui/app/components/app/connected-accounts-permissions/connected-accounts-permissions.component.js @@ -1,16 +1,16 @@ -import classnames from 'classnames' -import PropTypes from 'prop-types' -import React, { PureComponent } from 'react' -import CheckBox from '../../ui/check-box' +import classnames from 'classnames'; +import PropTypes from 'prop-types'; +import React, { PureComponent } from 'react'; +import CheckBox from '../../ui/check-box'; export default class ConnectedAccountsPermissions extends PureComponent { static contextTypes = { t: PropTypes.func.isRequired, - } + }; static defaultProps = { permissions: [], - } + }; static propTypes = { permissions: PropTypes.arrayOf( @@ -18,25 +18,25 @@ export default class ConnectedAccountsPermissions extends PureComponent { key: PropTypes.string.isRequired, }), ), - } + }; state = { expanded: false, - } + }; toggleExpanded = () => { this.setState((prevState) => ({ expanded: !prevState.expanded, - })) - } + })); + }; render() { - const { permissions } = this.props - const { t } = this.context - const { expanded } = this.state + const { permissions } = this.props; + const { t } = this.context; + const { expanded } = this.state; if (permissions.length === 0) { - return null + return null; } return ( @@ -81,6 +81,6 @@ export default class ConnectedAccountsPermissions extends PureComponent { - ) + ); } } diff --git a/ui/app/components/app/connected-accounts-permissions/index.js b/ui/app/components/app/connected-accounts-permissions/index.js index 6c6113c823..46bbd1ee98 100644 --- a/ui/app/components/app/connected-accounts-permissions/index.js +++ b/ui/app/components/app/connected-accounts-permissions/index.js @@ -1 +1 @@ -export { default } from './connected-accounts-permissions.component' +export { default } from './connected-accounts-permissions.component'; diff --git a/ui/app/components/app/connected-sites-list/connected-sites-list.component.js b/ui/app/components/app/connected-sites-list/connected-sites-list.component.js index 16bc23bd64..1e9513a58e 100644 --- a/ui/app/components/app/connected-sites-list/connected-sites-list.component.js +++ b/ui/app/components/app/connected-sites-list/connected-sites-list.component.js @@ -1,12 +1,12 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import SiteIcon from '../../ui/site-icon' -import { stripHttpSchemes } from '../../../helpers/utils/util' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import SiteIcon from '../../ui/site-icon'; +import { stripHttpSchemes } from '../../../helpers/utils/util'; export default class ConnectedSitesList extends Component { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { connectedDomains: PropTypes.arrayOf( @@ -19,11 +19,11 @@ export default class ConnectedSitesList extends Component { ).isRequired, onDisconnect: PropTypes.func.isRequired, domainHostCount: PropTypes.objectOf(PropTypes.number).isRequired, - } + }; render() { - const { connectedDomains, onDisconnect } = this.props - const { t } = this.context + const { connectedDomains, onDisconnect } = this.props; + const { t } = this.context; return (
    @@ -49,16 +49,16 @@ export default class ConnectedSitesList extends Component { ))}
    - ) + ); } getDomainDisplayName(domain) { if (domain.extensionId) { - return this.context.t('externalExtension') + return this.context.t('externalExtension'); } return this.props.domainHostCount[domain.host] > 1 ? domain.origin - : stripHttpSchemes(domain.origin) + : stripHttpSchemes(domain.origin); } } diff --git a/ui/app/components/app/connected-sites-list/index.js b/ui/app/components/app/connected-sites-list/index.js index 0f0a8e6f3d..70dc9f763f 100644 --- a/ui/app/components/app/connected-sites-list/index.js +++ b/ui/app/components/app/connected-sites-list/index.js @@ -1 +1 @@ -export { default } from './connected-sites-list.component' +export { default } from './connected-sites-list.component'; diff --git a/ui/app/components/app/connected-status-indicator/connected-status-indicator.js b/ui/app/components/app/connected-status-indicator/connected-status-indicator.js index 31cb2b1375..b8596d58fc 100644 --- a/ui/app/components/app/connected-status-indicator/connected-status-indicator.js +++ b/ui/app/components/app/connected-status-indicator/connected-status-indicator.js @@ -1,66 +1,68 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { useSelector } from 'react-redux' -import { findKey } from 'lodash' +import React from 'react'; +import PropTypes from 'prop-types'; +import { useSelector } from 'react-redux'; +import { findKey } from 'lodash'; import { STATUS_CONNECTED, STATUS_CONNECTED_TO_ANOTHER_ACCOUNT, STATUS_NOT_CONNECTED, -} from '../../../helpers/constants/connected-sites' -import ColorIndicator from '../../ui/color-indicator' -import { COLORS } from '../../../helpers/constants/design-system' -import { useI18nContext } from '../../../hooks/useI18nContext' +} from '../../../helpers/constants/connected-sites'; +import ColorIndicator from '../../ui/color-indicator'; +import { COLORS } from '../../../helpers/constants/design-system'; +import { useI18nContext } from '../../../hooks/useI18nContext'; import { getAddressConnectedDomainMap, getOriginOfCurrentTab, getSelectedAddress, -} from '../../../selectors' +} from '../../../selectors'; export default function ConnectedStatusIndicator({ onClick }) { - const t = useI18nContext() + const t = useI18nContext(); - const selectedAddress = useSelector(getSelectedAddress) - const addressConnectedDomainMap = useSelector(getAddressConnectedDomainMap) - const originOfCurrentTab = useSelector(getOriginOfCurrentTab) + const selectedAddress = useSelector(getSelectedAddress); + const addressConnectedDomainMap = useSelector(getAddressConnectedDomainMap); + const originOfCurrentTab = useSelector(getOriginOfCurrentTab); - const selectedAddressDomainMap = addressConnectedDomainMap[selectedAddress] + const selectedAddressDomainMap = addressConnectedDomainMap[selectedAddress]; const currentTabIsConnectedToSelectedAddress = Boolean( selectedAddressDomainMap && selectedAddressDomainMap[originOfCurrentTab], - ) - let status + ); + let status; if (currentTabIsConnectedToSelectedAddress) { - status = STATUS_CONNECTED + status = STATUS_CONNECTED; } else if (findKey(addressConnectedDomainMap, originOfCurrentTab)) { - status = STATUS_CONNECTED_TO_ANOTHER_ACCOUNT + status = STATUS_CONNECTED_TO_ANOTHER_ACCOUNT; } else { - status = STATUS_NOT_CONNECTED + status = STATUS_NOT_CONNECTED; } - let indicatorType = ColorIndicator.TYPES.OUTLINE - let indicatorColor = COLORS.UI4 + let indicatorType = ColorIndicator.TYPES.OUTLINE; + let indicatorColor = COLORS.UI4; if (status === STATUS_CONNECTED) { - indicatorColor = COLORS.SUCCESS1 - indicatorType = ColorIndicator.TYPES.PARTIAL + indicatorColor = COLORS.SUCCESS1; + indicatorType = ColorIndicator.TYPES.PARTIAL; } else if (status === STATUS_CONNECTED_TO_ANOTHER_ACCOUNT) { - indicatorColor = COLORS.ALERT1 + indicatorColor = COLORS.ALERT1; } const text = - status === STATUS_CONNECTED ? t('statusConnected') : t('statusNotConnected') + status === STATUS_CONNECTED + ? t('statusConnected') + : t('statusNotConnected'); return ( - ) + ); } ConnectedStatusIndicator.defaultProps = { onClick: undefined, -} +}; ConnectedStatusIndicator.propTypes = { onClick: PropTypes.func, -} +}; diff --git a/ui/app/components/app/connected-status-indicator/index.js b/ui/app/components/app/connected-status-indicator/index.js index 4f654fae4d..01c4a66ee9 100644 --- a/ui/app/components/app/connected-status-indicator/index.js +++ b/ui/app/components/app/connected-status-indicator/index.js @@ -1 +1 @@ -export { default } from './connected-status-indicator' +export { default } from './connected-status-indicator'; diff --git a/ui/app/components/app/contact-list/contact-list.component.js b/ui/app/components/app/contact-list/contact-list.component.js index 3b62741e6f..04e3a3abd0 100644 --- a/ui/app/components/app/contact-list/contact-list.component.js +++ b/ui/app/components/app/contact-list/contact-list.component.js @@ -1,7 +1,7 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import Button from '../../ui/button' -import RecipientGroup from './recipient-group/recipient-group.component' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import Button from '../../ui/button'; +import RecipientGroup from './recipient-group/recipient-group.component'; export default class ContactList extends PureComponent { static propTypes = { @@ -11,22 +11,22 @@ export default class ContactList extends PureComponent { selectRecipient: PropTypes.func, children: PropTypes.node, selectedAddress: PropTypes.string, - } + }; static contextTypes = { t: PropTypes.func, - } + }; state = { isShowingAllRecent: false, - } + }; renderRecents() { - const { t } = this.context - const { isShowingAllRecent } = this.state - const nonContacts = this.props.searchForRecents() + const { t } = this.context; + const { isShowingAllRecent } = this.state; + const nonContacts = this.props.searchForRecents(); - const showLoadMore = !isShowingAllRecent && nonContacts.length > 2 + const showLoadMore = !isShowingAllRecent && nonContacts.length > 2; return (
    @@ -46,28 +46,28 @@ export default class ContactList extends PureComponent { )}
    - ) + ); } renderAddressBook() { - const contacts = this.props.searchForContacts() + const contacts = this.props.searchForContacts(); const contactGroups = contacts.reduce((acc, contact) => { - const firstLetter = contact.name.slice(0, 1).toUpperCase() - acc[firstLetter] = acc[firstLetter] || [] - const bucket = acc[firstLetter] - bucket.push(contact) - return acc - }, {}) + const firstLetter = contact.name.slice(0, 1).toUpperCase(); + acc[firstLetter] = acc[firstLetter] || []; + const bucket = acc[firstLetter]; + bucket.push(contact); + return acc; + }, {}); return Object.entries(contactGroups) .sort(([letter1], [letter2]) => { if (letter1 > letter2) { - return 1 + return 1; } else if (letter1 === letter2) { - return 0 + return 0; } - return -1 + return -1; }) .map(([letter, groupItems]) => ( - )) + )); } renderMyAccounts() { - const myAccounts = this.props.searchForMyAccounts() + const myAccounts = this.props.searchForMyAccounts(); return ( - ) + ); } render() { @@ -98,7 +98,7 @@ export default class ContactList extends PureComponent { searchForRecents, searchForContacts, searchForMyAccounts, - } = this.props + } = this.props; return (
    @@ -107,6 +107,6 @@ export default class ContactList extends PureComponent { {searchForContacts && this.renderAddressBook()} {searchForMyAccounts && this.renderMyAccounts()}
    - ) + ); } } diff --git a/ui/app/components/app/contact-list/index.js b/ui/app/components/app/contact-list/index.js index d90c29b2b0..0b7ef4615b 100644 --- a/ui/app/components/app/contact-list/index.js +++ b/ui/app/components/app/contact-list/index.js @@ -1 +1 @@ -export { default } from './contact-list.component' +export { default } from './contact-list.component'; diff --git a/ui/app/components/app/contact-list/recipient-group/index.js b/ui/app/components/app/contact-list/recipient-group/index.js index 7d827523f2..75eeac29a4 100644 --- a/ui/app/components/app/contact-list/recipient-group/index.js +++ b/ui/app/components/app/contact-list/recipient-group/index.js @@ -1 +1 @@ -export { default } from './recipient-group.component' +export { default } from './recipient-group.component'; diff --git a/ui/app/components/app/contact-list/recipient-group/recipient-group.component.js b/ui/app/components/app/contact-list/recipient-group/recipient-group.component.js index a50b2eea32..d578549170 100644 --- a/ui/app/components/app/contact-list/recipient-group/recipient-group.component.js +++ b/ui/app/components/app/contact-list/recipient-group/recipient-group.component.js @@ -1,11 +1,11 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import Identicon from '../../../ui/identicon' -import { ellipsify } from '../../../../pages/send/send.utils' +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import Identicon from '../../../ui/identicon'; +import { ellipsify } from '../../../../pages/send/send.utils'; function addressesEqual(address1, address2) { - return String(address1).toLowerCase() === String(address2).toLowerCase() + return String(address1).toLowerCase() === String(address2).toLowerCase(); } export default function RecipientGroup({ @@ -15,7 +15,7 @@ export default function RecipientGroup({ selectedAddress, }) { if (!items || !items.length) { - return null + return null; } return ( @@ -54,7 +54,7 @@ export default function RecipientGroup({ ))} - ) + ); } RecipientGroup.propTypes = { @@ -67,4 +67,4 @@ RecipientGroup.propTypes = { ), onSelect: PropTypes.func.isRequired, selectedAddress: PropTypes.string, -} +}; diff --git a/ui/app/components/app/dropdowns/components/dropdown.js b/ui/app/components/app/dropdowns/components/dropdown.js index da67c700fd..0c1a7f88fa 100644 --- a/ui/app/components/app/dropdowns/components/dropdown.js +++ b/ui/app/components/app/dropdowns/components/dropdown.js @@ -1,6 +1,6 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import MenuDroppo from '../../menu-droppo' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import MenuDroppo from '../../menu-droppo'; export class Dropdown extends Component { render() { @@ -12,7 +12,7 @@ export class Dropdown extends Component { innerStyle, children, useCssTransition, - } = this.props + } = this.props; const innerStyleDefaults = { borderRadius: '4px', @@ -20,7 +20,7 @@ export class Dropdown extends Component { background: 'rgba(0, 0, 0, 0.8)', boxShadow: 'rgba(0, 0, 0, 0.15) 0px 2px 2px 2px', ...innerStyle, - } + }; return ( {children} - ) + ); } } Dropdown.defaultProps = { useCssTransition: false, -} +}; Dropdown.propTypes = { isOpen: PropTypes.bool.isRequired, @@ -60,23 +60,23 @@ Dropdown.propTypes = { innerStyle: PropTypes.object, useCssTransition: PropTypes.bool, containerClassName: PropTypes.string, -} +}; export class DropdownMenuItem extends Component { render() { - const { onClick, closeMenu, children, style } = this.props + const { onClick, closeMenu, children, style } = this.props; return (
  • { - onClick() - closeMenu() + onClick(); + closeMenu(); }} onKeyPress={(event) => { if (event.key === 'Enter') { - onClick() - closeMenu() + onClick(); + closeMenu(); } }} style={{ @@ -95,7 +95,7 @@ export class DropdownMenuItem extends Component { > {children}
  • - ) + ); } } @@ -104,4 +104,4 @@ DropdownMenuItem.propTypes = { onClick: PropTypes.func.isRequired, children: PropTypes.node, style: PropTypes.object, -} +}; diff --git a/ui/app/components/app/dropdowns/network-dropdown.js b/ui/app/components/app/dropdowns/network-dropdown.js index 4de92e7185..d01c71ba98 100644 --- a/ui/app/components/app/dropdowns/network-dropdown.js +++ b/ui/app/components/app/dropdowns/network-dropdown.js @@ -1,22 +1,22 @@ -import PropTypes from 'prop-types' -import React, { Component } from 'react' -import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom' -import { compose } from 'redux' -import * as actions from '../../../store/actions' -import { openAlert as displayInvalidCustomNetworkAlert } from '../../../ducks/alerts/invalid-custom-network' +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import { connect } from 'react-redux'; +import { withRouter } from 'react-router-dom'; +import { compose } from 'redux'; +import * as actions from '../../../store/actions'; +import { openAlert as displayInvalidCustomNetworkAlert } from '../../../ducks/alerts/invalid-custom-network'; import { NETWORKS_ROUTE, NETWORKS_FORM_ROUTE, -} from '../../../helpers/constants/routes' -import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../../shared/constants/app' -import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network' -import { isPrefixedFormattedHexString } from '../../../../../shared/modules/utils' -import { getEnvironmentType } from '../../../../../app/scripts/lib/util' +} from '../../../helpers/constants/routes'; +import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../../shared/constants/app'; +import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network'; +import { isPrefixedFormattedHexString } from '../../../../../shared/modules/utils'; +import { getEnvironmentType } from '../../../../../app/scripts/lib/util'; -import ColorIndicator from '../../ui/color-indicator' -import { COLORS, SIZES } from '../../../helpers/constants/design-system' -import { Dropdown, DropdownMenuItem } from './components/dropdown' +import ColorIndicator from '../../ui/color-indicator'; +import { COLORS, SIZES } from '../../../helpers/constants/design-system'; +import { Dropdown, DropdownMenuItem } from './components/dropdown'; // classes from nodes of the toggle element. const notToggleElementClassnames = [ @@ -25,39 +25,39 @@ const notToggleElementClassnames = [ 'network-indicator', 'network-caret', 'network-component', -] +]; const DROP_DOWN_MENU_ITEM_STYLE = { fontSize: '16px', lineHeight: '20px', padding: '12px 0', -} +}; function mapStateToProps(state) { return { provider: state.metamask.provider, frequentRpcListDetail: state.metamask.frequentRpcListDetail || [], networkDropdownOpen: state.appState.networkDropdownOpen, - } + }; } function mapDispatchToProps(dispatch) { return { setProviderType: (type) => { - dispatch(actions.setProviderType(type)) + dispatch(actions.setProviderType(type)); }, setRpcTarget: (target, chainId, ticker, nickname) => { - dispatch(actions.setRpcTarget(target, chainId, ticker, nickname)) + dispatch(actions.setRpcTarget(target, chainId, ticker, nickname)); }, hideNetworkDropdown: () => dispatch(actions.hideNetworkDropdown()), setNetworksTabAddMode: (isInAddMode) => { - dispatch(actions.setNetworksTabAddMode(isInAddMode)) + dispatch(actions.setNetworksTabAddMode(isInAddMode)); }, setSelectedSettingsRpcUrl: (url) => { - dispatch(actions.setSelectedSettingsRpcUrl(url)) + dispatch(actions.setSelectedSettingsRpcUrl(url)); }, displayInvalidCustomNetworkAlert: (networkName) => { - dispatch(displayInvalidCustomNetworkAlert(networkName)) + dispatch(displayInvalidCustomNetworkAlert(networkName)); }, showConfirmDeleteNetworkModal: ({ target, onConfirm }) => { return dispatch( @@ -66,16 +66,16 @@ function mapDispatchToProps(dispatch) { target, onConfirm, }), - ) + ); }, - } + }; } class NetworkDropdown extends Component { static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; static propTypes = { provider: PropTypes.shape({ @@ -94,14 +94,14 @@ class NetworkDropdown extends Component { history: PropTypes.object.isRequired, displayInvalidCustomNetworkAlert: PropTypes.func.isRequired, showConfirmDeleteNetworkModal: PropTypes.func.isRequired, - } + }; handleClick(newProviderType) { const { provider: { type: providerType }, setProviderType, - } = this.props - const { metricsEvent } = this.context + } = this.props; + const { metricsEvent } = this.context; metricsEvent({ eventOpts: { @@ -113,17 +113,17 @@ class NetworkDropdown extends Component { fromNetwork: providerType, toNetwork: newProviderType, }, - }) - setProviderType(newProviderType) + }); + setProviderType(newProviderType); } renderCustomRpcList(rpcListDetail, provider) { - const reversedRpcListDetail = rpcListDetail.slice().reverse() + const reversedRpcListDetail = rpcListDetail.slice().reverse(); return reversedRpcListDetail.map((entry) => { - const { rpcUrl, chainId, ticker = 'ETH', nickname = '' } = entry + const { rpcUrl, chainId, ticker = 'ETH', nickname = '' } = entry; const isCurrentRpcTarget = - provider.type === NETWORK_TYPE_RPC && rpcUrl === provider.rpcUrl + provider.type === NETWORK_TYPE_RPC && rpcUrl === provider.rpcUrl; return ( this.props.hideNetworkDropdown()} onClick={() => { if (isPrefixedFormattedHexString(chainId)) { - this.props.setRpcTarget(rpcUrl, chainId, ticker, nickname) + this.props.setRpcTarget(rpcUrl, chainId, ticker, nickname); } else { - this.props.displayInvalidCustomNetworkAlert(nickname || rpcUrl) + this.props.displayInvalidCustomNetworkAlert(nickname || rpcUrl); } }} style={{ @@ -165,46 +165,46 @@ class NetworkDropdown extends Component { { - e.stopPropagation() + e.stopPropagation(); this.props.showConfirmDeleteNetworkModal({ target: rpcUrl, onConfirm: () => undefined, - }) + }); }} /> )} - ) - }) + ); + }); } getNetworkName() { - const { provider } = this.props - const providerName = provider.type + const { provider } = this.props; + const providerName = provider.type; - let name + let name; if (providerName === 'mainnet') { - name = this.context.t('mainnet') + name = this.context.t('mainnet'); } else if (providerName === 'ropsten') { - name = this.context.t('ropsten') + name = this.context.t('ropsten'); } else if (providerName === 'kovan') { - name = this.context.t('kovan') + name = this.context.t('kovan'); } else if (providerName === 'rinkeby') { - name = this.context.t('rinkeby') + name = this.context.t('rinkeby'); } else if (providerName === 'goerli') { - name = this.context.t('goerli') + name = this.context.t('goerli'); } else { - name = provider.nickname || this.context.t('unknownNetwork') + name = provider.nickname || this.context.t('unknownNetwork'); } - return name + return name; } renderNetworkEntry(network) { const { provider: { type: providerType }, - } = this.props + } = this.props; return ( - ) + ); } render() { @@ -240,23 +240,23 @@ class NetworkDropdown extends Component { provider: { rpcUrl: activeNetwork }, setNetworksTabAddMode, setSelectedSettingsRpcUrl, - } = this.props - const rpcListDetail = this.props.frequentRpcListDetail - const isOpen = this.props.networkDropdownOpen + } = this.props; + const rpcListDetail = this.props.frequentRpcListDetail; + const isOpen = this.props.networkDropdownOpen; return ( { - const { classList } = event.target - const isInClassList = (className) => classList.contains(className) + const { classList } = event.target; + const isInClassList = (className) => classList.contains(className); const notToggleElementIndex = notToggleElementClassnames.findIndex( isInClassList, - ) + ); if (notToggleElementIndex === -1) { - event.stopPropagation() - this.props.hideNetworkDropdown() + event.stopPropagation(); + this.props.hideNetworkDropdown(); } }} containerClassName="network-droppo" @@ -294,9 +294,9 @@ class NetworkDropdown extends Component { getEnvironmentType() === ENVIRONMENT_TYPE_FULLSCREEN ? NETWORKS_ROUTE : NETWORKS_FORM_ROUTE, - ) - setSelectedSettingsRpcUrl('') - setNetworksTabAddMode(true) + ); + setSelectedSettingsRpcUrl(''); + setNetworksTabAddMode(true); }} style={DROP_DOWN_MENU_ITEM_STYLE} > @@ -321,11 +321,11 @@ class NetworkDropdown extends Component { - ) + ); } } export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps), -)(NetworkDropdown) +)(NetworkDropdown); diff --git a/ui/app/components/app/dropdowns/simple-dropdown.js b/ui/app/components/app/dropdowns/simple-dropdown.js index a1a97a8b62..cafaa4e620 100644 --- a/ui/app/components/app/dropdowns/simple-dropdown.js +++ b/ui/app/components/app/dropdowns/simple-dropdown.js @@ -1,6 +1,6 @@ -import classnames from 'classnames' -import PropTypes from 'prop-types' -import React, { Component } from 'react' +import classnames from 'classnames'; +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; class SimpleDropdown extends Component { static propTypes = { @@ -8,41 +8,41 @@ class SimpleDropdown extends Component { placeholder: PropTypes.string, onSelect: PropTypes.func, selectedOption: PropTypes.string, - } + }; state = { isOpen: false, - } + }; getDisplayValue() { - const { selectedOption, options } = this.props - const matchesOption = (option) => option.value === selectedOption - const matchingOption = options.find(matchesOption) + const { selectedOption, options } = this.props; + const matchesOption = (option) => option.value === selectedOption; + const matchingOption = options.find(matchesOption); return matchingOption ? matchingOption.displayValue || matchingOption.value - : selectedOption + : selectedOption; } handleClose() { - this.setState({ isOpen: false }) + this.setState({ isOpen: false }); } toggleOpen() { this.setState((prevState) => ({ isOpen: !prevState.isOpen, - })) + })); } renderOptions() { - const { options, onSelect, selectedOption } = this.props + const { options, onSelect, selectedOption } = this.props; return (
    { - event.stopPropagation() - this.handleClose() + event.stopPropagation(); + this.handleClose(); }} />
    @@ -54,12 +54,12 @@ class SimpleDropdown extends Component { })} key={option.value} onClick={(event) => { - event.stopPropagation() + event.stopPropagation(); if (option.value !== selectedOption) { - onSelect(option.value) + onSelect(option.value); } - this.handleClose() + this.handleClose(); }} > {option.displayValue || option.value} @@ -67,12 +67,12 @@ class SimpleDropdown extends Component { ))}
    - ) + ); } render() { - const { placeholder } = this.props - const { isOpen } = this.state + const { placeholder } = this.props; + const { isOpen } = this.state; return (
    this.toggleOpen()}> @@ -82,8 +82,8 @@ class SimpleDropdown extends Component { {isOpen && this.renderOptions()}
    - ) + ); } } -export default SimpleDropdown +export default SimpleDropdown; diff --git a/ui/app/components/app/dropdowns/tests/dropdown.test.js b/ui/app/components/app/dropdowns/tests/dropdown.test.js index 7ceb8227cd..63faf33414 100644 --- a/ui/app/components/app/dropdowns/tests/dropdown.test.js +++ b/ui/app/components/app/dropdowns/tests/dropdown.test.js @@ -1,13 +1,13 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import { shallow } from 'enzyme' -import { DropdownMenuItem } from '../components/dropdown' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import { shallow } from 'enzyme'; +import { DropdownMenuItem } from '../components/dropdown'; describe('Dropdown', function () { - let wrapper - const onClickSpy = sinon.spy() - const closeMenuSpy = sinon.spy() + let wrapper; + const onClickSpy = sinon.spy(); + const closeMenuSpy = sinon.spy(); beforeEach(function () { wrapper = shallow( @@ -16,20 +16,20 @@ describe('Dropdown', function () { style={{ test: 'style' }} closeMenu={closeMenuSpy} />, - ) - }) + ); + }); it('renders li with dropdown-menu-item class', function () { - assert.strictEqual(wrapper.find('li.dropdown-menu-item').length, 1) - }) + assert.strictEqual(wrapper.find('li.dropdown-menu-item').length, 1); + }); it('adds style based on props passed', function () { - assert.strictEqual(wrapper.prop('style').test, 'style') - }) + assert.strictEqual(wrapper.prop('style').test, 'style'); + }); it('simulates click event and calls onClick and closeMenu', function () { - wrapper.prop('onClick')() - assert.strictEqual(onClickSpy.callCount, 1) - assert.strictEqual(closeMenuSpy.callCount, 1) - }) -}) + wrapper.prop('onClick')(); + assert.strictEqual(onClickSpy.callCount, 1); + assert.strictEqual(closeMenuSpy.callCount, 1); + }); +}); diff --git a/ui/app/components/app/dropdowns/tests/network-dropdown.test.js b/ui/app/components/app/dropdowns/tests/network-dropdown.test.js index 50e607ac90..c7f872c6a4 100644 --- a/ui/app/components/app/dropdowns/tests/network-dropdown.test.js +++ b/ui/app/components/app/dropdowns/tests/network-dropdown.test.js @@ -1,15 +1,15 @@ -import assert from 'assert' -import React from 'react' -import configureMockStore from 'redux-mock-store' -import thunk from 'redux-thunk' -import { mountWithRouter } from '../../../../../../test/lib/render-helpers' -import NetworkDropdown from '../network-dropdown' -import { DropdownMenuItem } from '../components/dropdown' -import ColorIndicator from '../../../ui/color-indicator' +import assert from 'assert'; +import React from 'react'; +import configureMockStore from 'redux-mock-store'; +import thunk from 'redux-thunk'; +import { mountWithRouter } from '../../../../../../test/lib/render-helpers'; +import NetworkDropdown from '../network-dropdown'; +import { DropdownMenuItem } from '../components/dropdown'; +import ColorIndicator from '../../../ui/color-indicator'; describe('Network Dropdown', function () { - let wrapper - const createMockStore = configureMockStore([thunk]) + let wrapper; + const createMockStore = configureMockStore([thunk]); describe('NetworkDropdown in appState in false', function () { const mockState = { @@ -22,22 +22,22 @@ describe('Network Dropdown', function () { appState: { networkDropdownOpen: false, }, - } + }; - const store = createMockStore(mockState) + const store = createMockStore(mockState); beforeEach(function () { - wrapper = mountWithRouter() - }) + wrapper = mountWithRouter(); + }); it('checks for network droppo class', function () { - assert.strictEqual(wrapper.find('.network-droppo').length, 1) - }) + assert.strictEqual(wrapper.find('.network-droppo').length, 1); + }); it('renders only one child when networkDropdown is false in state', function () { - assert.strictEqual(wrapper.children().length, 1) - }) - }) + assert.strictEqual(wrapper.children().length, 1); + }); + }); describe('NetworkDropdown in appState is true', function () { const mockState = { @@ -54,59 +54,59 @@ describe('Network Dropdown', function () { appState: { networkDropdownOpen: true, }, - } - const store = createMockStore(mockState) + }; + const store = createMockStore(mockState); beforeEach(function () { - wrapper = mountWithRouter() - }) + wrapper = mountWithRouter(); + }); it('renders 8 DropDownMenuItems ', function () { - assert.strictEqual(wrapper.find(DropdownMenuItem).length, 8) - }) + assert.strictEqual(wrapper.find(DropdownMenuItem).length, 8); + }); it('checks background color for first ColorIndicator', function () { - const colorIndicator = wrapper.find(ColorIndicator).at(0) - assert.strictEqual(colorIndicator.prop('color'), 'mainnet') - assert.strictEqual(colorIndicator.prop('borderColor'), 'mainnet') - }) + const colorIndicator = wrapper.find(ColorIndicator).at(0); + assert.strictEqual(colorIndicator.prop('color'), 'mainnet'); + assert.strictEqual(colorIndicator.prop('borderColor'), 'mainnet'); + }); it('checks background color for second ColorIndicator', function () { - const colorIndicator = wrapper.find(ColorIndicator).at(1) - assert.strictEqual(colorIndicator.prop('color'), 'ropsten') - assert.strictEqual(colorIndicator.prop('borderColor'), 'ropsten') - }) + const colorIndicator = wrapper.find(ColorIndicator).at(1); + assert.strictEqual(colorIndicator.prop('color'), 'ropsten'); + assert.strictEqual(colorIndicator.prop('borderColor'), 'ropsten'); + }); it('checks background color for third ColorIndicator', function () { - const colorIndicator = wrapper.find(ColorIndicator).at(2) - assert.strictEqual(colorIndicator.prop('color'), 'kovan') - assert.strictEqual(colorIndicator.prop('borderColor'), 'kovan') - }) + const colorIndicator = wrapper.find(ColorIndicator).at(2); + assert.strictEqual(colorIndicator.prop('color'), 'kovan'); + assert.strictEqual(colorIndicator.prop('borderColor'), 'kovan'); + }); it('checks background color for fourth ColorIndicator', function () { - const colorIndicator = wrapper.find(ColorIndicator).at(3) - assert.strictEqual(colorIndicator.prop('color'), 'rinkeby') - assert.strictEqual(colorIndicator.prop('borderColor'), 'rinkeby') - }) + const colorIndicator = wrapper.find(ColorIndicator).at(3); + assert.strictEqual(colorIndicator.prop('color'), 'rinkeby'); + assert.strictEqual(colorIndicator.prop('borderColor'), 'rinkeby'); + }); it('checks background color for fifth ColorIndicator', function () { - const colorIndicator = wrapper.find(ColorIndicator).at(4) - assert.strictEqual(colorIndicator.prop('color'), 'goerli') - assert.strictEqual(colorIndicator.prop('borderColor'), 'goerli') - }) + const colorIndicator = wrapper.find(ColorIndicator).at(4); + assert.strictEqual(colorIndicator.prop('color'), 'goerli'); + assert.strictEqual(colorIndicator.prop('borderColor'), 'goerli'); + }); it('checks background color for sixth ColorIndicator', function () { - const colorIndicator = wrapper.find(ColorIndicator).at(5) - const customNetworkGray = 'ui-2' - assert.strictEqual(colorIndicator.prop('color'), customNetworkGray) - assert.strictEqual(colorIndicator.prop('borderColor'), customNetworkGray) - }) + const colorIndicator = wrapper.find(ColorIndicator).at(5); + const customNetworkGray = 'ui-2'; + assert.strictEqual(colorIndicator.prop('color'), customNetworkGray); + assert.strictEqual(colorIndicator.prop('borderColor'), customNetworkGray); + }); it('checks dropdown for frequestRPCList from state', function () { assert.strictEqual( wrapper.find(DropdownMenuItem).at(6).text(), '✓http://localhost:7545', - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js b/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js index a7c3270d01..e394b453a0 100644 --- a/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js +++ b/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js @@ -1,14 +1,14 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { debounce } from 'lodash' -import Tooltip from '../../../ui/tooltip' -import { MIN_GAS_LIMIT_DEC } from '../../../../pages/send/send.constants' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import { debounce } from 'lodash'; +import Tooltip from '../../../ui/tooltip'; +import { MIN_GAS_LIMIT_DEC } from '../../../../pages/send/send.constants'; export default class AdvancedGasInputs extends Component { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { updateCustomGasPrice: PropTypes.func, @@ -20,55 +20,55 @@ export default class AdvancedGasInputs extends Component { isSpeedUp: PropTypes.bool, customGasLimitMessage: PropTypes.string, minimumGasLimit: PropTypes.number, - } + }; static defaultProps = { minimumGasLimit: Number(MIN_GAS_LIMIT_DEC), - } + }; constructor(props) { - super(props) + super(props); this.state = { gasPrice: this.props.customGasPrice, gasLimit: this.props.customGasLimit, - } - this.changeGasPrice = debounce(this.changeGasPrice, 500) - this.changeGasLimit = debounce(this.changeGasLimit, 500) + }; + this.changeGasPrice = debounce(this.changeGasPrice, 500); + this.changeGasLimit = debounce(this.changeGasLimit, 500); } componentDidUpdate(prevProps) { const { customGasPrice: prevCustomGasPrice, customGasLimit: prevCustomGasLimit, - } = prevProps - const { customGasPrice, customGasLimit } = this.props - const { gasPrice, gasLimit } = this.state + } = prevProps; + const { customGasPrice, customGasLimit } = this.props; + const { gasPrice, gasLimit } = this.state; if (customGasPrice !== prevCustomGasPrice && customGasPrice !== gasPrice) { - this.setState({ gasPrice: customGasPrice }) + this.setState({ gasPrice: customGasPrice }); } if (customGasLimit !== prevCustomGasLimit && customGasLimit !== gasLimit) { - this.setState({ gasLimit: customGasLimit }) + this.setState({ gasLimit: customGasLimit }); } } onChangeGasLimit = (e) => { - this.setState({ gasLimit: e.target.value }) - this.changeGasLimit({ target: { value: e.target.value } }) - } + this.setState({ gasLimit: e.target.value }); + this.changeGasLimit({ target: { value: e.target.value } }); + }; changeGasLimit = (e) => { - this.props.updateCustomGasLimit(Number(e.target.value)) - } + this.props.updateCustomGasLimit(Number(e.target.value)); + }; onChangeGasPrice = (e) => { - this.setState({ gasPrice: e.target.value }) - this.changeGasPrice({ target: { value: e.target.value } }) - } + this.setState({ gasPrice: e.target.value }); + this.changeGasPrice({ target: { value: e.target.value } }); + }; changeGasPrice = (e) => { - this.props.updateCustomGasPrice(Number(e.target.value)) - } + this.props.updateCustomGasPrice(Number(e.target.value)); + }; gasPriceError({ insufficientBalance, @@ -76,44 +76,44 @@ export default class AdvancedGasInputs extends Component { isSpeedUp, gasPrice, }) { - const { t } = this.context + const { t } = this.context; if (insufficientBalance) { return { errorText: t('insufficientBalance'), errorType: 'error', - } + }; } else if (isSpeedUp && gasPrice === 0) { return { errorText: t('zeroGasPriceOnSpeedUpError'), errorType: 'error', - } + }; } else if (!customPriceIsSafe) { return { errorText: t('gasPriceExtremelyLow'), errorType: 'warning', - } + }; } - return {} + return {}; } gasLimitError({ insufficientBalance, gasLimit, minimumGasLimit }) { - const { t } = this.context + const { t } = this.context; if (insufficientBalance) { return { errorText: t('insufficientBalance'), errorType: 'error', - } + }; } else if (gasLimit < minimumGasLimit) { return { errorText: t('gasLimitTooLowWithDynamicFee', [minimumGasLimit]), errorType: 'error', - } + }; } - return {} + return {}; } renderGasInput({ @@ -175,7 +175,7 @@ export default class AdvancedGasInputs extends Component { {errorComponent || customMessageComponent}
    - ) + ); } render() { @@ -185,8 +185,8 @@ export default class AdvancedGasInputs extends Component { isSpeedUp, customGasLimitMessage, minimumGasLimit, - } = this.props - const { gasPrice, gasLimit } = this.state + } = this.props; + const { gasPrice, gasLimit } = this.state; const { errorText: gasPriceErrorText, @@ -196,32 +196,32 @@ export default class AdvancedGasInputs extends Component { customPriceIsSafe, isSpeedUp, gasPrice, - }) + }); const gasPriceErrorComponent = gasPriceErrorType ? (
    {gasPriceErrorText}
    - ) : null + ) : null; const { errorText: gasLimitErrorText, errorType: gasLimitErrorType, - } = this.gasLimitError({ insufficientBalance, gasLimit, minimumGasLimit }) + } = this.gasLimitError({ insufficientBalance, gasLimit, minimumGasLimit }); const gasLimitErrorComponent = gasLimitErrorType ? (
    {gasLimitErrorText}
    - ) : null + ) : null; const gasLimitCustomMessageComponent = customGasLimitMessage ? (
    {customGasLimitMessage}
    - ) : null + ) : null; return (
    @@ -243,6 +243,6 @@ export default class AdvancedGasInputs extends Component { errorType: gasLimitErrorType, })}
    - ) + ); } } diff --git a/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.container.js b/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.container.js index 949f23fea6..45cdaaa38b 100644 --- a/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.container.js +++ b/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.container.js @@ -1,17 +1,17 @@ -import { connect } from 'react-redux' +import { connect } from 'react-redux'; import { decGWEIToHexWEI, decimalToHex, hexWEIToDecGWEI, -} from '../../../../helpers/utils/conversions.util' -import AdvancedGasInputs from './advanced-gas-inputs.component' +} from '../../../../helpers/utils/conversions.util'; +import AdvancedGasInputs from './advanced-gas-inputs.component'; function convertGasPriceForInputs(gasPriceInHexWEI) { - return Number(hexWEIToDecGWEI(gasPriceInHexWEI)) + return Number(hexWEIToDecGWEI(gasPriceInHexWEI)); } function convertGasLimitForInputs(gasLimitInHexWEI) { - return parseInt(gasLimitInHexWEI, 16) || 0 + return parseInt(gasLimitInHexWEI, 16) || 0; } const mergeProps = (stateProps, dispatchProps, ownProps) => { @@ -20,7 +20,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { customGasLimit, updateCustomGasPrice, updateCustomGasLimit, - } = ownProps + } = ownProps; return { ...ownProps, ...stateProps, @@ -30,7 +30,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { updateCustomGasPrice: (price) => updateCustomGasPrice(decGWEIToHexWEI(price)), updateCustomGasLimit: (limit) => updateCustomGasLimit(decimalToHex(limit)), - } -} + }; +}; -export default connect(null, null, mergeProps)(AdvancedGasInputs) +export default connect(null, null, mergeProps)(AdvancedGasInputs); diff --git a/ui/app/components/app/gas-customization/advanced-gas-inputs/index.js b/ui/app/components/app/gas-customization/advanced-gas-inputs/index.js index bd8abaa3ea..e922ac6348 100644 --- a/ui/app/components/app/gas-customization/advanced-gas-inputs/index.js +++ b/ui/app/components/app/gas-customization/advanced-gas-inputs/index.js @@ -1 +1 @@ -export { default } from './advanced-gas-inputs.container' +export { default } from './advanced-gas-inputs.container'; diff --git a/ui/app/components/app/gas-customization/advanced-gas-inputs/tests/advanced-gas-input-component.test.js b/ui/app/components/app/gas-customization/advanced-gas-inputs/tests/advanced-gas-input-component.test.js index 8c17f4d52d..72311a3225 100644 --- a/ui/app/components/app/gas-customization/advanced-gas-inputs/tests/advanced-gas-input-component.test.js +++ b/ui/app/components/app/gas-customization/advanced-gas-inputs/tests/advanced-gas-input-component.test.js @@ -1,11 +1,11 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import { mount } from 'enzyme' -import AdvancedTabContent from '..' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import { mount } from 'enzyme'; +import AdvancedTabContent from '..'; describe('Advanced Gas Inputs', function () { - let wrapper, clock + let wrapper, clock; const props = { updateCustomGasPrice: sinon.spy(), @@ -18,91 +18,94 @@ describe('Advanced Gas Inputs', function () { customPriceIsSafe: true, isSpeedUp: false, minimumGasLimit: 21000, - } + }; beforeEach(function () { - clock = sinon.useFakeTimers() + clock = sinon.useFakeTimers(); wrapper = mount(, { context: { t: (str) => str, }, - }) - }) + }); + }); afterEach(function () { - clock.restore() - }) + clock.restore(); + }); it('wont update gasPrice in props before debounce', function () { - const event = { target: { value: 1 } } + const event = { target: { value: 1 } }; - wrapper.find('input').at(0).simulate('change', event) - clock.tick(499) + wrapper.find('input').at(0).simulate('change', event); + clock.tick(499); - assert.strictEqual(props.updateCustomGasPrice.callCount, 0) - }) + assert.strictEqual(props.updateCustomGasPrice.callCount, 0); + }); it('simulates onChange on gas price after debounce', function () { - const event = { target: { value: 1 } } + const event = { target: { value: 1 } }; - wrapper.find('input').at(0).simulate('change', event) - clock.tick(500) + wrapper.find('input').at(0).simulate('change', event); + clock.tick(500); - assert.strictEqual(props.updateCustomGasPrice.calledOnce, true) - assert.strictEqual(props.updateCustomGasPrice.calledWith(1), true) - }) + assert.strictEqual(props.updateCustomGasPrice.calledOnce, true); + assert.strictEqual(props.updateCustomGasPrice.calledWith(1), true); + }); it('wont update gasLimit in props before debounce', function () { - const event = { target: { value: 21000 } } + const event = { target: { value: 21000 } }; - wrapper.find('input').at(1).simulate('change', event) - clock.tick(499) + wrapper.find('input').at(1).simulate('change', event); + clock.tick(499); - assert.strictEqual(props.updateCustomGasLimit.callCount, 0) - }) + assert.strictEqual(props.updateCustomGasLimit.callCount, 0); + }); it('simulates onChange on gas limit after debounce', function () { - const event = { target: { value: 21000 } } + const event = { target: { value: 21000 } }; - wrapper.find('input').at(1).simulate('change', event) - clock.tick(500) + wrapper.find('input').at(1).simulate('change', event); + clock.tick(500); - assert.strictEqual(props.updateCustomGasLimit.calledOnce, true) - assert.strictEqual(props.updateCustomGasLimit.calledWith(21000), true) - }) + assert.strictEqual(props.updateCustomGasLimit.calledOnce, true); + assert.strictEqual(props.updateCustomGasLimit.calledWith(21000), true); + }); it('errors when insufficientBalance under gas price and gas limit', function () { - wrapper.setProps({ insufficientBalance: true }) + wrapper.setProps({ insufficientBalance: true }); const renderError = wrapper.find( '.advanced-gas-inputs__gas-edit-row__error-text', - ) - assert.strictEqual(renderError.length, 2) + ); + assert.strictEqual(renderError.length, 2); - assert.strictEqual(renderError.at(0).text(), 'insufficientBalance') - assert.strictEqual(renderError.at(1).text(), 'insufficientBalance') - }) + assert.strictEqual(renderError.at(0).text(), 'insufficientBalance'); + assert.strictEqual(renderError.at(1).text(), 'insufficientBalance'); + }); it('errors zero gas price / speed up', function () { - wrapper.setProps({ isSpeedUp: true }) + wrapper.setProps({ isSpeedUp: true }); const renderError = wrapper.find( '.advanced-gas-inputs__gas-edit-row__error-text', - ) - assert.strictEqual(renderError.length, 2) + ); + assert.strictEqual(renderError.length, 2); - assert.strictEqual(renderError.at(0).text(), 'zeroGasPriceOnSpeedUpError') - assert.strictEqual(renderError.at(1).text(), 'gasLimitTooLowWithDynamicFee') - }) + assert.strictEqual(renderError.at(0).text(), 'zeroGasPriceOnSpeedUpError'); + assert.strictEqual( + renderError.at(1).text(), + 'gasLimitTooLowWithDynamicFee', + ); + }); it('warns when custom gas price is too low', function () { - wrapper.setProps({ customPriceIsSafe: false }) + wrapper.setProps({ customPriceIsSafe: false }); const renderWarning = wrapper.find( '.advanced-gas-inputs__gas-edit-row__warning-text', - ) - assert.strictEqual(renderWarning.length, 1) + ); + assert.strictEqual(renderWarning.length, 1); - assert.strictEqual(renderWarning.text(), 'gasPriceExtremelyLow') - }) -}) + assert.strictEqual(renderWarning.text(), 'gasPriceExtremelyLow'); + }); +}); diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js index 8f2ddbc6cd..f6be3bc013 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js @@ -1,11 +1,11 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import AdvancedGasInputs from '../../advanced-gas-inputs' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import AdvancedGasInputs from '../../advanced-gas-inputs'; export default class AdvancedTabContent extends Component { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { updateCustomGasPrice: PropTypes.func, @@ -18,7 +18,7 @@ export default class AdvancedTabContent extends Component { isSpeedUp: PropTypes.bool, customGasLimitMessage: PropTypes.string, minimumGasLimit: PropTypes.number, - } + }; renderDataSummary(transactionFee) { return ( @@ -32,7 +32,7 @@ export default class AdvancedTabContent extends Component { - ) + ); } render() { @@ -47,7 +47,7 @@ export default class AdvancedTabContent extends Component { transactionFee, customGasLimitMessage, minimumGasLimit, - } = this.props + } = this.props; return (
    @@ -68,6 +68,6 @@ export default class AdvancedTabContent extends Component {
    - ) + ); } } diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/index.js b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/index.js index 492037f250..1bb49f30c8 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/index.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/index.js @@ -1 +1 @@ -export { default } from './advanced-tab-content.component' +export { default } from './advanced-tab-content.component'; diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js index b33dcadeef..4b1bdc21d4 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js @@ -1,18 +1,18 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import shallow from '../../../../../../../lib/shallow-with-context' -import AdvancedTabContent from '../advanced-tab-content.component' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import shallow from '../../../../../../../lib/shallow-with-context'; +import AdvancedTabContent from '../advanced-tab-content.component'; describe('AdvancedTabContent Component', function () { - let wrapper + let wrapper; beforeEach(function () { const propsMethodSpies = { updateCustomGasPrice: sinon.spy(), updateCustomGasLimit: sinon.spy(), - } - sinon.spy(AdvancedTabContent.prototype, 'renderDataSummary') + }; + sinon.spy(AdvancedTabContent.prototype, 'renderDataSummary'); wrapper = shallow( , - ) - }) + ); + }); afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); describe('render()', function () { it('should render the advanced-tab root node', function () { - assert(wrapper.hasClass('advanced-tab')) - }) + assert(wrapper.hasClass('advanced-tab')); + }); it('should render the expected child of the advanced-tab div', function () { - const advancedTabChildren = wrapper.children() - assert.strictEqual(advancedTabChildren.length, 2) + const advancedTabChildren = wrapper.children(); + assert.strictEqual(advancedTabChildren.length, 2); assert( advancedTabChildren .at(0) .hasClass('advanced-tab__transaction-data-summary'), - ) - }) + ); + }); it('should call renderDataSummary with the expected params', function () { const renderDataSummaryArgs = AdvancedTabContent.prototype.renderDataSummary.getCall( 0, - ).args - assert.deepStrictEqual(renderDataSummaryArgs, ['$0.25']) - }) - }) + ).args; + assert.deepStrictEqual(renderDataSummaryArgs, ['$0.25']); + }); + }); describe('renderDataSummary()', function () { - let dataSummary + let dataSummary; beforeEach(function () { dataSummary = shallow( wrapper.instance().renderDataSummary('mockTotalFee'), - ) - }) + ); + }); it('should render the transaction-data-summary root node', function () { - assert(dataSummary.hasClass('advanced-tab__transaction-data-summary')) - }) + assert(dataSummary.hasClass('advanced-tab__transaction-data-summary')); + }); it('should render titles of the data', function () { - const titlesNode = dataSummary.children().at(0) + const titlesNode = dataSummary.children().at(0); assert( titlesNode.hasClass('advanced-tab__transaction-data-summary__titles'), - ) + ); assert.strictEqual( titlesNode.children().at(0).text(), 'newTransactionFee', - ) - }) + ); + }); it('should render the data', function () { - const dataNode = dataSummary.children().at(1) + const dataNode = dataSummary.children().at(1); assert( dataNode.hasClass('advanced-tab__transaction-data-summary__container'), - ) - assert.strictEqual(dataNode.children().at(0).text(), 'mockTotalFee') - }) - }) -}) + ); + assert.strictEqual(dataNode.children().at(0).text(), 'mockTotalFee'); + }); + }); +}); diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js b/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js index 7ef85e7a47..85a06c89d7 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js @@ -1,20 +1,20 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import Loading from '../../../../ui/loading-screen' -import GasPriceButtonGroup from '../../gas-price-button-group' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import Loading from '../../../../ui/loading-screen'; +import GasPriceButtonGroup from '../../gas-price-button-group'; export default class BasicTabContent extends Component { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { gasPriceButtonGroupProps: PropTypes.object, - } + }; render() { - const { t } = this.context - const { gasPriceButtonGroupProps } = this.props + const { t } = this.context; + const { gasPriceButtonGroupProps } = this.props; return (
    @@ -37,6 +37,6 @@ export default class BasicTabContent extends Component { {t('acceleratingATransaction')}
    - ) + ); } } diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/index.js b/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/index.js index 078d50fce1..27b7eaa9d2 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/index.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/index.js @@ -1 +1 @@ -export { default } from './basic-tab-content.component' +export { default } from './basic-tab-content.component'; diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js index ae0829db06..e0597a5a0f 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js @@ -1,10 +1,10 @@ -import assert from 'assert' -import React from 'react' -import shallow from '../../../../../../../lib/shallow-with-context' -import BasicTabContent from '../basic-tab-content.component' -import GasPriceButtonGroup from '../../../gas-price-button-group' -import Loading from '../../../../../ui/loading-screen' -import { GAS_ESTIMATE_TYPES } from '../../../../../../helpers/constants/common' +import assert from 'assert'; +import React from 'react'; +import shallow from '../../../../../../../lib/shallow-with-context'; +import BasicTabContent from '../basic-tab-content.component'; +import GasPriceButtonGroup from '../../../gas-price-button-group'; +import Loading from '../../../../../ui/loading-screen'; +import { GAS_ESTIMATE_TYPES } from '../../../../../../helpers/constants/common'; const mockGasPriceButtonGroupProps = { buttonDataLoading: false, @@ -36,19 +36,19 @@ const mockGasPriceButtonGroupProps = { console.log('NewPrice: ', gasPrice), noButtonActiveByDefault: true, showCheck: true, -} +}; describe('BasicTabContent Component', function () { describe('render', function () { - let wrapper + let wrapper; beforeEach(function () { wrapper = shallow( , - ) - }) + ); + }); it('should have a title', function () { assert( @@ -56,12 +56,12 @@ describe('BasicTabContent Component', function () { .find('.basic-tab-content') .childAt(0) .hasClass('basic-tab-content__title'), - ) - }) + ); + }); it('should render a GasPriceButtonGroup compenent', function () { - assert.strictEqual(wrapper.find(GasPriceButtonGroup).length, 1) - }) + assert.strictEqual(wrapper.find(GasPriceButtonGroup).length, 1); + }); it('should pass correct props to GasPriceButtonGroup', function () { const { @@ -71,27 +71,27 @@ describe('BasicTabContent Component', function () { handleGasPriceSelection, noButtonActiveByDefault, showCheck, - } = wrapper.find(GasPriceButtonGroup).props() - assert.strictEqual(wrapper.find(GasPriceButtonGroup).length, 1) + } = wrapper.find(GasPriceButtonGroup).props(); + assert.strictEqual(wrapper.find(GasPriceButtonGroup).length, 1); assert.strictEqual( buttonDataLoading, mockGasPriceButtonGroupProps.buttonDataLoading, - ) - assert.strictEqual(className, mockGasPriceButtonGroupProps.className) + ); + assert.strictEqual(className, mockGasPriceButtonGroupProps.className); assert.strictEqual( noButtonActiveByDefault, mockGasPriceButtonGroupProps.noButtonActiveByDefault, - ) - assert.strictEqual(showCheck, mockGasPriceButtonGroupProps.showCheck) + ); + assert.strictEqual(showCheck, mockGasPriceButtonGroupProps.showCheck); assert.deepStrictEqual( gasButtonInfo, mockGasPriceButtonGroupProps.gasButtonInfo, - ) + ); assert.strictEqual( JSON.stringify(handleGasPriceSelection), JSON.stringify(mockGasPriceButtonGroupProps.handleGasPriceSelection), - ) - }) + ); + }); it('should render a loading component instead of the GasPriceButtonGroup if gasPriceButtonGroupProps.loading is true', function () { wrapper.setProps({ @@ -99,10 +99,10 @@ describe('BasicTabContent Component', function () { ...mockGasPriceButtonGroupProps, loading: true, }, - }) + }); - assert.strictEqual(wrapper.find(GasPriceButtonGroup).length, 0) - assert.strictEqual(wrapper.find(Loading).length, 1) - }) - }) -}) + assert.strictEqual(wrapper.find(GasPriceButtonGroup).length, 0); + assert.strictEqual(wrapper.find(Loading).length, 1); + }); + }); +}); diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index 05810f07fe..4c27f99003 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -1,16 +1,16 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import PageContainer from '../../../ui/page-container' -import { Tabs, Tab } from '../../../ui/tabs' -import AdvancedTabContent from './advanced-tab-content' -import BasicTabContent from './basic-tab-content' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import PageContainer from '../../../ui/page-container'; +import { Tabs, Tab } from '../../../ui/tabs'; +import AdvancedTabContent from './advanced-tab-content'; +import BasicTabContent from './basic-tab-content'; export default class GasModalPageContainer extends Component { static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, trackEvent: PropTypes.func, - } + }; static propTypes = { hideBasic: PropTypes.bool, @@ -35,16 +35,16 @@ export default class GasModalPageContainer extends Component { isSpeedUp: PropTypes.bool, isRetry: PropTypes.bool, disableSave: PropTypes.bool, - } + }; componentDidMount() { - this.props.fetchBasicGasEstimates() + this.props.fetchBasicGasEstimates(); } renderBasicTabContent(gasPriceButtonGroupProps) { return ( - ) + ); } renderAdvancedTabContent() { @@ -58,7 +58,7 @@ export default class GasModalPageContainer extends Component { isSpeedUp, isRetry, infoRowProps: { transactionFee }, - } = this.props + } = this.props; return ( - ) + ); } renderInfoRows(newTotalFiat, newTotalEth, sendAmount, transactionFee) { @@ -110,7 +110,7 @@ export default class GasModalPageContainer extends Component { - ) + ); } renderTabs() { @@ -118,7 +118,7 @@ export default class GasModalPageContainer extends Component { gasPriceButtonGroupProps, hideBasic, infoRowProps: { newTotalFiat, newTotalEth, sendAmount, transactionFee }, - } = this.props + } = this.props; let tabsToRender = [ { @@ -129,10 +129,10 @@ export default class GasModalPageContainer extends Component { name: this.context.t('advanced'), content: this.renderAdvancedTabContent(), }, - ] + ]; if (hideBasic) { - tabsToRender = tabsToRender.slice(1) + tabsToRender = tabsToRender.slice(1); } return ( @@ -151,7 +151,7 @@ export default class GasModalPageContainer extends Component { ))} - ) + ); } render() { @@ -162,7 +162,7 @@ export default class GasModalPageContainer extends Component { customModalGasLimitInHex, disableSave, isSpeedUp, - } = this.props + } = this.props; return (
    @@ -181,15 +181,15 @@ export default class GasModalPageContainer extends Component { action: 'Activity Log', name: 'Saved "Speed Up"', }, - }) + }); } - onSubmit(customModalGasLimitInHex, customModalGasPriceInHex) + onSubmit(customModalGasLimitInHex, customModalGasPriceInHex); }} submitText={this.context.t('save')} headerCloseText={this.context.t('close')} hideCancel />
    - ) + ); } } diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js index cacb39b09c..fc1b111b95 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -1,5 +1,5 @@ -import { connect } from 'react-redux' -import { addHexPrefix } from '../../../../../../app/scripts/lib/util' +import { connect } from 'react-redux'; +import { addHexPrefix } from '../../../../../../app/scripts/lib/util'; import { hideModal, setGasLimit, @@ -10,17 +10,17 @@ import { updateSendAmount, setGasTotal, updateTransaction, -} from '../../../../store/actions' +} from '../../../../store/actions'; import { setCustomGasPrice, setCustomGasLimit, resetCustomData, fetchBasicGasEstimates, -} from '../../../../ducks/gas/gas.duck' +} from '../../../../ducks/gas/gas.duck'; import { hideGasButtonGroup, updateSendErrors, -} from '../../../../ducks/send/send.duck' +} from '../../../../ducks/send/send.duck'; import { conversionRateSelector as getConversionRate, getCurrentCurrency, @@ -37,7 +37,7 @@ import { getTokenBalance, getSendMaxModeState, getAveragePriceEstimateInHexWEI, -} from '../../../../selectors' +} from '../../../../selectors'; import { addHexes, @@ -45,27 +45,27 @@ import { hexWEIToDecGWEI, getValueFromWeiHex, sumHexWEIsToRenderableFiat, -} from '../../../../helpers/utils/conversions.util' -import { formatETHFee } from '../../../../helpers/utils/formatters' +} from '../../../../helpers/utils/conversions.util'; +import { formatETHFee } from '../../../../helpers/utils/formatters'; import { calcGasTotal, isBalanceSufficient, -} from '../../../../pages/send/send.utils' -import { MIN_GAS_LIMIT_DEC } from '../../../../pages/send/send.constants' -import { calcMaxAmount } from '../../../../pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.utils' -import { TRANSACTION_STATUSES } from '../../../../../../shared/constants/transaction' -import GasModalPageContainer from './gas-modal-page-container.component' +} from '../../../../pages/send/send.utils'; +import { MIN_GAS_LIMIT_DEC } from '../../../../pages/send/send.constants'; +import { calcMaxAmount } from '../../../../pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.utils'; +import { TRANSACTION_STATUSES } from '../../../../../../shared/constants/transaction'; +import GasModalPageContainer from './gas-modal-page-container.component'; const mapStateToProps = (state, ownProps) => { - const { currentNetworkTxList, send } = state.metamask - const { modalState: { props: modalProps } = {} } = state.appState.modal || {} - const { txData = {} } = modalProps || {} - const { transaction = {} } = ownProps + const { currentNetworkTxList, send } = state.metamask; + const { modalState: { props: modalProps } = {} } = state.appState.modal || {}; + const { txData = {} } = modalProps || {}; + const { transaction = {} } = ownProps; const selectedTransaction = currentNetworkTxList.find( ({ id }) => id === (transaction.id || txData.id), - ) - const buttonDataLoading = getBasicGasEstimateLoadingStatus(state) - const sendToken = getSendToken(state) + ); + const buttonDataLoading = getBasicGasEstimateLoadingStatus(state); + const sendToken = getSendToken(state); // a "default" txParams is used during the send flow, since the transaction doesn't exist yet in that case const txParams = selectedTransaction?.txParams @@ -74,53 +74,53 @@ const mapStateToProps = (state, ownProps) => { gas: send.gasLimit || '0x5208', gasPrice: send.gasPrice || getAveragePriceEstimateInHexWEI(state, true), value: sendToken ? '0x0' : send.amount, - } + }; - const { gasPrice: currentGasPrice, gas: currentGasLimit, value } = txParams - const customModalGasPriceInHex = getCustomGasPrice(state) || currentGasPrice + const { gasPrice: currentGasPrice, gas: currentGasLimit, value } = txParams; + const customModalGasPriceInHex = getCustomGasPrice(state) || currentGasPrice; const customModalGasLimitInHex = - getCustomGasLimit(state) || currentGasLimit || '0x5208' + getCustomGasLimit(state) || currentGasLimit || '0x5208'; const customGasTotal = calcGasTotal( customModalGasLimitInHex, customModalGasPriceInHex, - ) + ); const gasButtonInfo = getRenderableBasicEstimateData( state, customModalGasLimitInHex, - ) + ); - const currentCurrency = getCurrentCurrency(state) - const conversionRate = getConversionRate(state) + const currentCurrency = getCurrentCurrency(state); + const conversionRate = getConversionRate(state); const newTotalFiat = sumHexWEIsToRenderableFiat( [value, customGasTotal], currentCurrency, conversionRate, - ) + ); - const { hideBasic } = state.appState.modal.modalState.props + const { hideBasic } = state.appState.modal.modalState.props; - const customGasPrice = calcCustomGasPrice(customModalGasPriceInHex) + const customGasPrice = calcCustomGasPrice(customModalGasPriceInHex); - const maxModeOn = getSendMaxModeState(state) + const maxModeOn = getSendMaxModeState(state); - const balance = getCurrentEthBalance(state) + const balance = getCurrentEthBalance(state); - const { showFiatInTestnets } = getPreferences(state) - const isMainnet = getIsMainnet(state) - const showFiat = Boolean(isMainnet || showFiatInTestnets) + const { showFiatInTestnets } = getPreferences(state); + const isMainnet = getIsMainnet(state); + const showFiat = Boolean(isMainnet || showFiatInTestnets); - const isSendTokenSet = Boolean(sendToken) + const isSendTokenSet = Boolean(sendToken); const newTotalEth = maxModeOn && !isSendTokenSet ? sumHexWEIsToRenderableEth([balance, '0x0']) - : sumHexWEIsToRenderableEth([value, customGasTotal]) + : sumHexWEIsToRenderableEth([value, customGasTotal]); const sendAmount = maxModeOn && !isSendTokenSet ? subtractHexWEIsFromRenderableEth(balance, customGasTotal) - : sumHexWEIsToRenderableEth([value, '0x0']) + : sumHexWEIsToRenderableEth([value, '0x0']); const insufficientBalance = maxModeOn ? false @@ -129,7 +129,7 @@ const mapStateToProps = (state, ownProps) => { gasTotal: customGasTotal, balance, conversionRate, - }) + }); return { hideBasic, @@ -173,47 +173,47 @@ const mapStateToProps = (state, ownProps) => { tokenBalance: getTokenBalance(state), conversionRate, value, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { const updateCustomGasPrice = (newPrice) => - dispatch(setCustomGasPrice(addHexPrefix(newPrice))) + dispatch(setCustomGasPrice(addHexPrefix(newPrice))); return { cancelAndClose: () => { - dispatch(resetCustomData()) - dispatch(hideModal()) + dispatch(resetCustomData()); + dispatch(hideModal()); }, hideModal: () => dispatch(hideModal()), updateCustomGasPrice, updateCustomGasLimit: (newLimit) => dispatch(setCustomGasLimit(addHexPrefix(newLimit))), setGasData: (newLimit, newPrice) => { - dispatch(setGasLimit(newLimit)) - dispatch(setGasPrice(newPrice)) + dispatch(setGasLimit(newLimit)); + dispatch(setGasPrice(newPrice)); }, updateConfirmTxGasAndCalculate: (gasLimit, gasPrice, updatedTx) => { - updateCustomGasPrice(gasPrice) - dispatch(setCustomGasLimit(addHexPrefix(gasLimit.toString(16)))) - return dispatch(updateTransaction(updatedTx)) + updateCustomGasPrice(gasPrice); + dispatch(setCustomGasLimit(addHexPrefix(gasLimit.toString(16)))); + return dispatch(updateTransaction(updatedTx)); }, createRetryTransaction: (txId, gasPrice, gasLimit) => { - return dispatch(createRetryTransaction(txId, gasPrice, gasLimit)) + return dispatch(createRetryTransaction(txId, gasPrice, gasLimit)); }, createSpeedUpTransaction: (txId, gasPrice, gasLimit) => { - return dispatch(createSpeedUpTransaction(txId, gasPrice, gasLimit)) + return dispatch(createSpeedUpTransaction(txId, gasPrice, gasLimit)); }, hideGasButtonGroup: () => dispatch(hideGasButtonGroup()), hideSidebar: () => dispatch(hideSidebar()), fetchBasicGasEstimates: () => dispatch(fetchBasicGasEstimates()), setGasTotal: (total) => dispatch(setGasTotal(total)), setAmountToMax: (maxAmountDataObject) => { - dispatch(updateSendErrors({ amount: null })) - dispatch(updateSendAmount(calcMaxAmount(maxAmountDataObject))) + dispatch(updateSendErrors({ amount: null })); + dispatch(updateSendAmount(calcMaxAmount(maxAmountDataObject))); }, - } -} + }; +}; const mergeProps = (stateProps, dispatchProps, ownProps) => { const { @@ -232,7 +232,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { tokenBalance, customGasLimit, transaction, - } = stateProps + } = stateProps; const { hideGasButtonGroup: dispatchHideGasButtonGroup, setGasData: dispatchSetGasData, @@ -244,7 +244,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { hideModal: dispatchHideModal, setAmountToMax: dispatchSetAmountToMax, ...otherDispatchProps - } = dispatchProps + } = dispatchProps; return { ...stateProps, @@ -259,21 +259,21 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { gas: gasLimit, gasPrice, }, - } - dispatchUpdateConfirmTxGasAndCalculate(gasLimit, gasPrice, updatedTx) - dispatchHideModal() + }; + dispatchUpdateConfirmTxGasAndCalculate(gasLimit, gasPrice, updatedTx); + dispatchHideModal(); } else if (isSpeedUp) { - dispatchCreateSpeedUpTransaction(txId, gasPrice, gasLimit) - dispatchHideSidebar() - dispatchCancelAndClose() + dispatchCreateSpeedUpTransaction(txId, gasPrice, gasLimit); + dispatchHideSidebar(); + dispatchCancelAndClose(); } else if (isRetry) { - dispatchCreateRetryTransaction(txId, gasPrice, gasLimit) - dispatchHideSidebar() - dispatchCancelAndClose() + dispatchCreateRetryTransaction(txId, gasPrice, gasLimit); + dispatchHideSidebar(); + dispatchCancelAndClose(); } else { - dispatchSetGasData(gasLimit, gasPrice) - dispatchHideGasButtonGroup() - dispatchCancelAndClose() + dispatchSetGasData(gasLimit, gasPrice); + dispatchHideGasButtonGroup(); + dispatchCancelAndClose(); } if (maxModeOn) { dispatchSetAmountToMax({ @@ -281,7 +281,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { gasTotal: customGasTotal, sendToken, tokenBalance, - }) + }); } }, gasPriceButtonGroupProps: { @@ -290,47 +290,47 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { otherDispatchProps.updateCustomGasPrice(gasPrice), }, cancelAndClose: () => { - dispatchCancelAndClose() + dispatchCancelAndClose(); if (isSpeedUp || isRetry) { - dispatchHideSidebar() + dispatchHideSidebar(); } }, disableSave: insufficientBalance || (isSpeedUp && customGasPrice === 0) || customGasLimit < Number(MIN_GAS_LIMIT_DEC), - } -} + }; +}; export default connect( mapStateToProps, mapDispatchToProps, mergeProps, -)(GasModalPageContainer) +)(GasModalPageContainer); function isConfirm(state) { - return Boolean(Object.keys(state.confirmTransaction.txData).length) + return Boolean(Object.keys(state.confirmTransaction.txData).length); } function calcCustomGasPrice(customGasPriceInHex) { - return Number(hexWEIToDecGWEI(customGasPriceInHex)) + return Number(hexWEIToDecGWEI(customGasPriceInHex)); } function calcCustomGasLimit(customGasLimitInHex) { - return parseInt(customGasLimitInHex, 16) + return parseInt(customGasLimitInHex, 16); } function sumHexWEIsToRenderableEth(hexWEIs) { - const hexWEIsSum = hexWEIs.filter(Boolean).reduce(addHexes) + const hexWEIsSum = hexWEIs.filter(Boolean).reduce(addHexes); return formatETHFee( getValueFromWeiHex({ value: hexWEIsSum, toCurrency: 'ETH', numberOfDecimals: 6, }), - ) + ); } function subtractHexWEIsFromRenderableEth(aHexWEI, bHexWEI) { - return formatETHFee(subtractHexWEIsToDec(aHexWEI, bHexWEI)) + return formatETHFee(subtractHexWEIsToDec(aHexWEI, bHexWEI)); } diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/index.js b/ui/app/components/app/gas-customization/gas-modal-page-container/index.js index ec0ebad22b..65e2a49bef 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/index.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/index.js @@ -1 +1 @@ -export { default } from './gas-modal-page-container.container' +export { default } from './gas-modal-page-container.container'; diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js index 8ae08274cb..1fede05036 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js @@ -1,16 +1,16 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import shallow from '../../../../../../lib/shallow-with-context' -import GasModalPageContainer from '../gas-modal-page-container.component' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import shallow from '../../../../../../lib/shallow-with-context'; +import GasModalPageContainer from '../gas-modal-page-container.component'; -import PageContainer from '../../../../ui/page-container' +import PageContainer from '../../../../ui/page-container'; -import { Tab } from '../../../../ui/tabs' +import { Tab } from '../../../../ui/tabs'; const mockBasicGasEstimates = { average: '20', -} +}; const propsMethodSpies = { cancelAndClose: sinon.spy(), @@ -18,7 +18,7 @@ const propsMethodSpies = { fetchBasicGasEstimates: sinon .stub() .returns(Promise.resolve(mockBasicGasEstimates)), -} +}; const mockGasPriceButtonGroupProps = { buttonDataLoading: false, @@ -48,7 +48,7 @@ const mockGasPriceButtonGroupProps = { showCheck: true, newTotalFiat: 'mockNewTotalFiat', newTotalEth: 'mockNewTotalEth', -} +}; const mockInfoRowProps = { originalTotalFiat: 'mockOriginalTotalFiat', originalTotalEth: 'mockOriginalTotalEth', @@ -57,11 +57,11 @@ const mockInfoRowProps = { sendAmount: 'mockSendAmount', transactionFee: 'mockTransactionFee', extraInfoRow: { label: 'mockLabel', value: 'mockValue' }, -} +}; -const GP = GasModalPageContainer.prototype +const GP = GasModalPageContainer.prototype; describe('GasModalPageContainer Component', function () { - let wrapper + let wrapper; beforeEach(function () { wrapper = shallow( @@ -78,114 +78,114 @@ describe('GasModalPageContainer Component', function () { insufficientBalance={false} disableSave={false} />, - ) - }) + ); + }); afterEach(function () { - propsMethodSpies.cancelAndClose.resetHistory() - }) + propsMethodSpies.cancelAndClose.resetHistory(); + }); describe('componentDidMount', function () { it('should call props.fetchBasicGasEstimates', function () { - propsMethodSpies.fetchBasicGasEstimates.resetHistory() - assert.strictEqual(propsMethodSpies.fetchBasicGasEstimates.callCount, 0) - wrapper.instance().componentDidMount() - assert.strictEqual(propsMethodSpies.fetchBasicGasEstimates.callCount, 1) - }) - }) + propsMethodSpies.fetchBasicGasEstimates.resetHistory(); + assert.strictEqual(propsMethodSpies.fetchBasicGasEstimates.callCount, 0); + wrapper.instance().componentDidMount(); + assert.strictEqual(propsMethodSpies.fetchBasicGasEstimates.callCount, 1); + }); + }); describe('render', function () { it('should render a PageContainer compenent', function () { - assert.strictEqual(wrapper.find(PageContainer).length, 1) - }) + assert.strictEqual(wrapper.find(PageContainer).length, 1); + }); it('should pass correct props to PageContainer', function () { - const { title, subtitle, disabled } = wrapper.find(PageContainer).props() - assert.strictEqual(title, 'customGas') - assert.strictEqual(subtitle, 'customGasSubTitle') - assert.strictEqual(disabled, false) - }) + const { title, subtitle, disabled } = wrapper.find(PageContainer).props(); + assert.strictEqual(title, 'customGas'); + assert.strictEqual(subtitle, 'customGasSubTitle'); + assert.strictEqual(disabled, false); + }); it('should pass the correct onCancel and onClose methods to PageContainer', function () { - const { onCancel, onClose } = wrapper.find(PageContainer).props() - assert.strictEqual(propsMethodSpies.cancelAndClose.callCount, 0) - onCancel() - assert.strictEqual(propsMethodSpies.cancelAndClose.callCount, 1) - onClose() - assert.strictEqual(propsMethodSpies.cancelAndClose.callCount, 2) - }) + const { onCancel, onClose } = wrapper.find(PageContainer).props(); + assert.strictEqual(propsMethodSpies.cancelAndClose.callCount, 0); + onCancel(); + assert.strictEqual(propsMethodSpies.cancelAndClose.callCount, 1); + onClose(); + assert.strictEqual(propsMethodSpies.cancelAndClose.callCount, 2); + }); it('should pass the correct renderTabs property to PageContainer', function () { - sinon.stub(GP, 'renderTabs').returns('mockTabs') + sinon.stub(GP, 'renderTabs').returns('mockTabs'); const renderTabsWrapperTester = shallow( , { context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) } }, - ) + ); const { tabsComponent } = renderTabsWrapperTester .find(PageContainer) - .props() - assert.strictEqual(tabsComponent, 'mockTabs') - GasModalPageContainer.prototype.renderTabs.restore() - }) - }) + .props(); + assert.strictEqual(tabsComponent, 'mockTabs'); + GasModalPageContainer.prototype.renderTabs.restore(); + }); + }); describe('renderTabs', function () { beforeEach(function () { - sinon.spy(GP, 'renderBasicTabContent') - sinon.spy(GP, 'renderAdvancedTabContent') - sinon.spy(GP, 'renderInfoRows') - }) + sinon.spy(GP, 'renderBasicTabContent'); + sinon.spy(GP, 'renderAdvancedTabContent'); + sinon.spy(GP, 'renderInfoRows'); + }); afterEach(function () { - GP.renderBasicTabContent.restore() - GP.renderAdvancedTabContent.restore() - GP.renderInfoRows.restore() - }) + GP.renderBasicTabContent.restore(); + GP.renderAdvancedTabContent.restore(); + GP.renderInfoRows.restore(); + }); it('should render a Tabs component with "Basic" and "Advanced" tabs', function () { - const renderTabsResult = wrapper.instance().renderTabs() - const renderedTabs = shallow(renderTabsResult) - assert.strictEqual(renderedTabs.props().className, 'tabs') + const renderTabsResult = wrapper.instance().renderTabs(); + const renderedTabs = shallow(renderTabsResult); + assert.strictEqual(renderedTabs.props().className, 'tabs'); - const tabs = renderedTabs.find(Tab) - assert.strictEqual(tabs.length, 2) + const tabs = renderedTabs.find(Tab); + assert.strictEqual(tabs.length, 2); - assert.strictEqual(tabs.at(0).props().name, 'basic') - assert.strictEqual(tabs.at(1).props().name, 'advanced') + assert.strictEqual(tabs.at(0).props().name, 'basic'); + assert.strictEqual(tabs.at(1).props().name, 'advanced'); assert.strictEqual( tabs.at(0).childAt(0).props().className, 'gas-modal-content', - ) + ); assert.strictEqual( tabs.at(1).childAt(0).props().className, 'gas-modal-content', - ) - }) + ); + }); it('should call renderInfoRows with the expected props', function () { - assert.strictEqual(GP.renderInfoRows.callCount, 0) + assert.strictEqual(GP.renderInfoRows.callCount, 0); - wrapper.instance().renderTabs() + wrapper.instance().renderTabs(); - assert.strictEqual(GP.renderInfoRows.callCount, 2) + assert.strictEqual(GP.renderInfoRows.callCount, 2); assert.deepStrictEqual(GP.renderInfoRows.getCall(0).args, [ 'mockNewTotalFiat', 'mockNewTotalEth', 'mockSendAmount', 'mockTransactionFee', - ]) + ]); assert.deepStrictEqual(GP.renderInfoRows.getCall(1).args, [ 'mockNewTotalFiat', 'mockNewTotalEth', 'mockSendAmount', 'mockTransactionFee', - ]) - }) + ]); + }); it('should not render the basic tab if hideBasic is true', function () { wrapper = shallow( @@ -203,32 +203,32 @@ describe('GasModalPageContainer Component', function () { disableSave={false} hideBasic />, - ) - const renderTabsResult = wrapper.instance().renderTabs() + ); + const renderTabsResult = wrapper.instance().renderTabs(); - const renderedTabs = shallow(renderTabsResult) - const tabs = renderedTabs.find(Tab) - assert.strictEqual(tabs.length, 1) - assert.strictEqual(tabs.at(0).props().name, 'advanced') - }) - }) + const renderedTabs = shallow(renderTabsResult); + const tabs = renderedTabs.find(Tab); + assert.strictEqual(tabs.length, 1); + assert.strictEqual(tabs.at(0).props().name, 'advanced'); + }); + }); describe('renderBasicTabContent', function () { it('should render', function () { const renderBasicTabContentResult = wrapper .instance() - .renderBasicTabContent(mockGasPriceButtonGroupProps) + .renderBasicTabContent(mockGasPriceButtonGroupProps); assert.deepStrictEqual( renderBasicTabContentResult.props.gasPriceButtonGroupProps, mockGasPriceButtonGroupProps, - ) - }) - }) + ); + }); + }); describe('renderInfoRows', function () { it('should render the info rows with the passed data', function () { - const baseClassName = 'gas-modal-content__info-row' + const baseClassName = 'gas-modal-content__info-row'; const renderedInfoRowsContainer = shallow( wrapper .instance() @@ -238,34 +238,34 @@ describe('GasModalPageContainer Component', function () { ' mockSendAmount', ' mockTransactionFee', ), - ) + ); - assert(renderedInfoRowsContainer.childAt(0).hasClass(baseClassName)) + assert(renderedInfoRowsContainer.childAt(0).hasClass(baseClassName)); - const renderedInfoRows = renderedInfoRowsContainer.childAt(0).children() - assert.strictEqual(renderedInfoRows.length, 4) - assert(renderedInfoRows.at(0).hasClass(`${baseClassName}__send-info`)) + const renderedInfoRows = renderedInfoRowsContainer.childAt(0).children(); + assert.strictEqual(renderedInfoRows.length, 4); + assert(renderedInfoRows.at(0).hasClass(`${baseClassName}__send-info`)); assert( renderedInfoRows.at(1).hasClass(`${baseClassName}__transaction-info`), - ) - assert(renderedInfoRows.at(2).hasClass(`${baseClassName}__total-info`)) + ); + assert(renderedInfoRows.at(2).hasClass(`${baseClassName}__total-info`)); assert( renderedInfoRows.at(3).hasClass(`${baseClassName}__fiat-total-info`), - ) + ); assert.strictEqual( renderedInfoRows.at(0).text(), 'sendAmount mockSendAmount', - ) + ); assert.strictEqual( renderedInfoRows.at(1).text(), 'transactionFee mockTransactionFee', - ) + ); assert.strictEqual( renderedInfoRows.at(2).text(), 'newTotal mockNewTotalEth', - ) - assert.strictEqual(renderedInfoRows.at(3).text(), 'mockNewTotalFiat') - }) - }) -}) + ); + assert.strictEqual(renderedInfoRows.at(3).text(), 'mockNewTotalFiat'); + }); + }); +}); diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js index 81934468c1..ac355d6567 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js @@ -1,39 +1,39 @@ -import assert from 'assert' -import proxyquire from 'proxyquire' -import sinon from 'sinon' -import { TRANSACTION_STATUSES } from '../../../../../../../shared/constants/transaction' +import assert from 'assert'; +import proxyquire from 'proxyquire'; +import sinon from 'sinon'; +import { TRANSACTION_STATUSES } from '../../../../../../../shared/constants/transaction'; -let mapStateToProps -let mapDispatchToProps -let mergeProps +let mapStateToProps; +let mapDispatchToProps; +let mergeProps; const actionSpies = { hideModal: sinon.spy(), setGasLimit: sinon.spy(), setGasPrice: sinon.spy(), -} +}; const gasActionSpies = { setCustomGasPrice: sinon.spy(), setCustomGasLimit: sinon.spy(), resetCustomData: sinon.spy(), -} +}; const confirmTransactionActionSpies = { updateGasAndCalculate: sinon.spy(), -} +}; const sendActionSpies = { hideGasButtonGroup: sinon.spy(), -} +}; proxyquire('../gas-modal-page-container.container.js', { 'react-redux': { connect: (ms, md, mp) => { - mapStateToProps = ms - mapDispatchToProps = md - mergeProps = mp - return () => ({}) + mapStateToProps = ms; + mapDispatchToProps = md; + mergeProps = mp; + return () => ({}); }, }, '../../../../selectors': { @@ -50,7 +50,7 @@ proxyquire('../gas-modal-page-container.container.js', { '../../../../ducks/gas/gas.duck': gasActionSpies, '../../../../ducks/confirm-transaction/confirm-transaction.duck': confirmTransactionActionSpies, '../../../../ducks/send/send.duck': sendActionSpies, -}) +}); describe('gas-modal-page-container container', function () { describe('mapStateToProps()', function () { @@ -120,7 +120,7 @@ describe('gas-modal-page-container container', function () { }, }, }, - } + }; const baseExpectedResult = { balance: '0x0', isConfirm: true, @@ -158,8 +158,8 @@ describe('gas-modal-page-container container', function () { id: 34, }, value: '0x640000000000000', - } - const baseMockOwnProps = { transaction: { id: 34 } } + }; + const baseMockOwnProps = { transaction: { id: 34 } }; const tests = [ { mockState: baseMockState, @@ -257,109 +257,109 @@ describe('gas-modal-page-container container', function () { mockOwnProps: baseMockOwnProps, expectedResult: baseExpectedResult, }, - ] + ]; - let result + let result; tests.forEach(({ mockState, mockOwnProps, expectedResult }) => { - result = mapStateToProps(mockState, mockOwnProps) - assert.deepStrictEqual(result, expectedResult) - }) - }) - }) + result = mapStateToProps(mockState, mockOwnProps); + assert.deepStrictEqual(result, expectedResult); + }); + }); + }); describe('mapDispatchToProps()', function () { - let dispatchSpy - let mapDispatchToPropsObject + let dispatchSpy; + let mapDispatchToPropsObject; beforeEach(function () { - dispatchSpy = sinon.spy() - mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy) - }) + dispatchSpy = sinon.spy(); + mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy); + }); afterEach(function () { - actionSpies.hideModal.resetHistory() - gasActionSpies.setCustomGasPrice.resetHistory() - gasActionSpies.setCustomGasLimit.resetHistory() - }) + actionSpies.hideModal.resetHistory(); + gasActionSpies.setCustomGasPrice.resetHistory(); + gasActionSpies.setCustomGasLimit.resetHistory(); + }); describe('hideGasButtonGroup()', function () { it('should dispatch a hideGasButtonGroup action', function () { - mapDispatchToPropsObject.hideGasButtonGroup() - assert(dispatchSpy.calledOnce) - assert(sendActionSpies.hideGasButtonGroup.calledOnce) - }) - }) + mapDispatchToPropsObject.hideGasButtonGroup(); + assert(dispatchSpy.calledOnce); + assert(sendActionSpies.hideGasButtonGroup.calledOnce); + }); + }); describe('cancelAndClose()', function () { it('should dispatch a hideModal action', function () { - mapDispatchToPropsObject.cancelAndClose() - assert(dispatchSpy.calledTwice) - assert(actionSpies.hideModal.calledOnce) - assert(gasActionSpies.resetCustomData.calledOnce) - }) - }) + mapDispatchToPropsObject.cancelAndClose(); + assert(dispatchSpy.calledTwice); + assert(actionSpies.hideModal.calledOnce); + assert(gasActionSpies.resetCustomData.calledOnce); + }); + }); describe('updateCustomGasPrice()', function () { it('should dispatch a setCustomGasPrice action with the arg passed to updateCustomGasPrice hex prefixed', function () { - mapDispatchToPropsObject.updateCustomGasPrice('ffff') - assert(dispatchSpy.calledOnce) - assert(gasActionSpies.setCustomGasPrice.calledOnce) + mapDispatchToPropsObject.updateCustomGasPrice('ffff'); + assert(dispatchSpy.calledOnce); + assert(gasActionSpies.setCustomGasPrice.calledOnce); assert.strictEqual( gasActionSpies.setCustomGasPrice.getCall(0).args[0], '0xffff', - ) - }) + ); + }); it('should dispatch a setCustomGasPrice action', function () { - mapDispatchToPropsObject.updateCustomGasPrice('0xffff') - assert(dispatchSpy.calledOnce) - assert(gasActionSpies.setCustomGasPrice.calledOnce) + mapDispatchToPropsObject.updateCustomGasPrice('0xffff'); + assert(dispatchSpy.calledOnce); + assert(gasActionSpies.setCustomGasPrice.calledOnce); assert.strictEqual( gasActionSpies.setCustomGasPrice.getCall(0).args[0], '0xffff', - ) - }) - }) + ); + }); + }); describe('updateCustomGasLimit()', function () { it('should dispatch a setCustomGasLimit action', function () { - mapDispatchToPropsObject.updateCustomGasLimit('0x10') - assert(dispatchSpy.calledOnce) - assert(gasActionSpies.setCustomGasLimit.calledOnce) + mapDispatchToPropsObject.updateCustomGasLimit('0x10'); + assert(dispatchSpy.calledOnce); + assert(gasActionSpies.setCustomGasLimit.calledOnce); assert.strictEqual( gasActionSpies.setCustomGasLimit.getCall(0).args[0], '0x10', - ) - }) - }) + ); + }); + }); describe('setGasData()', function () { it('should dispatch a setGasPrice and setGasLimit action with the correct props', function () { - mapDispatchToPropsObject.setGasData('ffff', 'aaaa') - assert(dispatchSpy.calledTwice) - assert(actionSpies.setGasPrice.calledOnce) - assert(actionSpies.setGasLimit.calledOnce) - assert.strictEqual(actionSpies.setGasLimit.getCall(0).args[0], 'ffff') - assert.strictEqual(actionSpies.setGasPrice.getCall(0).args[0], 'aaaa') - }) - }) + mapDispatchToPropsObject.setGasData('ffff', 'aaaa'); + assert(dispatchSpy.calledTwice); + assert(actionSpies.setGasPrice.calledOnce); + assert(actionSpies.setGasLimit.calledOnce); + assert.strictEqual(actionSpies.setGasLimit.getCall(0).args[0], 'ffff'); + assert.strictEqual(actionSpies.setGasPrice.getCall(0).args[0], 'aaaa'); + }); + }); describe('updateConfirmTxGasAndCalculate()', function () { it('should dispatch a updateGasAndCalculate action with the correct props', function () { - mapDispatchToPropsObject.updateConfirmTxGasAndCalculate('ffff', 'aaaa') - assert.strictEqual(dispatchSpy.callCount, 3) - assert(actionSpies.setGasPrice.calledOnce) - assert(actionSpies.setGasLimit.calledOnce) - assert.strictEqual(actionSpies.setGasLimit.getCall(0).args[0], 'ffff') - assert.strictEqual(actionSpies.setGasPrice.getCall(0).args[0], 'aaaa') - }) - }) - }) + mapDispatchToPropsObject.updateConfirmTxGasAndCalculate('ffff', 'aaaa'); + assert.strictEqual(dispatchSpy.callCount, 3); + assert(actionSpies.setGasPrice.calledOnce); + assert(actionSpies.setGasLimit.calledOnce); + assert.strictEqual(actionSpies.setGasLimit.getCall(0).args[0], 'ffff'); + assert.strictEqual(actionSpies.setGasPrice.getCall(0).args[0], 'aaaa'); + }); + }); + }); describe('mergeProps', function () { - let stateProps - let dispatchProps - let ownProps + let stateProps; + let dispatchProps; + let ownProps; beforeEach(function () { stateProps = { @@ -370,7 +370,7 @@ describe('gas-modal-page-container container', function () { isConfirm: true, someOtherStateProp: 'baz', transaction: {}, - } + }; dispatchProps = { updateCustomGasPrice: sinon.spy(), hideGasButtonGroup: sinon.spy(), @@ -381,135 +381,135 @@ describe('gas-modal-page-container container', function () { hideSidebar: sinon.spy(), hideModal: sinon.spy(), cancelAndClose: sinon.spy(), - } - ownProps = { someOwnProp: 123 } - }) + }; + ownProps = { someOwnProp: 123 }; + }); afterEach(function () { - dispatchProps.updateCustomGasPrice.resetHistory() - dispatchProps.hideGasButtonGroup.resetHistory() - dispatchProps.setGasData.resetHistory() - dispatchProps.updateConfirmTxGasAndCalculate.resetHistory() - dispatchProps.someOtherDispatchProp.resetHistory() - dispatchProps.createSpeedUpTransaction.resetHistory() - dispatchProps.hideSidebar.resetHistory() - dispatchProps.hideModal.resetHistory() - }) + dispatchProps.updateCustomGasPrice.resetHistory(); + dispatchProps.hideGasButtonGroup.resetHistory(); + dispatchProps.setGasData.resetHistory(); + dispatchProps.updateConfirmTxGasAndCalculate.resetHistory(); + dispatchProps.someOtherDispatchProp.resetHistory(); + dispatchProps.createSpeedUpTransaction.resetHistory(); + dispatchProps.hideSidebar.resetHistory(); + dispatchProps.hideModal.resetHistory(); + }); it('should return the expected props when isConfirm is true', function () { - const result = mergeProps(stateProps, dispatchProps, ownProps) + const result = mergeProps(stateProps, dispatchProps, ownProps); - assert.strictEqual(result.isConfirm, true) - assert.strictEqual(result.someOtherStateProp, 'baz') + assert.strictEqual(result.isConfirm, true); + assert.strictEqual(result.someOtherStateProp, 'baz'); assert.strictEqual( result.gasPriceButtonGroupProps.someGasPriceButtonGroupProp, 'foo', - ) + ); assert.strictEqual( result.gasPriceButtonGroupProps.anotherGasPriceButtonGroupProp, 'bar', - ) - assert.strictEqual(result.someOwnProp, 123) + ); + assert.strictEqual(result.someOwnProp, 123); assert.strictEqual( dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0, - ) - assert.strictEqual(dispatchProps.setGasData.callCount, 0) - assert.strictEqual(dispatchProps.hideGasButtonGroup.callCount, 0) - assert.strictEqual(dispatchProps.hideModal.callCount, 0) + ); + assert.strictEqual(dispatchProps.setGasData.callCount, 0); + assert.strictEqual(dispatchProps.hideGasButtonGroup.callCount, 0); + assert.strictEqual(dispatchProps.hideModal.callCount, 0); - result.onSubmit() + result.onSubmit(); assert.strictEqual( dispatchProps.updateConfirmTxGasAndCalculate.callCount, 1, - ) - assert.strictEqual(dispatchProps.setGasData.callCount, 0) - assert.strictEqual(dispatchProps.hideGasButtonGroup.callCount, 0) - assert.strictEqual(dispatchProps.hideModal.callCount, 1) + ); + assert.strictEqual(dispatchProps.setGasData.callCount, 0); + assert.strictEqual(dispatchProps.hideGasButtonGroup.callCount, 0); + assert.strictEqual(dispatchProps.hideModal.callCount, 1); - assert.strictEqual(dispatchProps.updateCustomGasPrice.callCount, 0) + assert.strictEqual(dispatchProps.updateCustomGasPrice.callCount, 0); result.gasPriceButtonGroupProps.handleGasPriceSelection({ gasPrice: '0x0', - }) - assert.strictEqual(dispatchProps.updateCustomGasPrice.callCount, 1) + }); + assert.strictEqual(dispatchProps.updateCustomGasPrice.callCount, 1); - assert.strictEqual(dispatchProps.someOtherDispatchProp.callCount, 0) - result.someOtherDispatchProp() - assert.strictEqual(dispatchProps.someOtherDispatchProp.callCount, 1) - }) + assert.strictEqual(dispatchProps.someOtherDispatchProp.callCount, 0); + result.someOtherDispatchProp(); + assert.strictEqual(dispatchProps.someOtherDispatchProp.callCount, 1); + }); it('should return the expected props when isConfirm is false', function () { const result = mergeProps( { ...stateProps, isConfirm: false }, dispatchProps, ownProps, - ) + ); - assert.strictEqual(result.isConfirm, false) - assert.strictEqual(result.someOtherStateProp, 'baz') + assert.strictEqual(result.isConfirm, false); + assert.strictEqual(result.someOtherStateProp, 'baz'); assert.strictEqual( result.gasPriceButtonGroupProps.someGasPriceButtonGroupProp, 'foo', - ) + ); assert.strictEqual( result.gasPriceButtonGroupProps.anotherGasPriceButtonGroupProp, 'bar', - ) - assert.strictEqual(result.someOwnProp, 123) + ); + assert.strictEqual(result.someOwnProp, 123); assert.strictEqual( dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0, - ) - assert.strictEqual(dispatchProps.setGasData.callCount, 0) - assert.strictEqual(dispatchProps.hideGasButtonGroup.callCount, 0) - assert.strictEqual(dispatchProps.cancelAndClose.callCount, 0) + ); + assert.strictEqual(dispatchProps.setGasData.callCount, 0); + assert.strictEqual(dispatchProps.hideGasButtonGroup.callCount, 0); + assert.strictEqual(dispatchProps.cancelAndClose.callCount, 0); - result.onSubmit('mockNewLimit', 'mockNewPrice') + result.onSubmit('mockNewLimit', 'mockNewPrice'); assert.strictEqual( dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0, - ) - assert.strictEqual(dispatchProps.setGasData.callCount, 1) + ); + assert.strictEqual(dispatchProps.setGasData.callCount, 1); assert.deepStrictEqual(dispatchProps.setGasData.getCall(0).args, [ 'mockNewLimit', 'mockNewPrice', - ]) - assert.strictEqual(dispatchProps.hideGasButtonGroup.callCount, 1) - assert.strictEqual(dispatchProps.cancelAndClose.callCount, 1) + ]); + assert.strictEqual(dispatchProps.hideGasButtonGroup.callCount, 1); + assert.strictEqual(dispatchProps.cancelAndClose.callCount, 1); - assert.strictEqual(dispatchProps.updateCustomGasPrice.callCount, 0) + assert.strictEqual(dispatchProps.updateCustomGasPrice.callCount, 0); result.gasPriceButtonGroupProps.handleGasPriceSelection({ gasPrice: '0x0', - }) - assert.strictEqual(dispatchProps.updateCustomGasPrice.callCount, 1) + }); + assert.strictEqual(dispatchProps.updateCustomGasPrice.callCount, 1); - assert.strictEqual(dispatchProps.someOtherDispatchProp.callCount, 0) - result.someOtherDispatchProp() - assert.strictEqual(dispatchProps.someOtherDispatchProp.callCount, 1) - }) + assert.strictEqual(dispatchProps.someOtherDispatchProp.callCount, 0); + result.someOtherDispatchProp(); + assert.strictEqual(dispatchProps.someOtherDispatchProp.callCount, 1); + }); it('should dispatch the expected actions from obSubmit when isConfirm is false and isSpeedUp is true', function () { const result = mergeProps( { ...stateProps, isSpeedUp: true, isConfirm: false }, dispatchProps, ownProps, - ) + ); - result.onSubmit() + result.onSubmit(); assert.strictEqual( dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0, - ) - assert.strictEqual(dispatchProps.setGasData.callCount, 0) - assert.strictEqual(dispatchProps.hideGasButtonGroup.callCount, 0) - assert.strictEqual(dispatchProps.cancelAndClose.callCount, 1) - - assert.strictEqual(dispatchProps.createSpeedUpTransaction.callCount, 1) - assert.strictEqual(dispatchProps.hideSidebar.callCount, 1) - }) - }) -}) + ); + assert.strictEqual(dispatchProps.setGasData.callCount, 0); + assert.strictEqual(dispatchProps.hideGasButtonGroup.callCount, 0); + assert.strictEqual(dispatchProps.cancelAndClose.callCount, 1); + + assert.strictEqual(dispatchProps.createSpeedUpTransaction.callCount, 1); + assert.strictEqual(dispatchProps.hideSidebar.callCount, 1); + }); + }); +}); diff --git a/ui/app/components/app/gas-customization/gas-price-button-group/gas-price-button-group.component.js b/ui/app/components/app/gas-customization/gas-price-button-group/gas-price-button-group.component.js index 044df3dc55..072c59b913 100644 --- a/ui/app/components/app/gas-customization/gas-price-button-group/gas-price-button-group.component.js +++ b/ui/app/components/app/gas-customization/gas-price-button-group/gas-price-button-group.component.js @@ -1,8 +1,8 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import ButtonGroup from '../../../ui/button-group' -import Button from '../../../ui/button' -import { GAS_ESTIMATE_TYPES } from '../../../../helpers/constants/common' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import ButtonGroup from '../../../ui/button-group'; +import Button from '../../../ui/button'; +import { GAS_ESTIMATE_TYPES } from '../../../../helpers/constants/common'; const GAS_OBJECT_PROPTYPES_SHAPE = { gasEstimateType: PropTypes.oneOf(Object.values(GAS_ESTIMATE_TYPES)) @@ -11,12 +11,12 @@ const GAS_OBJECT_PROPTYPES_SHAPE = { feeInSecondaryCurrency: PropTypes.string, timeEstimate: PropTypes.string, priceInHexWei: PropTypes.string, -} +}; export default class GasPriceButtonGroup extends Component { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { buttonDataLoading: PropTypes.bool, @@ -29,19 +29,19 @@ export default class GasPriceButtonGroup extends Component { newActiveButtonIndex: PropTypes.number, noButtonActiveByDefault: PropTypes.bool, showCheck: PropTypes.bool, - } + }; gasEstimateTypeLabel(gasEstimateType) { if (gasEstimateType === GAS_ESTIMATE_TYPES.SLOW) { - return this.context.t('slow') + return this.context.t('slow'); } else if (gasEstimateType === GAS_ESTIMATE_TYPES.AVERAGE) { - return this.context.t('average') + return this.context.t('average'); } else if (gasEstimateType === GAS_ESTIMATE_TYPES.FAST) { - return this.context.t('fast') + return this.context.t('fast'); } else if (gasEstimateType === GAS_ESTIMATE_TYPES.FASTEST) { - return this.context.t('fastest') + return this.context.t('fastest'); } - throw new Error(`Unrecognized gas estimate type: ${gasEstimateType}`) + throw new Error(`Unrecognized gas estimate type: ${gasEstimateType}`); } renderButtonContent( @@ -79,7 +79,7 @@ export default class GasPriceButtonGroup extends Component { )} - ) + ); } renderButton( @@ -106,7 +106,7 @@ export default class GasPriceButtonGroup extends Component { buttonContentPropsAndFlags, )} - ) + ); } render() { @@ -117,7 +117,7 @@ export default class GasPriceButtonGroup extends Component { noButtonActiveByDefault = false, buttonDataLoading, ...buttonPropsAndFlags - } = this.props + } = this.props; return buttonDataLoading ? (
    @@ -134,6 +134,6 @@ export default class GasPriceButtonGroup extends Component { this.renderButton(obj, buttonPropsAndFlags, index), )} - ) + ); } } diff --git a/ui/app/components/app/gas-customization/gas-price-button-group/index.js b/ui/app/components/app/gas-customization/gas-price-button-group/index.js index 7756483303..23a9d8dd27 100644 --- a/ui/app/components/app/gas-customization/gas-price-button-group/index.js +++ b/ui/app/components/app/gas-customization/gas-price-button-group/index.js @@ -1 +1 @@ -export { default } from './gas-price-button-group.component' +export { default } from './gas-price-button-group.component'; diff --git a/ui/app/components/app/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js b/ui/app/components/app/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js index 966d4e115f..7bf35c1a82 100644 --- a/ui/app/components/app/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js +++ b/ui/app/components/app/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js @@ -1,16 +1,16 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import shallow from '../../../../../../lib/shallow-with-context' -import GasPriceButtonGroup from '../gas-price-button-group.component' -import { GAS_ESTIMATE_TYPES } from '../../../../../helpers/constants/common' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import shallow from '../../../../../../lib/shallow-with-context'; +import GasPriceButtonGroup from '../gas-price-button-group.component'; +import { GAS_ESTIMATE_TYPES } from '../../../../../helpers/constants/common'; -import ButtonGroup from '../../../../ui/button-group' +import ButtonGroup from '../../../../ui/button-group'; describe('GasPriceButtonGroup Component', function () { - let mockButtonPropsAndFlags - let mockGasPriceButtonGroupProps - let wrapper + let mockButtonPropsAndFlags; + let mockGasPriceButtonGroupProps; + let wrapper; beforeEach(function () { mockGasPriceButtonGroupProps = { @@ -43,40 +43,42 @@ describe('GasPriceButtonGroup Component', function () { noButtonActiveByDefault: true, defaultActiveButtonIndex: 2, showCheck: true, - } + }; mockButtonPropsAndFlags = { className: mockGasPriceButtonGroupProps.className, handleGasPriceSelection: mockGasPriceButtonGroupProps.handleGasPriceSelection, showCheck: mockGasPriceButtonGroupProps.showCheck, - } + }; - sinon.spy(GasPriceButtonGroup.prototype, 'renderButton') - sinon.spy(GasPriceButtonGroup.prototype, 'renderButtonContent') + sinon.spy(GasPriceButtonGroup.prototype, 'renderButton'); + sinon.spy(GasPriceButtonGroup.prototype, 'renderButtonContent'); - wrapper = shallow() - }) + wrapper = shallow( + , + ); + }); afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); describe('render', function () { it('should render a ButtonGroup', function () { - assert(wrapper.is(ButtonGroup)) - }) + assert(wrapper.is(ButtonGroup)); + }); it('should render the correct props on the ButtonGroup', function () { const { className, defaultActiveButtonIndex, noButtonActiveByDefault, - } = wrapper.props() - assert.strictEqual(className, 'gas-price-button-group') - assert.strictEqual(defaultActiveButtonIndex, 2) - assert.strictEqual(noButtonActiveByDefault, true) - }) + } = wrapper.props(); + assert.strictEqual(className, 'gas-price-button-group'); + assert.strictEqual(defaultActiveButtonIndex, 2); + assert.strictEqual(noButtonActiveByDefault, true); + }); function renderButtonArgsTest(i, mockPropsAndFlags) { assert.deepStrictEqual( @@ -86,55 +88,55 @@ describe('GasPriceButtonGroup Component', function () { mockPropsAndFlags, i, ], - ) + ); } it('should call this.renderButton 3 times, with the correct args', function () { assert.strictEqual( GasPriceButtonGroup.prototype.renderButton.callCount, 3, - ) - renderButtonArgsTest(0, mockButtonPropsAndFlags) - renderButtonArgsTest(1, mockButtonPropsAndFlags) - renderButtonArgsTest(2, mockButtonPropsAndFlags) - }) + ); + renderButtonArgsTest(0, mockButtonPropsAndFlags); + renderButtonArgsTest(1, mockButtonPropsAndFlags); + renderButtonArgsTest(2, mockButtonPropsAndFlags); + }); it('should show loading if buttonDataLoading', function () { - wrapper.setProps({ buttonDataLoading: true }) - assert(wrapper.is('div')) - assert(wrapper.hasClass('gas-price-button-group__loading-container')) - assert.strictEqual(wrapper.text(), 'loading') - }) - }) + wrapper.setProps({ buttonDataLoading: true }); + assert(wrapper.is('div')); + assert(wrapper.hasClass('gas-price-button-group__loading-container')); + assert.strictEqual(wrapper.text(), 'loading'); + }); + }); describe('renderButton', function () { - let wrappedRenderButtonResult + let wrappedRenderButtonResult; beforeEach(function () { - GasPriceButtonGroup.prototype.renderButtonContent.resetHistory() + GasPriceButtonGroup.prototype.renderButtonContent.resetHistory(); const renderButtonResult = wrapper .instance() .renderButton( { ...mockGasPriceButtonGroupProps.gasButtonInfo[0] }, mockButtonPropsAndFlags, - ) - wrappedRenderButtonResult = shallow(renderButtonResult) - }) + ); + wrappedRenderButtonResult = shallow(renderButtonResult); + }); it('should render a button', function () { - assert.strictEqual(wrappedRenderButtonResult.type(), 'button') - }) + assert.strictEqual(wrappedRenderButtonResult.type(), 'button'); + }); it('should call the correct method when clicked', function () { assert.strictEqual( mockGasPriceButtonGroupProps.handleGasPriceSelection.callCount, 0, - ) - wrappedRenderButtonResult.props().onClick() + ); + wrappedRenderButtonResult.props().onClick(); assert.strictEqual( mockGasPriceButtonGroupProps.handleGasPriceSelection.callCount, 1, - ) + ); assert.deepStrictEqual( mockGasPriceButtonGroupProps.handleGasPriceSelection.getCall(0).args, [ @@ -145,21 +147,21 @@ describe('GasPriceButtonGroup Component', function () { mockGasPriceButtonGroupProps.gasButtonInfo[0].gasEstimateType, }, ], - ) - }) + ); + }); it('should call this.renderButtonContent with the correct args', function () { assert.strictEqual( GasPriceButtonGroup.prototype.renderButtonContent.callCount, 1, - ) + ); const { feeInPrimaryCurrency, feeInSecondaryCurrency, timeEstimate, gasEstimateType, - } = mockGasPriceButtonGroupProps.gasButtonInfo[0] - const { showCheck, className } = mockGasPriceButtonGroupProps + } = mockGasPriceButtonGroupProps.gasButtonInfo[0]; + const { showCheck, className } = mockGasPriceButtonGroupProps; assert.deepStrictEqual( GasPriceButtonGroup.prototype.renderButtonContent.getCall(0).args, [ @@ -174,9 +176,9 @@ describe('GasPriceButtonGroup Component', function () { className, }, ], - ) - }) - }) + ); + }); + }); describe('renderButtonContent', function () { it('should render a label if passed a gasEstimateType', function () { @@ -187,19 +189,19 @@ describe('GasPriceButtonGroup Component', function () { { className: 'someClass', }, - ) + ); const wrappedRenderButtonContentResult = shallow( renderButtonContentResult, - ) + ); assert.strictEqual( wrappedRenderButtonContentResult.childAt(0).children().length, 1, - ) + ); assert.strictEqual( wrappedRenderButtonContentResult.find('.someClass__label').text(), 'slow', - ) - }) + ); + }); it('should render a feeInPrimaryCurrency if passed a feeInPrimaryCurrency', function () { const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent( @@ -209,21 +211,21 @@ describe('GasPriceButtonGroup Component', function () { { className: 'someClass', }, - ) + ); const wrappedRenderButtonContentResult = shallow( renderButtonContentResult, - ) + ); assert.strictEqual( wrappedRenderButtonContentResult.childAt(0).children().length, 1, - ) + ); assert.strictEqual( wrappedRenderButtonContentResult .find('.someClass__primary-currency') .text(), 'mockFeeInPrimaryCurrency', - ) - }) + ); + }); it('should render a feeInSecondaryCurrency if passed a feeInSecondaryCurrency', function () { const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent( @@ -233,21 +235,21 @@ describe('GasPriceButtonGroup Component', function () { { className: 'someClass', }, - ) + ); const wrappedRenderButtonContentResult = shallow( renderButtonContentResult, - ) + ); assert.strictEqual( wrappedRenderButtonContentResult.childAt(0).children().length, 1, - ) + ); assert.strictEqual( wrappedRenderButtonContentResult .find('.someClass__secondary-currency') .text(), 'mockFeeInSecondaryCurrency', - ) - }) + ); + }); it('should render a timeEstimate if passed a timeEstimate', function () { const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent( @@ -257,21 +259,21 @@ describe('GasPriceButtonGroup Component', function () { { className: 'someClass', }, - ) + ); const wrappedRenderButtonContentResult = shallow( renderButtonContentResult, - ) + ); assert.strictEqual( wrappedRenderButtonContentResult.childAt(0).children().length, 1, - ) + ); assert.strictEqual( wrappedRenderButtonContentResult .find('.someClass__time-estimate') .text(), 'mockTimeEstimate', - ) - }) + ); + }); it('should render a check if showCheck is true', function () { const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent( @@ -280,15 +282,15 @@ describe('GasPriceButtonGroup Component', function () { className: 'someClass', showCheck: true, }, - ) + ); const wrappedRenderButtonContentResult = shallow( renderButtonContentResult, - ) + ); assert.strictEqual( wrappedRenderButtonContentResult.find('.fa-check').length, 1, - ) - }) + ); + }); it('should render all elements if all args passed', function () { const renderButtonContentResult = wrapper.instance().renderButtonContent( @@ -302,22 +304,22 @@ describe('GasPriceButtonGroup Component', function () { className: 'someClass', showCheck: true, }, - ) + ); const wrappedRenderButtonContentResult = shallow( renderButtonContentResult, - ) - assert.strictEqual(wrappedRenderButtonContentResult.children().length, 5) - }) + ); + assert.strictEqual(wrappedRenderButtonContentResult.children().length, 5); + }); it('should render no elements if all args passed', function () { const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent( {}, {}, - ) + ); const wrappedRenderButtonContentResult = shallow( renderButtonContentResult, - ) - assert.strictEqual(wrappedRenderButtonContentResult.children().length, 0) - }) - }) -}) + ); + assert.strictEqual(wrappedRenderButtonContentResult.children().length, 0); + }); + }); +}); diff --git a/ui/app/components/app/gas-customization/gas-slider/gas-slider.component.js b/ui/app/components/app/gas-customization/gas-slider/gas-slider.component.js index db5c01b8bb..89f4dbd36d 100644 --- a/ui/app/components/app/gas-customization/gas-slider/gas-slider.component.js +++ b/ui/app/components/app/gas-customization/gas-slider/gas-slider.component.js @@ -1,5 +1,5 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; export default class GasSlider extends Component { static propTypes = { @@ -10,10 +10,10 @@ export default class GasSlider extends Component { step: PropTypes.number, max: PropTypes.number, min: PropTypes.number, - } + }; render() { - const { onChange, lowLabel, highLabel, value, step, max, min } = this.props + const { onChange, lowLabel, highLabel, value, step, max, min } = this.props; return (
    @@ -35,6 +35,6 @@ export default class GasSlider extends Component { {highLabel}
    - ) + ); } } diff --git a/ui/app/components/app/gas-customization/gas-slider/index.js b/ui/app/components/app/gas-customization/gas-slider/index.js index f1752c93f9..663e578787 100644 --- a/ui/app/components/app/gas-customization/gas-slider/index.js +++ b/ui/app/components/app/gas-customization/gas-slider/index.js @@ -1 +1 @@ -export { default } from './gas-slider.component' +export { default } from './gas-slider.component'; diff --git a/ui/app/components/app/home-notification/home-notification.component.js b/ui/app/components/app/home-notification/home-notification.component.js index 0ae4d85f99..b5186db393 100644 --- a/ui/app/components/app/home-notification/home-notification.component.js +++ b/ui/app/components/app/home-notification/home-notification.component.js @@ -1,9 +1,9 @@ -import React, { useState } from 'react' -import classnames from 'classnames' -import PropTypes from 'prop-types' -import Button from '../../ui/button' -import Checkbox from '../../ui/check-box' -import Tooltip from '../../ui/tooltip' +import React, { useState } from 'react'; +import classnames from 'classnames'; +import PropTypes from 'prop-types'; +import Button from '../../ui/button'; +import Checkbox from '../../ui/check-box'; +import Tooltip from '../../ui/tooltip'; const HomeNotification = ({ acceptText, @@ -16,7 +16,7 @@ const HomeNotification = ({ onAccept, onIgnore, }) => { - const [checkboxState, setCheckBoxState] = useState(false) + const [checkboxState, setCheckBoxState] = useState(false); const checkboxElement = checkboxText && ( setCheckBoxState((checked) => !checked)} /> - ) + ); return (
    @@ -87,8 +87,8 @@ const HomeNotification = ({ ) : null}
    - ) -} + ); +}; HomeNotification.propTypes = { acceptText: PropTypes.node, @@ -100,6 +100,6 @@ HomeNotification.propTypes = { infoText: PropTypes.node, onAccept: PropTypes.func, onIgnore: PropTypes.func, -} +}; -export default HomeNotification +export default HomeNotification; diff --git a/ui/app/components/app/home-notification/index.js b/ui/app/components/app/home-notification/index.js index 918a35be20..5068da7aaf 100644 --- a/ui/app/components/app/home-notification/index.js +++ b/ui/app/components/app/home-notification/index.js @@ -1 +1 @@ -export { default } from './home-notification.component' +export { default } from './home-notification.component'; diff --git a/ui/app/components/app/info-box/index.js b/ui/app/components/app/info-box/index.js index 59b0d294be..011ff81894 100644 --- a/ui/app/components/app/info-box/index.js +++ b/ui/app/components/app/info-box/index.js @@ -1,3 +1,3 @@ -import InfoBox from './info-box.component' +import InfoBox from './info-box.component'; -export default InfoBox +export default InfoBox; diff --git a/ui/app/components/app/info-box/info-box.component.js b/ui/app/components/app/info-box/info-box.component.js index 84e8c3b63b..8ef9dc5f3a 100644 --- a/ui/app/components/app/info-box/info-box.component.js +++ b/ui/app/components/app/info-box/info-box.component.js @@ -1,33 +1,33 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; export default class InfoBox extends Component { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { onClose: PropTypes.func, title: PropTypes.string, description: PropTypes.string, - } + }; state = { isShowing: true, - } + }; handleClose() { - const { onClose } = this.props + const { onClose } = this.props; if (onClose) { - onClose() + onClose(); } else { - this.setState({ isShowing: false }) + this.setState({ isShowing: false }); } } render() { - const { title, description } = this.props + const { title, description } = this.props; return this.state.isShowing ? (
    @@ -35,6 +35,6 @@ export default class InfoBox extends Component {
    {title}
    {description}
    - ) : null + ) : null; } } diff --git a/ui/app/components/app/info-box/tests/info-box.test.js b/ui/app/components/app/info-box/tests/info-box.test.js index 82f019e01c..04c5056d5e 100644 --- a/ui/app/components/app/info-box/tests/info-box.test.js +++ b/ui/app/components/app/info-box/tests/info-box.test.js @@ -1,36 +1,36 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import { shallow } from 'enzyme' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import { shallow } from 'enzyme'; -import InfoBox from '..' +import InfoBox from '..'; describe('InfoBox', function () { - let wrapper + let wrapper; const props = { title: 'Title', description: 'Description', onClose: sinon.spy(), - } + }; beforeEach(function () { - wrapper = shallow() - }) + wrapper = shallow(); + }); it('renders title from props', function () { - const title = wrapper.find('.info-box__title') - assert.strictEqual(title.text(), props.title) - }) + const title = wrapper.find('.info-box__title'); + assert.strictEqual(title.text(), props.title); + }); it('renders description from props', function () { - const description = wrapper.find('.info-box__description') - assert.strictEqual(description.text(), props.description) - }) + const description = wrapper.find('.info-box__description'); + assert.strictEqual(description.text(), props.description); + }); it('closes info box', function () { - const close = wrapper.find('.info-box__close') - close.simulate('click') - assert(props.onClose.calledOnce) - }) -}) + const close = wrapper.find('.info-box__close'); + close.simulate('click'); + assert(props.onClose.calledOnce); + }); +}); diff --git a/ui/app/components/app/loading-network-screen/index.js b/ui/app/components/app/loading-network-screen/index.js index 726b4b530f..092184496d 100644 --- a/ui/app/components/app/loading-network-screen/index.js +++ b/ui/app/components/app/loading-network-screen/index.js @@ -1 +1 @@ -export { default } from './loading-network-screen.container' +export { default } from './loading-network-screen.container'; diff --git a/ui/app/components/app/loading-network-screen/loading-network-screen.component.js b/ui/app/components/app/loading-network-screen/loading-network-screen.component.js index 3f3def230c..0419aed42a 100644 --- a/ui/app/components/app/loading-network-screen/loading-network-screen.component.js +++ b/ui/app/components/app/loading-network-screen/loading-network-screen.component.js @@ -1,16 +1,16 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import Button from '../../ui/button' -import LoadingScreen from '../../ui/loading-screen' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import Button from '../../ui/button'; +import LoadingScreen from '../../ui/loading-screen'; export default class LoadingNetworkScreen extends PureComponent { state = { showErrorScreen: false, - } + }; static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { loadingMessage: PropTypes.string, @@ -22,43 +22,47 @@ export default class LoadingNetworkScreen extends PureComponent { setProviderType: PropTypes.func, rollbackToPreviousProvider: PropTypes.func, isLoadingNetwork: PropTypes.bool, - } + }; componentDidMount = () => { this.cancelCallTimeout = setTimeout( this.cancelCall, this.props.cancelTime || 15000, - ) - } + ); + }; getConnectingLabel = function (loadingMessage) { if (loadingMessage) { - return loadingMessage + return loadingMessage; } - const { provider, providerId } = this.props - const providerName = provider.type + const { provider, providerId } = this.props; + const providerName = provider.type; - let name + let name; if (providerName === 'mainnet') { - name = this.context.t('connectingToMainnet') + name = this.context.t('connectingToMainnet'); } else if (providerName === 'ropsten') { - name = this.context.t('connectingToRopsten') + name = this.context.t('connectingToRopsten'); } else if (providerName === 'kovan') { - name = this.context.t('connectingToKovan') + name = this.context.t('connectingToKovan'); } else if (providerName === 'rinkeby') { - name = this.context.t('connectingToRinkeby') + name = this.context.t('connectingToRinkeby'); } else if (providerName === 'goerli') { - name = this.context.t('connectingToGoerli') + name = this.context.t('connectingToGoerli'); } else { - name = this.context.t('connectingTo', [providerId]) + name = this.context.t('connectingTo', [providerId]); } - return name - } + return name; + }; renderErrorScreenContent = () => { - const { showNetworkDropdown, setProviderArgs, setProviderType } = this.props + const { + showNetworkDropdown, + setProviderArgs, + setProviderType, + } = this.props; return (
    @@ -68,8 +72,8 @@ export default class LoadingNetworkScreen extends PureComponent {
    - ) - } + ); + }; cancelCall = () => { - const { isLoadingNetwork } = this.props + const { isLoadingNetwork } = this.props; if (isLoadingNetwork) { - this.setState({ showErrorScreen: true }) + this.setState({ showErrorScreen: true }); } - } + }; componentDidUpdate = (prevProps) => { - const { provider } = this.props - const { provider: prevProvider } = prevProps + const { provider } = this.props; + const { provider: prevProvider } = prevProps; if (provider.type !== prevProvider.type) { - window.clearTimeout(this.cancelCallTimeout) - this.setState({ showErrorScreen: false }) + window.clearTimeout(this.cancelCallTimeout); + this.setState({ showErrorScreen: false }); this.cancelCallTimeout = setTimeout( this.cancelCall, this.props.cancelTime || 15000, - ) + ); } - } + }; componentWillUnmount = () => { - window.clearTimeout(this.cancelCallTimeout) - } + window.clearTimeout(this.cancelCallTimeout); + }; render() { - const { rollbackToPreviousProvider } = this.props + const { rollbackToPreviousProvider } = this.props; return ( - ) + ); } } diff --git a/ui/app/components/app/loading-network-screen/loading-network-screen.container.js b/ui/app/components/app/loading-network-screen/loading-network-screen.container.js index 9dbb96b852..5ebddae61a 100644 --- a/ui/app/components/app/loading-network-screen/loading-network-screen.container.js +++ b/ui/app/components/app/loading-network-screen/loading-network-screen.container.js @@ -1,18 +1,18 @@ -import { connect } from 'react-redux' -import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network' -import * as actions from '../../../store/actions' -import { getNetworkIdentifier } from '../../../selectors' -import LoadingNetworkScreen from './loading-network-screen.component' +import { connect } from 'react-redux'; +import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network'; +import * as actions from '../../../store/actions'; +import { getNetworkIdentifier } from '../../../selectors'; +import LoadingNetworkScreen from './loading-network-screen.component'; const mapStateToProps = (state) => { - const { loadingMessage } = state.appState - const { provider, network } = state.metamask - const { rpcUrl, chainId, ticker, nickname, type } = provider + const { loadingMessage } = state.appState; + const { provider, network } = state.metamask; + const { rpcUrl, chainId, ticker, nickname, type } = provider; const setProviderArgs = type === NETWORK_TYPE_RPC ? [rpcUrl, chainId, ticker, nickname] - : [provider.type] + : [provider.type]; return { isLoadingNetwork: network === 'loading', @@ -20,21 +20,21 @@ const mapStateToProps = (state) => { setProviderArgs, provider, providerId: getNetworkIdentifier(state), - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { setProviderType: (type) => { - dispatch(actions.setProviderType(type)) + dispatch(actions.setProviderType(type)); }, rollbackToPreviousProvider: () => dispatch(actions.rollbackToPreviousProvider()), showNetworkDropdown: () => dispatch(actions.showNetworkDropdown()), - } -} + }; +}; export default connect( mapStateToProps, mapDispatchToProps, -)(LoadingNetworkScreen) +)(LoadingNetworkScreen); diff --git a/ui/app/components/app/menu-bar/account-options-menu.js b/ui/app/components/app/menu-bar/account-options-menu.js index d3c9723e72..8d11bb0579 100644 --- a/ui/app/components/app/menu-bar/account-options-menu.js +++ b/ui/app/components/app/menu-bar/account-options-menu.js @@ -1,63 +1,63 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { useHistory } from 'react-router-dom' -import { useDispatch, useSelector } from 'react-redux' +import React from 'react'; +import PropTypes from 'prop-types'; +import { useHistory } from 'react-router-dom'; +import { useDispatch, useSelector } from 'react-redux'; -import { showModal } from '../../../store/actions' -import { CONNECTED_ROUTE } from '../../../helpers/constants/routes' -import { Menu, MenuItem } from '../../ui/menu' -import getAccountLink from '../../../../lib/account-link' +import { showModal } from '../../../store/actions'; +import { CONNECTED_ROUTE } from '../../../helpers/constants/routes'; +import { Menu, MenuItem } from '../../ui/menu'; +import getAccountLink from '../../../../lib/account-link'; import { getCurrentKeyring, getCurrentNetwork, getRpcPrefsForCurrentProvider, getSelectedIdentity, -} from '../../../selectors' -import { useI18nContext } from '../../../hooks/useI18nContext' -import { useMetricEvent } from '../../../hooks/useMetricEvent' -import { getEnvironmentType } from '../../../../../app/scripts/lib/util' -import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../../shared/constants/app' +} from '../../../selectors'; +import { useI18nContext } from '../../../hooks/useI18nContext'; +import { useMetricEvent } from '../../../hooks/useMetricEvent'; +import { getEnvironmentType } from '../../../../../app/scripts/lib/util'; +import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../../shared/constants/app'; export default function AccountOptionsMenu({ anchorElement, onClose }) { - const t = useI18nContext() - const dispatch = useDispatch() - const history = useHistory() + const t = useI18nContext(); + const dispatch = useDispatch(); + const history = useHistory(); const openFullscreenEvent = useMetricEvent({ eventOpts: { category: 'Navigation', action: 'Account Options', name: 'Clicked Expand View', }, - }) + }); const viewAccountDetailsEvent = useMetricEvent({ eventOpts: { category: 'Navigation', action: 'Account Options', name: 'Viewed Account Details', }, - }) + }); const viewOnEtherscanEvent = useMetricEvent({ eventOpts: { category: 'Navigation', action: 'Account Options', name: 'Clicked View on Etherscan', }, - }) + }); const openConnectedSitesEvent = useMetricEvent({ eventOpts: { category: 'Navigation', action: 'Account Options', name: 'Opened Connected Sites', }, - }) + }); - const keyring = useSelector(getCurrentKeyring) - const network = useSelector(getCurrentNetwork) - const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider) - const selectedIdentity = useSelector(getSelectedIdentity) + const keyring = useSelector(getCurrentKeyring); + const network = useSelector(getCurrentNetwork); + const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider); + const selectedIdentity = useSelector(getSelectedIdentity); - const { address } = selectedIdentity - const isRemovable = keyring.type !== 'HD Key Tree' + const { address } = selectedIdentity; + const isRemovable = keyring.type !== 'HD Key Tree'; return ( { - openFullscreenEvent() - global.platform.openExtensionInBrowser() - onClose() + openFullscreenEvent(); + global.platform.openExtensionInBrowser(); + onClose(); }} iconClassName="fas fa-expand-alt" > @@ -80,9 +80,9 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { { - dispatch(showModal({ name: 'ACCOUNT_DETAILS' })) - viewAccountDetailsEvent() - onClose() + dispatch(showModal({ name: 'ACCOUNT_DETAILS' })); + viewAccountDetailsEvent(); + onClose(); }} iconClassName="fas fa-qrcode" > @@ -90,11 +90,11 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { { - viewOnEtherscanEvent() + viewOnEtherscanEvent(); global.platform.openTab({ url: getAccountLink(address, network, rpcPrefs), - }) - onClose() + }); + onClose(); }} subtitle={ rpcPrefs.blockExplorerUrl ? ( @@ -110,9 +110,9 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { { - openConnectedSitesEvent() - history.push(CONNECTED_ROUTE) - onClose() + openConnectedSitesEvent(); + history.push(CONNECTED_ROUTE); + onClose(); }} iconClassName="account-options-menu__connected-sites" > @@ -127,8 +127,8 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { name: 'CONFIRM_REMOVE_ACCOUNT', identity: selectedIdentity, }), - ) - onClose() + ); + onClose(); }} iconClassName="fas fa-trash-alt" > @@ -136,14 +136,14 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { ) : null} - ) + ); } AccountOptionsMenu.propTypes = { anchorElement: PropTypes.instanceOf(window.Element), onClose: PropTypes.func.isRequired, -} +}; AccountOptionsMenu.defaultProps = { anchorElement: undefined, -} +}; diff --git a/ui/app/components/app/menu-bar/index.js b/ui/app/components/app/menu-bar/index.js index 19db09e191..7bc7913f9e 100644 --- a/ui/app/components/app/menu-bar/index.js +++ b/ui/app/components/app/menu-bar/index.js @@ -1 +1 @@ -export { default } from './menu-bar' +export { default } from './menu-bar'; diff --git a/ui/app/components/app/menu-bar/menu-bar.js b/ui/app/components/app/menu-bar/menu-bar.js index f6c70a43e5..7b623c2c6a 100644 --- a/ui/app/components/app/menu-bar/menu-bar.js +++ b/ui/app/components/app/menu-bar/menu-bar.js @@ -1,38 +1,38 @@ -import React, { useState } from 'react' -import extension from 'extensionizer' -import { useHistory } from 'react-router-dom' -import { useSelector } from 'react-redux' -import SelectedAccount from '../selected-account' -import ConnectedStatusIndicator from '../connected-status-indicator' -import { getEnvironmentType } from '../../../../../app/scripts/lib/util' -import { ENVIRONMENT_TYPE_POPUP } from '../../../../../shared/constants/app' -import { CONNECTED_ACCOUNTS_ROUTE } from '../../../helpers/constants/routes' -import { useI18nContext } from '../../../hooks/useI18nContext' -import { useMetricEvent } from '../../../hooks/useMetricEvent' -import { getOriginOfCurrentTab } from '../../../selectors' -import AccountOptionsMenu from './account-options-menu' +import React, { useState } from 'react'; +import extension from 'extensionizer'; +import { useHistory } from 'react-router-dom'; +import { useSelector } from 'react-redux'; +import SelectedAccount from '../selected-account'; +import ConnectedStatusIndicator from '../connected-status-indicator'; +import { getEnvironmentType } from '../../../../../app/scripts/lib/util'; +import { ENVIRONMENT_TYPE_POPUP } from '../../../../../shared/constants/app'; +import { CONNECTED_ACCOUNTS_ROUTE } from '../../../helpers/constants/routes'; +import { useI18nContext } from '../../../hooks/useI18nContext'; +import { useMetricEvent } from '../../../hooks/useMetricEvent'; +import { getOriginOfCurrentTab } from '../../../selectors'; +import AccountOptionsMenu from './account-options-menu'; export default function MenuBar() { - const t = useI18nContext() + const t = useI18nContext(); const openAccountOptionsEvent = useMetricEvent({ eventOpts: { category: 'Navigation', action: 'Home', name: 'Opened Account Options', }, - }) - const history = useHistory() + }); + const history = useHistory(); const [ accountOptionsButtonElement, setAccountOptionsButtonElement, - ] = useState(null) - const [accountOptionsMenuOpen, setAccountOptionsMenuOpen] = useState(false) - const origin = useSelector(getOriginOfCurrentTab) + ] = useState(null); + const [accountOptionsMenuOpen, setAccountOptionsMenuOpen] = useState(false); + const origin = useSelector(getOriginOfCurrentTab); const showStatus = getEnvironmentType() === ENVIRONMENT_TYPE_POPUP && origin && - origin !== extension.runtime.id + origin !== extension.runtime.id; return (
    @@ -50,8 +50,8 @@ export default function MenuBar() { ref={setAccountOptionsButtonElement} title={t('accountOptions')} onClick={() => { - openAccountOptionsEvent() - setAccountOptionsMenuOpen(true) + openAccountOptionsEvent(); + setAccountOptionsMenuOpen(true); }} /> @@ -62,5 +62,5 @@ export default function MenuBar() { /> )}
    - ) + ); } diff --git a/ui/app/components/app/menu-bar/tests/menu-bar.test.js b/ui/app/components/app/menu-bar/tests/menu-bar.test.js index 9df845409c..4960ef6274 100644 --- a/ui/app/components/app/menu-bar/tests/menu-bar.test.js +++ b/ui/app/components/app/menu-bar/tests/menu-bar.test.js @@ -1,9 +1,9 @@ -import assert from 'assert' -import React from 'react' -import { Provider } from 'react-redux' -import configureStore from 'redux-mock-store' -import { mountWithRouter } from '../../../../../../test/lib/render-helpers' -import MenuBar from '..' +import assert from 'assert'; +import React from 'react'; +import { Provider } from 'react-redux'; +import configureStore from 'redux-mock-store'; +import { mountWithRouter } from '../../../../../../test/lib/render-helpers'; +import MenuBar from '..'; const initState = { activeTab: {}, @@ -24,38 +24,38 @@ const initState = { ], frequentRpcListDetail: [], }, -} -const mockStore = configureStore() +}; +const mockStore = configureStore(); describe('MenuBar', function () { it('opens account detail menu when account options is clicked', function () { - const store = mockStore(initState) + const store = mockStore(initState); const wrapper = mountWithRouter( , - ) - assert.ok(!wrapper.exists('AccountOptionsMenu')) - const accountOptions = wrapper.find('.menu-bar__account-options') - accountOptions.simulate('click') - wrapper.update() - assert.ok(wrapper.exists('AccountOptionsMenu')) - }) + ); + assert.ok(!wrapper.exists('AccountOptionsMenu')); + const accountOptions = wrapper.find('.menu-bar__account-options'); + accountOptions.simulate('click'); + wrapper.update(); + assert.ok(wrapper.exists('AccountOptionsMenu')); + }); it('sets accountDetailsMenuOpen to false when closed', function () { - const store = mockStore(initState) + const store = mockStore(initState); const wrapper = mountWithRouter( , - ) - const accountOptions = wrapper.find('.menu-bar__account-options') - accountOptions.simulate('click') - wrapper.update() - assert.ok(wrapper.exists('AccountOptionsMenu')) - const accountDetailsMenu = wrapper.find('AccountOptionsMenu') - accountDetailsMenu.prop('onClose')() - wrapper.update() - assert.ok(!wrapper.exists('AccountOptionsMenu')) - }) -}) + ); + const accountOptions = wrapper.find('.menu-bar__account-options'); + accountOptions.simulate('click'); + wrapper.update(); + assert.ok(wrapper.exists('AccountOptionsMenu')); + const accountDetailsMenu = wrapper.find('AccountOptionsMenu'); + accountDetailsMenu.prop('onClose')(); + wrapper.update(); + assert.ok(!wrapper.exists('AccountOptionsMenu')); + }); +}); diff --git a/ui/app/components/app/menu-droppo.js b/ui/app/components/app/menu-droppo.js index d9895ec615..6888d5d681 100644 --- a/ui/app/components/app/menu-droppo.js +++ b/ui/app/components/app/menu-droppo.js @@ -1,7 +1,7 @@ -import PropTypes from 'prop-types' -import React, { Component } from 'react' -import { findDOMNode } from 'react-dom' -import ReactCSSTransitionGroup from 'react-transition-group/CSSTransitionGroup' +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import { findDOMNode } from 'react-dom'; +import ReactCSSTransitionGroup from 'react-transition-group/CSSTransitionGroup'; export default class MenuDroppoComponent extends Component { static propTypes = { @@ -14,27 +14,27 @@ export default class MenuDroppoComponent extends Component { style: PropTypes.object.isRequired, useCssTransition: PropTypes.bool, speed: PropTypes.string, - } + }; renderPrimary() { - const { isOpen } = this.props + const { isOpen } = this.props; if (!isOpen) { - return null + return null; } - const innerStyle = this.props.innerStyle || {} + const innerStyle = this.props.innerStyle || {}; return (
    {this.props.children}
    - ) + ); } globalClickOccurred = (event) => { - const { target } = event + const { target } = event; // eslint-disable-next-line react/no-find-dom-node - const container = findDOMNode(this) + const container = findDOMNode(this); if ( this.props.isOpen && @@ -42,36 +42,36 @@ export default class MenuDroppoComponent extends Component { !isDescendant(this.container, event.target) && this.props.onClickOutside ) { - this.props.onClickOutside(event) + this.props.onClickOutside(event); } - } + }; componentDidMount() { if (this && document.body) { - document.body.addEventListener('click', this.globalClickOccurred) + document.body.addEventListener('click', this.globalClickOccurred); // eslint-disable-next-line react/no-find-dom-node - const container = findDOMNode(this) - this.container = container + const container = findDOMNode(this); + this.container = container; } } componentWillUnmount() { if (this && document.body) { - document.body.removeEventListener('click', this.globalClickOccurred) + document.body.removeEventListener('click', this.globalClickOccurred); } } render() { - const { containerClassName = '', style } = this.props - const speed = this.props.speed || '300ms' - const { useCssTransition } = this.props - const zIndex = 'zIndex' in this.props ? this.props.zIndex : 0 + const { containerClassName = '', style } = this.props; + const speed = this.props.speed || '300ms'; + const { useCssTransition } = this.props; + const zIndex = 'zIndex' in this.props ? this.props.zIndex : 0; const baseStyle = { position: 'fixed', ...style, zIndex, - } + }; return (
    - ) + ); } } function isDescendant(parent, child) { - let node = child.parentNode + let node = child.parentNode; while (node !== null) { if (node === parent) { - return true + return true; } - node = node.parentNode + node = node.parentNode; } - return false + return false; } diff --git a/ui/app/components/app/metamask-template-renderer/index.js b/ui/app/components/app/metamask-template-renderer/index.js index b8028d2ce2..ed838c0c44 100644 --- a/ui/app/components/app/metamask-template-renderer/index.js +++ b/ui/app/components/app/metamask-template-renderer/index.js @@ -1 +1 @@ -export { default } from './metamask-template-renderer' +export { default } from './metamask-template-renderer'; diff --git a/ui/app/components/app/metamask-template-renderer/metamask-template-renderer.js b/ui/app/components/app/metamask-template-renderer/metamask-template-renderer.js index a4af965339..30e4b6b30d 100644 --- a/ui/app/components/app/metamask-template-renderer/metamask-template-renderer.js +++ b/ui/app/components/app/metamask-template-renderer/metamask-template-renderer.js @@ -1,33 +1,33 @@ -import React, { memo } from 'react' -import PropTypes from 'prop-types' -import { isEqual } from 'lodash' -import { safeComponentList } from './safe-component-list' +import React, { memo } from 'react'; +import PropTypes from 'prop-types'; +import { isEqual } from 'lodash'; +import { safeComponentList } from './safe-component-list'; function getElement(section) { - const { element } = section - const Element = safeComponentList[element] + const { element } = section; + const Element = safeComponentList[element]; if (!Element) { throw new Error( `${element} is not in the safe component list for MetaMask template renderer`, - ) + ); } - return Element + return Element; } const MetaMaskTemplateRenderer = ({ sections }) => { if (!sections) { // If sections is null eject early by returning null - return null + return null; } else if (typeof sections === 'string') { // React can render strings directly, so return the string - return sections + return sections; } else if ( sections && typeof sections === 'object' && !Array.isArray(sections) ) { // If dealing with a single entry, then render a single object without key - const Element = getElement(sections) + const Element = getElement(sections); return ( {typeof sections.children === 'object' ? ( @@ -36,7 +36,7 @@ const MetaMaskTemplateRenderer = ({ sections }) => { sections?.children )} - ) + ); } // The last case is dealing with an array of objects @@ -45,7 +45,7 @@ const MetaMaskTemplateRenderer = ({ sections }) => { {sections.reduce((allChildren, child) => { if (typeof child === 'string') { // React can render strings directly, so push them into the accumulator - allChildren.push(child) + allChildren.push(child); } else { // If the entry in array is not a string, then it must be a Section. // Sections are handled by the main function, but must @@ -53,35 +53,35 @@ const MetaMaskTemplateRenderer = ({ sections }) => { if (!child.key) { throw new Error( 'When using array syntax in MetaMask Template Language, you must specify a key for each child of the array', - ) + ); } if (typeof child?.children === 'object') { // If this child has its own children, check if children is an // object, and in that case use recursion to render. allChildren.push( , - ) + ); } else { // Otherwise render the element. - const Element = getElement(child) + const Element = getElement(child); allChildren.push( {child?.children} , - ) + ); } } - return allChildren + return allChildren; }, [])} - ) -} + ); +}; const SectionShape = { props: PropTypes.object, element: PropTypes.oneOf(Object.keys(safeComponentList)).isRequired, key: PropTypes.string, -} +}; const ValidChildren = PropTypes.oneOfType([ PropTypes.string, @@ -89,14 +89,14 @@ const ValidChildren = PropTypes.oneOfType([ PropTypes.arrayOf( PropTypes.oneOfType([PropTypes.shape(SectionShape), PropTypes.string]), ), -]) +]); -SectionShape.children = ValidChildren +SectionShape.children = ValidChildren; MetaMaskTemplateRenderer.propTypes = { sections: ValidChildren, -} +}; export default memo(MetaMaskTemplateRenderer, (prevProps, nextProps) => { - return isEqual(prevProps.sections, nextProps.sections) -}) + return isEqual(prevProps.sections, nextProps.sections); +}); diff --git a/ui/app/components/app/metamask-template-renderer/metamask-template-renderer.stories.js b/ui/app/components/app/metamask-template-renderer/metamask-template-renderer.stories.js index b0c4dc1a5a..5ad8aa4eec 100644 --- a/ui/app/components/app/metamask-template-renderer/metamask-template-renderer.stories.js +++ b/ui/app/components/app/metamask-template-renderer/metamask-template-renderer.stories.js @@ -1,11 +1,11 @@ -import React from 'react' -import { object } from '@storybook/addon-knobs' -import { COLORS, TYPOGRAPHY } from '../../../helpers/constants/design-system' -import MetaMaskTemplateRenderer from '.' +import React from 'react'; +import { object } from '@storybook/addon-knobs'; +import { COLORS, TYPOGRAPHY } from '../../../helpers/constants/design-system'; +import MetaMaskTemplateRenderer from '.'; export default { title: 'MetaMask Template Renderer', -} +}; const SECTIONS = { element: 'Box', @@ -83,10 +83,10 @@ const SECTIONS = { props: { justifyContent: 'space-between', padding: [0, 4] }, }, ], -} +}; export const metaMaskTemplateRenderer = () => ( -) +); export const withInvalidElement = () => ( ( }, ])} /> -) +); diff --git a/ui/app/components/app/metamask-template-renderer/safe-component-list.js b/ui/app/components/app/metamask-template-renderer/safe-component-list.js index fea24c2568..9e8c22991a 100644 --- a/ui/app/components/app/metamask-template-renderer/safe-component-list.js +++ b/ui/app/components/app/metamask-template-renderer/safe-component-list.js @@ -1,10 +1,10 @@ -import Button from '../../ui/button' -import Chip from '../../ui/chip' -import DefinitionList from '../../ui/definition-list' -import TruncatedDefinitionList from '../../ui/truncated-definition-list' -import Popover from '../../ui/popover' -import Typography from '../../ui/typography' -import Box from '../../ui/box' +import Button from '../../ui/button'; +import Chip from '../../ui/chip'; +import DefinitionList from '../../ui/definition-list'; +import TruncatedDefinitionList from '../../ui/truncated-definition-list'; +import Popover from '../../ui/popover'; +import Typography from '../../ui/typography'; +import Box from '../../ui/box'; export const safeComponentList = { b: 'b', @@ -18,4 +18,4 @@ export const safeComponentList = { Button, Popover, Box, -} +}; diff --git a/ui/app/components/app/modal/index.js b/ui/app/components/app/modal/index.js index 58309abbed..18c5905f4d 100644 --- a/ui/app/components/app/modal/index.js +++ b/ui/app/components/app/modal/index.js @@ -1,2 +1,2 @@ -export { default } from './modal.component' -export { default as ModalContent } from './modal-content' +export { default } from './modal.component'; +export { default as ModalContent } from './modal-content'; diff --git a/ui/app/components/app/modal/modal-content/index.js b/ui/app/components/app/modal/modal-content/index.js index 733cfb3b84..655fbb7977 100644 --- a/ui/app/components/app/modal/modal-content/index.js +++ b/ui/app/components/app/modal/modal-content/index.js @@ -1 +1 @@ -export { default } from './modal-content.component' +export { default } from './modal-content.component'; diff --git a/ui/app/components/app/modal/modal-content/modal-content.component.js b/ui/app/components/app/modal/modal-content/modal-content.component.js index 8f011e18f7..99f57bc036 100644 --- a/ui/app/components/app/modal/modal-content/modal-content.component.js +++ b/ui/app/components/app/modal/modal-content/modal-content.component.js @@ -1,14 +1,14 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; export default class ModalContent extends PureComponent { static propTypes = { title: PropTypes.string, description: PropTypes.string, - } + }; render() { - const { title, description } = this.props + const { title, description } = this.props; return (
    @@ -17,6 +17,6 @@ export default class ModalContent extends PureComponent {
    {description}
    )}
    - ) + ); } } diff --git a/ui/app/components/app/modal/modal-content/tests/modal-content.component.test.js b/ui/app/components/app/modal/modal-content/tests/modal-content.component.test.js index 8056563f60..485b2f9512 100644 --- a/ui/app/components/app/modal/modal-content/tests/modal-content.component.test.js +++ b/ui/app/components/app/modal/modal-content/tests/modal-content.component.test.js @@ -1,45 +1,45 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import ModalContent from '../modal-content.component' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import ModalContent from '../modal-content.component'; describe('ModalContent Component', function () { it('should render a title', function () { - const wrapper = shallow() + const wrapper = shallow(); - assert.strictEqual(wrapper.find('.modal-content__title').length, 1) + assert.strictEqual(wrapper.find('.modal-content__title').length, 1); assert.strictEqual( wrapper.find('.modal-content__title').text(), 'Modal Title', - ) - assert.strictEqual(wrapper.find('.modal-content__description').length, 0) - }) + ); + assert.strictEqual(wrapper.find('.modal-content__description').length, 0); + }); it('should render a description', function () { - const wrapper = shallow() + const wrapper = shallow(); - assert.strictEqual(wrapper.find('.modal-content__title').length, 0) - assert.strictEqual(wrapper.find('.modal-content__description').length, 1) + assert.strictEqual(wrapper.find('.modal-content__title').length, 0); + assert.strictEqual(wrapper.find('.modal-content__description').length, 1); assert.strictEqual( wrapper.find('.modal-content__description').text(), 'Modal Description', - ) - }) + ); + }); it('should render both a title and a description', function () { const wrapper = shallow( , - ) + ); - assert.strictEqual(wrapper.find('.modal-content__title').length, 1) + assert.strictEqual(wrapper.find('.modal-content__title').length, 1); assert.strictEqual( wrapper.find('.modal-content__title').text(), 'Modal Title', - ) - assert.strictEqual(wrapper.find('.modal-content__description').length, 1) + ); + assert.strictEqual(wrapper.find('.modal-content__description').length, 1); assert.strictEqual( wrapper.find('.modal-content__description').text(), 'Modal Description', - ) - }) -}) + ); + }); +}); diff --git a/ui/app/components/app/modal/modal.component.js b/ui/app/components/app/modal/modal.component.js index 57137270ca..89b8146104 100644 --- a/ui/app/components/app/modal/modal.component.js +++ b/ui/app/components/app/modal/modal.component.js @@ -1,7 +1,7 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import Button from '../../ui/button' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import Button from '../../ui/button'; export default class Modal extends PureComponent { static propTypes = { @@ -21,12 +21,12 @@ export default class Modal extends PureComponent { onCancel: PropTypes.func, cancelType: PropTypes.string, cancelText: PropTypes.string, - } + }; static defaultProps = { submitType: 'secondary', cancelType: 'default', - } + }; render() { const { @@ -43,7 +43,7 @@ export default class Modal extends PureComponent { contentClass, containerClass, hideFooter, - } = this.props + } = this.props; return (
    @@ -78,6 +78,6 @@ export default class Modal extends PureComponent {
    )}
    - ) + ); } } diff --git a/ui/app/components/app/modal/tests/modal.component.test.js b/ui/app/components/app/modal/tests/modal.component.test.js index a0ad195aeb..8af9d394b5 100644 --- a/ui/app/components/app/modal/tests/modal.component.test.js +++ b/ui/app/components/app/modal/tests/modal.component.test.js @@ -1,23 +1,23 @@ -import assert from 'assert' -import React from 'react' -import { mount, shallow } from 'enzyme' -import sinon from 'sinon' -import Modal from '../modal.component' -import Button from '../../../ui/button' +import assert from 'assert'; +import React from 'react'; +import { mount, shallow } from 'enzyme'; +import sinon from 'sinon'; +import Modal from '../modal.component'; +import Button from '../../../ui/button'; describe('Modal Component', function () { it('should render a modal with a submit button', function () { - const wrapper = shallow() + const wrapper = shallow(); - assert.strictEqual(wrapper.find('.modal-container').length, 1) - const buttons = wrapper.find(Button) - assert.strictEqual(buttons.length, 1) - assert.strictEqual(buttons.at(0).props().type, 'secondary') - }) + assert.strictEqual(wrapper.find('.modal-container').length, 1); + const buttons = wrapper.find(Button); + assert.strictEqual(buttons.length, 1); + assert.strictEqual(buttons.at(0).props().type, 'secondary'); + }); it('should render a modal with a cancel and a submit button', function () { - const handleCancel = sinon.spy() - const handleSubmit = sinon.spy() + const handleCancel = sinon.spy(); + const handleSubmit = sinon.spy(); const wrapper = shallow( , - ) - - const buttons = wrapper.find(Button) - assert.strictEqual(buttons.length, 2) - const cancelButton = buttons.at(0) - const submitButton = buttons.at(1) - - assert.strictEqual(cancelButton.props().type, 'default') - assert.strictEqual(cancelButton.props().children, 'Cancel') - assert.strictEqual(handleCancel.callCount, 0) - cancelButton.simulate('click') - assert.strictEqual(handleCancel.callCount, 1) - - assert.strictEqual(submitButton.props().type, 'secondary') - assert.strictEqual(submitButton.props().children, 'Submit') - assert.strictEqual(handleSubmit.callCount, 0) - submitButton.simulate('click') - assert.strictEqual(handleSubmit.callCount, 1) - }) + ); + + const buttons = wrapper.find(Button); + assert.strictEqual(buttons.length, 2); + const cancelButton = buttons.at(0); + const submitButton = buttons.at(1); + + assert.strictEqual(cancelButton.props().type, 'default'); + assert.strictEqual(cancelButton.props().children, 'Cancel'); + assert.strictEqual(handleCancel.callCount, 0); + cancelButton.simulate('click'); + assert.strictEqual(handleCancel.callCount, 1); + + assert.strictEqual(submitButton.props().type, 'secondary'); + assert.strictEqual(submitButton.props().children, 'Submit'); + assert.strictEqual(handleSubmit.callCount, 0); + submitButton.simulate('click'); + assert.strictEqual(handleSubmit.callCount, 1); + }); it('should render a modal with different button types', function () { const wrapper = shallow( @@ -55,13 +55,13 @@ describe('Modal Component', function () { submitText="Submit" submitType="confirm" />, - ) + ); - const buttons = wrapper.find(Button) - assert.strictEqual(buttons.length, 2) - assert.strictEqual(buttons.at(0).props().type, 'secondary') - assert.strictEqual(buttons.at(1).props().type, 'confirm') - }) + const buttons = wrapper.find(Button); + assert.strictEqual(buttons.length, 2); + assert.strictEqual(buttons.at(0).props().type, 'secondary'); + assert.strictEqual(buttons.at(1).props().type, 'confirm'); + }); it('should render a modal with children', function () { const wrapper = shallow( @@ -73,14 +73,14 @@ describe('Modal Component', function () { >
    , - ) + ); - assert.ok(wrapper.find('.test-class')) - }) + assert.ok(wrapper.find('.test-class')); + }); it('should render a modal with a header', function () { - const handleCancel = sinon.spy() - const handleSubmit = sinon.spy() + const handleCancel = sinon.spy(); + const handleSubmit = sinon.spy(); const wrapper = shallow( , - ) + ); - assert.ok(wrapper.find('.modal-container__header')) + assert.ok(wrapper.find('.modal-container__header')); assert.strictEqual( wrapper.find('.modal-container__header-text').text(), 'My Header', - ) - assert.strictEqual(handleCancel.callCount, 0) - assert.strictEqual(handleSubmit.callCount, 0) - wrapper.find('.modal-container__header-close').simulate('click') - assert.strictEqual(handleCancel.callCount, 1) - assert.strictEqual(handleSubmit.callCount, 0) - }) + ); + assert.strictEqual(handleCancel.callCount, 0); + assert.strictEqual(handleSubmit.callCount, 0); + wrapper.find('.modal-container__header-close').simulate('click'); + assert.strictEqual(handleCancel.callCount, 1); + assert.strictEqual(handleSubmit.callCount, 0); + }); it('should disable the submit button if submitDisabled is true', function () { - const handleCancel = sinon.spy() - const handleSubmit = sinon.spy() + const handleCancel = sinon.spy(); + const handleSubmit = sinon.spy(); const wrapper = mount( , - ) - - const buttons = wrapper.find(Button) - assert.strictEqual(buttons.length, 2) - const cancelButton = buttons.at(0) - const submitButton = buttons.at(1) - - assert.strictEqual(handleCancel.callCount, 0) - cancelButton.simulate('click') - assert.strictEqual(handleCancel.callCount, 1) - - assert.strictEqual(submitButton.props().disabled, true) - assert.strictEqual(handleSubmit.callCount, 0) - submitButton.simulate('click') - assert.strictEqual(handleSubmit.callCount, 0) - }) -}) + ); + + const buttons = wrapper.find(Button); + assert.strictEqual(buttons.length, 2); + const cancelButton = buttons.at(0); + const submitButton = buttons.at(1); + + assert.strictEqual(handleCancel.callCount, 0); + cancelButton.simulate('click'); + assert.strictEqual(handleCancel.callCount, 1); + + assert.strictEqual(submitButton.props().disabled, true); + assert.strictEqual(handleSubmit.callCount, 0); + submitButton.simulate('click'); + assert.strictEqual(handleSubmit.callCount, 0); + }); +}); diff --git a/ui/app/components/app/modals/account-details-modal/account-details-modal.component.js b/ui/app/components/app/modals/account-details-modal/account-details-modal.component.js index f3b6d55866..fb01b6e41e 100644 --- a/ui/app/components/app/modals/account-details-modal/account-details-modal.component.js +++ b/ui/app/components/app/modals/account-details-modal/account-details-modal.component.js @@ -1,10 +1,10 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import AccountModalContainer from '../account-modal-container' -import getAccountLink from '../../../../../lib/account-link' -import QrView from '../../../ui/qr-code' -import EditableLabel from '../../../ui/editable-label' -import Button from '../../../ui/button' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import AccountModalContainer from '../account-modal-container'; +import getAccountLink from '../../../../../lib/account-link'; +import QrView from '../../../ui/qr-code'; +import EditableLabel from '../../../ui/editable-label'; +import Button from '../../../ui/button'; export default class AccountDetailsModal extends Component { static propTypes = { @@ -14,11 +14,11 @@ export default class AccountDetailsModal extends Component { setAccountLabel: PropTypes.func, keyrings: PropTypes.array, rpcPrefs: PropTypes.object, - } + }; static contextTypes = { t: PropTypes.func, - } + }; render() { const { @@ -28,17 +28,17 @@ export default class AccountDetailsModal extends Component { setAccountLabel, keyrings, rpcPrefs, - } = this.props - const { name, address } = selectedIdentity + } = this.props; + const { name, address } = selectedIdentity; const keyring = keyrings.find((kr) => { - return kr.accounts.includes(address) - }) + return kr.accounts.includes(address); + }); - let exportPrivateKeyFeatureEnabled = true + let exportPrivateKeyFeatureEnabled = true; // This feature is disabled for hardware wallets if (keyring?.type?.search('Hardware') !== -1) { - exportPrivateKeyFeatureEnabled = false + exportPrivateKeyFeatureEnabled = false; } return ( @@ -63,7 +63,7 @@ export default class AccountDetailsModal extends Component { onClick={() => { global.platform.openTab({ url: getAccountLink(address, network, rpcPrefs), - }) + }); }} > {rpcPrefs.blockExplorerUrl @@ -83,6 +83,6 @@ export default class AccountDetailsModal extends Component { ) : null} - ) + ); } } diff --git a/ui/app/components/app/modals/account-details-modal/account-details-modal.container.js b/ui/app/components/app/modals/account-details-modal/account-details-modal.container.js index b29e99c544..8267e1a4b0 100644 --- a/ui/app/components/app/modals/account-details-modal/account-details-modal.container.js +++ b/ui/app/components/app/modals/account-details-modal/account-details-modal.container.js @@ -1,10 +1,10 @@ -import { connect } from 'react-redux' -import { showModal, setAccountLabel } from '../../../../store/actions' +import { connect } from 'react-redux'; +import { showModal, setAccountLabel } from '../../../../store/actions'; import { getSelectedIdentity, getRpcPrefsForCurrentProvider, -} from '../../../../selectors' -import AccountDetailsModal from './account-details-modal.component' +} from '../../../../selectors'; +import AccountDetailsModal from './account-details-modal.component'; const mapStateToProps = (state) => { return { @@ -12,8 +12,8 @@ const mapStateToProps = (state) => { selectedIdentity: getSelectedIdentity(state), keyrings: state.metamask.keyrings, rpcPrefs: getRpcPrefsForCurrentProvider(state), - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { @@ -21,7 +21,10 @@ const mapDispatchToProps = (dispatch) => { dispatch(showModal({ name: 'EXPORT_PRIVATE_KEY' })), setAccountLabel: (address, label) => dispatch(setAccountLabel(address, label)), - } -} + }; +}; -export default connect(mapStateToProps, mapDispatchToProps)(AccountDetailsModal) +export default connect( + mapStateToProps, + mapDispatchToProps, +)(AccountDetailsModal); diff --git a/ui/app/components/app/modals/account-details-modal/index.js b/ui/app/components/app/modals/account-details-modal/index.js index 433f4d1707..ccbfa1d1dd 100644 --- a/ui/app/components/app/modals/account-details-modal/index.js +++ b/ui/app/components/app/modals/account-details-modal/index.js @@ -1 +1 @@ -export { default } from './account-details-modal.container' +export { default } from './account-details-modal.container'; diff --git a/ui/app/components/app/modals/account-modal-container/account-modal-container.component.js b/ui/app/components/app/modals/account-modal-container/account-modal-container.component.js index 2ad338b23d..db93a2dc56 100644 --- a/ui/app/components/app/modals/account-modal-container/account-modal-container.component.js +++ b/ui/app/components/app/modals/account-modal-container/account-modal-container.component.js @@ -1,7 +1,7 @@ -import PropTypes from 'prop-types' -import React from 'react' -import classnames from 'classnames' -import Identicon from '../../../ui/identicon' +import PropTypes from 'prop-types'; +import React from 'react'; +import classnames from 'classnames'; +import Identicon from '../../../ui/identicon'; export default function AccountModalContainer(props, context) { const { @@ -11,7 +11,7 @@ export default function AccountModalContainer(props, context) { backButtonAction, hideModal, children, - } = props + } = props; return (
    - ) + ); } AccountModalContainer.contextTypes = { t: PropTypes.func, -} +}; AccountModalContainer.defaultProps = { showBackButton: false, children: null, backButtonAction: undefined, -} +}; AccountModalContainer.propTypes = { className: PropTypes.string, @@ -54,4 +54,4 @@ AccountModalContainer.propTypes = { backButtonAction: PropTypes.func, hideModal: PropTypes.func.isRequired, children: PropTypes.node, -} +}; diff --git a/ui/app/components/app/modals/account-modal-container/account-modal-container.container.js b/ui/app/components/app/modals/account-modal-container/account-modal-container.container.js index 2ad9b32ac5..0fb64bf1f0 100644 --- a/ui/app/components/app/modals/account-modal-container/account-modal-container.container.js +++ b/ui/app/components/app/modals/account-modal-container/account-modal-container.container.js @@ -1,23 +1,23 @@ -import { connect } from 'react-redux' -import { hideModal } from '../../../../store/actions' -import { getSelectedIdentity } from '../../../../selectors' -import AccountModalContainer from './account-modal-container.component' +import { connect } from 'react-redux'; +import { hideModal } from '../../../../store/actions'; +import { getSelectedIdentity } from '../../../../selectors'; +import AccountModalContainer from './account-modal-container.component'; function mapStateToProps(state, ownProps) { return { selectedIdentity: ownProps.selectedIdentity || getSelectedIdentity(state), - } + }; } function mapDispatchToProps(dispatch) { return { hideModal: () => { - dispatch(hideModal()) + dispatch(hideModal()); }, - } + }; } export default connect( mapStateToProps, mapDispatchToProps, -)(AccountModalContainer) +)(AccountModalContainer); diff --git a/ui/app/components/app/modals/account-modal-container/index.js b/ui/app/components/app/modals/account-modal-container/index.js index e37684b963..b79fcc79fe 100644 --- a/ui/app/components/app/modals/account-modal-container/index.js +++ b/ui/app/components/app/modals/account-modal-container/index.js @@ -1 +1 @@ -export { default } from './account-modal-container.container' +export { default } from './account-modal-container.container'; diff --git a/ui/app/components/app/modals/add-to-addressbook-modal/add-to-addressbook-modal.component.js b/ui/app/components/app/modals/add-to-addressbook-modal/add-to-addressbook-modal.component.js index 03e8e01553..70661e3c77 100644 --- a/ui/app/components/app/modals/add-to-addressbook-modal/add-to-addressbook-modal.component.js +++ b/ui/app/components/app/modals/add-to-addressbook-modal/add-to-addressbook-modal.component.js @@ -1,42 +1,42 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import Button from '../../../ui/button/button.component' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import Button from '../../../ui/button/button.component'; export default class AddToAddressBookModal extends Component { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { hideModal: PropTypes.func.isRequired, addToAddressBook: PropTypes.func.isRequired, recipient: PropTypes.string.isRequired, - } + }; state = { alias: '', - } + }; onSave = async () => { - const { recipient, addToAddressBook, hideModal } = this.props - await addToAddressBook(recipient, this.state.alias) - hideModal() - } + const { recipient, addToAddressBook, hideModal } = this.props; + await addToAddressBook(recipient, this.state.alias); + hideModal(); + }; onChange = (e) => { this.setState({ alias: e.target.value, - }) - } + }); + }; onKeyPress = async (e) => { if (e.key === 'Enter' && this.state.alias) { - this.onSave() + this.onSave(); } - } + }; render() { - const { t } = this.context + const { t } = this.context; return (
    @@ -70,6 +70,6 @@ export default class AddToAddressBookModal extends Component {
    - ) + ); } } diff --git a/ui/app/components/app/modals/add-to-addressbook-modal/add-to-addressbook-modal.container.js b/ui/app/components/app/modals/add-to-addressbook-modal/add-to-addressbook-modal.container.js index 4d041f2a9f..8d220a02af 100644 --- a/ui/app/components/app/modals/add-to-addressbook-modal/add-to-addressbook-modal.container.js +++ b/ui/app/components/app/modals/add-to-addressbook-modal/add-to-addressbook-modal.container.js @@ -1,11 +1,11 @@ -import { connect } from 'react-redux' -import * as actions from '../../../../store/actions' -import AddToAddressBookModal from './add-to-addressbook-modal.component' +import { connect } from 'react-redux'; +import * as actions from '../../../../store/actions'; +import AddToAddressBookModal from './add-to-addressbook-modal.component'; function mapStateToProps(state) { return { ...(state.appState.modal.modalState.props || {}), - } + }; } function mapDispatchToProps(dispatch) { @@ -13,10 +13,10 @@ function mapDispatchToProps(dispatch) { hideModal: () => dispatch(actions.hideModal()), addToAddressBook: (recipient, nickname) => dispatch(actions.addToAddressBook(recipient, nickname)), - } + }; } export default connect( mapStateToProps, mapDispatchToProps, -)(AddToAddressBookModal) +)(AddToAddressBookModal); diff --git a/ui/app/components/app/modals/add-to-addressbook-modal/index.js b/ui/app/components/app/modals/add-to-addressbook-modal/index.js index 9ed4f018ff..d35d21b102 100644 --- a/ui/app/components/app/modals/add-to-addressbook-modal/index.js +++ b/ui/app/components/app/modals/add-to-addressbook-modal/index.js @@ -1 +1 @@ -export { default } from './add-to-addressbook-modal.container' +export { default } from './add-to-addressbook-modal.container'; diff --git a/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/cancel-transaction-gas-fee.component.js b/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/cancel-transaction-gas-fee.component.js index ebcbe0d603..02583b0298 100644 --- a/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/cancel-transaction-gas-fee.component.js +++ b/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/cancel-transaction-gas-fee.component.js @@ -1,15 +1,15 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import UserPreferencedCurrencyDisplay from '../../../user-preferenced-currency-display' -import { PRIMARY, SECONDARY } from '../../../../../helpers/constants/common' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import UserPreferencedCurrencyDisplay from '../../../user-preferenced-currency-display'; +import { PRIMARY, SECONDARY } from '../../../../../helpers/constants/common'; export default class CancelTransaction extends PureComponent { static propTypes = { value: PropTypes.string, - } + }; render() { - const { value } = this.props + const { value } = this.props; return (
    @@ -24,6 +24,6 @@ export default class CancelTransaction extends PureComponent { type={SECONDARY} />
    - ) + ); } } diff --git a/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/index.js b/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/index.js index 1a9ae2e074..f063456bfd 100644 --- a/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/index.js +++ b/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/index.js @@ -1 +1 @@ -export { default } from './cancel-transaction-gas-fee.component' +export { default } from './cancel-transaction-gas-fee.component'; diff --git a/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/tests/cancel-transaction-gas-fee.component.test.js b/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/tests/cancel-transaction-gas-fee.component.test.js index c10971110c..5d4ca39e68 100644 --- a/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/tests/cancel-transaction-gas-fee.component.test.js +++ b/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/tests/cancel-transaction-gas-fee.component.test.js @@ -1,28 +1,28 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import CancelTransactionGasFee from '../cancel-transaction-gas-fee.component' -import UserPreferencedCurrencyDisplay from '../../../../user-preferenced-currency-display' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import CancelTransactionGasFee from '../cancel-transaction-gas-fee.component'; +import UserPreferencedCurrencyDisplay from '../../../../user-preferenced-currency-display'; describe('CancelTransactionGasFee Component', function () { it('should render', function () { - const wrapper = shallow() + const wrapper = shallow(); - assert.ok(wrapper) - assert.strictEqual(wrapper.find(UserPreferencedCurrencyDisplay).length, 2) - const ethDisplay = wrapper.find(UserPreferencedCurrencyDisplay).at(0) - const fiatDisplay = wrapper.find(UserPreferencedCurrencyDisplay).at(1) + assert.ok(wrapper); + assert.strictEqual(wrapper.find(UserPreferencedCurrencyDisplay).length, 2); + const ethDisplay = wrapper.find(UserPreferencedCurrencyDisplay).at(0); + const fiatDisplay = wrapper.find(UserPreferencedCurrencyDisplay).at(1); - assert.strictEqual(ethDisplay.props().value, '0x3b9aca00') + assert.strictEqual(ethDisplay.props().value, '0x3b9aca00'); assert.strictEqual( ethDisplay.props().className, 'cancel-transaction-gas-fee__eth', - ) + ); - assert.strictEqual(fiatDisplay.props().value, '0x3b9aca00') + assert.strictEqual(fiatDisplay.props().value, '0x3b9aca00'); assert.strictEqual( fiatDisplay.props().className, 'cancel-transaction-gas-fee__fiat', - ) - }) -}) + ); + }); +}); diff --git a/ui/app/components/app/modals/cancel-transaction/cancel-transaction.component.js b/ui/app/components/app/modals/cancel-transaction/cancel-transaction.component.js index 7bddafc347..d45ba6198c 100644 --- a/ui/app/components/app/modals/cancel-transaction/cancel-transaction.component.js +++ b/ui/app/components/app/modals/cancel-transaction/cancel-transaction.component.js @@ -1,13 +1,13 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import Modal from '../../modal' -import { TRANSACTION_STATUSES } from '../../../../../../shared/constants/transaction' -import CancelTransactionGasFee from './cancel-transaction-gas-fee' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import Modal from '../../modal'; +import { TRANSACTION_STATUSES } from '../../../../../../shared/constants/transaction'; +import CancelTransactionGasFee from './cancel-transaction-gas-fee'; export default class CancelTransaction extends PureComponent { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { createCancelTransaction: PropTypes.func, @@ -15,37 +15,37 @@ export default class CancelTransaction extends PureComponent { showTransactionConfirmedModal: PropTypes.func, transactionStatus: PropTypes.string, newGasFee: PropTypes.string, - } + }; state = { busy: false, - } + }; componentDidUpdate() { - const { transactionStatus, showTransactionConfirmedModal } = this.props + const { transactionStatus, showTransactionConfirmedModal } = this.props; if (transactionStatus !== TRANSACTION_STATUSES.SUBMITTED) { - showTransactionConfirmedModal() + showTransactionConfirmedModal(); } } handleSubmit = async () => { - const { createCancelTransaction, hideModal } = this.props + const { createCancelTransaction, hideModal } = this.props; - this.setState({ busy: true }) + this.setState({ busy: true }); - await createCancelTransaction() - this.setState({ busy: false }, () => hideModal()) - } + await createCancelTransaction(); + this.setState({ busy: false }, () => hideModal()); + }; handleCancel = () => { - this.props.hideModal() - } + this.props.hideModal(); + }; render() { - const { t } = this.context - const { newGasFee } = this.props - const { busy } = this.state + const { t } = this.context; + const { newGasFee } = this.props; + const { busy } = this.state; return ( - ) + ); } } diff --git a/ui/app/components/app/modals/cancel-transaction/cancel-transaction.container.js b/ui/app/components/app/modals/cancel-transaction/cancel-transaction.container.js index 1386c2b993..687986fa74 100644 --- a/ui/app/components/app/modals/cancel-transaction/cancel-transaction.container.js +++ b/ui/app/components/app/modals/cancel-transaction/cancel-transaction.container.js @@ -1,20 +1,20 @@ -import { connect } from 'react-redux' -import { compose } from 'redux' -import { multiplyCurrencies } from '../../../../helpers/utils/conversion-util' -import withModalProps from '../../../../helpers/higher-order-components/with-modal-props' -import { showModal, createCancelTransaction } from '../../../../store/actions' -import { getHexGasTotal } from '../../../../helpers/utils/confirm-tx.util' -import { addHexPrefix } from '../../../../../../app/scripts/lib/util' -import CancelTransaction from './cancel-transaction.component' +import { connect } from 'react-redux'; +import { compose } from 'redux'; +import { multiplyCurrencies } from '../../../../helpers/utils/conversion-util'; +import withModalProps from '../../../../helpers/higher-order-components/with-modal-props'; +import { showModal, createCancelTransaction } from '../../../../store/actions'; +import { getHexGasTotal } from '../../../../helpers/utils/confirm-tx.util'; +import { addHexPrefix } from '../../../../../../app/scripts/lib/util'; +import CancelTransaction from './cancel-transaction.component'; const mapStateToProps = (state, ownProps) => { - const { metamask } = state - const { transactionId, originalGasPrice } = ownProps - const { currentNetworkTxList } = metamask + const { metamask } = state; + const { transactionId, originalGasPrice } = ownProps; + const { currentNetworkTxList } = metamask; const transaction = currentNetworkTxList.find( ({ id }) => id === transactionId, - ) - const transactionStatus = transaction ? transaction.status : '' + ); + const transactionStatus = transaction ? transaction.status : ''; const defaultNewGasPrice = addHexPrefix( multiplyCurrencies(originalGasPrice, 1.1, { @@ -22,12 +22,12 @@ const mapStateToProps = (state, ownProps) => { multiplicandBase: 16, multiplierBase: 10, }), - ) + ); const newGasFee = getHexGasTotal({ gasPrice: defaultNewGasPrice, gasLimit: '0x5208', - }) + }); return { transactionId, @@ -35,23 +35,23 @@ const mapStateToProps = (state, ownProps) => { originalGasPrice, defaultNewGasPrice, newGasFee, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { createCancelTransaction: (txId, customGasPrice) => { - return dispatch(createCancelTransaction(txId, customGasPrice)) + return dispatch(createCancelTransaction(txId, customGasPrice)); }, showTransactionConfirmedModal: () => dispatch(showModal({ name: 'TRANSACTION_CONFIRMED' })), - } -} + }; +}; const mergeProps = (stateProps, dispatchProps, ownProps) => { - const { transactionId, defaultNewGasPrice, ...restStateProps } = stateProps + const { transactionId, defaultNewGasPrice, ...restStateProps } = stateProps; // eslint-disable-next-line no-shadow - const { createCancelTransaction, ...restDispatchProps } = dispatchProps + const { createCancelTransaction, ...restDispatchProps } = dispatchProps; return { ...restStateProps, @@ -59,10 +59,10 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { ...ownProps, createCancelTransaction: () => createCancelTransaction(transactionId, defaultNewGasPrice), - } -} + }; +}; export default compose( withModalProps, connect(mapStateToProps, mapDispatchToProps, mergeProps), -)(CancelTransaction) +)(CancelTransaction); diff --git a/ui/app/components/app/modals/cancel-transaction/index.js b/ui/app/components/app/modals/cancel-transaction/index.js index 7abc871ee9..1c428a0a69 100644 --- a/ui/app/components/app/modals/cancel-transaction/index.js +++ b/ui/app/components/app/modals/cancel-transaction/index.js @@ -1 +1 @@ -export { default } from './cancel-transaction.container' +export { default } from './cancel-transaction.container'; diff --git a/ui/app/components/app/modals/cancel-transaction/tests/cancel-transaction.component.test.js b/ui/app/components/app/modals/cancel-transaction/tests/cancel-transaction.component.test.js index 64e08944a0..9d75d3dab0 100644 --- a/ui/app/components/app/modals/cancel-transaction/tests/cancel-transaction.component.test.js +++ b/ui/app/components/app/modals/cancel-transaction/tests/cancel-transaction.component.test.js @@ -1,41 +1,41 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import sinon from 'sinon' -import CancelTransaction from '../cancel-transaction.component' -import CancelTransactionGasFee from '../cancel-transaction-gas-fee' -import Modal from '../../../modal' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import CancelTransaction from '../cancel-transaction.component'; +import CancelTransactionGasFee from '../cancel-transaction-gas-fee'; +import Modal from '../../../modal'; describe('CancelTransaction Component', function () { - const t = (key) => key + const t = (key) => key; it('should render a CancelTransaction modal', function () { const wrapper = shallow(, { context: { t }, - }) + }); - assert.ok(wrapper) - assert.strictEqual(wrapper.find(Modal).length, 1) - assert.strictEqual(wrapper.find(CancelTransactionGasFee).length, 1) + assert.ok(wrapper); + assert.strictEqual(wrapper.find(Modal).length, 1); + assert.strictEqual(wrapper.find(CancelTransactionGasFee).length, 1); assert.strictEqual( wrapper.find(CancelTransactionGasFee).props().value, '0x1319718a5000', - ) + ); assert.strictEqual( wrapper.find('.cancel-transaction__title').text(), 'cancellationGasFee', - ) + ); assert.strictEqual( wrapper.find('.cancel-transaction__description').text(), 'attemptToCancelDescription', - ) - }) + ); + }); it('should pass the correct props to the Modal component', async function () { const createCancelTransactionSpy = sinon .stub() - .callsFake(() => Promise.resolve()) - const hideModalSpy = sinon.spy() + .callsFake(() => Promise.resolve()); + const hideModalSpy = sinon.spy(); const wrapper = shallow( undefined} />, { context: { t } }, - ) + ); - assert.strictEqual(wrapper.find(Modal).length, 1) - const modalProps = wrapper.find(Modal).props() + assert.strictEqual(wrapper.find(Modal).length, 1); + const modalProps = wrapper.find(Modal).props(); - assert.strictEqual(modalProps.headerText, 'attemptToCancel') - assert.strictEqual(modalProps.submitText, 'yesLetsTry') - assert.strictEqual(modalProps.cancelText, 'nevermind') + assert.strictEqual(modalProps.headerText, 'attemptToCancel'); + assert.strictEqual(modalProps.submitText, 'yesLetsTry'); + assert.strictEqual(modalProps.cancelText, 'nevermind'); - assert.strictEqual(createCancelTransactionSpy.callCount, 0) - assert.strictEqual(hideModalSpy.callCount, 0) - await modalProps.onSubmit() - assert.strictEqual(createCancelTransactionSpy.callCount, 1) - assert.strictEqual(hideModalSpy.callCount, 1) - modalProps.onCancel() - assert.strictEqual(hideModalSpy.callCount, 2) - }) -}) + assert.strictEqual(createCancelTransactionSpy.callCount, 0); + assert.strictEqual(hideModalSpy.callCount, 0); + await modalProps.onSubmit(); + assert.strictEqual(createCancelTransactionSpy.callCount, 1); + assert.strictEqual(hideModalSpy.callCount, 1); + modalProps.onCancel(); + assert.strictEqual(hideModalSpy.callCount, 2); + }); +}); diff --git a/ui/app/components/app/modals/confirm-delete-network/confirm-delete-network.component.js b/ui/app/components/app/modals/confirm-delete-network/confirm-delete-network.component.js index a746cff08e..a8be936a5a 100644 --- a/ui/app/components/app/modals/confirm-delete-network/confirm-delete-network.component.js +++ b/ui/app/components/app/modals/confirm-delete-network/confirm-delete-network.component.js @@ -1,6 +1,6 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import Modal, { ModalContent } from '../../modal' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import Modal, { ModalContent } from '../../modal'; export default class ConfirmDeleteNetwork extends PureComponent { static propTypes = { @@ -8,21 +8,21 @@ export default class ConfirmDeleteNetwork extends PureComponent { delRpcTarget: PropTypes.func.isRequired, onConfirm: PropTypes.func.isRequired, target: PropTypes.string.isRequired, - } + }; static contextTypes = { t: PropTypes.func, - } + }; handleDelete = () => { this.props.delRpcTarget(this.props.target).then(() => { - this.props.onConfirm() - this.props.hideModal() - }) - } + this.props.onConfirm(); + this.props.hideModal(); + }); + }; render() { - const { t } = this.context + const { t } = this.context; return ( - ) + ); } } diff --git a/ui/app/components/app/modals/confirm-delete-network/confirm-delete-network.container.js b/ui/app/components/app/modals/confirm-delete-network/confirm-delete-network.container.js index b6a5c99f5e..5133e7824e 100644 --- a/ui/app/components/app/modals/confirm-delete-network/confirm-delete-network.container.js +++ b/ui/app/components/app/modals/confirm-delete-network/confirm-delete-network.container.js @@ -1,16 +1,16 @@ -import { connect } from 'react-redux' -import { compose } from 'redux' -import withModalProps from '../../../../helpers/higher-order-components/with-modal-props' -import { delRpcTarget } from '../../../../store/actions' -import ConfirmDeleteNetwork from './confirm-delete-network.component' +import { connect } from 'react-redux'; +import { compose } from 'redux'; +import withModalProps from '../../../../helpers/higher-order-components/with-modal-props'; +import { delRpcTarget } from '../../../../store/actions'; +import ConfirmDeleteNetwork from './confirm-delete-network.component'; const mapDispatchToProps = (dispatch) => { return { delRpcTarget: (target) => dispatch(delRpcTarget(target)), - } -} + }; +}; export default compose( withModalProps, connect(null, mapDispatchToProps), -)(ConfirmDeleteNetwork) +)(ConfirmDeleteNetwork); diff --git a/ui/app/components/app/modals/confirm-delete-network/index.js b/ui/app/components/app/modals/confirm-delete-network/index.js index de9543eea3..998f9160c3 100644 --- a/ui/app/components/app/modals/confirm-delete-network/index.js +++ b/ui/app/components/app/modals/confirm-delete-network/index.js @@ -1 +1 @@ -export { default } from './confirm-delete-network.container' +export { default } from './confirm-delete-network.container'; diff --git a/ui/app/components/app/modals/confirm-delete-network/tests/confirm-delete-network.test.js b/ui/app/components/app/modals/confirm-delete-network/tests/confirm-delete-network.test.js index 7d06ef4596..28d7e8214d 100644 --- a/ui/app/components/app/modals/confirm-delete-network/tests/confirm-delete-network.test.js +++ b/ui/app/components/app/modals/confirm-delete-network/tests/confirm-delete-network.test.js @@ -1,58 +1,58 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import { mount } from 'enzyme' -import ConfirmDeleteNetwork from '..' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import { mount } from 'enzyme'; +import ConfirmDeleteNetwork from '..'; describe('Confirm Delete Network', function () { - let wrapper + let wrapper; const props = { hideModal: sinon.spy(), delRpcTarget: sinon.stub().resolves(), onConfirm: sinon.spy(), target: '', - } + }; beforeEach(function () { wrapper = mount(, { context: { t: (str) => str, }, - }) - }) + }); + }); afterEach(function () { - props.hideModal.resetHistory() - props.delRpcTarget.resetHistory() - props.onConfirm.resetHistory() - }) + props.hideModal.resetHistory(); + props.delRpcTarget.resetHistory(); + props.onConfirm.resetHistory(); + }); it('renders delete network modal title', function () { - const modalTitle = wrapper.find('.modal-content__title') - assert.strictEqual(modalTitle.text(), 'deleteNetwork') - }) + const modalTitle = wrapper.find('.modal-content__title'); + assert.strictEqual(modalTitle.text(), 'deleteNetwork'); + }); it('clicks cancel to hide modal', function () { const cancelButton = wrapper.find( '.button.btn-default.modal-container__footer-button', - ) - cancelButton.simulate('click') + ); + cancelButton.simulate('click'); - assert(props.hideModal.calledOnce) - }) + assert(props.hideModal.calledOnce); + }); it('clicks delete to delete the target and hides modal', function () { const deleteButton = wrapper.find( '.button.btn-danger.modal-container__footer-button', - ) + ); - deleteButton.simulate('click') + deleteButton.simulate('click'); setImmediate(() => { - assert(props.delRpcTarget.calledOnce) - assert(props.hideModal.calledOnce) - assert(props.onConfirm.calledOnce) - }) - }) -}) + assert(props.delRpcTarget.calledOnce); + assert(props.hideModal.calledOnce); + assert(props.onConfirm.calledOnce); + }); + }); +}); diff --git a/ui/app/components/app/modals/confirm-remove-account/confirm-remove-account.component.js b/ui/app/components/app/modals/confirm-remove-account/confirm-remove-account.component.js index 49db8697c5..7c7213aa0f 100644 --- a/ui/app/components/app/modals/confirm-remove-account/confirm-remove-account.component.js +++ b/ui/app/components/app/modals/confirm-remove-account/confirm-remove-account.component.js @@ -1,9 +1,9 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import Modal from '../../modal' -import { addressSummary } from '../../../../helpers/utils/util' -import Identicon from '../../../ui/identicon' -import getAccountLink from '../../../../../lib/account-link' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import Modal from '../../modal'; +import { addressSummary } from '../../../../helpers/utils/util'; +import Identicon from '../../../ui/identicon'; +import getAccountLink from '../../../../../lib/account-link'; export default class ConfirmRemoveAccount extends Component { static propTypes = { @@ -11,24 +11,24 @@ export default class ConfirmRemoveAccount extends Component { removeAccount: PropTypes.func.isRequired, identity: PropTypes.object.isRequired, network: PropTypes.string.isRequired, - } + }; static contextTypes = { t: PropTypes.func, - } + }; handleRemove = () => { this.props .removeAccount(this.props.identity.address) - .then(() => this.props.hideModal()) - } + .then(() => this.props.hideModal()); + }; handleCancel = () => { - this.props.hideModal() - } + this.props.hideModal(); + }; renderSelectedAccount() { - const { identity } = this.props + const { identity } = this.props; return (
    @@ -61,11 +61,11 @@ export default class ConfirmRemoveAccount extends Component {
    - ) + ); } render() { - const { t } = this.context + const { t } = this.context; return ( - ) + ); } } diff --git a/ui/app/components/app/modals/confirm-remove-account/confirm-remove-account.container.js b/ui/app/components/app/modals/confirm-remove-account/confirm-remove-account.container.js index c3b54577c9..61d23978ce 100644 --- a/ui/app/components/app/modals/confirm-remove-account/confirm-remove-account.container.js +++ b/ui/app/components/app/modals/confirm-remove-account/confirm-remove-account.container.js @@ -1,22 +1,22 @@ -import { connect } from 'react-redux' -import { compose } from 'redux' -import withModalProps from '../../../../helpers/higher-order-components/with-modal-props' -import { removeAccount } from '../../../../store/actions' -import ConfirmRemoveAccount from './confirm-remove-account.component' +import { connect } from 'react-redux'; +import { compose } from 'redux'; +import withModalProps from '../../../../helpers/higher-order-components/with-modal-props'; +import { removeAccount } from '../../../../store/actions'; +import ConfirmRemoveAccount from './confirm-remove-account.component'; const mapStateToProps = (state) => { return { network: state.metamask.network, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { removeAccount: (address) => dispatch(removeAccount(address)), - } -} + }; +}; export default compose( withModalProps, connect(mapStateToProps, mapDispatchToProps), -)(ConfirmRemoveAccount) +)(ConfirmRemoveAccount); diff --git a/ui/app/components/app/modals/confirm-remove-account/index.js b/ui/app/components/app/modals/confirm-remove-account/index.js index ecb5f7790e..7f0156c559 100644 --- a/ui/app/components/app/modals/confirm-remove-account/index.js +++ b/ui/app/components/app/modals/confirm-remove-account/index.js @@ -1 +1 @@ -export { default } from './confirm-remove-account.container' +export { default } from './confirm-remove-account.container'; diff --git a/ui/app/components/app/modals/confirm-remove-account/tests/confirm-remove-account.test.js b/ui/app/components/app/modals/confirm-remove-account/tests/confirm-remove-account.test.js index e50b873081..f070092c29 100644 --- a/ui/app/components/app/modals/confirm-remove-account/tests/confirm-remove-account.test.js +++ b/ui/app/components/app/modals/confirm-remove-account/tests/confirm-remove-account.test.js @@ -1,18 +1,18 @@ -import assert from 'assert' -import React from 'react' -import PropTypes from 'prop-types' -import { Provider } from 'react-redux' -import sinon from 'sinon' -import configureStore from 'redux-mock-store' -import { mount } from 'enzyme' -import ConfirmRemoveAccount from '..' +import assert from 'assert'; +import React from 'react'; +import PropTypes from 'prop-types'; +import { Provider } from 'react-redux'; +import sinon from 'sinon'; +import configureStore from 'redux-mock-store'; +import { mount } from 'enzyme'; +import ConfirmRemoveAccount from '..'; describe('Confirm Remove Account', function () { - let wrapper + let wrapper; const state = { metamask: {}, - } + }; const props = { hideModal: sinon.spy(), @@ -22,10 +22,10 @@ describe('Confirm Remove Account', function () { address: '0xAddress', name: 'Account 1', }, - } + }; - const mockStore = configureStore() - const store = mockStore(state) + const mockStore = configureStore(); + const store = mockStore(state); beforeEach(function () { wrapper = mount( @@ -42,40 +42,40 @@ describe('Confirm Remove Account', function () { store: PropTypes.object, }, }, - ) - }) + ); + }); afterEach(function () { - props.hideModal.resetHistory() - }) + props.hideModal.resetHistory(); + }); it('nevermind', function () { - const nevermind = wrapper.find({ type: 'default' }) - nevermind.simulate('click') + const nevermind = wrapper.find({ type: 'default' }); + nevermind.simulate('click'); - assert(props.hideModal.calledOnce) - }) + assert(props.hideModal.calledOnce); + }); it('remove', function (done) { - const remove = wrapper.find({ type: 'secondary' }) - remove.simulate('click') + const remove = wrapper.find({ type: 'secondary' }); + remove.simulate('click'); - assert(props.removeAccount.calledOnce) + assert(props.removeAccount.calledOnce); assert.strictEqual( props.removeAccount.getCall(0).args[0], props.identity.address, - ) + ); setImmediate(() => { - assert(props.hideModal.calledOnce) - done() - }) - }) + assert(props.hideModal.calledOnce); + done(); + }); + }); it('closes', function () { - const close = wrapper.find('.modal-container__header-close') - close.simulate('click') + const close = wrapper.find('.modal-container__header-close'); + close.simulate('click'); - assert(props.hideModal.calledOnce) - }) -}) + assert(props.hideModal.calledOnce); + }); +}); diff --git a/ui/app/components/app/modals/confirm-reset-account/confirm-reset-account.component.js b/ui/app/components/app/modals/confirm-reset-account/confirm-reset-account.component.js index ba558c7fdf..c4e5a9a171 100644 --- a/ui/app/components/app/modals/confirm-reset-account/confirm-reset-account.component.js +++ b/ui/app/components/app/modals/confirm-reset-account/confirm-reset-account.component.js @@ -1,23 +1,23 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import Modal, { ModalContent } from '../../modal' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import Modal, { ModalContent } from '../../modal'; export default class ConfirmResetAccount extends PureComponent { static propTypes = { hideModal: PropTypes.func.isRequired, resetAccount: PropTypes.func.isRequired, - } + }; static contextTypes = { t: PropTypes.func, - } + }; handleReset = () => { - this.props.resetAccount().then(() => this.props.hideModal()) - } + this.props.resetAccount().then(() => this.props.hideModal()); + }; render() { - const { t } = this.context + const { t } = this.context; return ( - ) + ); } } diff --git a/ui/app/components/app/modals/confirm-reset-account/confirm-reset-account.container.js b/ui/app/components/app/modals/confirm-reset-account/confirm-reset-account.container.js index fcbcb9c7ae..cc226b3dfa 100644 --- a/ui/app/components/app/modals/confirm-reset-account/confirm-reset-account.container.js +++ b/ui/app/components/app/modals/confirm-reset-account/confirm-reset-account.container.js @@ -1,16 +1,16 @@ -import { connect } from 'react-redux' -import { compose } from 'redux' -import withModalProps from '../../../../helpers/higher-order-components/with-modal-props' -import { resetAccount } from '../../../../store/actions' -import ConfirmResetAccount from './confirm-reset-account.component' +import { connect } from 'react-redux'; +import { compose } from 'redux'; +import withModalProps from '../../../../helpers/higher-order-components/with-modal-props'; +import { resetAccount } from '../../../../store/actions'; +import ConfirmResetAccount from './confirm-reset-account.component'; const mapDispatchToProps = (dispatch) => { return { resetAccount: () => dispatch(resetAccount()), - } -} + }; +}; export default compose( withModalProps, connect(null, mapDispatchToProps), -)(ConfirmResetAccount) +)(ConfirmResetAccount); diff --git a/ui/app/components/app/modals/confirm-reset-account/index.js b/ui/app/components/app/modals/confirm-reset-account/index.js index ca4d9c5bf8..e38b615608 100644 --- a/ui/app/components/app/modals/confirm-reset-account/index.js +++ b/ui/app/components/app/modals/confirm-reset-account/index.js @@ -1 +1 @@ -export { default } from './confirm-reset-account.container' +export { default } from './confirm-reset-account.container'; diff --git a/ui/app/components/app/modals/confirm-reset-account/tests/confirm-reset-account.test.js b/ui/app/components/app/modals/confirm-reset-account/tests/confirm-reset-account.test.js index fad3a609a2..38af4a5a32 100644 --- a/ui/app/components/app/modals/confirm-reset-account/tests/confirm-reset-account.test.js +++ b/ui/app/components/app/modals/confirm-reset-account/tests/confirm-reset-account.test.js @@ -1,46 +1,46 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import { mount } from 'enzyme' -import ConfirmResetAccount from '..' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import { mount } from 'enzyme'; +import ConfirmResetAccount from '..'; describe('Confirm Reset Account', function () { - let wrapper + let wrapper; const props = { hideModal: sinon.spy(), resetAccount: sinon.stub().resolves(), - } + }; beforeEach(function () { wrapper = mount(, { context: { t: (str) => str, }, - }) - }) + }); + }); afterEach(function () { - props.hideModal.resetHistory() - }) + props.hideModal.resetHistory(); + }); it('hides modal when nevermind button is clicked', function () { const nevermind = wrapper.find( '.btn-default.modal-container__footer-button', - ) - nevermind.simulate('click') + ); + nevermind.simulate('click'); - assert(props.hideModal.calledOnce) - }) + assert(props.hideModal.calledOnce); + }); it('resets account and hides modal when reset button is clicked', function (done) { - const reset = wrapper.find('.btn-danger.modal-container__footer-button') - reset.simulate('click') + const reset = wrapper.find('.btn-danger.modal-container__footer-button'); + reset.simulate('click'); setImmediate(() => { - assert(props.resetAccount.calledOnce) - assert(props.hideModal.calledOnce) - done() - }) - }) -}) + assert(props.resetAccount.calledOnce); + assert(props.hideModal.calledOnce); + done(); + }); + }); +}); diff --git a/ui/app/components/app/modals/deposit-ether-modal/deposit-ether-modal.component.js b/ui/app/components/app/modals/deposit-ether-modal/deposit-ether-modal.component.js index a0043a539c..59522154ca 100644 --- a/ui/app/components/app/modals/deposit-ether-modal/deposit-ether-modal.component.js +++ b/ui/app/components/app/modals/deposit-ether-modal/deposit-ether-modal.component.js @@ -1,13 +1,13 @@ -import PropTypes from 'prop-types' -import React, { Component } from 'react' -import { getNetworkDisplayName } from '../../../../../../app/scripts/controllers/network/util' -import Button from '../../../ui/button' +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import { getNetworkDisplayName } from '../../../../../../app/scripts/controllers/network/util'; +import Button from '../../../ui/button'; export default class DepositEtherModal extends Component { static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func.isRequired, - } + }; static propTypes = { network: PropTypes.string.isRequired, @@ -17,17 +17,17 @@ export default class DepositEtherModal extends Component { hideWarning: PropTypes.func.isRequired, hideModal: PropTypes.func.isRequired, showAccountDetailModal: PropTypes.func.isRequired, - } + }; faucetRowText = (networkName) => { - return this.context.t('getEtherFromFaucet', [networkName]) - } + return this.context.t('getEtherFromFaucet', [networkName]); + }; goToAccountDetailsModal = () => { - this.props.hideWarning() - this.props.hideModal() - this.props.showAccountDetailModal() - } + this.props.hideWarning(); + this.props.hideModal(); + this.props.showAccountDetailModal(); + }; renderRow({ logo, @@ -43,7 +43,7 @@ export default class DepositEtherModal extends Component { showBackButton, }) { if (hide) { - return null + return null; } return ( @@ -82,14 +82,14 @@ export default class DepositEtherModal extends Component { )} - ) + ); } render() { - const { network, toWyre, address, toFaucet } = this.props + const { network, toWyre, address, toFaucet } = this.props; - const isTestNetwork = ['3', '4', '5', '42'].find((n) => n === network) - const networkName = getNetworkDisplayName(network) + const isTestNetwork = ['3', '4', '5', '42'].find((n) => n === network); + const networkName = getNetworkDisplayName(network); return (
    @@ -103,8 +103,8 @@ export default class DepositEtherModal extends Component {
    { - this.props.hideWarning() - this.props.hideModal() + this.props.hideWarning(); + this.props.hideModal(); }} />
    @@ -130,8 +130,8 @@ export default class DepositEtherModal extends Component { action: 'Deposit Ether', name: 'Click buy Ether via Wyre', }, - }) - toWyre(address) + }); + toWyre(address); }, hide: isTestNetwork, })} @@ -163,6 +163,6 @@ export default class DepositEtherModal extends Component {
    - ) + ); } } diff --git a/ui/app/components/app/modals/deposit-ether-modal/deposit-ether-modal.container.js b/ui/app/components/app/modals/deposit-ether-modal/deposit-ether-modal.container.js index abee66e48b..8e324c5b25 100644 --- a/ui/app/components/app/modals/deposit-ether-modal/deposit-ether-modal.container.js +++ b/ui/app/components/app/modals/deposit-ether-modal/deposit-ether-modal.container.js @@ -1,35 +1,35 @@ -import { connect } from 'react-redux' +import { connect } from 'react-redux'; import { buyEth, hideModal, showModal, hideWarning, -} from '../../../../store/actions' -import DepositEtherModal from './deposit-ether-modal.component' +} from '../../../../store/actions'; +import DepositEtherModal from './deposit-ether-modal.component'; function mapStateToProps(state) { return { network: state.metamask.network, address: state.metamask.selectedAddress, - } + }; } function mapDispatchToProps(dispatch) { return { toWyre: (address) => { - dispatch(buyEth({ service: 'wyre', address })) + dispatch(buyEth({ service: 'wyre', address })); }, hideModal: () => { - dispatch(hideModal()) + dispatch(hideModal()); }, hideWarning: () => { - dispatch(hideWarning()) + dispatch(hideWarning()); }, showAccountDetailModal: () => { - dispatch(showModal({ name: 'ACCOUNT_DETAILS' })) + dispatch(showModal({ name: 'ACCOUNT_DETAILS' })); }, toFaucet: (network) => dispatch(buyEth({ network })), - } + }; } -export default connect(mapStateToProps, mapDispatchToProps)(DepositEtherModal) +export default connect(mapStateToProps, mapDispatchToProps)(DepositEtherModal); diff --git a/ui/app/components/app/modals/deposit-ether-modal/index.js b/ui/app/components/app/modals/deposit-ether-modal/index.js index 01a262a73e..02f355cb06 100644 --- a/ui/app/components/app/modals/deposit-ether-modal/index.js +++ b/ui/app/components/app/modals/deposit-ether-modal/index.js @@ -1 +1 @@ -export { default } from './deposit-ether-modal.container' +export { default } from './deposit-ether-modal.container'; diff --git a/ui/app/components/app/modals/edit-approval-permission/edit-approval-permission.component.js b/ui/app/components/app/modals/edit-approval-permission/edit-approval-permission.component.js index e4a2bba6a9..2e100353fe 100644 --- a/ui/app/components/app/modals/edit-approval-permission/edit-approval-permission.component.js +++ b/ui/app/components/app/modals/edit-approval-permission/edit-approval-permission.component.js @@ -1,14 +1,14 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import log from 'loglevel' -import classnames from 'classnames' -import BigNumber from 'bignumber.js' -import Modal from '../../modal' -import Identicon from '../../../ui/identicon' -import TextField from '../../../ui/text-field' -import { calcTokenAmount } from '../../../../helpers/utils/token-util' - -const MAX_UNSIGNED_256_INT = new BigNumber(2).pow(256).minus(1).toString(10) +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import log from 'loglevel'; +import classnames from 'classnames'; +import BigNumber from 'bignumber.js'; +import Modal from '../../modal'; +import Identicon from '../../../ui/identicon'; +import TextField from '../../../ui/text-field'; +import { calcTokenAmount } from '../../../../helpers/utils/token-util'; + +const MAX_UNSIGNED_256_INT = new BigNumber(2).pow(256).minus(1).toString(10); export default class EditApprovalPermission extends PureComponent { static propTypes = { @@ -22,20 +22,20 @@ export default class EditApprovalPermission extends PureComponent { setCustomAmount: PropTypes.func, origin: PropTypes.string.isRequired, requiredMinimum: PropTypes.instanceOf(BigNumber), - } + }; static contextTypes = { t: PropTypes.func, - } + }; state = { // This is used as a TextField value, which should be a string. customSpendLimit: this.props.customTokenAmount || '', selectedOptionIsUnlimited: !this.props.customTokenAmount, - } + }; renderModalContent(error) { - const { t } = this.context + const { t } = this.context; const { hideModal, selectedIdentity, @@ -44,9 +44,9 @@ export default class EditApprovalPermission extends PureComponent { tokenBalance, customTokenAmount, origin, - } = this.props - const { name, address } = selectedIdentity || {} - const { selectedOptionIsUnlimited } = this.state + } = this.props; + const { name, address } = selectedIdentity || {}; + const { selectedOptionIsUnlimited } = this.state; return (
    @@ -154,9 +154,9 @@ export default class EditApprovalPermission extends PureComponent { customTokenAmount || tokenAmount, )} ${tokenSymbol}`} onChange={(event) => { - this.setState({ customSpendLimit: event.target.value }) + this.setState({ customSpendLimit: event.target.value }); if (selectedOptionIsUnlimited) { - this.setState({ selectedOptionIsUnlimited: false }) + this.setState({ selectedOptionIsUnlimited: false }); } }} fullWidth @@ -169,61 +169,61 @@ export default class EditApprovalPermission extends PureComponent {
    - ) + ); } validateSpendLimit() { - const { t } = this.context - const { decimals, requiredMinimum } = this.props - const { selectedOptionIsUnlimited, customSpendLimit } = this.state + const { t } = this.context; + const { decimals, requiredMinimum } = this.props; + const { selectedOptionIsUnlimited, customSpendLimit } = this.state; if (selectedOptionIsUnlimited || !customSpendLimit) { - return undefined + return undefined; } - let customSpendLimitNumber + let customSpendLimitNumber; try { - customSpendLimitNumber = new BigNumber(customSpendLimit) + customSpendLimitNumber = new BigNumber(customSpendLimit); } catch (error) { - log.debug(`Error converting '${customSpendLimit}' to BigNumber:`, error) - return t('spendLimitInvalid') + log.debug(`Error converting '${customSpendLimit}' to BigNumber:`, error); + return t('spendLimitInvalid'); } if (customSpendLimitNumber.isNegative()) { - return t('spendLimitInvalid') + return t('spendLimitInvalid'); } - const maxTokenAmount = calcTokenAmount(MAX_UNSIGNED_256_INT, decimals) + const maxTokenAmount = calcTokenAmount(MAX_UNSIGNED_256_INT, decimals); if (customSpendLimitNumber.greaterThan(maxTokenAmount)) { - return t('spendLimitTooLarge') + return t('spendLimitTooLarge'); } if ( requiredMinimum !== undefined && customSpendLimitNumber.lessThan(requiredMinimum) ) { - return t('spendLimitInsufficient') + return t('spendLimitInsufficient'); } - return undefined + return undefined; } render() { - const { t } = this.context - const { setCustomAmount, hideModal, customTokenAmount } = this.props - const { selectedOptionIsUnlimited, customSpendLimit } = this.state + const { t } = this.context; + const { setCustomAmount, hideModal, customTokenAmount } = this.props; + const { selectedOptionIsUnlimited, customSpendLimit } = this.state; - const error = this.validateSpendLimit() + const error = this.validateSpendLimit(); const disabled = Boolean( (customSpendLimit === customTokenAmount && !selectedOptionIsUnlimited) || error, - ) + ); return ( { - setCustomAmount(selectedOptionIsUnlimited ? '' : customSpendLimit) - hideModal() + setCustomAmount(selectedOptionIsUnlimited ? '' : customSpendLimit); + hideModal(); }} submitText={t('save')} submitType="primary" @@ -233,6 +233,6 @@ export default class EditApprovalPermission extends PureComponent { > {this.renderModalContent(error)} - ) + ); } } diff --git a/ui/app/components/app/modals/edit-approval-permission/edit-approval-permission.container.js b/ui/app/components/app/modals/edit-approval-permission/edit-approval-permission.container.js index 671d99cf61..4a3777c724 100644 --- a/ui/app/components/app/modals/edit-approval-permission/edit-approval-permission.container.js +++ b/ui/app/components/app/modals/edit-approval-permission/edit-approval-permission.container.js @@ -1,18 +1,18 @@ -import { connect } from 'react-redux' -import { compose } from 'redux' -import withModalProps from '../../../../helpers/higher-order-components/with-modal-props' -import { getSelectedIdentity } from '../../../../selectors' -import EditApprovalPermission from './edit-approval-permission.component' +import { connect } from 'react-redux'; +import { compose } from 'redux'; +import withModalProps from '../../../../helpers/higher-order-components/with-modal-props'; +import { getSelectedIdentity } from '../../../../selectors'; +import EditApprovalPermission from './edit-approval-permission.component'; const mapStateToProps = (state) => { - const modalStateProps = state.appState.modal.modalState.props || {} + const modalStateProps = state.appState.modal.modalState.props || {}; return { selectedIdentity: getSelectedIdentity(state), ...modalStateProps, - } -} + }; +}; export default compose( withModalProps, connect(mapStateToProps), -)(EditApprovalPermission) +)(EditApprovalPermission); diff --git a/ui/app/components/app/modals/edit-approval-permission/index.js b/ui/app/components/app/modals/edit-approval-permission/index.js index 3f50d3e999..ac4ff09266 100644 --- a/ui/app/components/app/modals/edit-approval-permission/index.js +++ b/ui/app/components/app/modals/edit-approval-permission/index.js @@ -1 +1 @@ -export { default } from './edit-approval-permission.container' +export { default } from './edit-approval-permission.container'; diff --git a/ui/app/components/app/modals/export-private-key-modal/export-private-key-modal.component.js b/ui/app/components/app/modals/export-private-key-modal/export-private-key-modal.component.js index 5b976765d6..6ac5219b3f 100644 --- a/ui/app/components/app/modals/export-private-key-modal/export-private-key-modal.component.js +++ b/ui/app/components/app/modals/export-private-key-modal/export-private-key-modal.component.js @@ -1,23 +1,23 @@ -import log from 'loglevel' -import PropTypes from 'prop-types' -import React, { Component } from 'react' +import log from 'loglevel'; +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; -import { stripHexPrefix } from 'ethereumjs-util' -import copyToClipboard from 'copy-to-clipboard' -import { checksumAddress } from '../../../../helpers/utils/util' -import ReadOnlyInput from '../../../ui/readonly-input' -import Button from '../../../ui/button' -import AccountModalContainer from '../account-modal-container' +import { stripHexPrefix } from 'ethereumjs-util'; +import copyToClipboard from 'copy-to-clipboard'; +import { checksumAddress } from '../../../../helpers/utils/util'; +import ReadOnlyInput from '../../../ui/readonly-input'; +import Button from '../../../ui/button'; +import AccountModalContainer from '../account-modal-container'; export default class ExportPrivateKeyModal extends Component { static contextTypes = { t: PropTypes.func, - } + }; static defaultProps = { warning: null, previousModalState: null, - } + }; static propTypes = { exportAccount: PropTypes.func.isRequired, @@ -28,21 +28,21 @@ export default class ExportPrivateKeyModal extends Component { hideWarning: PropTypes.func.isRequired, clearAccountDetails: PropTypes.func.isRequired, previousModalState: PropTypes.string, - } + }; state = { password: '', privateKey: null, showWarning: true, - } + }; componentWillUnmount() { - this.props.clearAccountDetails() - this.props.hideWarning() + this.props.clearAccountDetails(); + this.props.hideWarning(); } exportAccountAndGetPrivateKey = (password, address) => { - const { exportAccount } = this.props + const { exportAccount } = this.props; exportAccount(password, address) .then((privateKey) => @@ -51,8 +51,8 @@ export default class ExportPrivateKeyModal extends Component { showWarning: false, }), ) - .catch((e) => log.error(e)) - } + .catch((e) => log.error(e)); + }; renderPasswordLabel(privateKey) { return ( @@ -61,11 +61,11 @@ export default class ExportPrivateKeyModal extends Component { ? this.context.t('copyPrivateKey') : this.context.t('typePassword')} - ) + ); } renderPasswordInput(privateKey) { - const plainKey = privateKey && stripHexPrefix(privateKey) + const plainKey = privateKey && stripHexPrefix(privateKey); if (!privateKey) { return ( @@ -74,7 +74,7 @@ export default class ExportPrivateKeyModal extends Component { className="export-private-key-modal__password-input" onChange={(event) => this.setState({ password: event.target.value })} /> - ) + ); } return ( @@ -85,7 +85,7 @@ export default class ExportPrivateKeyModal extends Component { value={plainKey} onClick={() => copyToClipboard(plainKey)} /> - ) + ); } renderButtons(privateKey, address, hideModal) { @@ -124,7 +124,7 @@ export default class ExportPrivateKeyModal extends Component { )} - ) + ); } render() { @@ -134,10 +134,10 @@ export default class ExportPrivateKeyModal extends Component { showAccountDetailModal, hideModal, previousModalState, - } = this.props - const { name, address } = selectedIdentity + } = this.props; + const { name, address } = selectedIdentity; - const { privateKey, showWarning } = this.state + const { privateKey, showWarning } = this.state; return ( {this.renderButtons(privateKey, address, hideModal)} - ) + ); } } diff --git a/ui/app/components/app/modals/export-private-key-modal/export-private-key-modal.container.js b/ui/app/components/app/modals/export-private-key-modal/export-private-key-modal.container.js index 59a0252a11..6dd8acd928 100644 --- a/ui/app/components/app/modals/export-private-key-modal/export-private-key-modal.container.js +++ b/ui/app/components/app/modals/export-private-key-modal/export-private-key-modal.container.js @@ -1,48 +1,48 @@ -import { connect } from 'react-redux' +import { connect } from 'react-redux'; import { exportAccount, hideWarning, showModal, hideModal, clearAccountDetails, -} from '../../../../store/actions' -import { getSelectedIdentity } from '../../../../selectors' -import ExportPrivateKeyModal from './export-private-key-modal.component' +} from '../../../../store/actions'; +import { getSelectedIdentity } from '../../../../selectors'; +import ExportPrivateKeyModal from './export-private-key-modal.component'; function mapStateToPropsFactory() { - let selectedIdentity = null + let selectedIdentity = null; return function mapStateToProps(state) { // We should **not** change the identity displayed here even if it changes from underneath us. // If we do, we will be showing the user one private key and a **different** address and name. // Note that the selected identity **will** change from underneath us when we unlock the keyring // which is the expected behavior that we are side-stepping. - selectedIdentity = selectedIdentity || getSelectedIdentity(state) + selectedIdentity = selectedIdentity || getSelectedIdentity(state); return { warning: state.appState.warning, privateKey: state.appState.accountDetail.privateKey, selectedIdentity, previousModalState: state.appState.modal.previousModalState.name, - } - } + }; + }; } function mapDispatchToProps(dispatch) { return { exportAccount: (password, address) => { return dispatch(exportAccount(password, address)).then((res) => { - dispatch(hideWarning()) - return res - }) + dispatch(hideWarning()); + return res; + }); }, showAccountDetailModal: () => dispatch(showModal({ name: 'ACCOUNT_DETAILS' })), hideModal: () => dispatch(hideModal()), hideWarning: () => dispatch(hideWarning()), clearAccountDetails: () => dispatch(clearAccountDetails()), - } + }; } export default connect( mapStateToPropsFactory, mapDispatchToProps, -)(ExportPrivateKeyModal) +)(ExportPrivateKeyModal); diff --git a/ui/app/components/app/modals/export-private-key-modal/index.js b/ui/app/components/app/modals/export-private-key-modal/index.js index 996c995ca7..ffba2f7e87 100644 --- a/ui/app/components/app/modals/export-private-key-modal/index.js +++ b/ui/app/components/app/modals/export-private-key-modal/index.js @@ -1 +1 @@ -export { default } from './export-private-key-modal.container' +export { default } from './export-private-key-modal.container'; diff --git a/ui/app/components/app/modals/fade-modal.js b/ui/app/components/app/modals/fade-modal.js index 0b4edeb43c..e8c371f8db 100644 --- a/ui/app/components/app/modals/fade-modal.js +++ b/ui/app/components/app/modals/fade-modal.js @@ -1,46 +1,46 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; -let index = 0 -let extraSheet +let index = 0; +let extraSheet; const insertRule = (css) => { if (!extraSheet) { // First time, create an extra stylesheet for adding rules - extraSheet = document.createElement('style') - document.getElementsByTagName('head')[0].appendChild(extraSheet) + extraSheet = document.createElement('style'); + document.getElementsByTagName('head')[0].appendChild(extraSheet); // Keep reference to actual StyleSheet object (`styleSheet` for IE < 9) - extraSheet = extraSheet.sheet || extraSheet.styleSheet + extraSheet = extraSheet.sheet || extraSheet.styleSheet; } - extraSheet.insertRule(css, (extraSheet.cssRules || extraSheet.rules).length) + extraSheet.insertRule(css, (extraSheet.cssRules || extraSheet.rules).length); - return extraSheet -} + return extraSheet; +}; const insertKeyframesRule = (keyframes) => { // random name // eslint-disable-next-line no-plusplus - const name = `anim_${++index}${Number(new Date())}` - let css = `@keyframes ${name} {` + const name = `anim_${++index}${Number(new Date())}`; + let css = `@keyframes ${name} {`; Object.keys(keyframes).forEach((key) => { - css += `${key} {` + css += `${key} {`; Object.keys(keyframes[key]).forEach((property) => { - const part = `:${keyframes[key][property]};` - css += property + part - }) + const part = `:${keyframes[key][property]};`; + css += property + part; + }); - css += '}' - }) + css += '}'; + }); - css += '}' + css += '}'; - insertRule(css) + insertRule(css); - return name -} + return name; +}; const animation = { show: { @@ -83,41 +83,41 @@ const animation = { opacity: 0, }, }), -} +}; -const endEvents = ['transitionend', 'animationend'] +const endEvents = ['transitionend', 'animationend']; function addEventListener(node, eventName, eventListener) { - node.addEventListener(eventName, eventListener, false) + node.addEventListener(eventName, eventListener, false); } function removeEventListener(node, eventName, eventListener) { - node.removeEventListener(eventName, eventListener, false) + node.removeEventListener(eventName, eventListener, false); } const removeEndEventListener = (node, eventListener) => { if (endEvents.length === 0) { - return + return; } endEvents.forEach(function (endEvent) { - removeEventListener(node, endEvent, eventListener) - }) -} + removeEventListener(node, endEvent, eventListener); + }); +}; const addEndEventListener = (node, eventListener) => { if (endEvents.length === 0) { // If CSS transitions are not supported, trigger an "end animation" // event immediately. - window.setTimeout(eventListener, 0) - return + window.setTimeout(eventListener, 0); + return; } endEvents.forEach(function (endEvent) { - addEventListener(node, endEvent, eventListener) - }) -} + addEventListener(node, endEvent, eventListener); + }); +}; class FadeModal extends Component { - content = null + content = null; static propTypes = { backdrop: PropTypes.bool, @@ -129,7 +129,7 @@ class FadeModal extends Component { onShow: PropTypes.func, onHide: PropTypes.func, children: PropTypes.node, - } + }; static defaultProps = { onShow: () => undefined, @@ -141,43 +141,43 @@ class FadeModal extends Component { backdropStyle: {}, contentStyle: {}, children: [], - } + }; state = { willHide: true, hidden: true, - } + }; addTransitionListener = (node, handle) => { if (node) { const endListener = function (e) { if (e && e.target !== node) { - return + return; } - removeEndEventListener(node, endListener) - handle() - } - addEndEventListener(node, endListener) + removeEndEventListener(node, endListener); + handle(); + }; + addEndEventListener(node, endListener); } - } + }; handleBackdropClick = () => { if (this.props.closeOnClick) { - this.hide() + this.hide(); } - } + }; hasHidden = () => { - return this.state.hidden - } + return this.state.hidden; + }; render() { if (this.state.hidden) { - return null + return null; } - const { willHide } = this.state - const { modalStyle } = this.props + const { willHide } = this.state; + const { modalStyle } = this.props; const backdropStyle = { animationName: willHide ? animation.hideBackdropAnimation @@ -185,7 +185,7 @@ class FadeModal extends Component { animationTimingFunction: (willHide ? animation.hide : animation.show) .animationTimingFunction, ...this.props.backdropStyle, - } + }; const contentStyle = { animationDuration: (willHide ? animation.hide : animation.show) .animationDuration, @@ -195,7 +195,7 @@ class FadeModal extends Component { animationTimingFunction: (willHide ? animation.hide : animation.show) .animationTimingFunction, ...this.props.contentStyle, - } + }; const backdrop = this.props.backdrop ? (
    - ) : undefined + ) : undefined; if (willHide) { - this.addTransitionListener(this.content, this.leave) + this.addTransitionListener(this.content, this.leave); } return ( @@ -223,72 +223,72 @@ class FadeModal extends Component {
    {backdrop} - ) + ); } leave = () => { this.setState({ hidden: true, - }) - this.props.onHide(this.state.hideSource) - } + }); + this.props.onHide(this.state.hideSource); + }; enter = () => { - this.props.onShow() - } + this.props.onShow(); + }; show = () => { if (!this.state.hidden) { - return + return; } this.setState({ willHide: false, hidden: false, - }) + }); setTimeout( function () { - this.addTransitionListener(this.content, this.enter) + this.addTransitionListener(this.content, this.enter); }.bind(this), 0, - ) - } + ); + }; hide = () => { if (this.hasHidden()) { - return + return; } this.setState({ willHide: true, - }) - } + }); + }; listenKeyboard = (event) => { if (typeof this.props.keyboard === 'function') { - this.props.keyboard(event) + this.props.keyboard(event); } else { - this.closeOnEsc(event) + this.closeOnEsc(event); } - } + }; closeOnEsc = (event) => { if ( this.props.keyboard && (event.key === 'Escape' || event.keyCode === 27) ) { - this.hide() + this.hide(); } - } + }; UNSAFE_componentDidMount = () => { - window.addEventListener('keydown', this.listenKeyboard, true) - } + window.addEventListener('keydown', this.listenKeyboard, true); + }; UNSAFE_componentWillUnmount = () => { - window.removeEventListener('keydown', this.listenKeyboard, true) - } + window.removeEventListener('keydown', this.listenKeyboard, true); + }; } -export default FadeModal +export default FadeModal; diff --git a/ui/app/components/app/modals/hide-token-confirmation-modal/hide-token-confirmation-modal.js b/ui/app/components/app/modals/hide-token-confirmation-modal/hide-token-confirmation-modal.js index 592528038d..f8bdc5546b 100644 --- a/ui/app/components/app/modals/hide-token-confirmation-modal/hide-token-confirmation-modal.js +++ b/ui/app/components/app/modals/hide-token-confirmation-modal/hide-token-confirmation-modal.js @@ -1,15 +1,15 @@ -import PropTypes from 'prop-types' -import React, { Component } from 'react' -import { connect } from 'react-redux' -import * as actions from '../../../../store/actions' -import Identicon from '../../../ui/identicon' -import Button from '../../../ui/button' +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import { connect } from 'react-redux'; +import * as actions from '../../../../store/actions'; +import Identicon from '../../../ui/identicon'; +import Button from '../../../ui/button'; function mapStateToProps(state) { return { token: state.appState.modal.modalState.props.token, assetImages: state.metamask.assetImages, - } + }; } function mapDispatchToProps(dispatch) { @@ -17,16 +17,16 @@ function mapDispatchToProps(dispatch) { hideModal: () => dispatch(actions.hideModal()), hideToken: (address) => { dispatch(actions.removeToken(address)).then(() => { - dispatch(actions.hideModal()) - }) + dispatch(actions.hideModal()); + }); }, - } + }; } class HideTokenConfirmationModal extends Component { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { hideToken: PropTypes.func.isRequired, @@ -36,14 +36,14 @@ class HideTokenConfirmationModal extends Component { symbol: PropTypes.string, address: PropTypes.string, }), - } + }; - state = {} + state = {}; render() { - const { token, hideToken, hideModal, assetImages } = this.props - const { symbol, address } = token - const image = assetImages[address] + const { token, hideToken, hideModal, assetImages } = this.props; + const { symbol, address } = token; + const image = assetImages[address]; return (
    @@ -81,11 +81,11 @@ class HideTokenConfirmationModal extends Component {
    - ) + ); } } export default connect( mapStateToProps, mapDispatchToProps, -)(HideTokenConfirmationModal) +)(HideTokenConfirmationModal); diff --git a/ui/app/components/app/modals/hide-token-confirmation-modal/index.js b/ui/app/components/app/modals/hide-token-confirmation-modal/index.js index 31e8663986..d9f281c392 100644 --- a/ui/app/components/app/modals/hide-token-confirmation-modal/index.js +++ b/ui/app/components/app/modals/hide-token-confirmation-modal/index.js @@ -1 +1 @@ -export { default } from './hide-token-confirmation-modal' +export { default } from './hide-token-confirmation-modal'; diff --git a/ui/app/components/app/modals/index.js b/ui/app/components/app/modals/index.js index 9667e0d328..6d93ef89e8 100644 --- a/ui/app/components/app/modals/index.js +++ b/ui/app/components/app/modals/index.js @@ -1,3 +1,3 @@ -import Modal from './modal' +import Modal from './modal'; -export { Modal } +export { Modal }; diff --git a/ui/app/components/app/modals/loading-network-error/index.js b/ui/app/components/app/modals/loading-network-error/index.js index b3737458a1..634a5a6d0c 100644 --- a/ui/app/components/app/modals/loading-network-error/index.js +++ b/ui/app/components/app/modals/loading-network-error/index.js @@ -1 +1 @@ -export { default } from './loading-network-error.container' +export { default } from './loading-network-error.container'; diff --git a/ui/app/components/app/modals/loading-network-error/loading-network-error.component.js b/ui/app/components/app/modals/loading-network-error/loading-network-error.component.js index 9f5d1ad074..0b473f5f45 100644 --- a/ui/app/components/app/modals/loading-network-error/loading-network-error.component.js +++ b/ui/app/components/app/modals/loading-network-error/loading-network-error.component.js @@ -1,24 +1,24 @@ -import React from 'react' -import PropTypes from 'prop-types' -import Modal, { ModalContent } from '../../modal' +import React from 'react'; +import PropTypes from 'prop-types'; +import Modal, { ModalContent } from '../../modal'; const LoadingNetworkError = (props, context) => { - const { t } = context - const { hideModal } = props + const { t } = context; + const { hideModal } = props; return ( hideModal()} submitText={t('tryAgain')}> - ) -} + ); +}; LoadingNetworkError.contextTypes = { t: PropTypes.func, -} +}; LoadingNetworkError.propTypes = { hideModal: PropTypes.func, -} +}; -export default LoadingNetworkError +export default LoadingNetworkError; diff --git a/ui/app/components/app/modals/loading-network-error/loading-network-error.container.js b/ui/app/components/app/modals/loading-network-error/loading-network-error.container.js index 765cdf9c57..4206717a11 100644 --- a/ui/app/components/app/modals/loading-network-error/loading-network-error.container.js +++ b/ui/app/components/app/modals/loading-network-error/loading-network-error.container.js @@ -1,4 +1,4 @@ -import withModalProps from '../../../../helpers/higher-order-components/with-modal-props' -import LoadingNetworkError from './loading-network-error.component' +import withModalProps from '../../../../helpers/higher-order-components/with-modal-props'; +import LoadingNetworkError from './loading-network-error.component'; -export default withModalProps(LoadingNetworkError) +export default withModalProps(LoadingNetworkError); diff --git a/ui/app/components/app/modals/metametrics-opt-in-modal/index.js b/ui/app/components/app/modals/metametrics-opt-in-modal/index.js index 47f9467578..e41006182e 100644 --- a/ui/app/components/app/modals/metametrics-opt-in-modal/index.js +++ b/ui/app/components/app/modals/metametrics-opt-in-modal/index.js @@ -1 +1 @@ -export { default } from './metametrics-opt-in-modal.container' +export { default } from './metametrics-opt-in-modal.container'; diff --git a/ui/app/components/app/modals/metametrics-opt-in-modal/metametrics-opt-in-modal.component.js b/ui/app/components/app/modals/metametrics-opt-in-modal/metametrics-opt-in-modal.component.js index 6fbdb54c39..833d8b49d3 100644 --- a/ui/app/components/app/modals/metametrics-opt-in-modal/metametrics-opt-in-modal.component.js +++ b/ui/app/components/app/modals/metametrics-opt-in-modal/metametrics-opt-in-modal.component.js @@ -1,22 +1,22 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import MetaFoxLogo from '../../../ui/metafox-logo' -import PageContainerFooter from '../../../ui/page-container/page-container-footer' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import MetaFoxLogo from '../../../ui/metafox-logo'; +import PageContainerFooter from '../../../ui/page-container/page-container-footer'; export default class MetaMetricsOptInModal extends Component { static propTypes = { setParticipateInMetaMetrics: PropTypes.func, hideModal: PropTypes.func, - } + }; static contextTypes = { metricsEvent: PropTypes.func, t: PropTypes.func, - } + }; render() { - const { metricsEvent, t } = this.context - const { setParticipateInMetaMetrics, hideModal } = this.props + const { metricsEvent, t } = this.context; + const { setParticipateInMetaMetrics, hideModal } = this.props; return (
    @@ -115,9 +115,9 @@ export default class MetaMetricsOptInModal extends Component { { excludeMetaMetricsId: true, }, - ) - hideModal() - }) + ); + hideModal(); + }); }} cancelText={t('noThanks')} hideCancel={false} @@ -130,9 +130,9 @@ export default class MetaMetricsOptInModal extends Component { name: 'Metrics Opt In', }, isOptIn: true, - }) - hideModal() - }) + }); + hideModal(); + }); }} submitText={t('affirmAgree')} submitButtonType="confirm" @@ -141,6 +141,6 @@ export default class MetaMetricsOptInModal extends Component {
    - ) + ); } } diff --git a/ui/app/components/app/modals/metametrics-opt-in-modal/metametrics-opt-in-modal.container.js b/ui/app/components/app/modals/metametrics-opt-in-modal/metametrics-opt-in-modal.container.js index bb1322903f..e552477876 100644 --- a/ui/app/components/app/modals/metametrics-opt-in-modal/metametrics-opt-in-modal.container.js +++ b/ui/app/components/app/modals/metametrics-opt-in-modal/metametrics-opt-in-modal.container.js @@ -1,25 +1,25 @@ -import { connect } from 'react-redux' -import { compose } from 'redux' -import withModalProps from '../../../../helpers/higher-order-components/with-modal-props' -import { setParticipateInMetaMetrics } from '../../../../store/actions' -import MetaMetricsOptInModal from './metametrics-opt-in-modal.component' +import { connect } from 'react-redux'; +import { compose } from 'redux'; +import withModalProps from '../../../../helpers/higher-order-components/with-modal-props'; +import { setParticipateInMetaMetrics } from '../../../../store/actions'; +import MetaMetricsOptInModal from './metametrics-opt-in-modal.component'; const mapStateToProps = (_, ownProps) => { - const { unapprovedTxCount } = ownProps + const { unapprovedTxCount } = ownProps; return { unapprovedTxCount, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { setParticipateInMetaMetrics: (val) => dispatch(setParticipateInMetaMetrics(val)), - } -} + }; +}; export default compose( withModalProps, connect(mapStateToProps, mapDispatchToProps), -)(MetaMetricsOptInModal) +)(MetaMetricsOptInModal); diff --git a/ui/app/components/app/modals/metametrics-opt-in-modal/tests/metametrics-opt-in-modal.test.js b/ui/app/components/app/modals/metametrics-opt-in-modal/tests/metametrics-opt-in-modal.test.js index 5b9f4798db..a34ad99055 100644 --- a/ui/app/components/app/modals/metametrics-opt-in-modal/tests/metametrics-opt-in-modal.test.js +++ b/ui/app/components/app/modals/metametrics-opt-in-modal/tests/metametrics-opt-in-modal.test.js @@ -1,18 +1,18 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import { mount } from 'enzyme' -import MetaMetricsOptIn from '..' -import messages from '../../../../../../../app/_locales/en/messages.json' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import { mount } from 'enzyme'; +import MetaMetricsOptIn from '..'; +import messages from '../../../../../../../app/_locales/en/messages.json'; describe('MetaMetrics Opt In', function () { - let wrapper + let wrapper; const props = { setParticipateInMetaMetrics: sinon.stub().resolves(), hideModal: sinon.spy(), participateInMetaMetrics: null, - } + }; beforeEach(function () { wrapper = mount(, { @@ -20,43 +20,43 @@ describe('MetaMetrics Opt In', function () { metricsEvent: () => undefined, t: (key) => messages[key].message, }, - }) - }) + }); + }); afterEach(function () { - props.setParticipateInMetaMetrics.resetHistory() - props.hideModal.resetHistory() - }) + props.setParticipateInMetaMetrics.resetHistory(); + props.hideModal.resetHistory(); + }); it('passes false to setParticipateInMetaMetrics and hides modal', function (done) { - const noThanks = wrapper.find('.btn-default.page-container__footer-button') - noThanks.simulate('click') + const noThanks = wrapper.find('.btn-default.page-container__footer-button'); + noThanks.simulate('click'); setImmediate(() => { - assert(props.setParticipateInMetaMetrics.calledOnce) + assert(props.setParticipateInMetaMetrics.calledOnce); assert.strictEqual( props.setParticipateInMetaMetrics.getCall(0).args[0], false, - ) - assert(props.hideModal.calledOnce) - done() - }) - }) + ); + assert(props.hideModal.calledOnce); + done(); + }); + }); it('passes true to setParticipateInMetaMetrics and hides modal', function (done) { const affirmAgree = wrapper.find( '.btn-primary.page-container__footer-button', - ) - affirmAgree.simulate('click') + ); + affirmAgree.simulate('click'); setImmediate(() => { - assert(props.setParticipateInMetaMetrics.calledOnce) + assert(props.setParticipateInMetaMetrics.calledOnce); assert.strictEqual( props.setParticipateInMetaMetrics.getCall(0).args[0], true, - ) - assert(props.hideModal.calledOnce) - done() - }) - }) -}) + ); + assert(props.hideModal.calledOnce); + done(); + }); + }); +}); diff --git a/ui/app/components/app/modals/modal.js b/ui/app/components/app/modals/modal.js index 5ad7d3470b..9aa659d320 100644 --- a/ui/app/components/app/modals/modal.js +++ b/ui/app/components/app/modals/modal.js @@ -1,34 +1,34 @@ -import PropTypes from 'prop-types' -import React, { Component } from 'react' +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; -import { connect } from 'react-redux' -import * as actions from '../../../store/actions' -import { resetCustomData as resetCustomGasData } from '../../../ducks/gas/gas.duck' -import isMobileView from '../../../../lib/is-mobile-view' -import { getEnvironmentType } from '../../../../../app/scripts/lib/util' -import { ENVIRONMENT_TYPE_POPUP } from '../../../../../shared/constants/app' +import { connect } from 'react-redux'; +import * as actions from '../../../store/actions'; +import { resetCustomData as resetCustomGasData } from '../../../ducks/gas/gas.duck'; +import isMobileView from '../../../../lib/is-mobile-view'; +import { getEnvironmentType } from '../../../../../app/scripts/lib/util'; +import { ENVIRONMENT_TYPE_POPUP } from '../../../../../shared/constants/app'; // Modal Components -import ConfirmCustomizeGasModal from '../gas-customization/gas-modal-page-container' -import SwapsGasCustomizationModal from '../../../pages/swaps/swaps-gas-customization-modal' -import DepositEtherModal from './deposit-ether-modal' -import AccountDetailsModal from './account-details-modal' -import ExportPrivateKeyModal from './export-private-key-modal' -import HideTokenConfirmationModal from './hide-token-confirmation-modal' -import QRScanner from './qr-scanner' - -import ConfirmRemoveAccount from './confirm-remove-account' -import ConfirmResetAccount from './confirm-reset-account' -import TransactionConfirmed from './transaction-confirmed' -import CancelTransaction from './cancel-transaction' - -import FadeModal from './fade-modal' -import MetaMetricsOptInModal from './metametrics-opt-in-modal' -import RejectTransactions from './reject-transactions' -import ConfirmDeleteNetwork from './confirm-delete-network' -import AddToAddressBookModal from './add-to-addressbook-modal' -import EditApprovalPermission from './edit-approval-permission' -import NewAccountModal from './new-account-modal' +import ConfirmCustomizeGasModal from '../gas-customization/gas-modal-page-container'; +import SwapsGasCustomizationModal from '../../../pages/swaps/swaps-gas-customization-modal'; +import DepositEtherModal from './deposit-ether-modal'; +import AccountDetailsModal from './account-details-modal'; +import ExportPrivateKeyModal from './export-private-key-modal'; +import HideTokenConfirmationModal from './hide-token-confirmation-modal'; +import QRScanner from './qr-scanner'; + +import ConfirmRemoveAccount from './confirm-remove-account'; +import ConfirmResetAccount from './confirm-reset-account'; +import TransactionConfirmed from './transaction-confirmed'; +import CancelTransaction from './cancel-transaction'; + +import FadeModal from './fade-modal'; +import MetaMetricsOptInModal from './metametrics-opt-in-modal'; +import RejectTransactions from './reject-transactions'; +import ConfirmDeleteNetwork from './confirm-delete-network'; +import AddToAddressBookModal from './add-to-addressbook-modal'; +import EditApprovalPermission from './edit-approval-permission'; +import NewAccountModal from './new-account-modal'; const modalContainerBaseStyle = { transform: 'translate3d(-50%, 0, 0px)', @@ -36,19 +36,19 @@ const modalContainerBaseStyle = { borderRadius: '8px', backgroundColor: '#FFFFFF', boxShadow: '0 2px 22px 0 rgba(0,0,0,0.2)', -} +}; const modalContainerLaptopStyle = { ...modalContainerBaseStyle, width: '344px', top: '15%', -} +}; const modalContainerMobileStyle = { ...modalContainerBaseStyle, width: '309px', top: '12.5%', -} +}; const accountModalStyle = { mobileModalStyle: { @@ -76,7 +76,7 @@ const accountModalStyle = { contentStyle: { borderRadius: '4px', }, -} +}; const MODALS = { DEPOSIT_ETHER: { @@ -381,31 +381,31 @@ const MODALS = { mobileModalStyle: {}, laptopModalStyle: {}, }, -} +}; const BACKDROPSTYLE = { backgroundColor: 'rgba(0, 0, 0, 0.5)', -} +}; function mapStateToProps(state) { return { active: state.appState.modal.open, modalState: state.appState.modal.modalState, - } + }; } function mapDispatchToProps(dispatch) { return { hideModal: (customOnHideOpts) => { - dispatch(actions.hideModal()) + dispatch(actions.hideModal()); if (customOnHideOpts && customOnHideOpts.action) { - dispatch(customOnHideOpts.action(...customOnHideOpts.args)) + dispatch(customOnHideOpts.action(...customOnHideOpts.args)); } }, hideWarning: () => { - dispatch(actions.hideWarning()) + dispatch(actions.hideWarning()); }, - } + }; } class Modal extends Component { @@ -414,30 +414,30 @@ class Modal extends Component { hideModal: PropTypes.func.isRequired, hideWarning: PropTypes.func.isRequired, modalState: PropTypes.object.isRequired, - } + }; hide() { - this.modalRef.hide() + this.modalRef.hide(); } show() { - this.modalRef.show() + this.modalRef.show(); } UNSAFE_componentWillReceiveProps(nextProps, _) { if (nextProps.active) { - this.show() + this.show(); } else if (this.props.active) { - this.hide() + this.hide(); } } render() { - const modal = MODALS[this.props.modalState.name || 'DEFAULT'] - const { contents: children, disableBackdropClick = false } = modal + const modal = MODALS[this.props.modalState.name || 'DEFAULT']; + const { contents: children, disableBackdropClick = false } = modal; const modalStyle = - modal[isMobileView() ? 'mobileModalStyle' : 'laptopModalStyle'] - const contentStyle = modal.contentStyle || {} + modal[isMobileView() ? 'mobileModalStyle' : 'laptopModalStyle']; + const contentStyle = modal.contentStyle || {}; return ( { - this.modalRef = ref + this.modalRef = ref; }} modalStyle={modalStyle} contentStyle={contentStyle} @@ -460,8 +460,8 @@ class Modal extends Component { > {children} - ) + ); } } -export default connect(mapStateToProps, mapDispatchToProps)(Modal) +export default connect(mapStateToProps, mapDispatchToProps)(Modal); diff --git a/ui/app/components/app/modals/new-account-modal/index.js b/ui/app/components/app/modals/new-account-modal/index.js index 2c8b788904..f83a189519 100644 --- a/ui/app/components/app/modals/new-account-modal/index.js +++ b/ui/app/components/app/modals/new-account-modal/index.js @@ -1 +1 @@ -export { default } from './new-account-modal.container' +export { default } from './new-account-modal.container'; diff --git a/ui/app/components/app/modals/new-account-modal/new-account-modal.component.js b/ui/app/components/app/modals/new-account-modal/new-account-modal.component.js index 6129472492..18119a3f0e 100644 --- a/ui/app/components/app/modals/new-account-modal/new-account-modal.component.js +++ b/ui/app/components/app/modals/new-account-modal/new-account-modal.component.js @@ -1,42 +1,42 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import Button from '../../../ui/button/button.component' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import Button from '../../../ui/button/button.component'; export default class NewAccountModal extends Component { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { hideModal: PropTypes.func.isRequired, newAccountNumber: PropTypes.number.isRequired, onSave: PropTypes.func.isRequired, - } + }; state = { alias: this.context.t('newAccountNumberName', [ this.props.newAccountNumber, ]), - } + }; onChange = (e) => { this.setState({ alias: e.target.value, - }) - } + }); + }; onSubmit = () => { - this.props.onSave(this.state.alias).then(this.props.hideModal) - } + this.props.onSave(this.state.alias).then(this.props.hideModal); + }; onKeyPress = (e) => { if (e.key === 'Enter' && this.state.alias) { - this.onSubmit() + this.onSubmit(); } - } + }; render() { - const { t } = this.context + const { t } = this.context; return (
    @@ -74,6 +74,6 @@ export default class NewAccountModal extends Component {
    - ) + ); } } diff --git a/ui/app/components/app/modals/new-account-modal/new-account-modal.container.js b/ui/app/components/app/modals/new-account-modal/new-account-modal.container.js index ab3caccd89..2a1ba3175e 100644 --- a/ui/app/components/app/modals/new-account-modal/new-account-modal.container.js +++ b/ui/app/components/app/modals/new-account-modal/new-account-modal.container.js @@ -1,11 +1,11 @@ -import { connect } from 'react-redux' -import * as actions from '../../../../store/actions' -import NewAccountModal from './new-account-modal.component' +import { connect } from 'react-redux'; +import * as actions from '../../../../store/actions'; +import NewAccountModal from './new-account-modal.component'; function mapStateToProps(state) { return { ...(state.appState.modal.modalState.props || {}), - } + }; } function mapDispatchToProps(dispatch) { @@ -14,17 +14,17 @@ function mapDispatchToProps(dispatch) { createAccount: (newAccountName) => { return dispatch(actions.addNewAccount()).then((newAccountAddress) => { if (newAccountName) { - dispatch(actions.setAccountLabel(newAccountAddress, newAccountName)) + dispatch(actions.setAccountLabel(newAccountAddress, newAccountName)); } - return newAccountAddress - }) + return newAccountAddress; + }); }, - } + }; } function mergeProps(stateProps, dispatchProps) { - const { onCreateNewAccount } = stateProps - const { createAccount } = dispatchProps + const { onCreateNewAccount } = stateProps; + const { createAccount } = dispatchProps; return { ...stateProps, @@ -32,13 +32,13 @@ function mergeProps(stateProps, dispatchProps) { onSave: (newAccountName) => { return createAccount(newAccountName).then((newAccountAddress) => onCreateNewAccount(newAccountAddress), - ) + ); }, - } + }; } export default connect( mapStateToProps, mapDispatchToProps, mergeProps, -)(NewAccountModal) +)(NewAccountModal); diff --git a/ui/app/components/app/modals/qr-scanner/index.js b/ui/app/components/app/modals/qr-scanner/index.js index d96782c135..609ca893d3 100644 --- a/ui/app/components/app/modals/qr-scanner/index.js +++ b/ui/app/components/app/modals/qr-scanner/index.js @@ -1,3 +1,3 @@ -import QrScanner from './qr-scanner.container' +import QrScanner from './qr-scanner.container'; -export default QrScanner +export default QrScanner; diff --git a/ui/app/components/app/modals/qr-scanner/qr-scanner.component.js b/ui/app/components/app/modals/qr-scanner/qr-scanner.component.js index 2f82ce65f5..7ca6a50898 100644 --- a/ui/app/components/app/modals/qr-scanner/qr-scanner.component.js +++ b/ui/app/components/app/modals/qr-scanner/qr-scanner.component.js @@ -1,54 +1,54 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import log from 'loglevel' -import { BrowserQRCodeReader } from '@zxing/library' -import { getEnvironmentType } from '../../../../../../app/scripts/lib/util' -import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../../../shared/constants/app' -import Spinner from '../../../ui/spinner' -import WebcamUtils from '../../../../../lib/webcam-utils' -import PageContainerFooter from '../../../ui/page-container/page-container-footer/page-container-footer.component' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import log from 'loglevel'; +import { BrowserQRCodeReader } from '@zxing/library'; +import { getEnvironmentType } from '../../../../../../app/scripts/lib/util'; +import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../../../shared/constants/app'; +import Spinner from '../../../ui/spinner'; +import WebcamUtils from '../../../../../lib/webcam-utils'; +import PageContainerFooter from '../../../ui/page-container/page-container-footer/page-container-footer.component'; const READY_STATE = { ACCESSING_CAMERA: 'ACCESSING_CAMERA', NEED_TO_ALLOW_ACCESS: 'NEED_TO_ALLOW_ACCESS', READY: 'READY', -} +}; export default class QrScanner extends Component { static propTypes = { hideModal: PropTypes.func.isRequired, qrCodeDetected: PropTypes.func.isRequired, - } + }; static contextTypes = { t: PropTypes.func, - } + }; constructor(props) { - super(props) + super(props); - this.state = this.getInitialState() - this.codeReader = null - this.permissionChecker = null - this.mounted = false + this.state = this.getInitialState(); + this.codeReader = null; + this.permissionChecker = null; + this.mounted = false; // Clear pre-existing qr code data before scanning - this.props.qrCodeDetected(null) + this.props.qrCodeDetected(null); } componentDidMount() { - this.mounted = true - this.checkEnvironment() + this.mounted = true; + this.checkEnvironment(); } componentDidUpdate(_, prevState) { - const { ready } = this.state + const { ready } = this.state; if (prevState.ready !== ready) { if (ready === READY_STATE.READY) { - this.initCamera() + this.initCamera(); } else if (ready === READY_STATE.NEED_TO_ALLOW_ACCESS) { - this.checkPermissions() + this.checkPermissions(); } } } @@ -57,62 +57,62 @@ export default class QrScanner extends Component { return { ready: READY_STATE.ACCESSING_CAMERA, error: null, - } + }; } checkEnvironment = async () => { try { - const { environmentReady } = await WebcamUtils.checkStatus() + const { environmentReady } = await WebcamUtils.checkStatus(); if ( !environmentReady && getEnvironmentType() !== ENVIRONMENT_TYPE_FULLSCREEN ) { - const currentUrl = new URL(window.location.href) - const currentHash = currentUrl.hash - const currentRoute = currentHash ? currentHash.substring(1) : null - global.platform.openExtensionInBrowser(currentRoute) + const currentUrl = new URL(window.location.href); + const currentHash = currentUrl.hash; + const currentRoute = currentHash ? currentHash.substring(1) : null; + global.platform.openExtensionInBrowser(currentRoute); } } catch (error) { if (this.mounted) { - this.setState({ error }) + this.setState({ error }); } } // initial attempt is required to trigger permission prompt - this.initCamera() - } + this.initCamera(); + }; checkPermissions = async () => { try { - const { permissions } = await WebcamUtils.checkStatus() + const { permissions } = await WebcamUtils.checkStatus(); if (permissions) { // Let the video stream load first... - await new Promise((resolve) => setTimeout(resolve, 2000)) + await new Promise((resolve) => setTimeout(resolve, 2000)); if (!this.mounted) { - return + return; } - this.setState({ ready: READY_STATE.READY }) + this.setState({ ready: READY_STATE.READY }); } else if (this.mounted) { // Keep checking for permissions - this.permissionChecker = setTimeout(this.checkPermissions, 1000) + this.permissionChecker = setTimeout(this.checkPermissions, 1000); } } catch (error) { if (this.mounted) { - this.setState({ error }) + this.setState({ error }); } } - } + }; componentWillUnmount() { - this.mounted = false - clearTimeout(this.permissionChecker) - this.teardownCodeReader() + this.mounted = false; + clearTimeout(this.permissionChecker); + this.teardownCodeReader(); } teardownCodeReader() { if (this.codeReader) { - this.codeReader.reset() - this.codeReader.stop() - this.codeReader = null + this.codeReader.reset(); + this.codeReader.stop(); + this.codeReader = null; } } @@ -123,40 +123,40 @@ export default class QrScanner extends Component { // It's important to prevent this codeReader from being created twice; // Firefox otherwise starts 2 video streams, one of which cannot be stopped if (!this.codeReader) { - this.codeReader = new BrowserQRCodeReader() + this.codeReader = new BrowserQRCodeReader(); } try { - await this.codeReader.getVideoInputDevices() - this.checkPermissions() + await this.codeReader.getVideoInputDevices(); + this.checkPermissions(); const content = await this.codeReader.decodeFromInputVideoDevice( undefined, 'video', - ) - const result = this.parseContent(content.text) + ); + const result = this.parseContent(content.text); if (!this.mounted) { - return + return; } else if (result.type === 'unknown') { - this.setState({ error: new Error(this.context.t('unknownQrCode')) }) + this.setState({ error: new Error(this.context.t('unknownQrCode')) }); } else { - this.props.qrCodeDetected(result) - this.stopAndClose() + this.props.qrCodeDetected(result); + this.stopAndClose(); } } catch (error) { if (!this.mounted) { - return + return; } if (error.name === 'NotAllowedError') { - log.info(`Permission denied: '${error}'`) - this.setState({ ready: READY_STATE.NEED_TO_ALLOW_ACCESS }) + log.info(`Permission denied: '${error}'`); + this.setState({ ready: READY_STATE.NEED_TO_ALLOW_ACCESS }); } else { - this.setState({ error }) + this.setState({ error }); } } - } + }; parseContent(content) { - let type = 'unknown' - let values = {} + let type = 'unknown'; + let values = {}; // Here we could add more cases // To parse other type of links @@ -164,47 +164,47 @@ export default class QrScanner extends Component { // Ethereum address links - fox ex. ethereum:0x.....1111 if (content.split('ethereum:').length > 1) { - type = 'address' - values = { address: content.split('ethereum:')[1] } + type = 'address'; + values = { address: content.split('ethereum:')[1] }; // Regular ethereum addresses - fox ex. 0x.....1111 } else if (content.substring(0, 2).toLowerCase() === '0x') { - type = 'address' - values = { address: content } + type = 'address'; + values = { address: content }; } - return { type, values } + return { type, values }; } stopAndClose = () => { if (this.codeReader) { - this.teardownCodeReader() + this.teardownCodeReader(); } - this.props.hideModal() - } + this.props.hideModal(); + }; tryAgain = () => { - clearTimeout(this.permissionChecker) + clearTimeout(this.permissionChecker); if (this.codeReader) { - this.teardownCodeReader() + this.teardownCodeReader(); } this.setState(this.getInitialState(), () => { - this.checkEnvironment() - }) - } + this.checkEnvironment(); + }); + }; renderError() { - const { t } = this.context - const { error } = this.state + const { t } = this.context; + const { error } = this.state; - let title, msg + let title, msg; if (error.type === 'NO_WEBCAM_FOUND') { - title = t('noWebcamFoundTitle') - msg = t('noWebcamFound') + title = t('noWebcamFoundTitle'); + msg = t('noWebcamFound'); } else if (error.message === t('unknownQrCode')) { - msg = t('unknownQrCode') + msg = t('unknownQrCode'); } else { - title = t('unknownCameraErrorTitle') - msg = t('unknownCameraError') + title = t('unknownCameraErrorTitle'); + msg = t('unknownCameraError'); } return ( @@ -222,20 +222,20 @@ export default class QrScanner extends Component { submitButtonType="confirm" /> - ) + ); } renderVideo() { - const { t } = this.context - const { ready } = this.state + const { t } = this.context; + const { ready } = this.state; - let message + let message; if (ready === READY_STATE.ACCESSING_CAMERA) { - message = t('accessingYourCamera') + message = t('accessingYourCamera'); } else if (ready === READY_STATE.READY) { - message = t('scanInstructions') + message = t('scanInstructions'); } else if (ready === READY_STATE.NEED_TO_ALLOW_ACCESS) { - message = t('youNeedToAllowCameraAccess') + message = t('youNeedToAllowCameraAccess'); } return ( @@ -254,16 +254,16 @@ export default class QrScanner extends Component {
    {message}
    - ) + ); } render() { - const { error } = this.state + const { error } = this.state; return (
    {error ? this.renderError() : this.renderVideo()}
    - ) + ); } } diff --git a/ui/app/components/app/modals/qr-scanner/qr-scanner.container.js b/ui/app/components/app/modals/qr-scanner/qr-scanner.container.js index 98472c6ea3..3ee0209fc3 100644 --- a/ui/app/components/app/modals/qr-scanner/qr-scanner.container.js +++ b/ui/app/components/app/modals/qr-scanner/qr-scanner.container.js @@ -1,12 +1,12 @@ -import { connect } from 'react-redux' -import { hideModal, qrCodeDetected } from '../../../../store/actions' -import QrScanner from './qr-scanner.component' +import { connect } from 'react-redux'; +import { hideModal, qrCodeDetected } from '../../../../store/actions'; +import QrScanner from './qr-scanner.component'; const mapDispatchToProps = (dispatch) => { return { hideModal: () => dispatch(hideModal()), qrCodeDetected: (data) => dispatch(qrCodeDetected(data)), - } -} + }; +}; -export default connect(null, mapDispatchToProps)(QrScanner) +export default connect(null, mapDispatchToProps)(QrScanner); diff --git a/ui/app/components/app/modals/reject-transactions/index.js b/ui/app/components/app/modals/reject-transactions/index.js index fcdc372b69..8cb5055c47 100644 --- a/ui/app/components/app/modals/reject-transactions/index.js +++ b/ui/app/components/app/modals/reject-transactions/index.js @@ -1 +1 @@ -export { default } from './reject-transactions.container' +export { default } from './reject-transactions.container'; diff --git a/ui/app/components/app/modals/reject-transactions/reject-transactions.component.js b/ui/app/components/app/modals/reject-transactions/reject-transactions.component.js index 4d7ed241ad..3bb4cd9d91 100644 --- a/ui/app/components/app/modals/reject-transactions/reject-transactions.component.js +++ b/ui/app/components/app/modals/reject-transactions/reject-transactions.component.js @@ -1,28 +1,28 @@ -import PropTypes from 'prop-types' -import React, { PureComponent } from 'react' -import Modal from '../../modal' +import PropTypes from 'prop-types'; +import React, { PureComponent } from 'react'; +import Modal from '../../modal'; export default class RejectTransactionsModal extends PureComponent { static contextTypes = { t: PropTypes.func.isRequired, - } + }; static propTypes = { onSubmit: PropTypes.func.isRequired, hideModal: PropTypes.func.isRequired, unapprovedTxCount: PropTypes.number.isRequired, - } + }; onSubmit = async () => { - const { onSubmit, hideModal } = this.props + const { onSubmit, hideModal } = this.props; - await onSubmit() - hideModal() - } + await onSubmit(); + hideModal(); + }; render() { - const { t } = this.context - const { hideModal, unapprovedTxCount } = this.props + const { t } = this.context; + const { hideModal, unapprovedTxCount } = this.props; return ( - ) + ); } } diff --git a/ui/app/components/app/modals/reject-transactions/reject-transactions.container.js b/ui/app/components/app/modals/reject-transactions/reject-transactions.container.js index 08061a48d6..bcba593508 100644 --- a/ui/app/components/app/modals/reject-transactions/reject-transactions.container.js +++ b/ui/app/components/app/modals/reject-transactions/reject-transactions.container.js @@ -1,17 +1,17 @@ -import { connect } from 'react-redux' -import { compose } from 'redux' -import withModalProps from '../../../../helpers/higher-order-components/with-modal-props' -import RejectTransactionsModal from './reject-transactions.component' +import { connect } from 'react-redux'; +import { compose } from 'redux'; +import withModalProps from '../../../../helpers/higher-order-components/with-modal-props'; +import RejectTransactionsModal from './reject-transactions.component'; const mapStateToProps = (_, ownProps) => { - const { unapprovedTxCount } = ownProps + const { unapprovedTxCount } = ownProps; return { unapprovedTxCount, - } -} + }; +}; export default compose( withModalProps, connect(mapStateToProps), -)(RejectTransactionsModal) +)(RejectTransactionsModal); diff --git a/ui/app/components/app/modals/reject-transactions/tests/reject-transactions.test.js b/ui/app/components/app/modals/reject-transactions/tests/reject-transactions.test.js index f0151939d2..7988d2681b 100644 --- a/ui/app/components/app/modals/reject-transactions/tests/reject-transactions.test.js +++ b/ui/app/components/app/modals/reject-transactions/tests/reject-transactions.test.js @@ -1,49 +1,49 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import { mount } from 'enzyme' -import RejectTransactionsModal from '..' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import { mount } from 'enzyme'; +import RejectTransactionsModal from '..'; describe('Reject Transactions Model', function () { - let wrapper + let wrapper; const props = { onSubmit: sinon.spy(), hideModal: sinon.spy(), unapprovedTxCount: 2, - } + }; beforeEach(function () { wrapper = mount(, { context: { t: (str) => str, }, - }) - }) + }); + }); afterEach(function () { - props.hideModal.resetHistory() - }) + props.hideModal.resetHistory(); + }); it('hides modal when cancel button is clicked', function () { const cancelButton = wrapper.find( '.btn-default.modal-container__footer-button', - ) - cancelButton.simulate('click') + ); + cancelButton.simulate('click'); - assert(props.hideModal.calledOnce) - }) + assert(props.hideModal.calledOnce); + }); it('onSubmit is called and hides modal when reject all clicked', function (done) { const rejectAllButton = wrapper.find( '.btn-secondary.modal-container__footer-button', - ) - rejectAllButton.simulate('click') + ); + rejectAllButton.simulate('click'); setImmediate(() => { - assert(props.onSubmit.calledOnce) - assert(props.hideModal.calledOnce) - done() - }) - }) -}) + assert(props.onSubmit.calledOnce); + assert(props.hideModal.calledOnce); + done(); + }); + }); +}); diff --git a/ui/app/components/app/modals/tests/account-details-modal.test.js b/ui/app/components/app/modals/tests/account-details-modal.test.js index 62da1c56e3..f4da817e4c 100644 --- a/ui/app/components/app/modals/tests/account-details-modal.test.js +++ b/ui/app/components/app/modals/tests/account-details-modal.test.js @@ -1,13 +1,13 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import { shallow } from 'enzyme' -import AccountDetailsModal from '../account-details-modal' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import { shallow } from 'enzyme'; +import AccountDetailsModal from '../account-details-modal'; describe('Account Details Modal', function () { - let wrapper + let wrapper; - global.platform = { openTab: sinon.spy() } + global.platform = { openTab: sinon.spy() }; const props = { hideModal: sinon.spy(), @@ -31,50 +31,50 @@ describe('Account Details Modal', function () { name: 'Account 1', }, }, - } + }; beforeEach(function () { wrapper = shallow(, { context: { t: (str) => str, }, - }) - }) + }); + }); it('sets account label when changing default account label', function () { - const accountLabel = wrapper.find('.account-details-modal__name').first() - accountLabel.simulate('submit', 'New Label') + const accountLabel = wrapper.find('.account-details-modal__name').first(); + accountLabel.simulate('submit', 'New Label'); - assert(props.setAccountLabel.calledOnce) - assert.strictEqual(props.setAccountLabel.getCall(0).args[1], 'New Label') - }) + assert(props.setAccountLabel.calledOnce); + assert.strictEqual(props.setAccountLabel.getCall(0).args[1], 'New Label'); + }); it('opens new tab when view block explorer is clicked', function () { - const modalButton = wrapper.find('.account-details-modal__button') - const etherscanLink = modalButton.first() + const modalButton = wrapper.find('.account-details-modal__button'); + const etherscanLink = modalButton.first(); - etherscanLink.simulate('click') - assert(global.platform.openTab.calledOnce) - }) + etherscanLink.simulate('click'); + assert(global.platform.openTab.calledOnce); + }); it('shows export private key modal when clicked', function () { - const modalButton = wrapper.find('.account-details-modal__button') - const etherscanLink = modalButton.last() + const modalButton = wrapper.find('.account-details-modal__button'); + const etherscanLink = modalButton.last(); - etherscanLink.simulate('click') - assert(props.showExportPrivateKeyModal.calledOnce) - }) + etherscanLink.simulate('click'); + assert(props.showExportPrivateKeyModal.calledOnce); + }); it('sets blockexplorerview text when block explorer url in rpcPrefs exists', function () { - const blockExplorerUrl = 'https://block.explorer' - wrapper.setProps({ rpcPrefs: { blockExplorerUrl } }) + const blockExplorerUrl = 'https://block.explorer'; + wrapper.setProps({ rpcPrefs: { blockExplorerUrl } }); - const modalButton = wrapper.find('.account-details-modal__button') - const blockExplorerLink = modalButton.first() + const modalButton = wrapper.find('.account-details-modal__button'); + const blockExplorerLink = modalButton.first(); assert.strictEqual( blockExplorerLink.html(), '', - ) - }) -}) + ); + }); +}); diff --git a/ui/app/components/app/modals/transaction-confirmed/index.js b/ui/app/components/app/modals/transaction-confirmed/index.js index 7776b969e1..626b9c5773 100644 --- a/ui/app/components/app/modals/transaction-confirmed/index.js +++ b/ui/app/components/app/modals/transaction-confirmed/index.js @@ -1 +1 @@ -export { default } from './transaction-confirmed.container' +export { default } from './transaction-confirmed.container'; diff --git a/ui/app/components/app/modals/transaction-confirmed/tests/transaction-confirmed.test.js b/ui/app/components/app/modals/transaction-confirmed/tests/transaction-confirmed.test.js index f4d35facac..5ca6027851 100644 --- a/ui/app/components/app/modals/transaction-confirmed/tests/transaction-confirmed.test.js +++ b/ui/app/components/app/modals/transaction-confirmed/tests/transaction-confirmed.test.js @@ -1,15 +1,15 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import { mount } from 'enzyme' -import TransactionConfirmed from '..' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import { mount } from 'enzyme'; +import TransactionConfirmed from '..'; describe('Transaction Confirmed', function () { it('clicks ok to submit and hide modal', function () { const props = { onSubmit: sinon.spy(), hideModal: sinon.spy(), - } + }; const wrapper = mount( , { @@ -17,11 +17,13 @@ describe('Transaction Confirmed', function () { t: (str) => str, }, }, - ) - const submit = wrapper.find('.btn-secondary.modal-container__footer-button') - submit.simulate('click') + ); + const submit = wrapper.find( + '.btn-secondary.modal-container__footer-button', + ); + submit.simulate('click'); - assert(props.onSubmit.calledOnce) - assert(props.hideModal.calledOnce) - }) -}) + assert(props.onSubmit.calledOnce); + assert(props.hideModal.calledOnce); + }); +}); diff --git a/ui/app/components/app/modals/transaction-confirmed/transaction-confirmed.component.js b/ui/app/components/app/modals/transaction-confirmed/transaction-confirmed.component.js index aded7cb651..570867df20 100644 --- a/ui/app/components/app/modals/transaction-confirmed/transaction-confirmed.component.js +++ b/ui/app/components/app/modals/transaction-confirmed/transaction-confirmed.component.js @@ -1,29 +1,29 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import Modal from '../../modal' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import Modal from '../../modal'; export default class TransactionConfirmed extends PureComponent { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { onSubmit: PropTypes.func, hideModal: PropTypes.func, - } + }; handleSubmit = () => { - const { hideModal, onSubmit } = this.props + const { hideModal, onSubmit } = this.props; - hideModal() + hideModal(); if (onSubmit && typeof onSubmit === 'function') { - onSubmit() + onSubmit(); } - } + }; render() { - const { t } = this.context + const { t } = this.context; return ( @@ -37,6 +37,6 @@ export default class TransactionConfirmed extends PureComponent { - ) + ); } } diff --git a/ui/app/components/app/modals/transaction-confirmed/transaction-confirmed.container.js b/ui/app/components/app/modals/transaction-confirmed/transaction-confirmed.container.js index 3109c5e27c..eba868a9cc 100644 --- a/ui/app/components/app/modals/transaction-confirmed/transaction-confirmed.container.js +++ b/ui/app/components/app/modals/transaction-confirmed/transaction-confirmed.container.js @@ -1,4 +1,4 @@ -import withModalProps from '../../../../helpers/higher-order-components/with-modal-props' -import TransactionConfirmed from './transaction-confirmed.component' +import withModalProps from '../../../../helpers/higher-order-components/with-modal-props'; +import TransactionConfirmed from './transaction-confirmed.component'; -export default withModalProps(TransactionConfirmed) +export default withModalProps(TransactionConfirmed); diff --git a/ui/app/components/app/multiple-notifications/index.js b/ui/app/components/app/multiple-notifications/index.js index a27a651876..2e7429ed0f 100644 --- a/ui/app/components/app/multiple-notifications/index.js +++ b/ui/app/components/app/multiple-notifications/index.js @@ -1 +1 @@ -export { default } from './multiple-notifications.component' +export { default } from './multiple-notifications.component'; diff --git a/ui/app/components/app/multiple-notifications/multiple-notifications.component.js b/ui/app/components/app/multiple-notifications/multiple-notifications.component.js index 9d16d1dfe7..4bc64ab142 100644 --- a/ui/app/components/app/multiple-notifications/multiple-notifications.component.js +++ b/ui/app/components/app/multiple-notifications/multiple-notifications.component.js @@ -1,29 +1,29 @@ -import React, { PureComponent } from 'react' -import classnames from 'classnames' -import PropTypes from 'prop-types' +import React, { PureComponent } from 'react'; +import classnames from 'classnames'; +import PropTypes from 'prop-types'; export default class MultipleNotifications extends PureComponent { static defaultProps = { children: [], classNames: [], - } + }; static propTypes = { children: PropTypes.array, classNames: PropTypes.array, - } + }; state = { showAll: false, - } + }; render() { - const { showAll } = this.state - const { children, classNames } = this.props + const { showAll } = this.state; + const { children, classNames } = this.props; - const childrenToRender = children.filter(Boolean) + const childrenToRender = children.filter(Boolean); if (childrenToRender.length === 0) { - return null + return null; } return ( @@ -47,6 +47,6 @@ export default class MultipleNotifications extends PureComponent { ) : null} - ) + ); } } diff --git a/ui/app/components/app/network-display/index.js b/ui/app/components/app/network-display/index.js index 6e361e9050..bf11d54501 100644 --- a/ui/app/components/app/network-display/index.js +++ b/ui/app/components/app/network-display/index.js @@ -1 +1 @@ -export { default } from './network-display' +export { default } from './network-display'; diff --git a/ui/app/components/app/network-display/network-display.js b/ui/app/components/app/network-display/network-display.js index 351725a183..beda834984 100644 --- a/ui/app/components/app/network-display/network-display.js +++ b/ui/app/components/app/network-display/network-display.js @@ -1,18 +1,18 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { useSelector } from 'react-redux' -import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network' +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import { useSelector } from 'react-redux'; +import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network'; -import LoadingIndicator from '../../ui/loading-indicator' -import ColorIndicator from '../../ui/color-indicator' +import LoadingIndicator from '../../ui/loading-indicator'; +import ColorIndicator from '../../ui/color-indicator'; import { COLORS, SIZES, TYPOGRAPHY, -} from '../../../helpers/constants/design-system' -import Chip from '../../ui/chip/chip' -import { useI18nContext } from '../../../hooks/useI18nContext' +} from '../../../helpers/constants/design-system'; +import Chip from '../../ui/chip/chip'; +import { useI18nContext } from '../../../hooks/useI18nContext'; export default function NetworkDisplay({ colored, @@ -27,8 +27,8 @@ export default function NetworkDisplay({ network: state.metamask.network, networkNickname: state.metamask.provider.nickname, networkType: state.metamask.provider.type, - })) - const t = useI18nContext() + })); + const t = useI18nContext(); return ( - ) + ); } NetworkDisplay.propTypes = { colored: PropTypes.bool, @@ -82,9 +82,9 @@ NetworkDisplay.propTypes = { disabled: PropTypes.bool, iconClassName: PropTypes.string, onClick: PropTypes.func, -} +}; NetworkDisplay.defaultProps = { colored: true, indicatorSize: SIZES.LG, -} +}; diff --git a/ui/app/components/app/permission-page-container/index.js b/ui/app/components/app/permission-page-container/index.js index 8fe6b44b96..9c9615212e 100644 --- a/ui/app/components/app/permission-page-container/index.js +++ b/ui/app/components/app/permission-page-container/index.js @@ -1,2 +1,2 @@ -export { default } from './permission-page-container.container' -export { default as PermissionPageContainerContent } from './permission-page-container-content' +export { default } from './permission-page-container.container'; +export { default as PermissionPageContainerContent } from './permission-page-container-content'; diff --git a/ui/app/components/app/permission-page-container/permission-page-container-content/index.js b/ui/app/components/app/permission-page-container/permission-page-container-content/index.js index 014e4ff59c..762b02a7c3 100644 --- a/ui/app/components/app/permission-page-container/permission-page-container-content/index.js +++ b/ui/app/components/app/permission-page-container/permission-page-container-content/index.js @@ -1 +1 @@ -export { default } from './permission-page-container-content.component' +export { default } from './permission-page-container-content.component'; diff --git a/ui/app/components/app/permission-page-container/permission-page-container-content/permission-page-container-content.component.js b/ui/app/components/app/permission-page-container/permission-page-container-content/permission-page-container-content.component.js index 650b9333b1..3213e896bb 100644 --- a/ui/app/components/app/permission-page-container/permission-page-container-content/permission-page-container-content.component.js +++ b/ui/app/components/app/permission-page-container/permission-page-container-content/permission-page-container-content.component.js @@ -1,8 +1,8 @@ -import PropTypes from 'prop-types' -import React, { PureComponent } from 'react' -import PermissionsConnectHeader from '../../permissions-connect-header' -import Tooltip from '../../../ui/tooltip' -import CheckBox from '../../../ui/check-box' +import PropTypes from 'prop-types'; +import React, { PureComponent } from 'react'; +import PermissionsConnectHeader from '../../permissions-connect-header'; +import Tooltip from '../../../ui/tooltip'; +import CheckBox from '../../../ui/check-box'; export default class PermissionPageContainerContent extends PureComponent { static propTypes = { @@ -17,29 +17,29 @@ export default class PermissionPageContainerContent extends PureComponent { onPermissionToggle: PropTypes.func.isRequired, selectedIdentities: PropTypes.array, allIdentitiesSelected: PropTypes.bool, - } + }; static defaultProps = { selectedIdentities: [], allIdentitiesSelected: false, - } + }; static contextTypes = { t: PropTypes.func, - } + }; renderRequestedPermissions() { - const { selectedPermissions, onPermissionToggle } = this.props - const { t } = this.context + const { selectedPermissions, onPermissionToggle } = this.props; + const { t } = this.context; const items = Object.keys(selectedPermissions).map((permissionName) => { - const description = t(permissionName) + const description = t(permissionName); // don't allow deselecting eth_accounts - const isDisabled = permissionName === 'eth_accounts' - const isChecked = Boolean(selectedPermissions[permissionName]) + const isDisabled = permissionName === 'eth_accounts'; + const isChecked = Boolean(selectedPermissions[permissionName]); const title = isChecked ? t('permissionCheckedIconDescription') - : t('permissionUncheckedIconDescription') + : t('permissionUncheckedIconDescription'); return (
    { if (!isDisabled) { - onPermissionToggle(permissionName) + onPermissionToggle(permissionName); } }} > @@ -60,25 +60,25 @@ export default class PermissionPageContainerContent extends PureComponent { />
    - ) - }) + ); + }); return (
    {items}
    - ) + ); } getAccountDescriptor(identity) { return `${identity.label} (...${identity.address.slice( identity.address.length - 4, - )})` + )})`; } renderAccountTooltip(textContent) { - const { selectedIdentities } = this.props - const { t } = this.context + const { selectedIdentities } = this.props; + const { t } = this.context; return ( {this.getAccountDescriptor(identity)} - ) + ); })} {selectedIdentities.length > 6 ? t('plusXMore', [selectedIdentities.length - 6]) @@ -102,7 +102,7 @@ export default class PermissionPageContainerContent extends PureComponent { > {textContent} - ) + ); } getTitle() { @@ -110,30 +110,30 @@ export default class PermissionPageContainerContent extends PureComponent { domainMetadata, selectedIdentities, allIdentitiesSelected, - } = this.props - const { t } = this.context + } = this.props; + const { t } = this.context; if (domainMetadata.extensionId) { - return t('externalExtension', [domainMetadata.extensionId]) + return t('externalExtension', [domainMetadata.extensionId]); } else if (allIdentitiesSelected) { return t('connectToAll', [ this.renderAccountTooltip(t('connectToAllAccounts')), - ]) + ]); } else if (selectedIdentities.length > 1) { return t('connectToMultiple', [ this.renderAccountTooltip( t('connectToMultipleNumberOfAccounts', [selectedIdentities.length]), ), - ]) + ]); } - return t('connectTo', [this.getAccountDescriptor(selectedIdentities[0])]) + return t('connectTo', [this.getAccountDescriptor(selectedIdentities[0])]); } render() { - const { domainMetadata } = this.props - const { t } = this.context + const { domainMetadata } = this.props; + const { t } = this.context; - const title = this.getTitle() + const title = this.getTitle(); return (
    @@ -154,6 +154,6 @@ export default class PermissionPageContainerContent extends PureComponent {
    - ) + ); } } diff --git a/ui/app/components/app/permission-page-container/permission-page-container.component.js b/ui/app/components/app/permission-page-container/permission-page-container.component.js index 14441adfa3..a8378f746a 100644 --- a/ui/app/components/app/permission-page-container/permission-page-container.component.js +++ b/ui/app/components/app/permission-page-container/permission-page-container.component.js @@ -1,9 +1,9 @@ -import PropTypes from 'prop-types' -import React, { Component } from 'react' -import { isEqual } from 'lodash' -import { PageContainerFooter } from '../../ui/page-container' -import PermissionsConnectFooter from '../permissions-connect-footer' -import { PermissionPageContainerContent } from '.' +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import { isEqual } from 'lodash'; +import { PageContainerFooter } from '../../ui/page-container'; +import PermissionsConnectFooter from '../permissions-connect-footer'; +import { PermissionPageContainerContent } from '.'; export default class PermissionPageContainer extends Component { static propTypes = { @@ -20,46 +20,46 @@ export default class PermissionPageContainer extends Component { name: PropTypes.string.isRequired, origin: PropTypes.string.isRequired, }), - } + }; static defaultProps = { request: {}, requestMetadata: {}, selectedIdentities: [], allIdentitiesSelected: false, - } + }; static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; state = { selectedPermissions: this.getRequestedMethodState( this.getRequestedMethodNames(this.props), ), - } + }; componentDidUpdate() { - const newMethodNames = this.getRequestedMethodNames(this.props) + const newMethodNames = this.getRequestedMethodNames(this.props); if (!isEqual(Object.keys(this.state.selectedPermissions), newMethodNames)) { // this should be a new request, so just overwrite this.setState({ selectedPermissions: this.getRequestedMethodState(newMethodNames), - }) + }); } } getRequestedMethodState(methodNames) { return methodNames.reduce((acc, methodName) => { - acc[methodName] = true - return acc - }, {}) + acc[methodName] = true; + return acc; + }, {}); } getRequestedMethodNames(props) { - return Object.keys(props.request.permissions || {}) + return Object.keys(props.request.permissions || {}); } onPermissionToggle = (methodName) => { @@ -68,8 +68,8 @@ export default class PermissionPageContainer extends Component { ...this.state.selectedPermissions, [methodName]: !this.state.selectedPermissions[methodName], }, - }) - } + }); + }; componentDidMount() { this.context.metricsEvent({ @@ -78,13 +78,13 @@ export default class PermissionPageContainer extends Component { action: 'Connect', name: 'Tab Opened', }, - }) + }); } onCancel = () => { - const { request, rejectPermissionsRequest } = this.props - rejectPermissionsRequest(request.metadata.id) - } + const { request, rejectPermissionsRequest } = this.props; + rejectPermissionsRequest(request.metadata.id); + }; onSubmit = () => { const { @@ -92,28 +92,28 @@ export default class PermissionPageContainer extends Component { approvePermissionsRequest, rejectPermissionsRequest, selectedIdentities, - } = this.props + } = this.props; const request = { ..._request, permissions: { ..._request.permissions }, - } + }; Object.keys(this.state.selectedPermissions).forEach((key) => { if (!this.state.selectedPermissions[key]) { - delete request.permissions[key] + delete request.permissions[key]; } - }) + }); if (Object.keys(request.permissions).length > 0) { approvePermissionsRequest( request, selectedIdentities.map((selectedIdentity) => selectedIdentity.address), - ) + ); } else { - rejectPermissionsRequest(request.metadata.id) + rejectPermissionsRequest(request.metadata.id); } - } + }; render() { const { @@ -121,7 +121,7 @@ export default class PermissionPageContainer extends Component { targetDomainMetadata, selectedIdentities, allIdentitiesSelected, - } = this.props + } = this.props; return (
    @@ -146,6 +146,6 @@ export default class PermissionPageContainer extends Component { />
    - ) + ); } } diff --git a/ui/app/components/app/permission-page-container/permission-page-container.container.js b/ui/app/components/app/permission-page-container/permission-page-container.container.js index e0b3ff49fd..031dfa6f05 100644 --- a/ui/app/components/app/permission-page-container/permission-page-container.container.js +++ b/ui/app/components/app/permission-page-container/permission-page-container.container.js @@ -1,18 +1,18 @@ -import { connect } from 'react-redux' -import { getMetaMaskIdentities } from '../../../selectors' -import PermissionPageContainer from './permission-page-container.component' +import { connect } from 'react-redux'; +import { getMetaMaskIdentities } from '../../../selectors'; +import PermissionPageContainer from './permission-page-container.component'; const mapStateToProps = (state, ownProps) => { - const { selectedIdentities } = ownProps + const { selectedIdentities } = ownProps; - const allIdentities = getMetaMaskIdentities(state) + const allIdentities = getMetaMaskIdentities(state); const allIdentitiesSelected = Object.keys(selectedIdentities).length === - Object.keys(allIdentities).length && selectedIdentities.length > 1 + Object.keys(allIdentities).length && selectedIdentities.length > 1; return { allIdentitiesSelected, - } -} + }; +}; -export default connect(mapStateToProps)(PermissionPageContainer) +export default connect(mapStateToProps)(PermissionPageContainer); diff --git a/ui/app/components/app/permissions-connect-footer/index.js b/ui/app/components/app/permissions-connect-footer/index.js index 8096e1e3d6..6d47aff6ad 100644 --- a/ui/app/components/app/permissions-connect-footer/index.js +++ b/ui/app/components/app/permissions-connect-footer/index.js @@ -1 +1 @@ -export { default } from './permissions-connect-footer.component' +export { default } from './permissions-connect-footer.component'; diff --git a/ui/app/components/app/permissions-connect-footer/permissions-connect-footer.component.js b/ui/app/components/app/permissions-connect-footer/permissions-connect-footer.component.js index 5a1aef1a47..52713aeb13 100644 --- a/ui/app/components/app/permissions-connect-footer/permissions-connect-footer.component.js +++ b/ui/app/components/app/permissions-connect-footer/permissions-connect-footer.component.js @@ -1,13 +1,13 @@ -import PropTypes from 'prop-types' -import React, { Component } from 'react' +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; export default class PermissionsConnectFooter extends Component { static contextTypes = { t: PropTypes.func, - } + }; render() { - const { t } = this.context + const { t } = this.context; return (
    @@ -18,13 +18,13 @@ export default class PermissionsConnectFooter extends Component { global.platform.openTab({ url: 'https://medium.com/metamask/privacy-mode-is-now-enabled-by-default-1c1c957f4d57', - }) + }); }} > {t('learnMore')}
    - ) + ); } } diff --git a/ui/app/components/app/permissions-connect-header/index.js b/ui/app/components/app/permissions-connect-header/index.js index e9de1a06a9..eab021bfba 100644 --- a/ui/app/components/app/permissions-connect-header/index.js +++ b/ui/app/components/app/permissions-connect-header/index.js @@ -1 +1 @@ -export { default } from './permissions-connect-header.component' +export { default } from './permissions-connect-header.component'; diff --git a/ui/app/components/app/permissions-connect-header/permissions-connect-header.component.js b/ui/app/components/app/permissions-connect-header/permissions-connect-header.component.js index 0a71d0d61b..b0d8920ff2 100644 --- a/ui/app/components/app/permissions-connect-header/permissions-connect-header.component.js +++ b/ui/app/components/app/permissions-connect-header/permissions-connect-header.component.js @@ -1,6 +1,6 @@ -import PropTypes from 'prop-types' -import React, { Component } from 'react' -import SiteIcon from '../../ui/site-icon' +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import SiteIcon from '../../ui/site-icon'; export default class PermissionsConnectHeader extends Component { static propTypes = { @@ -9,33 +9,33 @@ export default class PermissionsConnectHeader extends Component { siteOrigin: PropTypes.string.isRequired, headerTitle: PropTypes.node, headerText: PropTypes.string, - } + }; static defaultProps = { icon: null, headerTitle: '', headerText: '', - } + }; renderHeaderIcon() { - const { icon, iconName, siteOrigin } = this.props + const { icon, iconName, siteOrigin } = this.props; return (
    {siteOrigin}
    - ) + ); } render() { - const { headerTitle, headerText } = this.props + const { headerTitle, headerText } = this.props; return (
    {this.renderHeaderIcon()}
    {headerTitle}
    {headerText}
    - ) + ); } } diff --git a/ui/app/components/app/selected-account/index.js b/ui/app/components/app/selected-account/index.js index 7a362f09ef..95793e3cc0 100644 --- a/ui/app/components/app/selected-account/index.js +++ b/ui/app/components/app/selected-account/index.js @@ -1,3 +1,3 @@ -import SelectedAccount from './selected-account.container' +import SelectedAccount from './selected-account.container'; -export default SelectedAccount +export default SelectedAccount; diff --git a/ui/app/components/app/selected-account/selected-account.component.js b/ui/app/components/app/selected-account/selected-account.component.js index b3b04b5d0c..f703678a1a 100644 --- a/ui/app/components/app/selected-account/selected-account.component.js +++ b/ui/app/components/app/selected-account/selected-account.component.js @@ -1,38 +1,38 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import copyToClipboard from 'copy-to-clipboard' -import { shortenAddress, checksumAddress } from '../../../helpers/utils/util' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import copyToClipboard from 'copy-to-clipboard'; +import { shortenAddress, checksumAddress } from '../../../helpers/utils/util'; -import Tooltip from '../../ui/tooltip' +import Tooltip from '../../ui/tooltip'; class SelectedAccount extends Component { state = { copied: false, - } + }; static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { selectedIdentity: PropTypes.object.isRequired, - } + }; componentDidMount() { - this.copyTimeout = null + this.copyTimeout = null; } componentWillUnmount() { if (this.copyTimeout) { - clearTimeout(this.copyTimeout) - this.copyTimeout = null + clearTimeout(this.copyTimeout); + this.copyTimeout = null; } } render() { - const { t } = this.context - const { selectedIdentity } = this.props - const checksummedAddress = checksumAddress(selectedIdentity.address) + const { t } = this.context; + const { selectedIdentity } = this.props; + const checksummedAddress = checksumAddress(selectedIdentity.address); return (
    @@ -46,12 +46,12 @@ class SelectedAccount extends Component {
    - ) + ); } } -export default SelectedAccount +export default SelectedAccount; diff --git a/ui/app/components/app/selected-account/selected-account.container.js b/ui/app/components/app/selected-account/selected-account.container.js index 154bf43114..3e29bd3ec2 100644 --- a/ui/app/components/app/selected-account/selected-account.container.js +++ b/ui/app/components/app/selected-account/selected-account.container.js @@ -1,11 +1,11 @@ -import { connect } from 'react-redux' -import { getSelectedIdentity } from '../../../selectors' -import SelectedAccount from './selected-account.component' +import { connect } from 'react-redux'; +import { getSelectedIdentity } from '../../../selectors'; +import SelectedAccount from './selected-account.component'; const mapStateToProps = (state) => { return { selectedIdentity: getSelectedIdentity(state), - } -} + }; +}; -export default connect(mapStateToProps)(SelectedAccount) +export default connect(mapStateToProps)(SelectedAccount); diff --git a/ui/app/components/app/selected-account/tests/selected-account-component.test.js b/ui/app/components/app/selected-account/tests/selected-account-component.test.js index fcb924c258..4cc81396d9 100644 --- a/ui/app/components/app/selected-account/tests/selected-account-component.test.js +++ b/ui/app/components/app/selected-account/tests/selected-account-component.test.js @@ -1,7 +1,7 @@ -import assert from 'assert' -import React from 'react' -import { render } from 'enzyme' -import SelectedAccount from '../selected-account.component' +import assert from 'assert'; +import React from 'react'; +import { render } from 'enzyme'; +import SelectedAccount from '../selected-account.component'; describe('SelectedAccount Component', function () { it('should render checksummed address', function () { @@ -13,15 +13,15 @@ describe('SelectedAccount Component', function () { }} />, { context: { t: () => undefined } }, - ) + ); // Checksummed version of address is displayed assert.strictEqual( wrapper.find('.selected-account__address').text(), '0x1B82...5C9D', - ) + ); assert.strictEqual( wrapper.find('.selected-account__name').text(), 'testName', - ) - }) -}) + ); + }); +}); diff --git a/ui/app/components/app/sidebars/index.js b/ui/app/components/app/sidebars/index.js index 732925f69f..d5d5026c6d 100644 --- a/ui/app/components/app/sidebars/index.js +++ b/ui/app/components/app/sidebars/index.js @@ -1 +1 @@ -export { default } from './sidebar.component' +export { default } from './sidebar.component'; diff --git a/ui/app/components/app/sidebars/sidebar.component.js b/ui/app/components/app/sidebars/sidebar.component.js index 37c1abcd93..7a31f2be4d 100644 --- a/ui/app/components/app/sidebars/sidebar.component.js +++ b/ui/app/components/app/sidebars/sidebar.component.js @@ -1,7 +1,7 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import ReactCSSTransitionGroup from 'react-transition-group/CSSTransitionGroup' -import CustomizeGas from '../gas-customization/gas-modal-page-container' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import ReactCSSTransitionGroup from 'react-transition-group/CSSTransitionGroup'; +import CustomizeGas from '../gas-customization/gas-modal-page-container'; export default class Sidebar extends Component { static propTypes = { @@ -12,45 +12,45 @@ export default class Sidebar extends Component { type: PropTypes.string, sidebarProps: PropTypes.object, onOverlayClose: PropTypes.func, - } + }; renderOverlay() { - const { onOverlayClose } = this.props + const { onOverlayClose } = this.props; return (
    { - onOverlayClose?.() - this.props.hideSidebar() + onOverlayClose?.(); + this.props.hideSidebar(); }} /> - ) + ); } renderSidebarContent() { - const { type, sidebarProps = {} } = this.props - const { transaction = {} } = sidebarProps + const { type, sidebarProps = {} } = this.props; + const { transaction = {} } = sidebarProps; switch (type) { case 'customize-gas': return (
    - ) + ); default: - return null + return null; } } componentDidUpdate(prevProps) { if (!prevProps.sidebarShouldClose && this.props.sidebarShouldClose) { - this.props.hideSidebar() + this.props.hideSidebar(); } } render() { - const { transitionName, sidebarOpen, sidebarShouldClose } = this.props + const { transitionName, sidebarOpen, sidebarShouldClose } = this.props; return (
    @@ -65,6 +65,6 @@ export default class Sidebar extends Component { {sidebarOpen && !sidebarShouldClose ? this.renderOverlay() : null}
    - ) + ); } } diff --git a/ui/app/components/app/sidebars/tests/sidebars-component.test.js b/ui/app/components/app/sidebars/tests/sidebars-component.test.js index 87d9377c0c..6ce792716a 100644 --- a/ui/app/components/app/sidebars/tests/sidebars-component.test.js +++ b/ui/app/components/app/sidebars/tests/sidebars-component.test.js @@ -1,18 +1,18 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import sinon from 'sinon' -import ReactCSSTransitionGroup from 'react-transition-group/CSSTransitionGroup' -import Sidebar from '../sidebar.component' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import ReactCSSTransitionGroup from 'react-transition-group/CSSTransitionGroup'; +import Sidebar from '../sidebar.component'; -import CustomizeGas from '../../gas-customization/gas-modal-page-container' +import CustomizeGas from '../../gas-customization/gas-modal-page-container'; const propsMethodSpies = { hideSidebar: sinon.spy(), -} +}; describe('Sidebar Component', function () { - let wrapper + let wrapper; beforeEach(function () { wrapper = shallow( @@ -22,69 +22,71 @@ describe('Sidebar Component', function () { transitionName="someTransition" type="customize-gas" />, - ) - }) + ); + }); afterEach(function () { - propsMethodSpies.hideSidebar.resetHistory() - }) + propsMethodSpies.hideSidebar.resetHistory(); + }); describe('renderOverlay', function () { - let renderOverlay + let renderOverlay; beforeEach(function () { - renderOverlay = shallow(wrapper.instance().renderOverlay()) - }) + renderOverlay = shallow(wrapper.instance().renderOverlay()); + }); it('should render a overlay element', function () { - assert(renderOverlay.hasClass('sidebar-overlay')) - }) + assert(renderOverlay.hasClass('sidebar-overlay')); + }); it('should pass the correct onClick function to the element', function () { - assert.strictEqual(propsMethodSpies.hideSidebar.callCount, 0) - renderOverlay.props().onClick() - assert.strictEqual(propsMethodSpies.hideSidebar.callCount, 1) - }) - }) + assert.strictEqual(propsMethodSpies.hideSidebar.callCount, 0); + renderOverlay.props().onClick(); + assert.strictEqual(propsMethodSpies.hideSidebar.callCount, 1); + }); + }); describe('renderSidebarContent', function () { - let renderSidebarContent + let renderSidebarContent; beforeEach(function () { - renderSidebarContent = wrapper.instance().renderSidebarContent() - }) + renderSidebarContent = wrapper.instance().renderSidebarContent(); + }); it('should render sidebar content with the type customize-gas', function () { - renderSidebarContent = wrapper.instance().renderSidebarContent() - const renderedSidebarContent = shallow(renderSidebarContent) - assert(renderedSidebarContent.hasClass('sidebar-left')) - assert(renderedSidebarContent.childAt(0).is(CustomizeGas)) - }) + renderSidebarContent = wrapper.instance().renderSidebarContent(); + const renderedSidebarContent = shallow(renderSidebarContent); + assert(renderedSidebarContent.hasClass('sidebar-left')); + assert(renderedSidebarContent.childAt(0).is(CustomizeGas)); + }); it('should not render with an unrecognized type', function () { - wrapper.setProps({ type: 'foobar' }) - renderSidebarContent = wrapper.instance().renderSidebarContent() - assert.strictEqual(renderSidebarContent, null) - }) - }) + wrapper.setProps({ type: 'foobar' }); + renderSidebarContent = wrapper.instance().renderSidebarContent(); + assert.strictEqual(renderSidebarContent, null); + }); + }); describe('render', function () { it('should render a div with one child', function () { - assert(wrapper.is('div')) - assert.strictEqual(wrapper.children().length, 1) - }) + assert(wrapper.is('div')); + assert.strictEqual(wrapper.children().length, 1); + }); it('should render the ReactCSSTransitionGroup without any children', function () { - assert(wrapper.children().at(0).is(ReactCSSTransitionGroup)) - assert.strictEqual(wrapper.children().at(0).children().length, 0) - }) + assert(wrapper.children().at(0).is(ReactCSSTransitionGroup)); + assert.strictEqual(wrapper.children().at(0).children().length, 0); + }); it('should render sidebar content and the overlay if sidebarOpen is true', function () { - wrapper.setProps({ sidebarOpen: true }) - assert.strictEqual(wrapper.children().length, 2) - assert(wrapper.children().at(1).hasClass('sidebar-overlay')) - assert.strictEqual(wrapper.children().at(0).children().length, 1) - assert(wrapper.children().at(0).children().at(0).hasClass('sidebar-left')) + wrapper.setProps({ sidebarOpen: true }); + assert.strictEqual(wrapper.children().length, 2); + assert(wrapper.children().at(1).hasClass('sidebar-overlay')); + assert.strictEqual(wrapper.children().at(0).children().length, 1); + assert( + wrapper.children().at(0).children().at(0).hasClass('sidebar-left'), + ); assert( wrapper .children() @@ -94,7 +96,7 @@ describe('Sidebar Component', function () { .children() .at(0) .is(CustomizeGas), - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/ui/app/components/app/signature-request-original/index.js b/ui/app/components/app/signature-request-original/index.js index 00a9067857..23d7a6df35 100644 --- a/ui/app/components/app/signature-request-original/index.js +++ b/ui/app/components/app/signature-request-original/index.js @@ -1 +1 @@ -export { default } from './signature-request-original.container' +export { default } from './signature-request-original.container'; diff --git a/ui/app/components/app/signature-request-original/signature-request-original.component.js b/ui/app/components/app/signature-request-original/signature-request-original.component.js index 32f8aafcc7..ab7bd6c50f 100644 --- a/ui/app/components/app/signature-request-original/signature-request-original.component.js +++ b/ui/app/components/app/signature-request-original/signature-request-original.component.js @@ -1,25 +1,25 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import ethUtil from 'ethereumjs-util' -import classnames from 'classnames' -import { ObjectInspector } from 'react-inspector' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import ethUtil from 'ethereumjs-util'; +import classnames from 'classnames'; +import { ObjectInspector } from 'react-inspector'; import { ENVIRONMENT_TYPE_NOTIFICATION, MESSAGE_TYPE, -} from '../../../../../shared/constants/app' -import { getEnvironmentType } from '../../../../../app/scripts/lib/util' -import Identicon from '../../ui/identicon' -import AccountListItem from '../account-list-item' -import { conversionUtil } from '../../../helpers/utils/conversion-util' -import Button from '../../ui/button' -import SiteIcon from '../../ui/site-icon' +} from '../../../../../shared/constants/app'; +import { getEnvironmentType } from '../../../../../app/scripts/lib/util'; +import Identicon from '../../ui/identicon'; +import AccountListItem from '../account-list-item'; +import { conversionUtil } from '../../../helpers/utils/conversion-util'; +import Button from '../../ui/button'; +import SiteIcon from '../../ui/site-icon'; export default class SignatureRequestOriginal extends Component { static contextTypes = { t: PropTypes.func.isRequired, metricsEvent: PropTypes.func.isRequired, - } + }; static propTypes = { fromAccount: PropTypes.shape({ @@ -36,41 +36,41 @@ export default class SignatureRequestOriginal extends Component { sign: PropTypes.func.isRequired, txData: PropTypes.object.isRequired, domainMetadata: PropTypes.object, - } + }; state = { fromAccount: this.props.fromAccount, - } + }; componentDidMount = () => { if (getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION) { - window.addEventListener('beforeunload', this._beforeUnload) + window.addEventListener('beforeunload', this._beforeUnload); } - } + }; componentWillUnmount = () => { - this._removeBeforeUnload() - } + this._removeBeforeUnload(); + }; _beforeUnload = (event) => { - const { clearConfirmTransaction, cancel } = this.props - const { metricsEvent } = this.context + const { clearConfirmTransaction, cancel } = this.props; + const { metricsEvent } = this.context; metricsEvent({ eventOpts: { category: 'Transactions', action: 'Sign Request', name: 'Cancel Sig Request Via Notification Close', }, - }) - clearConfirmTransaction() - cancel(event) - } + }); + clearConfirmTransaction(); + cancel(event); + }; _removeBeforeUnload = () => { if (getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION) { - window.removeEventListener('beforeunload', this._beforeUnload) + window.removeEventListener('beforeunload', this._beforeUnload); } - } + }; renderHeader = () => { return ( @@ -85,11 +85,11 @@ export default class SignatureRequestOriginal extends Component {
    - ) - } + ); + }; renderAccount = () => { - const { fromAccount } = this.state + const { fromAccount } = this.state; return (
    @@ -101,14 +101,14 @@ export default class SignatureRequestOriginal extends Component {
    - ) - } + ); + }; renderBalance = () => { - const { conversionRate } = this.props + const { conversionRate } = this.props; const { fromAccount: { balance }, - } = this.state + } = this.state; const balanceInEther = conversionUtil(balance, { fromNumericBase: 'hex', @@ -116,7 +116,7 @@ export default class SignatureRequestOriginal extends Component { fromDenomination: 'WEI', numberOfDecimals: 6, conversionRate, - }) + }); return (
    @@ -127,18 +127,18 @@ export default class SignatureRequestOriginal extends Component { {`${balanceInEther} ETH`}
    - ) - } + ); + }; renderRequestIcon = () => { - const { requesterAddress } = this.props + const { requesterAddress } = this.props; return (
    - ) - } + ); + }; renderAccountInfo = () => { return ( @@ -147,16 +147,16 @@ export default class SignatureRequestOriginal extends Component { {this.renderRequestIcon()} {this.renderBalance()} - ) - } + ); + }; renderOriginInfo = () => { - const { txData, domainMetadata } = this.props - const { t } = this.context + const { txData, domainMetadata } = this.props; + const { t } = this.context; const originMetadata = txData.msgParams.origin ? domainMetadata?.[txData.msgParams.origin] - : null + : null; return (
    @@ -174,21 +174,21 @@ export default class SignatureRequestOriginal extends Component { {txData.msgParams.origin}
    - ) - } + ); + }; msgHexToText = (hex) => { try { - const stripped = ethUtil.stripHexPrefix(hex) - const buff = Buffer.from(stripped, 'hex') - return buff.length === 32 ? hex : buff.toString('utf8') + const stripped = ethUtil.stripHexPrefix(hex); + const buff = Buffer.from(stripped, 'hex'); + return buff.length === 32 ? hex : buff.toString('utf8'); } catch (e) { - return hex + return hex; } - } + }; renderTypedData = (data) => { - const { domain, message } = JSON.parse(data) + const { domain, message } = JSON.parse(data); return (
    {domain ? ( @@ -208,28 +208,28 @@ export default class SignatureRequestOriginal extends Component { '' )}
    - ) - } + ); + }; renderBody = () => { - let rows - let notice = `${this.context.t('youSign')}:` + let rows; + let notice = `${this.context.t('youSign')}:`; - const { txData } = this.props + const { txData } = this.props; const { type, msgParams: { data }, - } = txData + } = txData; if (type === MESSAGE_TYPE.PERSONAL_SIGN) { rows = [ { name: this.context.t('message'), value: this.msgHexToText(data) }, - ] + ]; } else if (type === MESSAGE_TYPE.ETH_SIGN_TYPED_DATA) { - rows = data + rows = data; } else if (type === MESSAGE_TYPE.ETH_SIGN) { - rows = [{ name: this.context.t('message'), value: data }] - notice = this.context.t('signNotice') + rows = [{ name: this.context.t('message'), value: data }]; + notice = this.context.t('signNotice'); } return ( @@ -249,7 +249,7 @@ export default class SignatureRequestOriginal extends Component { global.platform.openTab({ url: 'https://metamask.zendesk.com/hc/en-us/articles/360015488751', - }) + }); }} > {this.context.t('learnMore')} @@ -260,7 +260,7 @@ export default class SignatureRequestOriginal extends Component { {rows.map(({ name, value }, index) => { if (typeof value === 'boolean') { // eslint-disable-next-line no-param-reassign - value = value.toString() + value = value.toString(); } return (
    {`${name}:`}
    {value}
    - ) + ); })} - ) - } + ); + }; renderFooter = () => { const { @@ -284,7 +284,7 @@ export default class SignatureRequestOriginal extends Component { history, mostRecentOverviewPage, sign, - } = this.props + } = this.props; return (
    @@ -293,17 +293,17 @@ export default class SignatureRequestOriginal extends Component { large className="request-signature__footer__cancel-button" onClick={async (event) => { - this._removeBeforeUnload() - await cancel(event) + this._removeBeforeUnload(); + await cancel(event); this.context.metricsEvent({ eventOpts: { category: 'Transactions', action: 'Sign Request', name: 'Cancel', }, - }) - clearConfirmTransaction() - history.push(mostRecentOverviewPage) + }); + clearConfirmTransaction(); + history.push(mostRecentOverviewPage); }} > {this.context.t('cancel')} @@ -314,24 +314,24 @@ export default class SignatureRequestOriginal extends Component { large className="request-signature__footer__sign-button" onClick={async (event) => { - this._removeBeforeUnload() - await sign(event) + this._removeBeforeUnload(); + await sign(event); this.context.metricsEvent({ eventOpts: { category: 'Transactions', action: 'Sign Request', name: 'Confirm', }, - }) - clearConfirmTransaction() - history.push(mostRecentOverviewPage) + }); + clearConfirmTransaction(); + history.push(mostRecentOverviewPage); }} > {this.context.t('sign')}
    - ) - } + ); + }; render = () => { return ( @@ -340,6 +340,6 @@ export default class SignatureRequestOriginal extends Component { {this.renderBody()} {this.renderFooter()} - ) - } + ); + }; } diff --git a/ui/app/components/app/signature-request-original/signature-request-original.container.js b/ui/app/components/app/signature-request-original/signature-request-original.container.js index 90b78b7349..c32e30d66f 100644 --- a/ui/app/components/app/signature-request-original/signature-request-original.container.js +++ b/ui/app/components/app/signature-request-original/signature-request-original.container.js @@ -1,18 +1,18 @@ -import { connect } from 'react-redux' -import { compose } from 'redux' -import { withRouter } from 'react-router-dom' +import { connect } from 'react-redux'; +import { compose } from 'redux'; +import { withRouter } from 'react-router-dom'; -import { MESSAGE_TYPE } from '../../../../../shared/constants/app' -import { goHome } from '../../../store/actions' +import { MESSAGE_TYPE } from '../../../../../shared/constants/app'; +import { goHome } from '../../../store/actions'; import { accountsWithSendEtherInfoSelector, conversionRateSelector, getDomainMetadata, -} from '../../../selectors' -import { getAccountByAddress } from '../../../helpers/utils/util' -import { clearConfirmTransaction } from '../../../ducks/confirm-transaction/confirm-transaction.duck' -import { getMostRecentOverviewPage } from '../../../ducks/history/history' -import SignatureRequestOriginal from './signature-request-original.component' +} from '../../../selectors'; +import { getAccountByAddress } from '../../../helpers/utils/util'; +import { clearConfirmTransaction } from '../../../ducks/confirm-transaction/confirm-transaction.duck'; +import { getMostRecentOverviewPage } from '../../../ducks/history/history'; +import SignatureRequestOriginal from './signature-request-original.component'; function mapStateToProps(state) { return { @@ -23,14 +23,14 @@ function mapStateToProps(state) { // not passed to component allAccounts: accountsWithSendEtherInfoSelector(state), domainMetadata: getDomainMetadata(state), - } + }; } function mapDispatchToProps(dispatch) { return { goHome: () => dispatch(goHome()), clearConfirmTransaction: () => dispatch(clearConfirmTransaction()), - } + }; } function mergeProps(stateProps, dispatchProps, ownProps) { @@ -42,28 +42,28 @@ function mergeProps(stateProps, dispatchProps, ownProps) { signMessage, cancelMessage, txData, - } = ownProps + } = ownProps; - const { allAccounts, ...otherStateProps } = stateProps + const { allAccounts, ...otherStateProps } = stateProps; const { type, msgParams: { from }, - } = txData + } = txData; - const fromAccount = getAccountByAddress(allAccounts, from) + const fromAccount = getAccountByAddress(allAccounts, from); - let cancel - let sign + let cancel; + let sign; if (type === MESSAGE_TYPE.PERSONAL_SIGN) { - cancel = cancelPersonalMessage - sign = signPersonalMessage + cancel = cancelPersonalMessage; + sign = signPersonalMessage; } else if (type === MESSAGE_TYPE.ETH_SIGN_TYPED_DATA) { - cancel = cancelTypedMessage - sign = signTypedMessage + cancel = cancelTypedMessage; + sign = signTypedMessage; } else if (type === MESSAGE_TYPE.ETH_SIGN) { - cancel = cancelMessage - sign = signMessage + cancel = cancelMessage; + sign = signMessage; } return { @@ -74,10 +74,10 @@ function mergeProps(stateProps, dispatchProps, ownProps) { txData, cancel, sign, - } + }; } export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps, mergeProps), -)(SignatureRequestOriginal) +)(SignatureRequestOriginal); diff --git a/ui/app/components/app/signature-request/index.js b/ui/app/components/app/signature-request/index.js index b1c8a1960d..8a01d820ee 100644 --- a/ui/app/components/app/signature-request/index.js +++ b/ui/app/components/app/signature-request/index.js @@ -1 +1 @@ -export { default } from './signature-request.container' +export { default } from './signature-request.container'; diff --git a/ui/app/components/app/signature-request/signature-request-footer/index.js b/ui/app/components/app/signature-request/signature-request-footer/index.js index 11d0b3944e..2b27bbb661 100644 --- a/ui/app/components/app/signature-request/signature-request-footer/index.js +++ b/ui/app/components/app/signature-request/signature-request-footer/index.js @@ -1 +1 @@ -export { default } from './signature-request-footer.component' +export { default } from './signature-request-footer.component'; diff --git a/ui/app/components/app/signature-request/signature-request-footer/signature-request-footer.component.js b/ui/app/components/app/signature-request/signature-request-footer/signature-request-footer.component.js index 0f925e3e33..c0a08812bf 100644 --- a/ui/app/components/app/signature-request/signature-request-footer/signature-request-footer.component.js +++ b/ui/app/components/app/signature-request/signature-request-footer/signature-request-footer.component.js @@ -1,19 +1,19 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import Button from '../../../ui/button' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import Button from '../../../ui/button'; export default class SignatureRequestFooter extends PureComponent { static propTypes = { cancelAction: PropTypes.func.isRequired, signAction: PropTypes.func.isRequired, - } + }; static contextTypes = { t: PropTypes.func, - } + }; render() { - const { cancelAction, signAction } = this.props + const { cancelAction, signAction } = this.props; return (
    - ) + ); } } diff --git a/ui/app/components/app/signature-request/signature-request-header/index.js b/ui/app/components/app/signature-request/signature-request-header/index.js index fa596383ad..b12d0cb733 100644 --- a/ui/app/components/app/signature-request/signature-request-header/index.js +++ b/ui/app/components/app/signature-request/signature-request-header/index.js @@ -1 +1 @@ -export { default } from './signature-request-header.component' +export { default } from './signature-request-header.component'; diff --git a/ui/app/components/app/signature-request/signature-request-header/signature-request-header.component.js b/ui/app/components/app/signature-request/signature-request-header/signature-request-header.component.js index 42468d276b..684a3abcef 100644 --- a/ui/app/components/app/signature-request/signature-request-header/signature-request-header.component.js +++ b/ui/app/components/app/signature-request/signature-request-header/signature-request-header.component.js @@ -1,15 +1,15 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import AccountListItem from '../../account-list-item' -import NetworkDisplay from '../../network-display' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import AccountListItem from '../../account-list-item'; +import NetworkDisplay from '../../network-display'; export default class SignatureRequestHeader extends PureComponent { static propTypes = { fromAccount: PropTypes.object, - } + }; render() { - const { fromAccount } = this.props + const { fromAccount } = this.props; return (
    @@ -20,6 +20,6 @@ export default class SignatureRequestHeader extends PureComponent {
    - ) + ); } } diff --git a/ui/app/components/app/signature-request/signature-request-message/index.js b/ui/app/components/app/signature-request/signature-request-message/index.js index e62265a5f8..5fe8ddb1ca 100644 --- a/ui/app/components/app/signature-request/signature-request-message/index.js +++ b/ui/app/components/app/signature-request/signature-request-message/index.js @@ -1 +1 @@ -export { default } from './signature-request-message.component' +export { default } from './signature-request-message.component'; diff --git a/ui/app/components/app/signature-request/signature-request-message/signature-request-message.component.js b/ui/app/components/app/signature-request/signature-request-message/signature-request-message.component.js index 848f5b38be..7802fd5910 100644 --- a/ui/app/components/app/signature-request/signature-request-message/signature-request-message.component.js +++ b/ui/app/components/app/signature-request/signature-request-message/signature-request-message.component.js @@ -1,15 +1,15 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; export default class SignatureRequestMessage extends PureComponent { static propTypes = { data: PropTypes.object.isRequired, - } + }; static contextTypes = { t: PropTypes.func, - } + }; renderNode(data) { return ( @@ -35,11 +35,11 @@ export default class SignatureRequestMessage extends PureComponent { ))} - ) + ); } render() { - const { data } = this.props + const { data } = this.props; return (
    @@ -53,6 +53,6 @@ export default class SignatureRequestMessage extends PureComponent { {this.renderNode(data)}
    - ) + ); } } diff --git a/ui/app/components/app/signature-request/signature-request.component.js b/ui/app/components/app/signature-request/signature-request.component.js index 712c5e8c2f..9515ac02ab 100644 --- a/ui/app/components/app/signature-request/signature-request.component.js +++ b/ui/app/components/app/signature-request/signature-request.component.js @@ -1,11 +1,11 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import { getEnvironmentType } from '../../../../../app/scripts/lib/util' -import Identicon from '../../ui/identicon' -import Header from './signature-request-header' -import Footer from './signature-request-footer' -import Message from './signature-request-message' -import { ENVIRONMENT_TYPE_NOTIFICATION } from './signature-request.constants' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { getEnvironmentType } from '../../../../../app/scripts/lib/util'; +import Identicon from '../../ui/identicon'; +import Header from './signature-request-header'; +import Footer from './signature-request-footer'; +import Message from './signature-request-message'; +import { ENVIRONMENT_TYPE_NOTIFICATION } from './signature-request.constants'; export default class SignatureRequest extends PureComponent { static propTypes = { @@ -19,16 +19,16 @@ export default class SignatureRequest extends PureComponent { clearConfirmTransaction: PropTypes.func.isRequired, cancel: PropTypes.func.isRequired, sign: PropTypes.func.isRequired, - } + }; static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; componentDidMount() { - const { clearConfirmTransaction, cancel } = this.props - const { metricsEvent } = this.context + const { clearConfirmTransaction, cancel } = this.props; + const { metricsEvent } = this.context; if (getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION) { window.addEventListener('beforeunload', (event) => { metricsEvent({ @@ -37,10 +37,10 @@ export default class SignatureRequest extends PureComponent { action: 'Sign Request', name: 'Cancel Sig Request Via Notification Close', }, - }) - clearConfirmTransaction() - cancel(event) - }) + }); + clearConfirmTransaction(); + cancel(event); + }); } } @@ -48,7 +48,7 @@ export default class SignatureRequest extends PureComponent { return `${wallet.slice(0, 8)}...${wallet.slice( wallet.length - 8, wallet.length, - )}` + )}`; } render() { @@ -59,9 +59,9 @@ export default class SignatureRequest extends PureComponent { }, cancel, sign, - } = this.props - const { address: fromAddress } = fromAccount - const { message, domain = {} } = JSON.parse(data) + } = this.props; + const { address: fromAddress } = fromAccount; + const { message, domain = {} } = JSON.parse(data); return (
    @@ -88,6 +88,6 @@ export default class SignatureRequest extends PureComponent {
    - ) + ); } } diff --git a/ui/app/components/app/signature-request/signature-request.constants.js b/ui/app/components/app/signature-request/signature-request.constants.js index 7311a7a18f..34ac7b40dd 100644 --- a/ui/app/components/app/signature-request/signature-request.constants.js +++ b/ui/app/components/app/signature-request/signature-request.constants.js @@ -1,3 +1,3 @@ -import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../../shared/constants/app' +import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../../shared/constants/app'; -export { ENVIRONMENT_TYPE_NOTIFICATION } +export { ENVIRONMENT_TYPE_NOTIFICATION }; diff --git a/ui/app/components/app/signature-request/signature-request.container.js b/ui/app/components/app/signature-request/signature-request.container.js index 0c69f1c7a5..4c45a256db 100644 --- a/ui/app/components/app/signature-request/signature-request.container.js +++ b/ui/app/components/app/signature-request/signature-request.container.js @@ -1,25 +1,25 @@ -import { connect } from 'react-redux' -import { clearConfirmTransaction } from '../../../ducks/confirm-transaction/confirm-transaction.duck' -import { accountsWithSendEtherInfoSelector } from '../../../selectors' -import { getAccountByAddress } from '../../../helpers/utils/util' -import { MESSAGE_TYPE } from '../../../../../shared/constants/app' -import SignatureRequest from './signature-request.component' +import { connect } from 'react-redux'; +import { clearConfirmTransaction } from '../../../ducks/confirm-transaction/confirm-transaction.duck'; +import { accountsWithSendEtherInfoSelector } from '../../../selectors'; +import { getAccountByAddress } from '../../../helpers/utils/util'; +import { MESSAGE_TYPE } from '../../../../../shared/constants/app'; +import SignatureRequest from './signature-request.component'; function mapStateToProps(state) { return { // not forwarded to component allAccounts: accountsWithSendEtherInfoSelector(state), - } + }; } function mapDispatchToProps(dispatch) { return { clearConfirmTransaction: () => dispatch(clearConfirmTransaction()), - } + }; } function mergeProps(stateProps, dispatchProps, ownProps) { - const { allAccounts } = stateProps + const { allAccounts } = stateProps; const { signPersonalMessage, signTypedMessage, @@ -28,27 +28,27 @@ function mergeProps(stateProps, dispatchProps, ownProps) { signMessage, cancelMessage, txData, - } = ownProps + } = ownProps; const { type, msgParams: { from }, - } = txData + } = txData; - const fromAccount = getAccountByAddress(allAccounts, from) + const fromAccount = getAccountByAddress(allAccounts, from); - let cancel - let sign + let cancel; + let sign; if (type === MESSAGE_TYPE.PERSONAL_SIGN) { - cancel = cancelPersonalMessage - sign = signPersonalMessage + cancel = cancelPersonalMessage; + sign = signPersonalMessage; } else if (type === MESSAGE_TYPE.ETH_SIGN_TYPED_DATA) { - cancel = cancelTypedMessage - sign = signTypedMessage + cancel = cancelTypedMessage; + sign = signTypedMessage; } else if (type === MESSAGE_TYPE.ETH_SIGN) { - cancel = cancelMessage - sign = signMessage + cancel = cancelMessage; + sign = signMessage; } return { @@ -58,11 +58,11 @@ function mergeProps(stateProps, dispatchProps, ownProps) { txData, cancel, sign, - } + }; } export default connect( mapStateToProps, mapDispatchToProps, mergeProps, -)(SignatureRequest) +)(SignatureRequest); diff --git a/ui/app/components/app/signature-request/tests/signature-request.test.js b/ui/app/components/app/signature-request/tests/signature-request.test.js index 8966c014e1..261576f166 100644 --- a/ui/app/components/app/signature-request/tests/signature-request.test.js +++ b/ui/app/components/app/signature-request/tests/signature-request.test.js @@ -1,11 +1,11 @@ -import assert from 'assert' -import React from 'react' -import shallow from '../../../../../lib/shallow-with-context' -import SignatureRequest from '../signature-request.component' +import assert from 'assert'; +import React from 'react'; +import shallow from '../../../../../lib/shallow-with-context'; +import SignatureRequest from '../signature-request.component'; describe('Signature Request Component', function () { describe('render', function () { - const fromAddress = '0x123456789abcdef' + const fromAddress = '0x123456789abcdef'; it('should render a div with one child', function () { const wrapper = shallow( , - ) + ); - assert(wrapper.is('div')) - assert.strictEqual(wrapper.length, 1) - assert(wrapper.hasClass('signature-request')) - }) - }) -}) + assert(wrapper.is('div')); + assert.strictEqual(wrapper.length, 1); + assert(wrapper.hasClass('signature-request')); + }); + }); +}); diff --git a/ui/app/components/app/tab-bar/index.js b/ui/app/components/app/tab-bar/index.js index 74f9a75292..07e3c945d5 100644 --- a/ui/app/components/app/tab-bar/index.js +++ b/ui/app/components/app/tab-bar/index.js @@ -1 +1 @@ -export { default } from './tab-bar' +export { default } from './tab-bar'; diff --git a/ui/app/components/app/tab-bar/tab-bar.js b/ui/app/components/app/tab-bar/tab-bar.js index e4f38feac5..51cefb8a76 100644 --- a/ui/app/components/app/tab-bar/tab-bar.js +++ b/ui/app/components/app/tab-bar/tab-bar.js @@ -1,9 +1,9 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; const TabBar = (props) => { - const { tabs = [], onSelect, isActive } = props + const { tabs = [], onSelect, isActive } = props; return (
    @@ -25,13 +25,13 @@ const TabBar = (props) => { ))}
    - ) -} + ); +}; TabBar.propTypes = { isActive: PropTypes.func.isRequired, tabs: PropTypes.array, onSelect: PropTypes.func, -} +}; -export default TabBar +export default TabBar; diff --git a/ui/app/components/app/tests/signature-request.test.js b/ui/app/components/app/tests/signature-request.test.js index f95bed3af4..700b99a912 100644 --- a/ui/app/components/app/tests/signature-request.test.js +++ b/ui/app/components/app/tests/signature-request.test.js @@ -1,13 +1,13 @@ -import assert from 'assert' -import React from 'react' -import { Provider } from 'react-redux' -import sinon from 'sinon' -import configureMockStore from 'redux-mock-store' -import { mountWithRouter } from '../../../../../test/lib/render-helpers' -import SignatureRequest from '../signature-request' +import assert from 'assert'; +import React from 'react'; +import { Provider } from 'react-redux'; +import sinon from 'sinon'; +import configureMockStore from 'redux-mock-store'; +import { mountWithRouter } from '../../../../../test/lib/render-helpers'; +import SignatureRequest from '../signature-request'; describe('Signature Request', function () { - let wrapper + let wrapper; const mockStore = { metamask: { @@ -23,8 +23,8 @@ describe('Signature Request', function () { cachedBalances: {}, selectedAddress: '0xd8f6a2ffb0fc5952d16c9768b71cfd35b6399aa5', }, - } - const store = configureMockStore()(mockStore) + }; + const store = configureMockStore()(mockStore); const props = { fromAccount: { @@ -49,7 +49,7 @@ describe('Signature Request', function () { time: 1, type: 'eth_sign', }, - } + }; beforeEach(function () { wrapper = mountWithRouter( @@ -57,24 +57,24 @@ describe('Signature Request', function () { , store, - ) - }) + ); + }); afterEach(function () { - props.clearConfirmTransaction.resetHistory() - }) + props.clearConfirmTransaction.resetHistory(); + }); it('cancel', function () { - const cancelButton = wrapper.find('button.btn-default') - cancelButton.simulate('click') + const cancelButton = wrapper.find('button.btn-default'); + cancelButton.simulate('click'); - assert(props.cancel.calledOnce) - }) + assert(props.cancel.calledOnce); + }); it('sign', function () { - const signButton = wrapper.find('button.btn-primary') - signButton.simulate('click') + const signButton = wrapper.find('button.btn-primary'); + signButton.simulate('click'); - assert(props.sign.calledOnce) - }) -}) + assert(props.sign.calledOnce); + }); +}); diff --git a/ui/app/components/app/token-cell/index.js b/ui/app/components/app/token-cell/index.js index c33e36adb2..3d871c9a8b 100644 --- a/ui/app/components/app/token-cell/index.js +++ b/ui/app/components/app/token-cell/index.js @@ -1 +1 @@ -export { default } from './token-cell' +export { default } from './token-cell'; diff --git a/ui/app/components/app/token-cell/token-cell.js b/ui/app/components/app/token-cell/token-cell.js index 9c3a4bcff1..777e9b5607 100644 --- a/ui/app/components/app/token-cell/token-cell.js +++ b/ui/app/components/app/token-cell/token-cell.js @@ -1,11 +1,11 @@ -import classnames from 'classnames' -import PropTypes from 'prop-types' -import React from 'react' -import { useSelector } from 'react-redux' -import AssetListItem from '../asset-list-item' -import { getSelectedAddress } from '../../../selectors' -import { useI18nContext } from '../../../hooks/useI18nContext' -import { useTokenFiatAmount } from '../../../hooks/useTokenFiatAmount' +import classnames from 'classnames'; +import PropTypes from 'prop-types'; +import React from 'react'; +import { useSelector } from 'react-redux'; +import AssetListItem from '../asset-list-item'; +import { getSelectedAddress } from '../../../selectors'; +import { useI18nContext } from '../../../hooks/useI18nContext'; +import { useTokenFiatAmount } from '../../../hooks/useTokenFiatAmount'; export default function TokenCell({ address, @@ -16,10 +16,10 @@ export default function TokenCell({ image, onClick, }) { - const userAddress = useSelector(getSelectedAddress) - const t = useI18nContext() + const userAddress = useSelector(getSelectedAddress); + const t = useI18nContext(); - const formattedFiat = useTokenFiatAmount(address, string, symbol) + const formattedFiat = useTokenFiatAmount(address, string, symbol); const warning = balanceError ? ( @@ -34,7 +34,7 @@ export default function TokenCell({ {t('here')} - ) : null + ) : null; return ( - ) + ); } TokenCell.propTypes = { @@ -62,8 +62,8 @@ TokenCell.propTypes = { string: PropTypes.string, image: PropTypes.string, onClick: PropTypes.func.isRequired, -} +}; TokenCell.defaultProps = { balanceError: null, -} +}; diff --git a/ui/app/components/app/token-cell/token-cell.test.js b/ui/app/components/app/token-cell/token-cell.test.js index 08b4e545d3..6771024185 100644 --- a/ui/app/components/app/token-cell/token-cell.test.js +++ b/ui/app/components/app/token-cell/token-cell.test.js @@ -1,17 +1,17 @@ -import assert from 'assert' -import React from 'react' -import thunk from 'redux-thunk' -import { Provider } from 'react-redux' -import configureMockStore from 'redux-mock-store' -import { mount } from 'enzyme' -import sinon from 'sinon' -import { MemoryRouter } from 'react-router-dom' +import assert from 'assert'; +import React from 'react'; +import thunk from 'redux-thunk'; +import { Provider } from 'react-redux'; +import configureMockStore from 'redux-mock-store'; +import { mount } from 'enzyme'; +import sinon from 'sinon'; +import { MemoryRouter } from 'react-router-dom'; -import Identicon from '../../ui/identicon' -import TokenCell from '.' +import Identicon from '../../ui/identicon'; +import TokenCell from '.'; describe('Token Cell', function () { - let wrapper + let wrapper; const state = { metamask: { @@ -33,16 +33,16 @@ describe('Token Cell', function () { isOpen: true, }, }, - } + }; - const middlewares = [thunk] - const mockStore = configureMockStore(middlewares) - const store = mockStore(state) + const middlewares = [thunk]; + const mockStore = configureMockStore(middlewares); + const store = mockStore(state); - let onClick + let onClick; beforeEach(function () { - onClick = sinon.stub() + onClick = sinon.stub(); wrapper = mount( @@ -56,45 +56,45 @@ describe('Token Cell', function () { /> , - ) - }) + ); + }); afterEach(function () { - sinon.restore() - }) + sinon.restore(); + }); it('renders Identicon with props from token cell', function () { assert.strictEqual( wrapper.find(Identicon).prop('address'), '0xAnotherToken', - ) - assert.strictEqual(wrapper.find(Identicon).prop('image'), './test-image') - }) + ); + assert.strictEqual(wrapper.find(Identicon).prop('image'), './test-image'); + }); it('renders token balance', function () { assert.strictEqual( wrapper.find('.asset-list-item__token-value').text(), '5.000', - ) - }) + ); + }); it('renders token symbol', function () { assert.strictEqual( wrapper.find('.asset-list-item__token-symbol').text(), 'TEST', - ) - }) + ); + }); it('renders converted fiat amount', function () { assert.strictEqual( wrapper.find('.list-item__subheading').text(), '$0.52 USD', - ) - }) + ); + }); it('calls onClick when clicked', function () { - assert.ok(!onClick.called) - wrapper.simulate('click') - assert.ok(onClick.called) - }) -}) + assert.ok(!onClick.called); + wrapper.simulate('click'); + assert.ok(onClick.called); + }); +}); diff --git a/ui/app/components/app/token-list/index.js b/ui/app/components/app/token-list/index.js index 613fc96682..b07c45d746 100644 --- a/ui/app/components/app/token-list/index.js +++ b/ui/app/components/app/token-list/index.js @@ -1 +1 @@ -export { default } from './token-list' +export { default } from './token-list'; diff --git a/ui/app/components/app/token-list/token-list.js b/ui/app/components/app/token-list/token-list.js index f01726dc42..298dda081d 100644 --- a/ui/app/components/app/token-list/token-list.js +++ b/ui/app/components/app/token-list/token-list.js @@ -1,22 +1,22 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { isEqual } from 'lodash' +import React from 'react'; +import PropTypes from 'prop-types'; +import { isEqual } from 'lodash'; -import { useSelector } from 'react-redux' -import TokenCell from '../token-cell' -import { useI18nContext } from '../../../hooks/useI18nContext' -import { useTokenTracker } from '../../../hooks/useTokenTracker' -import { getAssetImages } from '../../../selectors' -import { getTokens } from '../../../ducks/metamask/metamask' +import { useSelector } from 'react-redux'; +import TokenCell from '../token-cell'; +import { useI18nContext } from '../../../hooks/useI18nContext'; +import { useTokenTracker } from '../../../hooks/useTokenTracker'; +import { getAssetImages } from '../../../selectors'; +import { getTokens } from '../../../ducks/metamask/metamask'; export default function TokenList({ onTokenClick }) { - const t = useI18nContext() - const assetImages = useSelector(getAssetImages) + const t = useI18nContext(); + const assetImages = useSelector(getAssetImages); // use `isEqual` comparison function because the token array is serialized // from the background so it has a new reference with each background update, // even if the tokens haven't changed - const tokens = useSelector(getTokens, isEqual) - const { loading, tokensWithBalances } = useTokenTracker(tokens, true) + const tokens = useSelector(getTokens, isEqual); + const { loading, tokensWithBalances } = useTokenTracker(tokens, true); if (loading) { return ( @@ -31,19 +31,19 @@ export default function TokenList({ onTokenClick }) { > {t('loadingTokens')} - ) + ); } return (
    {tokensWithBalances.map((tokenData, index) => { - tokenData.image = assetImages[tokenData.address] - return + tokenData.image = assetImages[tokenData.address]; + return ; })}
    - ) + ); } TokenList.propTypes = { onTokenClick: PropTypes.func.isRequired, -} +}; diff --git a/ui/app/components/app/transaction-activity-log/index.js b/ui/app/components/app/transaction-activity-log/index.js index a33da15a3b..c9e02fc86c 100644 --- a/ui/app/components/app/transaction-activity-log/index.js +++ b/ui/app/components/app/transaction-activity-log/index.js @@ -1 +1 @@ -export { default } from './transaction-activity-log.container' +export { default } from './transaction-activity-log.container'; diff --git a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.component.test.js b/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.component.test.js index d07f987645..149ebd4c42 100644 --- a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.component.test.js +++ b/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.component.test.js @@ -1,7 +1,7 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import TransactionActivityLog from '../transaction-activity-log.component' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import TransactionActivityLog from '../transaction-activity-log.component'; describe('TransactionActivityLog Component', function () { it('should render properly', function () { @@ -38,7 +38,7 @@ describe('TransactionActivityLog Component', function () { timestamp: 1543958029960, value: '0x1502634b5800', }, - ] + ]; const wrapper = shallow( , { context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) } }, - ) + ); - assert.ok(wrapper.hasClass('transaction-activity-log')) - assert.ok(wrapper.hasClass('test-class')) - }) + assert.ok(wrapper.hasClass('transaction-activity-log')); + assert.ok(wrapper.hasClass('test-class')); + }); it('should render inline retry and cancel buttons for earliest pending transaction', function () { const activities = [ @@ -90,7 +90,7 @@ describe('TransactionActivityLog Component', function () { timestamp: 4, value: '0x1', }, - ] + ]; const wrapper = shallow( , { context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) } }, - ) + ); - assert.ok(wrapper.hasClass('transaction-activity-log')) - assert.ok(wrapper.hasClass('test-class')) + assert.ok(wrapper.hasClass('transaction-activity-log')); + assert.ok(wrapper.hasClass('test-class')); assert.strictEqual( wrapper.find('.transaction-activity-log__action-link').length, 2, - ) - }) + ); + }); it('should not render inline retry and cancel buttons for newer pending transactions', function () { const activities = [ @@ -147,7 +147,7 @@ describe('TransactionActivityLog Component', function () { timestamp: 4, value: '0x1', }, - ] + ]; const wrapper = shallow( , { context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) } }, - ) + ); - assert.ok(wrapper.hasClass('transaction-activity-log')) - assert.ok(wrapper.hasClass('test-class')) + assert.ok(wrapper.hasClass('transaction-activity-log')); + assert.ok(wrapper.hasClass('test-class')); assert.strictEqual( wrapper.find('.transaction-activity-log__action-link').length, 0, - ) - }) -}) + ); + }); +}); diff --git a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.container.test.js b/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.container.test.js index f54f2ce945..b1608684c9 100644 --- a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.container.test.js +++ b/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.container.test.js @@ -1,16 +1,16 @@ -import assert from 'assert' -import proxyquire from 'proxyquire' +import assert from 'assert'; +import proxyquire from 'proxyquire'; -let mapStateToProps +let mapStateToProps; proxyquire('../transaction-activity-log.container.js', { 'react-redux': { connect: (ms) => { - mapStateToProps = ms - return () => ({}) + mapStateToProps = ms; + return () => ({}); }, }, -}) +}); describe('TransactionActivityLog container', function () { describe('mapStateToProps()', function () { @@ -20,12 +20,12 @@ describe('TransactionActivityLog container', function () { conversionRate: 280.45, nativeCurrency: 'ETH', }, - } + }; assert.deepStrictEqual(mapStateToProps(mockState), { conversionRate: 280.45, nativeCurrency: 'ETH', - }) - }) - }) -}) + }); + }); + }); +}); diff --git a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.util.test.js b/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.util.test.js index 8b03326db0..e01a5a9de6 100644 --- a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.util.test.js +++ b/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.util.test.js @@ -1,18 +1,18 @@ -import assert from 'assert' +import assert from 'assert'; import { TRANSACTION_STATUSES, TRANSACTION_TYPES, -} from '../../../../../../shared/constants/transaction' +} from '../../../../../../shared/constants/transaction'; import { combineTransactionHistories, getActivities, -} from '../transaction-activity-log.util' +} from '../transaction-activity-log.util'; describe('TransactionActivityLog utils', function () { describe('combineTransactionHistories', function () { it('should return no activities for an empty list of transactions', function () { - assert.deepStrictEqual(combineTransactionHistories([]), []) - }) + assert.deepStrictEqual(combineTransactionHistories([]), []); + }); it('should return activities for an array of transactions', function () { const transactions = [ @@ -180,7 +180,7 @@ describe('TransactionActivityLog utils', function () { }, type: TRANSACTION_TYPES.RETRY, }, - ] + ]; const expected = [ { @@ -215,14 +215,14 @@ describe('TransactionActivityLog utils', function () { timestamp: 1543958897165, value: '0x171c3a061400', }, - ] + ]; assert.deepStrictEqual( combineTransactionHistories(transactions), expected, - ) - }) - }) + ); + }); + }); describe('getActivities', function () { it('should return no activities for an empty history', function () { @@ -238,10 +238,10 @@ describe('TransactionActivityLog utils', function () { to: '0x2', value: '0x2386f26fc10000', }, - } + }; - assert.deepStrictEqual(getActivities(transaction), []) - }) + assert.deepStrictEqual(getActivities(transaction), []); + }); it("should return activities for a transaction's history", function () { const transaction = { @@ -389,7 +389,7 @@ describe('TransactionActivityLog utils', function () { value: '0x2386f26fc10000', }, hash: '0xabc', - } + }; const expectedResult = [ { @@ -413,9 +413,9 @@ describe('TransactionActivityLog utils', function () { id: 1, hash: '0xabc', }, - ] + ]; - assert.deepStrictEqual(getActivities(transaction, true), expectedResult) - }) - }) -}) + assert.deepStrictEqual(getActivities(transaction, true), expectedResult); + }); + }); +}); diff --git a/ui/app/components/app/transaction-activity-log/transaction-activity-log-icon/index.js b/ui/app/components/app/transaction-activity-log/transaction-activity-log-icon/index.js index 86b12360a1..7d36bdef97 100644 --- a/ui/app/components/app/transaction-activity-log/transaction-activity-log-icon/index.js +++ b/ui/app/components/app/transaction-activity-log/transaction-activity-log-icon/index.js @@ -1 +1 @@ -export { default } from './transaction-activity-log-icon.component' +export { default } from './transaction-activity-log-icon.component'; diff --git a/ui/app/components/app/transaction-activity-log/transaction-activity-log-icon/transaction-activity-log-icon.component.js b/ui/app/components/app/transaction-activity-log/transaction-activity-log-icon/transaction-activity-log-icon.component.js index f00b493e18..9e1c913552 100644 --- a/ui/app/components/app/transaction-activity-log/transaction-activity-log-icon/transaction-activity-log-icon.component.js +++ b/ui/app/components/app/transaction-activity-log/transaction-activity-log-icon/transaction-activity-log-icon.component.js @@ -1,6 +1,6 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; import { TRANSACTION_CREATED_EVENT, @@ -11,7 +11,7 @@ import { TRANSACTION_ERRORED_EVENT, TRANSACTION_CANCEL_ATTEMPTED_EVENT, TRANSACTION_CANCEL_SUCCESS_EVENT, -} from '../transaction-activity-log.constants' +} from '../transaction-activity-log.constants'; const imageHash = { [TRANSACTION_CREATED_EVENT]: '/images/icons/new.svg', @@ -22,26 +22,26 @@ const imageHash = { [TRANSACTION_ERRORED_EVENT]: '/images/icons/error.svg', [TRANSACTION_CANCEL_ATTEMPTED_EVENT]: '/images/icons/cancelled.svg', [TRANSACTION_CANCEL_SUCCESS_EVENT]: '/images/icons/cancelled.svg', -} +}; export default class TransactionActivityLogIcon extends PureComponent { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { className: PropTypes.string, eventKey: PropTypes.oneOf(Object.keys(imageHash)), - } + }; render() { - const { className, eventKey } = this.props - const imagePath = imageHash[eventKey] + const { className, eventKey } = this.props; + const imagePath = imageHash[eventKey]; return (
    {imagePath && }
    - ) + ); } } diff --git a/ui/app/components/app/transaction-activity-log/transaction-activity-log.component.js b/ui/app/components/app/transaction-activity-log/transaction-activity-log.component.js index 9320a1ac29..ef38504c04 100644 --- a/ui/app/components/app/transaction-activity-log/transaction-activity-log.component.js +++ b/ui/app/components/app/transaction-activity-log/transaction-activity-log.component.js @@ -1,20 +1,20 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; import { getEthConversionFromWeiHex, getValueFromWeiHex, -} from '../../../helpers/utils/conversions.util' -import { formatDate } from '../../../helpers/utils/util' -import { getEtherscanNetworkPrefix } from '../../../../lib/etherscan-prefix-for-network' -import TransactionActivityLogIcon from './transaction-activity-log-icon' -import { CONFIRMED_STATUS } from './transaction-activity-log.constants' +} from '../../../helpers/utils/conversions.util'; +import { formatDate } from '../../../helpers/utils/util'; +import { getEtherscanNetworkPrefix } from '../../../../lib/etherscan-prefix-for-network'; +import TransactionActivityLogIcon from './transaction-activity-log-icon'; +import { CONFIRMED_STATUS } from './transaction-activity-log.constants'; export default class TransactionActivityLog extends PureComponent { static contextTypes = { t: PropTypes.func, metricEvent: PropTypes.func, - } + }; static propTypes = { activities: PropTypes.array, @@ -27,27 +27,27 @@ export default class TransactionActivityLog extends PureComponent { onRetry: PropTypes.func, primaryTransaction: PropTypes.object, isEarliestNonce: PropTypes.bool, - } + }; handleActivityClick = (hash) => { - const { primaryTransaction } = this.props - const { metamaskNetworkId } = primaryTransaction + const { primaryTransaction } = this.props; + const { metamaskNetworkId } = primaryTransaction; - const prefix = getEtherscanNetworkPrefix(metamaskNetworkId) - const etherscanUrl = `https://${prefix}etherscan.io/tx/${hash}` + const prefix = getEtherscanNetworkPrefix(metamaskNetworkId); + const etherscanUrl = `https://${prefix}etherscan.io/tx/${hash}`; - global.platform.openTab({ url: etherscanUrl }) - } + global.platform.openTab({ url: etherscanUrl }); + }; renderInlineRetry(index) { - const { t } = this.context + const { t } = this.context; const { inlineRetryIndex, primaryTransaction = {}, onRetry, isEarliestNonce, - } = this.props - const { status } = primaryTransaction + } = this.props; + const { status } = primaryTransaction; return isEarliestNonce && status !== CONFIRMED_STATUS && @@ -55,18 +55,18 @@ export default class TransactionActivityLog extends PureComponent {
    {t('speedUpTransaction')}
    - ) : null + ) : null; } renderInlineCancel(index) { - const { t } = this.context + const { t } = this.context; const { inlineCancelIndex, primaryTransaction = {}, onCancel, isEarliestNonce, - } = this.props - const { status } = primaryTransaction + } = this.props; + const { status } = primaryTransaction; return isEarliestNonce && status !== CONFIRMED_STATUS && @@ -74,12 +74,12 @@ export default class TransactionActivityLog extends PureComponent {
    {t('speedUpCancellation')}
    - ) : null + ) : null; } renderActivity(activity, index) { - const { conversionRate, nativeCurrency } = this.props - const { eventKey, value, timestamp, hash } = activity + const { conversionRate, nativeCurrency } = this.props; + const { eventKey, value, timestamp, hash } = activity; const ethValue = index === 0 ? `${getValueFromWeiHex({ @@ -94,12 +94,12 @@ export default class TransactionActivityLog extends PureComponent { fromCurrency: 'ETH', conversionRate, numberOfDecimals: 3, - }) - const formattedTimestamp = formatDate(timestamp, "T 'on' M/d/y") + }); + const formattedTimestamp = formatDate(timestamp, "T 'on' M/d/y"); const activityText = this.context.t(eventKey, [ ethValue, formattedTimestamp, - ]) + ]); return (
    @@ -119,15 +119,15 @@ export default class TransactionActivityLog extends PureComponent { {this.renderInlineCancel(index)}
    - ) + ); } render() { - const { t } = this.context - const { className, activities } = this.props + const { t } = this.context; + const { className, activities } = this.props; if (activities.length === 0) { - return null + return null; } return ( @@ -141,6 +141,6 @@ export default class TransactionActivityLog extends PureComponent { )} - ) + ); } } diff --git a/ui/app/components/app/transaction-activity-log/transaction-activity-log.constants.js b/ui/app/components/app/transaction-activity-log/transaction-activity-log.constants.js index 72e63d85c6..367eae150c 100644 --- a/ui/app/components/app/transaction-activity-log/transaction-activity-log.constants.js +++ b/ui/app/components/app/transaction-activity-log/transaction-activity-log.constants.js @@ -1,13 +1,13 @@ -export const TRANSACTION_CREATED_EVENT = 'transactionCreated' -export const TRANSACTION_SUBMITTED_EVENT = 'transactionSubmitted' -export const TRANSACTION_RESUBMITTED_EVENT = 'transactionResubmitted' -export const TRANSACTION_CONFIRMED_EVENT = 'transactionConfirmed' -export const TRANSACTION_DROPPED_EVENT = 'transactionDropped' -export const TRANSACTION_UPDATED_EVENT = 'transactionUpdated' -export const TRANSACTION_ERRORED_EVENT = 'transactionErrored' -export const TRANSACTION_CANCEL_ATTEMPTED_EVENT = 'transactionCancelAttempted' -export const TRANSACTION_CANCEL_SUCCESS_EVENT = 'transactionCancelSuccess' +export const TRANSACTION_CREATED_EVENT = 'transactionCreated'; +export const TRANSACTION_SUBMITTED_EVENT = 'transactionSubmitted'; +export const TRANSACTION_RESUBMITTED_EVENT = 'transactionResubmitted'; +export const TRANSACTION_CONFIRMED_EVENT = 'transactionConfirmed'; +export const TRANSACTION_DROPPED_EVENT = 'transactionDropped'; +export const TRANSACTION_UPDATED_EVENT = 'transactionUpdated'; +export const TRANSACTION_ERRORED_EVENT = 'transactionErrored'; +export const TRANSACTION_CANCEL_ATTEMPTED_EVENT = 'transactionCancelAttempted'; +export const TRANSACTION_CANCEL_SUCCESS_EVENT = 'transactionCancelSuccess'; -export const SUBMITTED_STATUS = 'submitted' -export const CONFIRMED_STATUS = 'confirmed' -export const DROPPED_STATUS = 'dropped' +export const SUBMITTED_STATUS = 'submitted'; +export const CONFIRMED_STATUS = 'confirmed'; +export const DROPPED_STATUS = 'dropped'; diff --git a/ui/app/components/app/transaction-activity-log/transaction-activity-log.container.js b/ui/app/components/app/transaction-activity-log/transaction-activity-log.container.js index 07339193d0..bea5e6f7a4 100644 --- a/ui/app/components/app/transaction-activity-log/transaction-activity-log.container.js +++ b/ui/app/components/app/transaction-activity-log/transaction-activity-log.container.js @@ -1,38 +1,38 @@ -import { connect } from 'react-redux' -import { findLastIndex } from 'lodash' -import { conversionRateSelector, getNativeCurrency } from '../../../selectors' -import TransactionActivityLog from './transaction-activity-log.component' -import { combineTransactionHistories } from './transaction-activity-log.util' +import { connect } from 'react-redux'; +import { findLastIndex } from 'lodash'; +import { conversionRateSelector, getNativeCurrency } from '../../../selectors'; +import TransactionActivityLog from './transaction-activity-log.component'; +import { combineTransactionHistories } from './transaction-activity-log.util'; import { TRANSACTION_RESUBMITTED_EVENT, TRANSACTION_CANCEL_ATTEMPTED_EVENT, -} from './transaction-activity-log.constants' +} from './transaction-activity-log.constants'; const matchesEventKey = (matchEventKey) => ({ eventKey }) => - eventKey === matchEventKey + eventKey === matchEventKey; const mapStateToProps = (state) => { return { conversionRate: conversionRateSelector(state), nativeCurrency: getNativeCurrency(state), - } -} + }; +}; const mergeProps = (stateProps, dispatchProps, ownProps) => { const { transactionGroup: { transactions = [], primaryTransaction } = {}, ...restOwnProps - } = ownProps + } = ownProps; - const activities = combineTransactionHistories(transactions) + const activities = combineTransactionHistories(transactions); const inlineRetryIndex = findLastIndex( activities, matchesEventKey(TRANSACTION_RESUBMITTED_EVENT), - ) + ); const inlineCancelIndex = findLastIndex( activities, matchesEventKey(TRANSACTION_CANCEL_ATTEMPTED_EVENT), - ) + ); return { ...stateProps, @@ -42,11 +42,11 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { inlineRetryIndex, inlineCancelIndex, primaryTransaction, - } -} + }; +}; export default connect( mapStateToProps, null, mergeProps, -)(TransactionActivityLog) +)(TransactionActivityLog); diff --git a/ui/app/components/app/transaction-activity-log/transaction-activity-log.util.js b/ui/app/components/app/transaction-activity-log/transaction-activity-log.util.js index 8b7b7ba249..0846b85bcb 100644 --- a/ui/app/components/app/transaction-activity-log/transaction-activity-log.util.js +++ b/ui/app/components/app/transaction-activity-log/transaction-activity-log.util.js @@ -1,5 +1,5 @@ -import { TRANSACTION_TYPES } from '../../../../../shared/constants/transaction' -import { getHexGasTotal } from '../../../helpers/utils/confirm-tx.util' +import { TRANSACTION_TYPES } from '../../../../../shared/constants/transaction'; +import { getHexGasTotal } from '../../../helpers/utils/confirm-tx.util'; import { // event constants @@ -16,27 +16,27 @@ import { SUBMITTED_STATUS, CONFIRMED_STATUS, DROPPED_STATUS, -} from './transaction-activity-log.constants' +} from './transaction-activity-log.constants'; // path constants -const STATUS_PATH = '/status' -const GAS_PRICE_PATH = '/txParams/gasPrice' -const GAS_LIMIT_PATH = '/txParams/gas' +const STATUS_PATH = '/status'; +const GAS_PRICE_PATH = '/txParams/gasPrice'; +const GAS_LIMIT_PATH = '/txParams/gas'; // op constants -const REPLACE_OP = 'replace' +const REPLACE_OP = 'replace'; const eventPathsHash = { [STATUS_PATH]: true, [GAS_PRICE_PATH]: true, [GAS_LIMIT_PATH]: true, -} +}; const statusHash = { [SUBMITTED_STATUS]: TRANSACTION_SUBMITTED_EVENT, [CONFIRMED_STATUS]: TRANSACTION_CONFIRMED_EVENT, [DROPPED_STATUS]: TRANSACTION_DROPPED_EVENT, -} +}; /** * @name getActivities @@ -54,10 +54,10 @@ export function getActivities(transaction, isFirstTransaction = false) { txParams: { gas: paramsGasLimit, gasPrice: paramsGasPrice }, xReceipt: { status } = {}, type, - } = transaction + } = transaction; - let cachedGasLimit = '0x0' - let cachedGasPrice = '0x0' + let cachedGasLimit = '0x0'; + let cachedGasPrice = '0x0'; const historyActivities = history.reduce((acc, base, index) => { // First history item should be transaction creation @@ -65,12 +65,12 @@ export function getActivities(transaction, isFirstTransaction = false) { const { time: timestamp, txParams: { value, gas = '0x0', gasPrice = '0x0' } = {}, - } = base + } = base; // The cached gas limit and gas price are used to display the gas fee in the activity log. We // need to cache these values because the status update history events don't provide us with // the latest gas limit and gas price. - cachedGasLimit = gas - cachedGasPrice = gasPrice + cachedGasLimit = gas; + cachedGasPrice = gasPrice; if (isFirstTransaction) { return acc.concat({ @@ -79,17 +79,17 @@ export function getActivities(transaction, isFirstTransaction = false) { eventKey: TRANSACTION_CREATED_EVENT, timestamp, value, - }) + }); } // An entry in the history may be an array of more sub-entries. } else if (Array.isArray(base)) { - const events = [] + const events = []; base.forEach((entry) => { - const { op, path, value, timestamp: entryTimestamp } = entry + const { op, path, value, timestamp: entryTimestamp } = entry; // Not all sub-entries in a history entry have a timestamp. If the sub-entry does not have a // timestamp, the first sub-entry in a history entry should. - const timestamp = entryTimestamp || (base[0] && base[0].timestamp) + const timestamp = entryTimestamp || (base[0] && base[0].timestamp); if (path in eventPathsHash && op === REPLACE_OP) { switch (path) { @@ -103,22 +103,22 @@ export function getActivities(transaction, isFirstTransaction = false) { : getHexGasTotal({ gasLimit: cachedGasLimit, gasPrice: cachedGasPrice, - }) + }); if (value in statusHash) { - let eventKey = statusHash[value] + let eventKey = statusHash[value]; // If the status is 'submitted', we need to determine whether the event is a // transaction retry or a cancellation attempt. if (value === SUBMITTED_STATUS) { if (type === TRANSACTION_TYPES.RETRY) { - eventKey = TRANSACTION_RESUBMITTED_EVENT + eventKey = TRANSACTION_RESUBMITTED_EVENT; } else if (type === TRANSACTION_TYPES.CANCEL) { - eventKey = TRANSACTION_CANCEL_ATTEMPTED_EVENT + eventKey = TRANSACTION_CANCEL_ATTEMPTED_EVENT; } } else if (value === CONFIRMED_STATUS) { if (type === TRANSACTION_TYPES.CANCEL) { - eventKey = TRANSACTION_CANCEL_SUCCESS_EVENT + eventKey = TRANSACTION_CANCEL_SUCCESS_EVENT; } } @@ -128,10 +128,10 @@ export function getActivities(transaction, isFirstTransaction = false) { eventKey, timestamp, value: gasFee, - }) + }); } - break + break; } // If the gas price or gas limit has been changed, we update the gasFee of the @@ -139,13 +139,13 @@ export function getActivities(transaction, isFirstTransaction = false) { // changed at the confirm screen. case GAS_PRICE_PATH: case GAS_LIMIT_PATH: { - const lastEvent = events[events.length - 1] || {} - const { lastEventKey } = lastEvent + const lastEvent = events[events.length - 1] || {}; + const { lastEventKey } = lastEvent; if (path === GAS_LIMIT_PATH) { - cachedGasLimit = value + cachedGasLimit = value; } else if (path === GAS_PRICE_PATH) { - cachedGasPrice = value + cachedGasPrice = value; } if ( @@ -155,10 +155,10 @@ export function getActivities(transaction, isFirstTransaction = false) { lastEvent.value = getHexGasTotal({ gasLimit: cachedGasLimit, gasPrice: cachedGasPrice, - }) + }); } - break + break; } default: { @@ -167,17 +167,17 @@ export function getActivities(transaction, isFirstTransaction = false) { hash, eventKey: TRANSACTION_UPDATED_EVENT, timestamp, - }) + }); } } } - }) + }); - return acc.concat(events) + return acc.concat(events); } - return acc - }, []) + return acc; + }, []); // If txReceipt.status is '0x0', that means that an on-chain error occurred for the transaction, // so we add an error entry to the Activity Log. @@ -187,7 +187,7 @@ export function getActivities(transaction, isFirstTransaction = false) { hash, eventKey: TRANSACTION_ERRORED_EVENT, }) - : historyActivities + : historyActivities; } /** @@ -200,28 +200,28 @@ export function getActivities(transaction, isFirstTransaction = false) { * @returns {Array} */ function filterSortedActivities(activities) { - const filteredActivities = [] + const filteredActivities = []; const hasConfirmedActivity = Boolean( activities.find( ({ eventKey }) => eventKey === TRANSACTION_CONFIRMED_EVENT || eventKey === TRANSACTION_CANCEL_SUCCESS_EVENT, ), - ) - let addedDroppedActivity = false + ); + let addedDroppedActivity = false; activities.forEach((activity) => { if (activity.eventKey === TRANSACTION_DROPPED_EVENT) { if (!hasConfirmedActivity && !addedDroppedActivity) { - filteredActivities.push(activity) - addedDroppedActivity = true + filteredActivities.push(activity); + addedDroppedActivity = true; } } else { - filteredActivities.push(activity) + filteredActivities.push(activity); } - }) + }); - return filteredActivities + return filteredActivities; } /** @@ -231,19 +231,19 @@ function filterSortedActivities(activities) { */ export function combineTransactionHistories(transactions = []) { if (!transactions.length) { - return [] + return []; } - const activities = [] + const activities = []; transactions.forEach((transaction, index) => { // The first transaction should be the transaction with the earliest submittedTime. We show the // 'created' and 'submitted' activities here. All subsequent transactions will use 'resubmitted' // instead. - const transactionActivities = getActivities(transaction, index === 0) - activities.push(...transactionActivities) - }) + const transactionActivities = getActivities(transaction, index === 0); + activities.push(...transactionActivities); + }); - const sortedActivities = activities.sort((a, b) => a.timestamp - b.timestamp) - return filterSortedActivities(sortedActivities) + const sortedActivities = activities.sort((a, b) => a.timestamp - b.timestamp); + return filterSortedActivities(sortedActivities); } diff --git a/ui/app/components/app/transaction-breakdown/index.js b/ui/app/components/app/transaction-breakdown/index.js index 4a5b526639..61d6fef97e 100644 --- a/ui/app/components/app/transaction-breakdown/index.js +++ b/ui/app/components/app/transaction-breakdown/index.js @@ -1 +1 @@ -export { default } from './transaction-breakdown.container' +export { default } from './transaction-breakdown.container'; diff --git a/ui/app/components/app/transaction-breakdown/tests/transaction-breakdown.component.test.js b/ui/app/components/app/transaction-breakdown/tests/transaction-breakdown.component.test.js index a4baa21b28..1e4b89a8f5 100644 --- a/ui/app/components/app/transaction-breakdown/tests/transaction-breakdown.component.test.js +++ b/ui/app/components/app/transaction-breakdown/tests/transaction-breakdown.component.test.js @@ -1,8 +1,8 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import TransactionBreakdown from '../transaction-breakdown.component' -import { TRANSACTION_STATUSES } from '../../../../../../shared/constants/transaction' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import TransactionBreakdown from '../transaction-breakdown.component'; +import { TRANSACTION_STATUSES } from '../../../../../../shared/constants/transaction'; describe('TransactionBreakdown Component', function () { it('should render properly', function () { @@ -18,14 +18,14 @@ describe('TransactionBreakdown Component', function () { to: '0x2', value: '0x2386f26fc10000', }, - } + }; const wrapper = shallow( , { context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) } }, - ) + ); - assert.ok(wrapper.hasClass('transaction-breakdown')) - assert.ok(wrapper.hasClass('test-class')) - }) -}) + assert.ok(wrapper.hasClass('transaction-breakdown')); + assert.ok(wrapper.hasClass('test-class')); + }); +}); diff --git a/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/index.js b/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/index.js index 557bf75fb7..a661081c6f 100644 --- a/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/index.js +++ b/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/index.js @@ -1 +1 @@ -export { default } from './transaction-breakdown-row.component' +export { default } from './transaction-breakdown-row.component'; diff --git a/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/tests/transaction-breakdown-row.component.test.js b/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/tests/transaction-breakdown-row.component.test.js index db5ebef70e..70929e527a 100644 --- a/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/tests/transaction-breakdown-row.component.test.js +++ b/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/tests/transaction-breakdown-row.component.test.js @@ -1,8 +1,8 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import TransactionBreakdownRow from '../transaction-breakdown-row.component' -import Button from '../../../../ui/button' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import TransactionBreakdownRow from '../transaction-breakdown-row.component'; +import Button from '../../../../ui/button'; describe('TransactionBreakdownRow Component', function () { it('should render text properly', function () { @@ -11,18 +11,18 @@ describe('TransactionBreakdownRow Component', function () { Test , { context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) } }, - ) + ); - assert.ok(wrapper.hasClass('transaction-breakdown-row')) + assert.ok(wrapper.hasClass('transaction-breakdown-row')); assert.strictEqual( wrapper.find('.transaction-breakdown-row__title').text(), 'test', - ) + ); assert.strictEqual( wrapper.find('.transaction-breakdown-row__value').text(), 'Test', - ) - }) + ); + }); it('should render components properly', function () { const wrapper = shallow( @@ -30,13 +30,13 @@ describe('TransactionBreakdownRow Component', function () { , { context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) } }, - ) + ); - assert.ok(wrapper.hasClass('transaction-breakdown-row')) + assert.ok(wrapper.hasClass('transaction-breakdown-row')); assert.strictEqual( wrapper.find('.transaction-breakdown-row__title').text(), 'test', - ) - assert.ok(wrapper.find('.transaction-breakdown-row__value').find(Button)) - }) -}) + ); + assert.ok(wrapper.find('.transaction-breakdown-row__value').find(Button)); + }); +}); diff --git a/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/transaction-breakdown-row.component.js b/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/transaction-breakdown-row.component.js index ce652f02d5..2668811b1f 100644 --- a/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/transaction-breakdown-row.component.js +++ b/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/transaction-breakdown-row.component.js @@ -1,22 +1,22 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; export default class TransactionBreakdownRow extends PureComponent { static propTypes = { title: PropTypes.string, children: PropTypes.node, className: PropTypes.string, - } + }; render() { - const { title, children, className } = this.props + const { title, children, className } = this.props; return (
    {title}
    {children}
    - ) + ); } } diff --git a/ui/app/components/app/transaction-breakdown/transaction-breakdown.component.js b/ui/app/components/app/transaction-breakdown/transaction-breakdown.component.js index 3e4259f4b7..4698819cf1 100644 --- a/ui/app/components/app/transaction-breakdown/transaction-breakdown.component.js +++ b/ui/app/components/app/transaction-breakdown/transaction-breakdown.component.js @@ -1,16 +1,16 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import CurrencyDisplay from '../../ui/currency-display' -import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display' -import HexToDecimal from '../../ui/hex-to-decimal' -import { GWEI, PRIMARY, SECONDARY } from '../../../helpers/constants/common' -import TransactionBreakdownRow from './transaction-breakdown-row' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import CurrencyDisplay from '../../ui/currency-display'; +import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display'; +import HexToDecimal from '../../ui/hex-to-decimal'; +import { GWEI, PRIMARY, SECONDARY } from '../../../helpers/constants/common'; +import TransactionBreakdownRow from './transaction-breakdown-row'; export default class TransactionBreakdown extends PureComponent { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { className: PropTypes.string, @@ -23,14 +23,14 @@ export default class TransactionBreakdown extends PureComponent { gasPrice: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), gasUsed: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), totalInHex: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - } + }; static defaultProps = { showFiat: true, - } + }; render() { - const { t } = this.context + const { t } = this.context; const { gas, gasPrice, @@ -42,7 +42,7 @@ export default class TransactionBreakdown extends PureComponent { totalInHex, gasUsed, isTokenApprove, - } = this.props + } = this.props; return (
    {t('transaction')}
    @@ -116,6 +116,6 @@ export default class TransactionBreakdown extends PureComponent {
    - ) + ); } } diff --git a/ui/app/components/app/transaction-breakdown/transaction-breakdown.container.js b/ui/app/components/app/transaction-breakdown/transaction-breakdown.container.js index d4bf56100e..1ab3b4818d 100644 --- a/ui/app/components/app/transaction-breakdown/transaction-breakdown.container.js +++ b/ui/app/components/app/transaction-breakdown/transaction-breakdown.container.js @@ -1,30 +1,30 @@ -import { connect } from 'react-redux' +import { connect } from 'react-redux'; import { getIsMainnet, getNativeCurrency, getPreferences, -} from '../../../selectors' -import { getHexGasTotal } from '../../../helpers/utils/confirm-tx.util' -import { sumHexes } from '../../../helpers/utils/transactions.util' -import { TRANSACTION_CATEGORIES } from '../../../../../shared/constants/transaction' -import TransactionBreakdown from './transaction-breakdown.component' +} from '../../../selectors'; +import { getHexGasTotal } from '../../../helpers/utils/confirm-tx.util'; +import { sumHexes } from '../../../helpers/utils/transactions.util'; +import { TRANSACTION_CATEGORIES } from '../../../../../shared/constants/transaction'; +import TransactionBreakdown from './transaction-breakdown.component'; const mapStateToProps = (state, ownProps) => { - const { transaction, transactionCategory } = ownProps + const { transaction, transactionCategory } = ownProps; const { txParams: { gas, gasPrice, value } = {}, txReceipt: { gasUsed } = {}, - } = transaction - const { showFiatInTestnets } = getPreferences(state) - const isMainnet = getIsMainnet(state) + } = transaction; + const { showFiatInTestnets } = getPreferences(state); + const isMainnet = getIsMainnet(state); const isTokenApprove = - transactionCategory === TRANSACTION_CATEGORIES.TOKEN_METHOD_APPROVE + transactionCategory === TRANSACTION_CATEGORIES.TOKEN_METHOD_APPROVE; - const gasLimit = typeof gasUsed === 'string' ? gasUsed : gas + const gasLimit = typeof gasUsed === 'string' ? gasUsed : gas; const hexGasTotal = - (gasLimit && gasPrice && getHexGasTotal({ gasLimit, gasPrice })) || '0x0' - const totalInHex = sumHexes(hexGasTotal, value) + (gasLimit && gasPrice && getHexGasTotal({ gasLimit, gasPrice })) || '0x0'; + const totalInHex = sumHexes(hexGasTotal, value); return { nativeCurrency: getNativeCurrency(state), @@ -34,7 +34,7 @@ const mapStateToProps = (state, ownProps) => { gasPrice, gasUsed, isTokenApprove, - } -} + }; +}; -export default connect(mapStateToProps)(TransactionBreakdown) +export default connect(mapStateToProps)(TransactionBreakdown); diff --git a/ui/app/components/app/transaction-icon/index.js b/ui/app/components/app/transaction-icon/index.js index d41970a54f..cca6a32d84 100644 --- a/ui/app/components/app/transaction-icon/index.js +++ b/ui/app/components/app/transaction-icon/index.js @@ -1 +1 @@ -export { default } from './transaction-icon' +export { default } from './transaction-icon'; diff --git a/ui/app/components/app/transaction-icon/transaction-icon.js b/ui/app/components/app/transaction-icon/transaction-icon.js index fe6aa0e5a4..5fd8a3cd72 100644 --- a/ui/app/components/app/transaction-icon/transaction-icon.js +++ b/ui/app/components/app/transaction-icon/transaction-icon.js @@ -1,16 +1,16 @@ -import React from 'react' -import PropTypes from 'prop-types' -import Approve from '../../ui/icon/approve-icon.component' -import Interaction from '../../ui/icon/interaction-icon.component' -import Receive from '../../ui/icon/receive-icon.component' -import Send from '../../ui/icon/send-icon.component' -import Sign from '../../ui/icon/sign-icon.component' -import Swap from '../../ui/icon/swap-icon-for-list.component' +import React from 'react'; +import PropTypes from 'prop-types'; +import Approve from '../../ui/icon/approve-icon.component'; +import Interaction from '../../ui/icon/interaction-icon.component'; +import Receive from '../../ui/icon/receive-icon.component'; +import Send from '../../ui/icon/send-icon.component'; +import Sign from '../../ui/icon/sign-icon.component'; +import Swap from '../../ui/icon/swap-icon-for-list.component'; import { TRANSACTION_GROUP_CATEGORIES, TRANSACTION_GROUP_STATUSES, TRANSACTION_STATUSES, -} from '../../../../../shared/constants/transaction' +} from '../../../../../shared/constants/transaction'; const ICON_MAP = { [TRANSACTION_GROUP_CATEGORIES.APPROVAL]: Approve, @@ -19,11 +19,11 @@ const ICON_MAP = { [TRANSACTION_GROUP_CATEGORIES.SIGNATURE_REQUEST]: Sign, [TRANSACTION_GROUP_CATEGORIES.RECEIVE]: Receive, [TRANSACTION_GROUP_CATEGORIES.SWAP]: Swap, -} +}; -const FAIL_COLOR = '#D73A49' -const PENDING_COLOR = '#6A737D' -const OK_COLOR = '#2F80ED' +const FAIL_COLOR = '#D73A49'; +const PENDING_COLOR = '#6A737D'; +const OK_COLOR = '#2F80ED'; const COLOR_MAP = { [TRANSACTION_GROUP_STATUSES.PENDING]: PENDING_COLOR, @@ -33,17 +33,17 @@ const COLOR_MAP = { [TRANSACTION_STATUSES.REJECTED]: FAIL_COLOR, [TRANSACTION_GROUP_STATUSES.CANCELLED]: FAIL_COLOR, [TRANSACTION_STATUSES.DROPPED]: FAIL_COLOR, -} +}; export default function TransactionIcon({ status, category }) { - const color = COLOR_MAP[status] || OK_COLOR + const color = COLOR_MAP[status] || OK_COLOR; - const Icon = ICON_MAP[category] + const Icon = ICON_MAP[category]; - return + return ; } TransactionIcon.propTypes = { status: PropTypes.string.isRequired, category: PropTypes.string.isRequired, -} +}; diff --git a/ui/app/components/app/transaction-list-item-details/index.js b/ui/app/components/app/transaction-list-item-details/index.js index 83bd53e7d5..e01ce230cb 100644 --- a/ui/app/components/app/transaction-list-item-details/index.js +++ b/ui/app/components/app/transaction-list-item-details/index.js @@ -1 +1 @@ -export { default } from './transaction-list-item-details.container' +export { default } from './transaction-list-item-details.container'; diff --git a/ui/app/components/app/transaction-list-item-details/tests/transaction-list-item-details.component.test.js b/ui/app/components/app/transaction-list-item-details/tests/transaction-list-item-details.component.test.js index 5027cc05b2..a333ecd982 100644 --- a/ui/app/components/app/transaction-list-item-details/tests/transaction-list-item-details.component.test.js +++ b/ui/app/components/app/transaction-list-item-details/tests/transaction-list-item-details.component.test.js @@ -1,12 +1,12 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import TransactionListItemDetails from '../transaction-list-item-details.component' -import Button from '../../../ui/button' -import SenderToRecipient from '../../../ui/sender-to-recipient' -import TransactionBreakdown from '../../transaction-breakdown' -import TransactionActivityLog from '../../transaction-activity-log' -import { TRANSACTION_STATUSES } from '../../../../../../shared/constants/transaction' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import TransactionListItemDetails from '../transaction-list-item-details.component'; +import Button from '../../../ui/button'; +import SenderToRecipient from '../../../ui/sender-to-recipient'; +import TransactionBreakdown from '../../transaction-breakdown'; +import TransactionActivityLog from '../../transaction-activity-log'; +import { TRANSACTION_STATUSES } from '../../../../../../shared/constants/transaction'; describe('TransactionListItemDetails Component', function () { it('should render properly', function () { @@ -22,13 +22,13 @@ describe('TransactionListItemDetails Component', function () { to: '0x2', value: '0x2386f26fc10000', }, - } + }; const transactionGroup = { transactions: [transaction], primaryTransaction: transaction, initialTransaction: transaction, - } + }; const wrapper = shallow( , { context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) } }, - ) - const child = wrapper.childAt(0) - assert.ok(child.hasClass('transaction-list-item-details')) - assert.strictEqual(child.find(Button).length, 2) - assert.strictEqual(child.find(SenderToRecipient).length, 1) - assert.strictEqual(child.find(TransactionBreakdown).length, 1) - assert.strictEqual(child.find(TransactionActivityLog).length, 1) - }) + ); + const child = wrapper.childAt(0); + assert.ok(child.hasClass('transaction-list-item-details')); + assert.strictEqual(child.find(Button).length, 2); + assert.strictEqual(child.find(SenderToRecipient).length, 1); + assert.strictEqual(child.find(TransactionBreakdown).length, 1); + assert.strictEqual(child.find(TransactionActivityLog).length, 1); + }); it('should render a retry button', function () { const transaction = { @@ -63,7 +63,7 @@ describe('TransactionListItemDetails Component', function () { to: '0x2', value: '0x2386f26fc10000', }, - } + }; const transactionGroup = { transactions: [transaction], @@ -72,7 +72,7 @@ describe('TransactionListItemDetails Component', function () { nonce: '0xa4', hasRetried: false, hasCancelled: false, - } + }; const wrapper = shallow( , { context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) } }, - ) + ); - const child = wrapper.childAt(0) + const child = wrapper.childAt(0); - assert.ok(child.hasClass('transaction-list-item-details')) - assert.strictEqual(child.find(Button).length, 3) - }) + assert.ok(child.hasClass('transaction-list-item-details')); + assert.strictEqual(child.find(Button).length, 3); + }); it('should disable the Copy Tx ID and View In Etherscan buttons when tx hash is missing', function () { const transaction = { @@ -106,13 +106,13 @@ describe('TransactionListItemDetails Component', function () { to: '0x2', value: '0x2386f26fc10000', }, - } + }; const transactionGroup = { transactions: [transaction], primaryTransaction: transaction, initialTransaction: transaction, - } + }; const wrapper = shallow( , { context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) } }, - ) + ); - const child = wrapper.childAt(0) + const child = wrapper.childAt(0); - assert.ok(child.hasClass('transaction-list-item-details')) - const buttons = child.find(Button) - assert.strictEqual(buttons.at(0).prop('disabled'), true) - assert.strictEqual(buttons.at(1).prop('disabled'), true) - }) + assert.ok(child.hasClass('transaction-list-item-details')); + const buttons = child.find(Button); + assert.strictEqual(buttons.at(0).prop('disabled'), true); + assert.strictEqual(buttons.at(1).prop('disabled'), true); + }); it('should render functional Copy Tx ID and View In Etherscan buttons when tx hash exists', function () { const transaction = { @@ -148,13 +148,13 @@ describe('TransactionListItemDetails Component', function () { to: '0x2', value: '0x2386f26fc10000', }, - } + }; const transactionGroup = { transactions: [transaction], primaryTransaction: transaction, initialTransaction: transaction, - } + }; const wrapper = shallow( , { context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) } }, - ) + ); - const child = wrapper.childAt(0) + const child = wrapper.childAt(0); - assert.ok(child.hasClass('transaction-list-item-details')) - const buttons = child.find(Button) - assert.strictEqual(buttons.at(0).prop('disabled'), false) - assert.strictEqual(buttons.at(1).prop('disabled'), false) - }) -}) + assert.ok(child.hasClass('transaction-list-item-details')); + const buttons = child.find(Button); + assert.strictEqual(buttons.at(0).prop('disabled'), false); + assert.strictEqual(buttons.at(1).prop('disabled'), false); + }); +}); diff --git a/ui/app/components/app/transaction-list-item-details/transaction-list-item-details.component.js b/ui/app/components/app/transaction-list-item-details/transaction-list-item-details.component.js index 31c3adc3e3..faa80846c0 100644 --- a/ui/app/components/app/transaction-list-item-details/transaction-list-item-details.component.js +++ b/ui/app/components/app/transaction-list-item-details/transaction-list-item-details.component.js @@ -1,25 +1,25 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import copyToClipboard from 'copy-to-clipboard' -import { getBlockExplorerUrlForTx } from '../../../helpers/utils/transactions.util' -import SenderToRecipient from '../../ui/sender-to-recipient' -import { FLAT_VARIANT } from '../../ui/sender-to-recipient/sender-to-recipient.constants' -import TransactionActivityLog from '../transaction-activity-log' -import TransactionBreakdown from '../transaction-breakdown' -import Button from '../../ui/button' -import Tooltip from '../../ui/tooltip' -import Copy from '../../ui/icon/copy-icon.component' -import Popover from '../../ui/popover' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import copyToClipboard from 'copy-to-clipboard'; +import { getBlockExplorerUrlForTx } from '../../../helpers/utils/transactions.util'; +import SenderToRecipient from '../../ui/sender-to-recipient'; +import { FLAT_VARIANT } from '../../ui/sender-to-recipient/sender-to-recipient.constants'; +import TransactionActivityLog from '../transaction-activity-log'; +import TransactionBreakdown from '../transaction-breakdown'; +import Button from '../../ui/button'; +import Tooltip from '../../ui/tooltip'; +import Copy from '../../ui/icon/copy-icon.component'; +import Popover from '../../ui/popover'; export default class TransactionListItemDetails extends PureComponent { static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; static defaultProps = { recipientEns: null, - } + }; static propTypes = { onCancel: PropTypes.func, @@ -40,18 +40,18 @@ export default class TransactionListItemDetails extends PureComponent { tryReverseResolveAddress: PropTypes.func.isRequired, senderNickname: PropTypes.string.isRequired, recipientNickname: PropTypes.string, - } + }; state = { justCopied: false, - } + }; handleEtherscanClick = () => { const { transactionGroup: { primaryTransaction }, rpcPrefs, - } = this.props - const { hash, metamaskNetworkId } = primaryTransaction + } = this.props; + const { hash, metamaskNetworkId } = primaryTransaction; this.context.metricsEvent({ eventOpts: { @@ -59,29 +59,29 @@ export default class TransactionListItemDetails extends PureComponent { action: 'Activity Log', name: 'Clicked "View on Etherscan"', }, - }) + }); global.platform.openTab({ url: getBlockExplorerUrlForTx(metamaskNetworkId, hash, rpcPrefs), - }) - } + }); + }; handleCancel = (event) => { - const { onCancel, onClose } = this.props - onCancel(event) - onClose() - } + const { onCancel, onClose } = this.props; + onCancel(event); + onClose(); + }; handleRetry = (event) => { - const { onClose, onRetry } = this.props - onRetry(event) - onClose() - } + const { onClose, onRetry } = this.props; + onRetry(event); + onClose(); + }; handleCopyTxId = () => { - const { transactionGroup } = this.props - const { primaryTransaction: transaction } = transactionGroup - const { hash } = transaction + const { transactionGroup } = this.props; + const { primaryTransaction: transaction } = transactionGroup; + const { hash } = transaction; this.context.metricsEvent({ eventOpts: { @@ -89,28 +89,28 @@ export default class TransactionListItemDetails extends PureComponent { action: 'Activity Log', name: 'Copied Transaction ID', }, - }) + }); this.setState({ justCopied: true }, () => { - copyToClipboard(hash) - setTimeout(() => this.setState({ justCopied: false }), 1000) - }) - } + copyToClipboard(hash); + setTimeout(() => this.setState({ justCopied: false }), 1000); + }); + }; componentDidMount() { - const { recipientAddress, tryReverseResolveAddress } = this.props + const { recipientAddress, tryReverseResolveAddress } = this.props; if (recipientAddress) { - tryReverseResolveAddress(recipientAddress) + tryReverseResolveAddress(recipientAddress); } } renderCancel() { - const { t } = this.context - const { showCancel, cancelDisabled } = this.props + const { t } = this.context; + const { showCancel, cancelDisabled } = this.props; if (!showCancel) { - return null + return null; } return cancelDisabled ? ( @@ -134,12 +134,12 @@ export default class TransactionListItemDetails extends PureComponent { > {t('cancel')} - ) + ); } render() { - const { t } = this.context - const { justCopied } = this.state + const { t } = this.context; + const { justCopied } = this.state; const { transactionGroup, primaryCurrency, @@ -154,12 +154,12 @@ export default class TransactionListItemDetails extends PureComponent { title, onClose, recipientNickname, - } = this.props + } = this.props; const { primaryTransaction: transaction, initialTransaction: { transactionCategory }, - } = transactionGroup - const { hash } = transaction + } = transactionGroup; + const { hash } = transaction; return ( @@ -240,7 +240,7 @@ export default class TransactionListItemDetails extends PureComponent { action: 'Activity Log', name: 'Copied "To" Address', }, - }) + }); }} onSenderClick={() => { this.context.metricsEvent({ @@ -249,7 +249,7 @@ export default class TransactionListItemDetails extends PureComponent { action: 'Activity Log', name: 'Copied "From" Address', }, - }) + }); }} /> @@ -272,6 +272,6 @@ export default class TransactionListItemDetails extends PureComponent { - ) + ); } } diff --git a/ui/app/components/app/transaction-list-item-details/transaction-list-item-details.container.js b/ui/app/components/app/transaction-list-item-details/transaction-list-item-details.container.js index 55fcf8582a..4a96082c7a 100644 --- a/ui/app/components/app/transaction-list-item-details/transaction-list-item-details.container.js +++ b/ui/app/components/app/transaction-list-item-details/transaction-list-item-details.container.js @@ -1,48 +1,48 @@ -import { connect } from 'react-redux' -import { checksumAddress } from '../../../helpers/utils/util' -import { tryReverseResolveAddress } from '../../../store/actions' +import { connect } from 'react-redux'; +import { checksumAddress } from '../../../helpers/utils/util'; +import { tryReverseResolveAddress } from '../../../store/actions'; import { getAddressBook, getRpcPrefsForCurrentProvider, -} from '../../../selectors' -import TransactionListItemDetails from './transaction-list-item-details.component' +} from '../../../selectors'; +import TransactionListItemDetails from './transaction-list-item-details.component'; const mapStateToProps = (state, ownProps) => { - const { metamask } = state - const { ensResolutionsByAddress } = metamask - const { recipientAddress, senderAddress } = ownProps - let recipientEns + const { metamask } = state; + const { ensResolutionsByAddress } = metamask; + const { recipientAddress, senderAddress } = ownProps; + let recipientEns; if (recipientAddress) { - const address = checksumAddress(recipientAddress) - recipientEns = ensResolutionsByAddress[address] || '' + const address = checksumAddress(recipientAddress); + recipientEns = ensResolutionsByAddress[address] || ''; } - const addressBook = getAddressBook(state) + const addressBook = getAddressBook(state); const getNickName = (address) => { const entry = addressBook.find((contact) => { - return address.toLowerCase() === contact.address.toLowerCase() - }) - return (entry && entry.name) || '' - } - const rpcPrefs = getRpcPrefsForCurrentProvider(state) + return address.toLowerCase() === contact.address.toLowerCase(); + }); + return (entry && entry.name) || ''; + }; + const rpcPrefs = getRpcPrefsForCurrentProvider(state); return { rpcPrefs, recipientEns, senderNickname: getNickName(senderAddress), recipientNickname: recipientAddress ? getNickName(recipientAddress) : null, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { tryReverseResolveAddress: (address) => { - return dispatch(tryReverseResolveAddress(address)) + return dispatch(tryReverseResolveAddress(address)); }, - } -} + }; +}; export default connect( mapStateToProps, mapDispatchToProps, -)(TransactionListItemDetails) +)(TransactionListItemDetails); diff --git a/ui/app/components/app/transaction-list-item/index.js b/ui/app/components/app/transaction-list-item/index.js index 1fdbb29ac2..03a62d9e4b 100644 --- a/ui/app/components/app/transaction-list-item/index.js +++ b/ui/app/components/app/transaction-list-item/index.js @@ -1 +1 @@ -export { default } from './transaction-list-item.component' +export { default } from './transaction-list-item.component'; diff --git a/ui/app/components/app/transaction-list-item/transaction-list-item.component.js b/ui/app/components/app/transaction-list-item/transaction-list-item.component.js index 64a617cda8..ec29e04d64 100644 --- a/ui/app/components/app/transaction-list-item/transaction-list-item.component.js +++ b/ui/app/components/app/transaction-list-item/transaction-list-item.component.js @@ -1,45 +1,45 @@ -import React, { useMemo, useState, useCallback } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { useHistory } from 'react-router-dom' -import ListItem from '../../ui/list-item' -import { useTransactionDisplayData } from '../../../hooks/useTransactionDisplayData' -import { useI18nContext } from '../../../hooks/useI18nContext' -import { useCancelTransaction } from '../../../hooks/useCancelTransaction' -import { useRetryTransaction } from '../../../hooks/useRetryTransaction' -import Button from '../../ui/button' -import Tooltip from '../../ui/tooltip' -import TransactionListItemDetails from '../transaction-list-item-details' -import { CONFIRM_TRANSACTION_ROUTE } from '../../../helpers/constants/routes' -import { useShouldShowSpeedUp } from '../../../hooks/useShouldShowSpeedUp' -import TransactionStatus from '../transaction-status/transaction-status.component' -import TransactionIcon from '../transaction-icon' +import React, { useMemo, useState, useCallback } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import { useHistory } from 'react-router-dom'; +import ListItem from '../../ui/list-item'; +import { useTransactionDisplayData } from '../../../hooks/useTransactionDisplayData'; +import { useI18nContext } from '../../../hooks/useI18nContext'; +import { useCancelTransaction } from '../../../hooks/useCancelTransaction'; +import { useRetryTransaction } from '../../../hooks/useRetryTransaction'; +import Button from '../../ui/button'; +import Tooltip from '../../ui/tooltip'; +import TransactionListItemDetails from '../transaction-list-item-details'; +import { CONFIRM_TRANSACTION_ROUTE } from '../../../helpers/constants/routes'; +import { useShouldShowSpeedUp } from '../../../hooks/useShouldShowSpeedUp'; +import TransactionStatus from '../transaction-status/transaction-status.component'; +import TransactionIcon from '../transaction-icon'; import { TRANSACTION_GROUP_CATEGORIES, TRANSACTION_STATUSES, -} from '../../../../../shared/constants/transaction' +} from '../../../../../shared/constants/transaction'; export default function TransactionListItem({ transactionGroup, isEarliestNonce = false, }) { - const t = useI18nContext() - const history = useHistory() - const { hasCancelled } = transactionGroup - const [showDetails, setShowDetails] = useState(false) + const t = useI18nContext(); + const history = useHistory(); + const { hasCancelled } = transactionGroup; + const [showDetails, setShowDetails] = useState(false); const { initialTransaction: { id }, primaryTransaction: { err, status }, - } = transactionGroup + } = transactionGroup; const [cancelEnabled, cancelTransaction] = useCancelTransaction( transactionGroup, - ) - const retryTransaction = useRetryTransaction(transactionGroup) + ); + const retryTransaction = useRetryTransaction(transactionGroup); const shouldShowSpeedUp = useShouldShowSpeedUp( transactionGroup, isEarliestNonce, - ) + ); const { title, @@ -53,13 +53,13 @@ export default function TransactionListItem({ displayedStatusKey, isPending, senderAddress, - } = useTransactionDisplayData(transactionGroup) + } = useTransactionDisplayData(transactionGroup); const isSignatureReq = - category === TRANSACTION_GROUP_CATEGORIES.SIGNATURE_REQUEST - const isApproval = category === TRANSACTION_GROUP_CATEGORIES.APPROVAL - const isUnapproved = status === TRANSACTION_STATUSES.UNAPPROVED - const isSwap = category === TRANSACTION_GROUP_CATEGORIES.SWAP + category === TRANSACTION_GROUP_CATEGORIES.SIGNATURE_REQUEST; + const isApproval = category === TRANSACTION_GROUP_CATEGORIES.APPROVAL; + const isUnapproved = status === TRANSACTION_STATUSES.UNAPPROVED; + const isSwap = category === TRANSACTION_GROUP_CATEGORIES.SWAP; const className = classnames('transaction-list-item', { 'transaction-list-item--unconfirmed': @@ -69,15 +69,15 @@ export default function TransactionListItem({ TRANSACTION_STATUSES.DROPPED, TRANSACTION_STATUSES.REJECTED, ].includes(displayedStatusKey), - }) + }); const toggleShowDetails = useCallback(() => { if (isUnapproved) { - history.push(`${CONFIRM_TRANSACTION_ROUTE}/${id}`) - return + history.push(`${CONFIRM_TRANSACTION_ROUTE}/${id}`); + return; } - setShowDetails((prev) => !prev) - }, [isUnapproved, history, id]) + setShowDetails((prev) => !prev); + }, [isUnapproved, history, id]); const cancelButton = useMemo(() => { const btn = ( @@ -89,9 +89,9 @@ export default function TransactionListItem({ > {t('cancel')} - ) + ); if (hasCancelled || !isPending || isUnapproved) { - return null + return null; } return cancelEnabled ? ( @@ -100,7 +100,7 @@ export default function TransactionListItem({
    {btn}
    - ) + ); }, [ isPending, t, @@ -108,11 +108,11 @@ export default function TransactionListItem({ cancelEnabled, cancelTransaction, hasCancelled, - ]) + ]); const speedUpButton = useMemo(() => { if (!shouldShowSpeedUp || !isPending || isUnapproved) { - return null + return null; } return ( - ) - }, [shouldShowSpeedUp, isUnapproved, t, isPending, retryTransaction]) + ); + }, [shouldShowSpeedUp, isUnapproved, t, isPending, retryTransaction]); return ( <> @@ -196,10 +196,10 @@ export default function TransactionListItem({ /> )} - ) + ); } TransactionListItem.propTypes = { transactionGroup: PropTypes.object.isRequired, isEarliestNonce: PropTypes.bool, -} +}; diff --git a/ui/app/components/app/transaction-list/index.js b/ui/app/components/app/transaction-list/index.js index 1ec6c5124b..f5d9bba6ff 100644 --- a/ui/app/components/app/transaction-list/index.js +++ b/ui/app/components/app/transaction-list/index.js @@ -1 +1 @@ -export { default } from './transaction-list.component' +export { default } from './transaction-list.component'; diff --git a/ui/app/components/app/transaction-list/transaction-list.component.js b/ui/app/components/app/transaction-list/transaction-list.component.js index 31f690740f..e69523329e 100644 --- a/ui/app/components/app/transaction-list/transaction-list.component.js +++ b/ui/app/components/app/transaction-list/transaction-list.component.js @@ -1,18 +1,18 @@ -import React, { useMemo, useState, useCallback } from 'react' -import PropTypes from 'prop-types' -import { useSelector } from 'react-redux' +import React, { useMemo, useState, useCallback } from 'react'; +import PropTypes from 'prop-types'; +import { useSelector } from 'react-redux'; import { nonceSortedCompletedTransactionsSelector, nonceSortedPendingTransactionsSelector, -} from '../../../selectors/transactions' -import { useI18nContext } from '../../../hooks/useI18nContext' -import TransactionListItem from '../transaction-list-item' -import Button from '../../ui/button' -import { TOKEN_CATEGORY_HASH } from '../../../helpers/constants/transactions' -import { SWAPS_CONTRACT_ADDRESS } from '../../../helpers/constants/swaps' -import { TRANSACTION_CATEGORIES } from '../../../../../shared/constants/transaction' +} from '../../../selectors/transactions'; +import { useI18nContext } from '../../../hooks/useI18nContext'; +import TransactionListItem from '../transaction-list-item'; +import Button from '../../ui/button'; +import { TOKEN_CATEGORY_HASH } from '../../../helpers/constants/transactions'; +import { SWAPS_CONTRACT_ADDRESS } from '../../../helpers/constants/swaps'; +import { TRANSACTION_CATEGORIES } from '../../../../../shared/constants/transaction'; -const PAGE_INCREMENT = 10 +const PAGE_INCREMENT = 10; const getTransactionGroupRecipientAddressFilter = (recipientAddress) => { return ({ initialTransaction: { txParams } }) => { @@ -20,9 +20,9 @@ const getTransactionGroupRecipientAddressFilter = (recipientAddress) => { txParams?.to === recipientAddress || (txParams?.to === SWAPS_CONTRACT_ADDRESS && txParams.data.match(recipientAddress.slice(2))) - ) - } -} + ); + }; +}; const tokenTransactionFilter = ({ initialTransaction: { @@ -32,12 +32,12 @@ const tokenTransactionFilter = ({ }, }) => { if (TOKEN_CATEGORY_HASH[transactionCategory]) { - return false + return false; } else if (transactionCategory === TRANSACTION_CATEGORIES.SWAP) { - return destinationTokenSymbol === 'ETH' || sourceTokenSymbol === 'ETH' + return destinationTokenSymbol === 'ETH' || sourceTokenSymbol === 'ETH'; } - return true -} + return true; +}; const getFilteredTransactionGroups = ( transactionGroups, @@ -45,28 +45,28 @@ const getFilteredTransactionGroups = ( tokenAddress, ) => { if (hideTokenTransactions) { - return transactionGroups.filter(tokenTransactionFilter) + return transactionGroups.filter(tokenTransactionFilter); } else if (tokenAddress) { return transactionGroups.filter( getTransactionGroupRecipientAddressFilter(tokenAddress), - ) + ); } - return transactionGroups -} + return transactionGroups; +}; export default function TransactionList({ hideTokenTransactions, tokenAddress, }) { - const [limit, setLimit] = useState(PAGE_INCREMENT) - const t = useI18nContext() + const [limit, setLimit] = useState(PAGE_INCREMENT); + const t = useI18nContext(); const unfilteredPendingTransactions = useSelector( nonceSortedPendingTransactionsSelector, - ) + ); const unfilteredCompletedTransactions = useSelector( nonceSortedCompletedTransactionsSelector, - ) + ); const pendingTransactions = useMemo( () => @@ -76,7 +76,7 @@ export default function TransactionList({ tokenAddress, ), [hideTokenTransactions, tokenAddress, unfilteredPendingTransactions], - ) + ); const completedTransactions = useMemo( () => getFilteredTransactionGroups( @@ -85,14 +85,14 @@ export default function TransactionList({ tokenAddress, ), [hideTokenTransactions, tokenAddress, unfilteredCompletedTransactions], - ) + ); const viewMore = useCallback( () => setLimit((prev) => prev + PAGE_INCREMENT), [], - ) + ); - const pendingLength = pendingTransactions.length + const pendingLength = pendingTransactions.length; return (
    @@ -144,15 +144,15 @@ export default function TransactionList({
    - ) + ); } TransactionList.propTypes = { hideTokenTransactions: PropTypes.bool, tokenAddress: PropTypes.string, -} +}; TransactionList.defaultProps = { hideTokenTransactions: false, tokenAddress: undefined, -} +}; diff --git a/ui/app/components/app/transaction-status/index.js b/ui/app/components/app/transaction-status/index.js index dece41e9ca..61bb74e201 100644 --- a/ui/app/components/app/transaction-status/index.js +++ b/ui/app/components/app/transaction-status/index.js @@ -1 +1 @@ -export { default } from './transaction-status.component' +export { default } from './transaction-status.component'; diff --git a/ui/app/components/app/transaction-status/tests/transaction-status.component.test.js b/ui/app/components/app/transaction-status/tests/transaction-status.component.test.js index 016d4d5a92..2300081de2 100644 --- a/ui/app/components/app/transaction-status/tests/transaction-status.component.test.js +++ b/ui/app/components/app/transaction-status/tests/transaction-status.component.test.js @@ -1,24 +1,24 @@ -import assert from 'assert' -import React from 'react' -import { mount } from 'enzyme' -import sinon from 'sinon' -import * as i18nHook from '../../../../hooks/useI18nContext' -import TransactionStatus from '../transaction-status.component' -import Tooltip from '../../../ui/tooltip' +import assert from 'assert'; +import React from 'react'; +import { mount } from 'enzyme'; +import sinon from 'sinon'; +import * as i18nHook from '../../../../hooks/useI18nContext'; +import TransactionStatus from '../transaction-status.component'; +import Tooltip from '../../../ui/tooltip'; describe('TransactionStatus Component', function () { before(function () { - sinon.stub(i18nHook, 'useI18nContext').returns((str) => str.toUpperCase()) - }) + sinon.stub(i18nHook, 'useI18nContext').returns((str) => str.toUpperCase()); + }); it('should render CONFIRMED properly', function () { const wrapper = mount( , - ) + ); - assert.ok(wrapper) - assert.strictEqual(wrapper.text(), 'June 1') - }) + assert.ok(wrapper); + assert.strictEqual(wrapper.text(), 'June 1'); + }); it('should render PENDING properly when status is APPROVED', function () { const wrapper = mount( @@ -27,45 +27,45 @@ describe('TransactionStatus Component', function () { isEarliestNonce error={{ message: 'test-title' }} />, - ) + ); - assert.ok(wrapper) - assert.strictEqual(wrapper.text(), 'PENDING') - assert.strictEqual(wrapper.find(Tooltip).props().title, 'test-title') - }) + assert.ok(wrapper); + assert.strictEqual(wrapper.text(), 'PENDING'); + assert.strictEqual(wrapper.find(Tooltip).props().title, 'test-title'); + }); it('should render PENDING properly', function () { const wrapper = mount( , - ) + ); - assert.ok(wrapper) - assert.strictEqual(wrapper.text(), 'PENDING') - }) + assert.ok(wrapper); + assert.strictEqual(wrapper.text(), 'PENDING'); + }); it('should render QUEUED properly', function () { - const wrapper = mount() + const wrapper = mount(); - assert.ok(wrapper) + assert.ok(wrapper); assert.ok( wrapper.find('.transaction-status--queued').length, 'queued className not found', - ) - assert.strictEqual(wrapper.text(), 'QUEUED') - }) + ); + assert.strictEqual(wrapper.text(), 'QUEUED'); + }); it('should render UNAPPROVED properly', function () { - const wrapper = mount() + const wrapper = mount(); - assert.ok(wrapper) + assert.ok(wrapper); assert.ok( wrapper.find('.transaction-status--unapproved').length, 'unapproved className not found', - ) - assert.strictEqual(wrapper.text(), 'UNAPPROVED') - }) + ); + assert.strictEqual(wrapper.text(), 'UNAPPROVED'); + }); after(function () { - sinon.restore() - }) -}) + sinon.restore(); + }); +}); diff --git a/ui/app/components/app/transaction-status/transaction-status.component.js b/ui/app/components/app/transaction-status/transaction-status.component.js index 5c5dd35151..6049a33a99 100644 --- a/ui/app/components/app/transaction-status/transaction-status.component.js +++ b/ui/app/components/app/transaction-status/transaction-status.component.js @@ -1,15 +1,15 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import Tooltip from '../../ui/tooltip' +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import Tooltip from '../../ui/tooltip'; -import { useI18nContext } from '../../../hooks/useI18nContext' +import { useI18nContext } from '../../../hooks/useI18nContext'; import { TRANSACTION_GROUP_STATUSES, TRANSACTION_STATUSES, -} from '../../../../../shared/constants/transaction' +} from '../../../../../shared/constants/transaction'; -const QUEUED_PSEUDO_STATUS = 'queued' +const QUEUED_PSEUDO_STATUS = 'queued'; /** * A note about status logic for this component: @@ -25,7 +25,7 @@ const pendingStatusHash = { [TRANSACTION_STATUSES.SUBMITTED]: TRANSACTION_GROUP_STATUSES.PENDING, [TRANSACTION_STATUSES.APPROVED]: TRANSACTION_GROUP_STATUSES.PENDING, [TRANSACTION_STATUSES.SIGNED]: TRANSACTION_GROUP_STATUSES.PENDING, -} +}; const statusToClassNameHash = { [TRANSACTION_STATUSES.UNAPPROVED]: 'transaction-status--unapproved', @@ -35,7 +35,7 @@ const statusToClassNameHash = { [TRANSACTION_GROUP_STATUSES.CANCELLED]: 'transaction-status--cancelled', [QUEUED_PSEUDO_STATUS]: 'transaction-status--queued', [TRANSACTION_GROUP_STATUSES.PENDING]: 'transaction-status--pending', -} +}; export default function TransactionStatus({ status, @@ -44,17 +44,17 @@ export default function TransactionStatus({ isEarliestNonce, className, }) { - const t = useI18nContext() - const tooltipText = error?.rpc?.message || error?.message - let statusKey = status + const t = useI18nContext(); + const tooltipText = error?.rpc?.message || error?.message; + let statusKey = status; if (pendingStatusHash[status]) { statusKey = isEarliestNonce ? TRANSACTION_GROUP_STATUSES.PENDING - : QUEUED_PSEUDO_STATUS + : QUEUED_PSEUDO_STATUS; } const statusText = - statusKey === TRANSACTION_STATUSES.CONFIRMED ? date : t(statusKey) + statusKey === TRANSACTION_STATUSES.CONFIRMED ? date : t(statusKey); return ( {statusText} - ) + ); } TransactionStatus.propTypes = { @@ -77,4 +77,4 @@ TransactionStatus.propTypes = { date: PropTypes.string, error: PropTypes.object, isEarliestNonce: PropTypes.bool, -} +}; diff --git a/ui/app/components/app/user-preferenced-currency-display/index.js b/ui/app/components/app/user-preferenced-currency-display/index.js index 5bc2d42465..e0976593bf 100644 --- a/ui/app/components/app/user-preferenced-currency-display/index.js +++ b/ui/app/components/app/user-preferenced-currency-display/index.js @@ -1 +1 @@ -export { default } from './user-preferenced-currency-display.component' +export { default } from './user-preferenced-currency-display.component'; diff --git a/ui/app/components/app/user-preferenced-currency-display/tests/user-preferenced-currency-display.component.test.js b/ui/app/components/app/user-preferenced-currency-display/tests/user-preferenced-currency-display.component.test.js index 4c2533de59..7b57d92653 100644 --- a/ui/app/components/app/user-preferenced-currency-display/tests/user-preferenced-currency-display.component.test.js +++ b/ui/app/components/app/user-preferenced-currency-display/tests/user-preferenced-currency-display.component.test.js @@ -1,40 +1,40 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import sinon from 'sinon' -import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display.component' -import CurrencyDisplay from '../../../ui/currency-display' -import * as currencyHook from '../../../../hooks/useCurrencyDisplay' -import * as currencyPrefHook from '../../../../hooks/useUserPreferencedCurrency' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display.component'; +import CurrencyDisplay from '../../../ui/currency-display'; +import * as currencyHook from '../../../../hooks/useCurrencyDisplay'; +import * as currencyPrefHook from '../../../../hooks/useUserPreferencedCurrency'; describe('UserPreferencedCurrencyDisplay Component', function () { describe('rendering', function () { beforeEach(function () { - sinon.stub(currencyHook, 'useCurrencyDisplay').returns(['1', {}]) + sinon.stub(currencyHook, 'useCurrencyDisplay').returns(['1', {}]); sinon .stub(currencyPrefHook, 'useUserPreferencedCurrency') - .returns({ currency: 'ETH', decimals: 6 }) - }) + .returns({ currency: 'ETH', decimals: 6 }); + }); it('should render properly', function () { - const wrapper = shallow() + const wrapper = shallow(); - assert.ok(wrapper) - assert.strictEqual(wrapper.find(CurrencyDisplay).length, 1) - }) + assert.ok(wrapper); + assert.strictEqual(wrapper.find(CurrencyDisplay).length, 1); + }); it('should pass all props to the CurrencyDisplay child component', function () { const wrapper = shallow( , - ) + ); - assert.ok(wrapper) - assert.strictEqual(wrapper.find(CurrencyDisplay).length, 1) - assert.strictEqual(wrapper.find(CurrencyDisplay).props().prop1, true) - assert.strictEqual(wrapper.find(CurrencyDisplay).props().prop2, 'test') - assert.strictEqual(wrapper.find(CurrencyDisplay).props().prop3, 1) - }) + assert.ok(wrapper); + assert.strictEqual(wrapper.find(CurrencyDisplay).length, 1); + assert.strictEqual(wrapper.find(CurrencyDisplay).props().prop1, true); + assert.strictEqual(wrapper.find(CurrencyDisplay).props().prop2, 'test'); + assert.strictEqual(wrapper.find(CurrencyDisplay).props().prop3, 1); + }); afterEach(function () { - sinon.restore() - }) - }) -}) + sinon.restore(); + }); + }); +}); diff --git a/ui/app/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.js b/ui/app/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.js index 8496d7ca11..dfcc235e25 100644 --- a/ui/app/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.js +++ b/ui/app/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.js @@ -1,8 +1,8 @@ -import React, { useMemo } from 'react' -import PropTypes from 'prop-types' -import { PRIMARY, SECONDARY, ETH } from '../../../helpers/constants/common' -import CurrencyDisplay from '../../ui/currency-display' -import { useUserPreferencedCurrency } from '../../../hooks/useUserPreferencedCurrency' +import React, { useMemo } from 'react'; +import PropTypes from 'prop-types'; +import { PRIMARY, SECONDARY, ETH } from '../../../helpers/constants/common'; +import CurrencyDisplay from '../../ui/currency-display'; +import { useUserPreferencedCurrency } from '../../../hooks/useUserPreferencedCurrency'; export default function UserPreferencedCurrencyDisplay({ 'data-testid': dataTestId, @@ -18,13 +18,13 @@ export default function UserPreferencedCurrencyDisplay({ ethNumberOfDecimals, fiatNumberOfDecimals, numberOfDecimals: propsNumberOfDecimals, - }) + }); const prefixComponent = useMemo(() => { return ( currency === ETH && showEthLogo && - ) - }, [currency, showEthLogo, ethLogoHeight]) + ); + }, [currency, showEthLogo, ethLogoHeight]); return ( - ) + ); } UserPreferencedCurrencyDisplay.propTypes = { @@ -57,4 +57,4 @@ UserPreferencedCurrencyDisplay.propTypes = { PropTypes.string, PropTypes.number, ]), -} +}; diff --git a/ui/app/components/app/user-preferenced-currency-input/index.js b/ui/app/components/app/user-preferenced-currency-input/index.js index 4dc70db3d1..36ca1ca49b 100644 --- a/ui/app/components/app/user-preferenced-currency-input/index.js +++ b/ui/app/components/app/user-preferenced-currency-input/index.js @@ -1 +1 @@ -export { default } from './user-preferenced-currency-input.container' +export { default } from './user-preferenced-currency-input.container'; diff --git a/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js b/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js index 30052e039a..f0c7044593 100644 --- a/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js +++ b/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js @@ -1,28 +1,28 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import UserPreferencedCurrencyInput from '../user-preferenced-currency-input.component' -import CurrencyInput from '../../../ui/currency-input' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import UserPreferencedCurrencyInput from '../user-preferenced-currency-input.component'; +import CurrencyInput from '../../../ui/currency-input'; describe('UserPreferencedCurrencyInput Component', function () { describe('rendering', function () { it('should render properly', function () { - const wrapper = shallow() + const wrapper = shallow(); - assert.ok(wrapper) - assert.strictEqual(wrapper.find(CurrencyInput).length, 1) - }) + assert.ok(wrapper); + assert.strictEqual(wrapper.find(CurrencyInput).length, 1); + }); it('should render useFiat for CurrencyInput based on preferences.useNativeCurrencyAsPrimaryCurrency', function () { const wrapper = shallow( , - ) + ); - assert.ok(wrapper) - assert.strictEqual(wrapper.find(CurrencyInput).length, 1) - assert.strictEqual(wrapper.find(CurrencyInput).props().useFiat, false) - wrapper.setProps({ useNativeCurrencyAsPrimaryCurrency: false }) - assert.strictEqual(wrapper.find(CurrencyInput).props().useFiat, true) - }) - }) -}) + assert.ok(wrapper); + assert.strictEqual(wrapper.find(CurrencyInput).length, 1); + assert.strictEqual(wrapper.find(CurrencyInput).props().useFiat, false); + wrapper.setProps({ useNativeCurrencyAsPrimaryCurrency: false }); + assert.strictEqual(wrapper.find(CurrencyInput).props().useFiat, true); + }); + }); +}); diff --git a/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js b/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js index a687d469d6..40234c9c5d 100644 --- a/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js +++ b/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js @@ -1,16 +1,16 @@ -import assert from 'assert' -import proxyquire from 'proxyquire' +import assert from 'assert'; +import proxyquire from 'proxyquire'; -let mapStateToProps +let mapStateToProps; proxyquire('../user-preferenced-currency-input.container.js', { 'react-redux': { connect: (ms) => { - mapStateToProps = ms - return () => ({}) + mapStateToProps = ms; + return () => ({}); }, }, -}) +}); describe('UserPreferencedCurrencyInput container', function () { describe('mapStateToProps()', function () { @@ -21,11 +21,11 @@ describe('UserPreferencedCurrencyInput container', function () { useNativeCurrencyAsPrimaryCurrency: true, }, }, - } + }; assert.deepStrictEqual(mapStateToProps(mockState), { useNativeCurrencyAsPrimaryCurrency: true, - }) - }) - }) -}) + }); + }); + }); +}); diff --git a/ui/app/components/app/user-preferenced-currency-input/user-preferenced-currency-input.component.js b/ui/app/components/app/user-preferenced-currency-input/user-preferenced-currency-input.component.js index f92a74b1d6..abd8cabfbc 100644 --- a/ui/app/components/app/user-preferenced-currency-input/user-preferenced-currency-input.component.js +++ b/ui/app/components/app/user-preferenced-currency-input/user-preferenced-currency-input.component.js @@ -1,20 +1,20 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import CurrencyInput from '../../ui/currency-input' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import CurrencyInput from '../../ui/currency-input'; export default class UserPreferencedCurrencyInput extends PureComponent { static propTypes = { useNativeCurrencyAsPrimaryCurrency: PropTypes.bool, - } + }; render() { - const { useNativeCurrencyAsPrimaryCurrency, ...restProps } = this.props + const { useNativeCurrencyAsPrimaryCurrency, ...restProps } = this.props; return ( - ) + ); } } diff --git a/ui/app/components/app/user-preferenced-currency-input/user-preferenced-currency-input.container.js b/ui/app/components/app/user-preferenced-currency-input/user-preferenced-currency-input.container.js index 2cce580279..e04e0c6893 100644 --- a/ui/app/components/app/user-preferenced-currency-input/user-preferenced-currency-input.container.js +++ b/ui/app/components/app/user-preferenced-currency-input/user-preferenced-currency-input.container.js @@ -1,13 +1,13 @@ -import { connect } from 'react-redux' -import { getPreferences } from '../../../selectors' -import UserPreferencedCurrencyInput from './user-preferenced-currency-input.component' +import { connect } from 'react-redux'; +import { getPreferences } from '../../../selectors'; +import UserPreferencedCurrencyInput from './user-preferenced-currency-input.component'; const mapStateToProps = (state) => { - const { useNativeCurrencyAsPrimaryCurrency } = getPreferences(state) + const { useNativeCurrencyAsPrimaryCurrency } = getPreferences(state); return { useNativeCurrencyAsPrimaryCurrency, - } -} + }; +}; -export default connect(mapStateToProps)(UserPreferencedCurrencyInput) +export default connect(mapStateToProps)(UserPreferencedCurrencyInput); diff --git a/ui/app/components/app/user-preferenced-token-input/index.js b/ui/app/components/app/user-preferenced-token-input/index.js index 54167e6339..454444e2f5 100644 --- a/ui/app/components/app/user-preferenced-token-input/index.js +++ b/ui/app/components/app/user-preferenced-token-input/index.js @@ -1 +1 @@ -export { default } from './user-preferenced-token-input.container' +export { default } from './user-preferenced-token-input.container'; diff --git a/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js b/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js index dcc5b68742..3fc20f6574 100644 --- a/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js +++ b/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js @@ -1,19 +1,19 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import UserPreferencedTokenInput from '../user-preferenced-token-input.component' -import TokenInput from '../../../ui/token-input' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import UserPreferencedTokenInput from '../user-preferenced-token-input.component'; +import TokenInput from '../../../ui/token-input'; describe('UserPreferencedCurrencyInput Component', function () { describe('rendering', function () { it('should render properly', function () { const wrapper = shallow( , - ) + ); - assert.ok(wrapper) - assert.strictEqual(wrapper.find(TokenInput).length, 1) - }) + assert.ok(wrapper); + assert.strictEqual(wrapper.find(TokenInput).length, 1); + }); it('should render showFiat for TokenInput based on preferences.useNativeCurrencyAsPrimaryCurrency', function () { const wrapper = shallow( @@ -21,13 +21,13 @@ describe('UserPreferencedCurrencyInput Component', function () { token={{ address: '0x0' }} useNativeCurrencyAsPrimaryCurrency />, - ) + ); - assert.ok(wrapper) - assert.strictEqual(wrapper.find(TokenInput).length, 1) - assert.strictEqual(wrapper.find(TokenInput).props().showFiat, false) - wrapper.setProps({ useNativeCurrencyAsPrimaryCurrency: false }) - assert.strictEqual(wrapper.find(TokenInput).props().showFiat, true) - }) - }) -}) + assert.ok(wrapper); + assert.strictEqual(wrapper.find(TokenInput).length, 1); + assert.strictEqual(wrapper.find(TokenInput).props().showFiat, false); + wrapper.setProps({ useNativeCurrencyAsPrimaryCurrency: false }); + assert.strictEqual(wrapper.find(TokenInput).props().showFiat, true); + }); + }); +}); diff --git a/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js b/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js index 8011f4885a..9ff33f0f5c 100644 --- a/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js +++ b/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js @@ -1,16 +1,16 @@ -import assert from 'assert' -import proxyquire from 'proxyquire' +import assert from 'assert'; +import proxyquire from 'proxyquire'; -let mapStateToProps +let mapStateToProps; proxyquire('../user-preferenced-token-input.container.js', { 'react-redux': { connect: (ms) => { - mapStateToProps = ms - return () => ({}) + mapStateToProps = ms; + return () => ({}); }, }, -}) +}); describe('UserPreferencedTokenInput container', function () { describe('mapStateToProps()', function () { @@ -21,11 +21,11 @@ describe('UserPreferencedTokenInput container', function () { useNativeCurrencyAsPrimaryCurrency: true, }, }, - } + }; assert.deepStrictEqual(mapStateToProps(mockState), { useNativeCurrencyAsPrimaryCurrency: true, - }) - }) - }) -}) + }); + }); + }); +}); diff --git a/ui/app/components/app/user-preferenced-token-input/user-preferenced-token-input.component.js b/ui/app/components/app/user-preferenced-token-input/user-preferenced-token-input.component.js index 6e26b6dec5..d08e547013 100644 --- a/ui/app/components/app/user-preferenced-token-input/user-preferenced-token-input.component.js +++ b/ui/app/components/app/user-preferenced-token-input/user-preferenced-token-input.component.js @@ -1,6 +1,6 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import TokenInput from '../../ui/token-input' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import TokenInput from '../../ui/token-input'; export default class UserPreferencedTokenInput extends PureComponent { static propTypes = { @@ -10,16 +10,16 @@ export default class UserPreferencedTokenInput extends PureComponent { symbol: PropTypes.string, }).isRequired, useNativeCurrencyAsPrimaryCurrency: PropTypes.bool, - } + }; render() { - const { useNativeCurrencyAsPrimaryCurrency, ...restProps } = this.props + const { useNativeCurrencyAsPrimaryCurrency, ...restProps } = this.props; return ( - ) + ); } } diff --git a/ui/app/components/app/user-preferenced-token-input/user-preferenced-token-input.container.js b/ui/app/components/app/user-preferenced-token-input/user-preferenced-token-input.container.js index 1d8799d30a..33afd8ce24 100644 --- a/ui/app/components/app/user-preferenced-token-input/user-preferenced-token-input.container.js +++ b/ui/app/components/app/user-preferenced-token-input/user-preferenced-token-input.container.js @@ -1,19 +1,19 @@ -import { connect } from 'react-redux' -import PropTypes from 'prop-types' -import { getPreferences } from '../../../selectors' -import UserPreferencedTokenInput from './user-preferenced-token-input.component' +import { connect } from 'react-redux'; +import PropTypes from 'prop-types'; +import { getPreferences } from '../../../selectors'; +import UserPreferencedTokenInput from './user-preferenced-token-input.component'; const mapStateToProps = (state) => { - const { useNativeCurrencyAsPrimaryCurrency } = getPreferences(state) + const { useNativeCurrencyAsPrimaryCurrency } = getPreferences(state); return { useNativeCurrencyAsPrimaryCurrency, - } -} + }; +}; const UserPreferencedTokenInputContainer = connect(mapStateToProps)( UserPreferencedTokenInput, -) +); UserPreferencedTokenInputContainer.propTypes = { token: PropTypes.shape({ @@ -21,6 +21,6 @@ UserPreferencedTokenInputContainer.propTypes = { decimals: PropTypes.number, symbol: PropTypes.string, }).isRequired, -} +}; -export default UserPreferencedTokenInputContainer +export default UserPreferencedTokenInputContainer; diff --git a/ui/app/components/app/wallet-overview/eth-overview.js b/ui/app/components/app/wallet-overview/eth-overview.js index 69aef63829..17bcb86734 100644 --- a/ui/app/components/app/wallet-overview/eth-overview.js +++ b/ui/app/components/app/wallet-overview/eth-overview.js @@ -1,74 +1,74 @@ -import React, { useContext } from 'react' -import PropTypes from 'prop-types' -import { useDispatch, useSelector } from 'react-redux' -import classnames from 'classnames' -import { useHistory } from 'react-router-dom' +import React, { useContext } from 'react'; +import PropTypes from 'prop-types'; +import { useDispatch, useSelector } from 'react-redux'; +import classnames from 'classnames'; +import { useHistory } from 'react-router-dom'; -import Identicon from '../../ui/identicon' -import { I18nContext } from '../../../contexts/i18n' +import Identicon from '../../ui/identicon'; +import { I18nContext } from '../../../contexts/i18n'; import { SEND_ROUTE, BUILD_QUOTE_ROUTE, -} from '../../../helpers/constants/routes' +} from '../../../helpers/constants/routes'; import { useMetricEvent, useNewMetricEvent, -} from '../../../hooks/useMetricEvent' -import { useSwapsEthToken } from '../../../hooks/useSwapsEthToken' -import Tooltip from '../../ui/tooltip' -import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display' -import { PRIMARY, SECONDARY } from '../../../helpers/constants/common' -import { showModal } from '../../../store/actions' +} from '../../../hooks/useMetricEvent'; +import { useSwapsEthToken } from '../../../hooks/useSwapsEthToken'; +import Tooltip from '../../ui/tooltip'; +import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display'; +import { PRIMARY, SECONDARY } from '../../../helpers/constants/common'; +import { showModal } from '../../../store/actions'; import { isBalanceCached, getSelectedAccount, getShouldShowFiat, getCurrentChainId, getCurrentKeyring, -} from '../../../selectors/selectors' -import SwapIcon from '../../ui/icon/swap-icon.component' -import BuyIcon from '../../ui/icon/overview-buy-icon.component' -import SendIcon from '../../ui/icon/overview-send-icon.component' +} from '../../../selectors/selectors'; +import SwapIcon from '../../ui/icon/swap-icon.component'; +import BuyIcon from '../../ui/icon/overview-buy-icon.component'; +import SendIcon from '../../ui/icon/overview-send-icon.component'; import { getSwapsFeatureLiveness, setSwapsFromToken, -} from '../../../ducks/swaps/swaps' -import IconButton from '../../ui/icon-button' -import { MAINNET_CHAIN_ID } from '../../../../../shared/constants/network' -import WalletOverview from './wallet-overview' +} from '../../../ducks/swaps/swaps'; +import IconButton from '../../ui/icon-button'; +import { MAINNET_CHAIN_ID } from '../../../../../shared/constants/network'; +import WalletOverview from './wallet-overview'; const EthOverview = ({ className }) => { - const dispatch = useDispatch() - const t = useContext(I18nContext) + const dispatch = useDispatch(); + const t = useContext(I18nContext); const sendEvent = useMetricEvent({ eventOpts: { category: 'Navigation', action: 'Home', name: 'Clicked Send: Eth', }, - }) + }); const depositEvent = useMetricEvent({ eventOpts: { category: 'Navigation', action: 'Home', name: 'Clicked Deposit', }, - }) - const history = useHistory() - const keyring = useSelector(getCurrentKeyring) - const usingHardwareWallet = keyring.type.search('Hardware') !== -1 - const balanceIsCached = useSelector(isBalanceCached) - const showFiat = useSelector(getShouldShowFiat) - const selectedAccount = useSelector(getSelectedAccount) - const { balance } = selectedAccount - const chainId = useSelector(getCurrentChainId) + }); + const history = useHistory(); + const keyring = useSelector(getCurrentKeyring); + const usingHardwareWallet = keyring.type.search('Hardware') !== -1; + const balanceIsCached = useSelector(isBalanceCached); + const showFiat = useSelector(getShouldShowFiat); + const selectedAccount = useSelector(getSelectedAccount); + const { balance } = selectedAccount; + const chainId = useSelector(getCurrentChainId); const enteredSwapsEvent = useNewMetricEvent({ event: 'Swaps Opened', properties: { source: 'Main View', active_currency: 'ETH' }, category: 'swaps', - }) - const swapsEnabled = useSelector(getSwapsFeatureLiveness) - const swapsEthToken = useSwapsEthToken() + }); + const swapsEnabled = useSelector(getSwapsFeatureLiveness); + const swapsEthToken = useSwapsEthToken(); return ( { Icon={BuyIcon} label={t('buy')} onClick={() => { - depositEvent() - dispatch(showModal({ name: 'DEPOSIT_ETHER' })) + depositEvent(); + dispatch(showModal({ name: 'DEPOSIT_ETHER' })); }} /> { Icon={SendIcon} label={t('send')} onClick={() => { - sendEvent() - history.push(SEND_ROUTE) + sendEvent(); + history.push(SEND_ROUTE); }} /> {swapsEnabled ? ( @@ -138,12 +138,12 @@ const EthOverview = ({ className }) => { Icon={SwapIcon} onClick={() => { if (chainId === MAINNET_CHAIN_ID) { - enteredSwapsEvent() - dispatch(setSwapsFromToken(swapsEthToken)) + enteredSwapsEvent(); + dispatch(setSwapsFromToken(swapsEthToken)); if (usingHardwareWallet) { - global.platform.openExtensionInBrowser(BUILD_QUOTE_ROUTE) + global.platform.openExtensionInBrowser(BUILD_QUOTE_ROUTE); } else { - history.push(BUILD_QUOTE_ROUTE) + history.push(BUILD_QUOTE_ROUTE); } } }} @@ -164,15 +164,15 @@ const EthOverview = ({ className }) => { className={className} icon={} /> - ) -} + ); +}; EthOverview.propTypes = { className: PropTypes.string, -} +}; EthOverview.defaultProps = { className: undefined, -} +}; -export default EthOverview +export default EthOverview; diff --git a/ui/app/components/app/wallet-overview/index.js b/ui/app/components/app/wallet-overview/index.js index e8205ea586..d0142dbf11 100644 --- a/ui/app/components/app/wallet-overview/index.js +++ b/ui/app/components/app/wallet-overview/index.js @@ -1,2 +1,2 @@ -export { default as EthOverview } from './eth-overview' -export { default as TokenOverview } from './token-overview' +export { default as EthOverview } from './eth-overview'; +export { default as TokenOverview } from './token-overview'; diff --git a/ui/app/components/app/wallet-overview/token-overview.js b/ui/app/components/app/wallet-overview/token-overview.js index 58b5673db8..e705461d9f 100644 --- a/ui/app/components/app/wallet-overview/token-overview.js +++ b/ui/app/components/app/wallet-overview/token-overview.js @@ -1,70 +1,70 @@ -import React, { useContext } from 'react' -import PropTypes from 'prop-types' -import { useDispatch, useSelector } from 'react-redux' -import { useHistory } from 'react-router-dom' +import React, { useContext } from 'react'; +import PropTypes from 'prop-types'; +import { useDispatch, useSelector } from 'react-redux'; +import { useHistory } from 'react-router-dom'; -import Identicon from '../../ui/identicon' -import Tooltip from '../../ui/tooltip' -import CurrencyDisplay from '../../ui/currency-display' -import { I18nContext } from '../../../contexts/i18n' +import Identicon from '../../ui/identicon'; +import Tooltip from '../../ui/tooltip'; +import CurrencyDisplay from '../../ui/currency-display'; +import { I18nContext } from '../../../contexts/i18n'; import { SEND_ROUTE, BUILD_QUOTE_ROUTE, -} from '../../../helpers/constants/routes' +} from '../../../helpers/constants/routes'; import { useMetricEvent, useNewMetricEvent, -} from '../../../hooks/useMetricEvent' -import { useTokenTracker } from '../../../hooks/useTokenTracker' -import { useTokenFiatAmount } from '../../../hooks/useTokenFiatAmount' -import { updateSendToken } from '../../../store/actions' +} from '../../../hooks/useMetricEvent'; +import { useTokenTracker } from '../../../hooks/useTokenTracker'; +import { useTokenFiatAmount } from '../../../hooks/useTokenFiatAmount'; +import { updateSendToken } from '../../../store/actions'; import { getSwapsFeatureLiveness, setSwapsFromToken, -} from '../../../ducks/swaps/swaps' +} from '../../../ducks/swaps/swaps'; import { getAssetImages, getCurrentKeyring, getCurrentChainId, -} from '../../../selectors/selectors' -import { MAINNET_CHAIN_ID } from '../../../../../shared/constants/network' +} from '../../../selectors/selectors'; +import { MAINNET_CHAIN_ID } from '../../../../../shared/constants/network'; -import SwapIcon from '../../ui/icon/swap-icon.component' -import SendIcon from '../../ui/icon/overview-send-icon.component' +import SwapIcon from '../../ui/icon/swap-icon.component'; +import SendIcon from '../../ui/icon/overview-send-icon.component'; -import IconButton from '../../ui/icon-button' -import WalletOverview from './wallet-overview' +import IconButton from '../../ui/icon-button'; +import WalletOverview from './wallet-overview'; const TokenOverview = ({ className, token }) => { - const dispatch = useDispatch() - const t = useContext(I18nContext) + const dispatch = useDispatch(); + const t = useContext(I18nContext); const sendTokenEvent = useMetricEvent({ eventOpts: { category: 'Navigation', action: 'Home', name: 'Clicked Send: Token', }, - }) - const history = useHistory() - const assetImages = useSelector(getAssetImages) + }); + const history = useHistory(); + const assetImages = useSelector(getAssetImages); - const keyring = useSelector(getCurrentKeyring) - const usingHardwareWallet = keyring.type.search('Hardware') !== -1 - const { tokensWithBalances } = useTokenTracker([token]) - const balanceToRender = tokensWithBalances[0]?.string - const balance = tokensWithBalances[0]?.balance + const keyring = useSelector(getCurrentKeyring); + const usingHardwareWallet = keyring.type.search('Hardware') !== -1; + const { tokensWithBalances } = useTokenTracker([token]); + const balanceToRender = tokensWithBalances[0]?.string; + const balance = tokensWithBalances[0]?.balance; const formattedFiatBalance = useTokenFiatAmount( token.address, balanceToRender, token.symbol, - ) - const chainId = useSelector(getCurrentChainId) + ); + const chainId = useSelector(getCurrentChainId); const enteredSwapsEvent = useNewMetricEvent({ event: 'Swaps Opened', properties: { source: 'Token View', active_currency: token.symbol }, category: 'swaps', - }) - const swapsEnabled = useSelector(getSwapsFeatureLiveness) + }); + const swapsEnabled = useSelector(getSwapsFeatureLiveness); return ( { { - sendTokenEvent() - dispatch(updateSendToken(token)) - history.push(SEND_ROUTE) + sendTokenEvent(); + dispatch(updateSendToken(token)); + history.push(SEND_ROUTE); }} Icon={SendIcon} label={t('send')} @@ -104,7 +104,7 @@ const TokenOverview = ({ className, token }) => { Icon={SwapIcon} onClick={() => { if (chainId === MAINNET_CHAIN_ID) { - enteredSwapsEvent() + enteredSwapsEvent(); dispatch( setSwapsFromToken({ ...token, @@ -112,11 +112,11 @@ const TokenOverview = ({ className, token }) => { balance, string: balanceToRender, }), - ) + ); if (usingHardwareWallet) { - global.platform.openExtensionInBrowser(BUILD_QUOTE_ROUTE) + global.platform.openExtensionInBrowser(BUILD_QUOTE_ROUTE); } else { - history.push(BUILD_QUOTE_ROUTE) + history.push(BUILD_QUOTE_ROUTE); } } }} @@ -143,8 +143,8 @@ const TokenOverview = ({ className, token }) => { /> } /> - ) -} + ); +}; TokenOverview.propTypes = { className: PropTypes.string, @@ -153,10 +153,10 @@ TokenOverview.propTypes = { decimals: PropTypes.number, symbol: PropTypes.string, }).isRequired, -} +}; TokenOverview.defaultProps = { className: undefined, -} +}; -export default TokenOverview +export default TokenOverview; diff --git a/ui/app/components/app/wallet-overview/wallet-overview.js b/ui/app/components/app/wallet-overview/wallet-overview.js index b4ca1b4ff8..6f5d1341d3 100644 --- a/ui/app/components/app/wallet-overview/wallet-overview.js +++ b/ui/app/components/app/wallet-overview/wallet-overview.js @@ -1,6 +1,6 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; const WalletOverview = ({ balance, buttons, className, icon }) => { return ( @@ -11,18 +11,18 @@ const WalletOverview = ({ balance, buttons, className, icon }) => {
    {buttons}
    - ) -} + ); +}; WalletOverview.propTypes = { balance: PropTypes.element.isRequired, buttons: PropTypes.element.isRequired, className: PropTypes.string, icon: PropTypes.element.isRequired, -} +}; WalletOverview.defaultProps = { className: undefined, -} +}; -export default WalletOverview +export default WalletOverview; diff --git a/ui/app/components/ui/account-mismatch-warning/account-mismatch-warning.component.js b/ui/app/components/ui/account-mismatch-warning/account-mismatch-warning.component.js index 6fcb10e15b..797ce00141 100644 --- a/ui/app/components/ui/account-mismatch-warning/account-mismatch-warning.component.js +++ b/ui/app/components/ui/account-mismatch-warning/account-mismatch-warning.component.js @@ -1,17 +1,17 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import PropTypes from 'prop-types' -import Tooltip from '../tooltip' -import { getSelectedAccount } from '../../../selectors' -import InfoIcon from '../icon/info-icon.component' -import { useI18nContext } from '../../../hooks/useI18nContext' -import { SEVERITIES } from '../../../helpers/constants/design-system' +import React from 'react'; +import { useSelector } from 'react-redux'; +import PropTypes from 'prop-types'; +import Tooltip from '../tooltip'; +import { getSelectedAccount } from '../../../selectors'; +import InfoIcon from '../icon/info-icon.component'; +import { useI18nContext } from '../../../hooks/useI18nContext'; +import { SEVERITIES } from '../../../helpers/constants/design-system'; export default function AccountMismatchWarning({ address }) { - const selectedAccount = useSelector(getSelectedAccount) - const t = useI18nContext() + const selectedAccount = useSelector(getSelectedAccount); + const t = useI18nContext(); if (selectedAccount.address === address) { - return null + return null; } return ( @@ -25,9 +25,9 @@ export default function AccountMismatchWarning({ address }) { - ) + ); } AccountMismatchWarning.propTypes = { address: PropTypes.string.isRequired, -} +}; diff --git a/ui/app/components/ui/account-mismatch-warning/tests/acccount-mismatch-warning.component.test.js b/ui/app/components/ui/account-mismatch-warning/tests/acccount-mismatch-warning.component.test.js index 733d81241a..febddd53b1 100644 --- a/ui/app/components/ui/account-mismatch-warning/tests/acccount-mismatch-warning.component.test.js +++ b/ui/app/components/ui/account-mismatch-warning/tests/acccount-mismatch-warning.component.test.js @@ -1,32 +1,34 @@ -import assert from 'assert' -import React from 'react' -import * as reactRedux from 'react-redux' -import sinon from 'sinon' -import { shallow } from 'enzyme' -import InfoIcon from '../../icon/info-icon.component' -import AccountMismatchWarning from '../account-mismatch-warning.component' -import { getSelectedAccount } from '../../../../selectors' +import assert from 'assert'; +import React from 'react'; +import * as reactRedux from 'react-redux'; +import sinon from 'sinon'; +import { shallow } from 'enzyme'; +import InfoIcon from '../../icon/info-icon.component'; +import AccountMismatchWarning from '../account-mismatch-warning.component'; +import { getSelectedAccount } from '../../../../selectors'; describe('AccountMismatchWarning', function () { before(function () { sinon.stub(reactRedux, 'useSelector').callsFake((selector) => { if (selector === getSelectedAccount) { - return { address: 'mockedAddress' } + return { address: 'mockedAddress' }; } throw new Error( `${selector.name} is not cared for in the AccountMismatchWarning test useSelector stub`, - ) - }) - }) + ); + }); + }); it('renders nothing when the addresses match', function () { - const wrapper = shallow() - assert.strictEqual(wrapper.find(InfoIcon).length, 0) - }) + const wrapper = shallow(); + assert.strictEqual(wrapper.find(InfoIcon).length, 0); + }); it('renders a warning info icon when addresses do not match', function () { - const wrapper = shallow() - assert.strictEqual(wrapper.find(InfoIcon).length, 1) - }) + const wrapper = shallow( + , + ); + assert.strictEqual(wrapper.find(InfoIcon).length, 1); + }); after(function () { - sinon.restore() - }) -}) + sinon.restore(); + }); +}); diff --git a/ui/app/components/ui/alert-circle-icon/alert-circle-icon.component.js b/ui/app/components/ui/alert-circle-icon/alert-circle-icon.component.js index 7c8a37aaa7..71eca77839 100644 --- a/ui/app/components/ui/alert-circle-icon/alert-circle-icon.component.js +++ b/ui/app/components/ui/alert-circle-icon/alert-circle-icon.component.js @@ -1,6 +1,6 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import CircleIcon from '../circle-icon' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import CircleIcon from '../circle-icon'; const typeConfig = { danger: { @@ -11,14 +11,14 @@ const typeConfig = { circleClass: 'alert-circle-icon--warning', iconSource: 'images/icons/yellow-bell.svg', }, -} +}; export default class AlertCircleIcon extends Component { static propTypes = { type: PropTypes.oneOf(Object.keys(typeConfig)).isRequired, - } + }; render() { - return + return ; } } diff --git a/ui/app/components/ui/alert-circle-icon/alert-circle-icon.stories.js b/ui/app/components/ui/alert-circle-icon/alert-circle-icon.stories.js index 8b2dd5574d..e4f0ec8460 100644 --- a/ui/app/components/ui/alert-circle-icon/alert-circle-icon.stories.js +++ b/ui/app/components/ui/alert-circle-icon/alert-circle-icon.stories.js @@ -1,10 +1,10 @@ -import React from 'react' -import AlertCircleIcon from './alert-circle-icon.component' +import React from 'react'; +import AlertCircleIcon from './alert-circle-icon.component'; export default { title: 'AlertCircleIcon', -} +}; -export const dangerCircleIcon = () => +export const dangerCircleIcon = () => ; -export const warningCircleIcon = () => +export const warningCircleIcon = () => ; diff --git a/ui/app/components/ui/alert-circle-icon/index.js b/ui/app/components/ui/alert-circle-icon/index.js index 3cf3199253..80ab7a4c93 100644 --- a/ui/app/components/ui/alert-circle-icon/index.js +++ b/ui/app/components/ui/alert-circle-icon/index.js @@ -1 +1 @@ -export { default } from './alert-circle-icon.component' +export { default } from './alert-circle-icon.component'; diff --git a/ui/app/components/ui/alert/index.js b/ui/app/components/ui/alert/index.js index e047785691..44677cf0b5 100644 --- a/ui/app/components/ui/alert/index.js +++ b/ui/app/components/ui/alert/index.js @@ -1,19 +1,19 @@ -import classnames from 'classnames' -import PropTypes from 'prop-types' -import React, { Component } from 'react' +import classnames from 'classnames'; +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; class Alert extends Component { state = { visible: false, msg: false, className: '', - } + }; UNSAFE_componentWillReceiveProps(nextProps) { if (!this.props.visible && nextProps.visible) { - this.animateIn(nextProps.msg) + this.animateIn(nextProps.msg); } else if (this.props.visible && !nextProps.visible) { - this.animateOut() + this.animateOut(); } } @@ -22,18 +22,18 @@ class Alert extends Component { msg, visible: true, className: 'visible', - }) + }); } animateOut() { this.setState({ msg: null, className: 'hidden', - }) + }); setTimeout((_) => { - this.setState({ visible: false }) - }, 500) + this.setState({ visible: false }); + }, 500); } render() { @@ -42,14 +42,14 @@ class Alert extends Component { - ) + ); } - return null + return null; } } Alert.propTypes = { visible: PropTypes.bool.isRequired, msg: PropTypes.string /* eslint-disable-line react/no-unused-prop-types */, -} -export default Alert +}; +export default Alert; diff --git a/ui/app/components/ui/alert/tests/alert.test.js b/ui/app/components/ui/alert/tests/alert.test.js index c8d36528b0..64c519e0e8 100644 --- a/ui/app/components/ui/alert/tests/alert.test.js +++ b/ui/app/components/ui/alert/tests/alert.test.js @@ -1,41 +1,41 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import { shallow } from 'enzyme' -import Alert from '..' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import { shallow } from 'enzyme'; +import Alert from '..'; describe('Alert', function () { - let wrapper + let wrapper; beforeEach(function () { - wrapper = shallow() - }) + wrapper = shallow(); + }); it('renders nothing with no visible boolean in state', function () { - const alert = wrapper.find('.global-alert') - assert.strictEqual(alert.length, 0) - }) + const alert = wrapper.find('.global-alert'); + assert.strictEqual(alert.length, 0); + }); it('renders when visible in state is true, and message', function () { - const errorMessage = 'Error Message' + const errorMessage = 'Error Message'; - wrapper.setState({ visible: true, msg: errorMessage }) + wrapper.setState({ visible: true, msg: errorMessage }); - const alert = wrapper.find('.global-alert') - assert.strictEqual(alert.length, 1) + const alert = wrapper.find('.global-alert'); + assert.strictEqual(alert.length, 1); - const errorText = wrapper.find('.msg') - assert.strictEqual(errorText.text(), errorMessage) - }) + const errorText = wrapper.find('.msg'); + assert.strictEqual(errorText.text(), errorMessage); + }); it('calls component method when componentWillReceiveProps is called', function () { - const animateInSpy = sinon.stub(wrapper.instance(), 'animateIn') - const animateOutSpy = sinon.stub(wrapper.instance(), 'animateOut') + const animateInSpy = sinon.stub(wrapper.instance(), 'animateIn'); + const animateOutSpy = sinon.stub(wrapper.instance(), 'animateOut'); - wrapper.setProps({ visible: true }) - assert(animateInSpy.calledOnce) + wrapper.setProps({ visible: true }); + assert(animateInSpy.calledOnce); - wrapper.setProps({ visible: false }) - assert(animateOutSpy.calledOnce) - }) -}) + wrapper.setProps({ visible: false }); + assert(animateOutSpy.calledOnce); + }); +}); diff --git a/ui/app/components/ui/box/box.js b/ui/app/components/ui/box/box.js index 85567e6c64..006d566ce9 100644 --- a/ui/app/components/ui/box/box.js +++ b/ui/app/components/ui/box/box.js @@ -1,6 +1,6 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; import { ALIGN_ITEMS, BLOCK_SIZES, @@ -9,26 +9,26 @@ import { DISPLAY, JUSTIFY_CONTENT, SIZES, -} from '../../../helpers/constants/design-system' +} from '../../../helpers/constants/design-system'; -const ValidSize = PropTypes.oneOf([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) -const ArrayOfValidSizes = PropTypes.arrayOf(ValidSize) -const MultipleSizes = PropTypes.oneOfType([ValidSize, ArrayOfValidSizes]) +const ValidSize = PropTypes.oneOf([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]); +const ArrayOfValidSizes = PropTypes.arrayOf(ValidSize); +const MultipleSizes = PropTypes.oneOfType([ValidSize, ArrayOfValidSizes]); function generateSizeClasses(baseClass, type, main, top, right, bottom, left) { - const arr = Array.isArray(main) ? main : [] - const singleDigit = Array.isArray(main) ? undefined : main + const arr = Array.isArray(main) ? main : []; + const singleDigit = Array.isArray(main) ? undefined : main; if (Array.isArray(main) && ![2, 3, 4].includes(main.length)) { throw new Error( `Expected prop ${type} to have length between 2 and 4, received ${main.length}`, - ) + ); } - const isHorizontalAndVertical = arr.length === 2 - const isTopHorizontalAndBottom = arr.length === 3 - const isAllFour = arr.length === 4 - const hasAtLeastTwo = arr.length >= 2 - const hasAtLeastThree = arr.length >= 3 + const isHorizontalAndVertical = arr.length === 2; + const isTopHorizontalAndBottom = arr.length === 3; + const isAllFour = arr.length === 4; + const hasAtLeastTwo = arr.length >= 2; + const hasAtLeastThree = arr.length >= 3; return { [`${baseClass}--${type}-${singleDigit}`]: singleDigit !== undefined, [`${baseClass}--${type}-top-${top}`]: typeof top === 'number', @@ -50,7 +50,7 @@ function generateSizeClasses(baseClass, type, main, top, right, bottom, left) { isHorizontalAndVertical || isTopHorizontalAndBottom, // If an array has 4 values, the fourth number is the left value [`${baseClass}--${type}-left-${arr?.[3]}`]: isAllFour, - } + }; } export default function Box({ @@ -117,12 +117,12 @@ export default function Box({ // width & height [`box--width-${width}`]: Boolean(width), [`box--height-${height}`]: Boolean(height), - }) + }); // Apply Box styles to any other component using function pattern if (typeof children === 'function') { - return children(boxClassName) + return children(boxClassName); } - return
    {children}
    + return
    {children}
    ; } Box.propTypes = { @@ -146,4 +146,4 @@ Box.propTypes = { display: PropTypes.oneOf(Object.values(DISPLAY)), width: PropTypes.oneOf(Object.values(BLOCK_SIZES)), height: PropTypes.oneOf(Object.values(BLOCK_SIZES)), -} +}; diff --git a/ui/app/components/ui/box/box.stories.js b/ui/app/components/ui/box/box.stories.js index bae0f257ad..a76d2fff5e 100644 --- a/ui/app/components/ui/box/box.stories.js +++ b/ui/app/components/ui/box/box.stories.js @@ -1,5 +1,5 @@ -import { number, select } from '@storybook/addon-knobs' -import React from 'react' +import { number, select } from '@storybook/addon-knobs'; +import React from 'react'; import { ALIGN_ITEMS, BLOCK_SIZES, @@ -7,25 +7,25 @@ import { COLORS, DISPLAY, JUSTIFY_CONTENT, -} from '../../../helpers/constants/design-system' -import Box from './box' +} from '../../../helpers/constants/design-system'; +import Box from './box'; export default { title: 'Box', -} +}; -const sizeKnobOptions = [undefined, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] +const sizeKnobOptions = [undefined, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; export const box = () => { - const items = [] + const items = []; const size = number( 'size', 100, { range: true, min: 50, max: 500, step: 10 }, 'children', - ) + ); for (let $i = 0; $i < number('items', 1, {}, 'children'); $i++) { - items.push() + items.push(); } return ( { > {items} - ) -} + ); +}; diff --git a/ui/app/components/ui/box/index.js b/ui/app/components/ui/box/index.js index e5b58f3732..20292302cc 100644 --- a/ui/app/components/ui/box/index.js +++ b/ui/app/components/ui/box/index.js @@ -1 +1 @@ -export { default } from './box' +export { default } from './box'; diff --git a/ui/app/components/ui/breadcrumbs/breadcrumbs.component.js b/ui/app/components/ui/breadcrumbs/breadcrumbs.component.js index 192fb1f422..c00844aa1c 100644 --- a/ui/app/components/ui/breadcrumbs/breadcrumbs.component.js +++ b/ui/app/components/ui/breadcrumbs/breadcrumbs.component.js @@ -1,16 +1,16 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; export default class Breadcrumbs extends PureComponent { static propTypes = { className: PropTypes.string, currentIndex: PropTypes.number, total: PropTypes.number, - } + }; render() { - const { className, currentIndex, total } = this.props + const { className, currentIndex, total } = this.props; return (
    @@ -26,6 +26,6 @@ export default class Breadcrumbs extends PureComponent { /> ))}
    - ) + ); } } diff --git a/ui/app/components/ui/breadcrumbs/index.js b/ui/app/components/ui/breadcrumbs/index.js index 07a11574f6..f169c7d6ac 100644 --- a/ui/app/components/ui/breadcrumbs/index.js +++ b/ui/app/components/ui/breadcrumbs/index.js @@ -1 +1 @@ -export { default } from './breadcrumbs.component' +export { default } from './breadcrumbs.component'; diff --git a/ui/app/components/ui/breadcrumbs/tests/breadcrumbs.component.test.js b/ui/app/components/ui/breadcrumbs/tests/breadcrumbs.component.test.js index 9d9abbdc65..c2f7af83b2 100644 --- a/ui/app/components/ui/breadcrumbs/tests/breadcrumbs.component.test.js +++ b/ui/app/components/ui/breadcrumbs/tests/breadcrumbs.component.test.js @@ -1,26 +1,26 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import Breadcrumbs from '../breadcrumbs.component' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import Breadcrumbs from '../breadcrumbs.component'; describe('Breadcrumbs Component', function () { it('should render with the correct colors', function () { - const wrapper = shallow() + const wrapper = shallow(); - assert.ok(wrapper) - assert.strictEqual(wrapper.find('.breadcrumbs').length, 1) - assert.strictEqual(wrapper.find('.breadcrumb').length, 3) + assert.ok(wrapper); + assert.strictEqual(wrapper.find('.breadcrumbs').length, 1); + assert.strictEqual(wrapper.find('.breadcrumb').length, 3); assert.strictEqual( wrapper.find('.breadcrumb').at(0).props().style.backgroundColor, '#FFFFFF', - ) + ); assert.strictEqual( wrapper.find('.breadcrumb').at(1).props().style.backgroundColor, '#D8D8D8', - ) + ); assert.strictEqual( wrapper.find('.breadcrumb').at(2).props().style.backgroundColor, '#FFFFFF', - ) - }) -}) + ); + }); +}); diff --git a/ui/app/components/ui/button-group/button-group.component.js b/ui/app/components/ui/button-group/button-group.component.js index aeb9b37d3a..d1f20e9615 100644 --- a/ui/app/components/ui/button-group/button-group.component.js +++ b/ui/app/components/ui/button-group/button-group.component.js @@ -1,6 +1,6 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; export default class ButtonGroup extends PureComponent { static propTypes = { @@ -12,19 +12,19 @@ export default class ButtonGroup extends PureComponent { style: PropTypes.object, newActiveButtonIndex: PropTypes.number, variant: PropTypes.oneOf(['radiogroup', 'default']), - } + }; static defaultProps = { className: 'button-group', defaultActiveButtonIndex: 0, variant: 'default', - } + }; state = { activeButtonIndex: this.props.noButtonActiveByDefault ? null : this.props.defaultActiveButtonIndex, - } + }; componentDidUpdate(_, prevState) { // Provides an API for dynamically updating the activeButtonIndex @@ -32,16 +32,16 @@ export default class ButtonGroup extends PureComponent { typeof this.props.newActiveButtonIndex === 'number' && prevState.activeButtonIndex !== this.props.newActiveButtonIndex ) { - this.setState({ activeButtonIndex: this.props.newActiveButtonIndex }) + this.setState({ activeButtonIndex: this.props.newActiveButtonIndex }); } } handleButtonClick(activeButtonIndex) { - this.setState({ activeButtonIndex }) + this.setState({ activeButtonIndex }); } renderButtons() { - const { children, disabled, variant } = this.props + const { children, disabled, variant } = this.props; return React.Children.map(children, (child, index) => { return ( @@ -62,8 +62,8 @@ export default class ButtonGroup extends PureComponent { }, )} onClick={() => { - this.handleButtonClick(index) - child.props.onClick?.() + this.handleButtonClick(index); + child.props.onClick?.(); }} disabled={disabled || child.props.disabled} key={index} @@ -71,12 +71,12 @@ export default class ButtonGroup extends PureComponent { {child.props.children} ) - ) - }) + ); + }); } render() { - const { className, style, variant } = this.props + const { className, style, variant } = this.props; return (
    {this.renderButtons()}
    - ) + ); } } diff --git a/ui/app/components/ui/button-group/button-group.stories.js b/ui/app/components/ui/button-group/button-group.stories.js index d9cbdf3d5b..29b7804d43 100644 --- a/ui/app/components/ui/button-group/button-group.stories.js +++ b/ui/app/components/ui/button-group/button-group.stories.js @@ -1,13 +1,13 @@ -import React from 'react' -import { action } from '@storybook/addon-actions' -import classnames from 'classnames' -import { text, boolean } from '@storybook/addon-knobs' -import Button from '../button' -import ButtonGroup from '.' +import React from 'react'; +import { action } from '@storybook/addon-actions'; +import classnames from 'classnames'; +import { text, boolean } from '@storybook/addon-knobs'; +import Button from '../button'; +import ButtonGroup from '.'; export default { title: 'ButtonGroup', -} +}; export const withButtons = () => ( ( -) +); export const withDisabledButton = () => ( @@ -28,7 +28,7 @@ export const withDisabledButton = () => ( {text('Button2', 'Disabled')} -) +); export const radioButtons = () => ( ( {text('Button3', '5%')} -) +); diff --git a/ui/app/components/ui/button-group/index.js b/ui/app/components/ui/button-group/index.js index df470bd571..eab4b74ff7 100644 --- a/ui/app/components/ui/button-group/index.js +++ b/ui/app/components/ui/button-group/index.js @@ -1 +1 @@ -export { default } from './button-group.component' +export { default } from './button-group.component'; diff --git a/ui/app/components/ui/button-group/tests/button-group-component.test.js b/ui/app/components/ui/button-group/tests/button-group-component.test.js index e64c866fa3..a7e82cc45e 100644 --- a/ui/app/components/ui/button-group/tests/button-group-component.test.js +++ b/ui/app/components/ui/button-group/tests/button-group-component.test.js @@ -1,15 +1,15 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import sinon from 'sinon' -import ButtonGroup from '../button-group.component' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import ButtonGroup from '../button-group.component'; describe('ButtonGroup Component', function () { - let wrapper + let wrapper; const childButtonSpies = { onClick: sinon.spy(), - } + }; const mockButtons = [ , , , - ] + ]; before(function () { - sinon.spy(ButtonGroup.prototype, 'handleButtonClick') - sinon.spy(ButtonGroup.prototype, 'renderButtons') - }) + sinon.spy(ButtonGroup.prototype, 'handleButtonClick'); + sinon.spy(ButtonGroup.prototype, 'renderButtons'); + }); beforeEach(function () { wrapper = shallow( @@ -34,95 +34,95 @@ describe('ButtonGroup Component', function () { > {mockButtons} , - ) - }) + ); + }); afterEach(function () { - childButtonSpies.onClick.resetHistory() - ButtonGroup.prototype.handleButtonClick.resetHistory() - ButtonGroup.prototype.renderButtons.resetHistory() - }) + childButtonSpies.onClick.resetHistory(); + ButtonGroup.prototype.handleButtonClick.resetHistory(); + ButtonGroup.prototype.renderButtons.resetHistory(); + }); after(function () { - sinon.restore() - }) + sinon.restore(); + }); describe('componentDidUpdate', function () { it('should set the activeButtonIndex to the updated newActiveButtonIndex', function () { - assert.strictEqual(wrapper.state('activeButtonIndex'), 1) - wrapper.setProps({ newActiveButtonIndex: 2 }) - assert.strictEqual(wrapper.state('activeButtonIndex'), 2) - }) + assert.strictEqual(wrapper.state('activeButtonIndex'), 1); + wrapper.setProps({ newActiveButtonIndex: 2 }); + assert.strictEqual(wrapper.state('activeButtonIndex'), 2); + }); it('should not set the activeButtonIndex to an updated newActiveButtonIndex that is not a number', function () { - assert.strictEqual(wrapper.state('activeButtonIndex'), 1) - wrapper.setProps({ newActiveButtonIndex: null }) - assert.strictEqual(wrapper.state('activeButtonIndex'), 1) - }) - }) + assert.strictEqual(wrapper.state('activeButtonIndex'), 1); + wrapper.setProps({ newActiveButtonIndex: null }); + assert.strictEqual(wrapper.state('activeButtonIndex'), 1); + }); + }); describe('handleButtonClick', function () { it('should set the activeButtonIndex', function () { - assert.strictEqual(wrapper.state('activeButtonIndex'), 1) - wrapper.instance().handleButtonClick(2) - assert.strictEqual(wrapper.state('activeButtonIndex'), 2) - }) - }) + assert.strictEqual(wrapper.state('activeButtonIndex'), 1); + wrapper.instance().handleButtonClick(2); + assert.strictEqual(wrapper.state('activeButtonIndex'), 2); + }); + }); describe('renderButtons', function () { it('should render a button for each child', function () { - const childButtons = wrapper.find('.button-group__button') - assert.strictEqual(childButtons.length, 3) - }) + const childButtons = wrapper.find('.button-group__button'); + assert.strictEqual(childButtons.length, 3); + }); it('should render the correct button with an active state', function () { - const childButtons = wrapper.find('.button-group__button') - const activeChildButton = wrapper.find('.button-group__button--active') - assert.deepStrictEqual(childButtons.get(1), activeChildButton.get(0)) - }) + const childButtons = wrapper.find('.button-group__button'); + const activeChildButton = wrapper.find('.button-group__button--active'); + assert.deepStrictEqual(childButtons.get(1), activeChildButton.get(0)); + }); it("should call handleButtonClick and the respective button's onClick method when a button is clicked", function () { - assert.strictEqual(ButtonGroup.prototype.handleButtonClick.callCount, 0) - assert.strictEqual(childButtonSpies.onClick.callCount, 0) - const childButtons = wrapper.find('.button-group__button') - childButtons.at(0).props().onClick() - childButtons.at(1).props().onClick() - childButtons.at(2).props().onClick() - assert.strictEqual(ButtonGroup.prototype.handleButtonClick.callCount, 3) - assert.strictEqual(childButtonSpies.onClick.callCount, 3) - }) + assert.strictEqual(ButtonGroup.prototype.handleButtonClick.callCount, 0); + assert.strictEqual(childButtonSpies.onClick.callCount, 0); + const childButtons = wrapper.find('.button-group__button'); + childButtons.at(0).props().onClick(); + childButtons.at(1).props().onClick(); + childButtons.at(2).props().onClick(); + assert.strictEqual(ButtonGroup.prototype.handleButtonClick.callCount, 3); + assert.strictEqual(childButtonSpies.onClick.callCount, 3); + }); it('should render all child buttons as disabled if props.disabled is true', function () { - const childButtons = wrapper.find('.button-group__button') + const childButtons = wrapper.find('.button-group__button'); childButtons.forEach((button) => { - assert.strictEqual(button.props().disabled, undefined) - }) - wrapper.setProps({ disabled: true }) - const disabledChildButtons = wrapper.find('[disabled=true]') - assert.strictEqual(disabledChildButtons.length, 3) - }) + assert.strictEqual(button.props().disabled, undefined); + }); + wrapper.setProps({ disabled: true }); + const disabledChildButtons = wrapper.find('[disabled=true]'); + assert.strictEqual(disabledChildButtons.length, 3); + }); it('should render the children of the button', function () { - const mockClass = wrapper.find('.mockClass') - assert.strictEqual(mockClass.length, 1) - }) - }) + const mockClass = wrapper.find('.mockClass'); + assert.strictEqual(mockClass.length, 1); + }); + }); describe('render', function () { it('should render a div with the expected class and style', function () { assert.strictEqual( wrapper.find('div').at(0).props().className, 'someClassName', - ) + ); assert.deepStrictEqual(wrapper.find('div').at(0).props().style, { color: 'red', - }) - }) + }); + }); it('should call renderButtons when rendering', function () { - assert.strictEqual(ButtonGroup.prototype.renderButtons.callCount, 1) - wrapper.instance().render() - assert.strictEqual(ButtonGroup.prototype.renderButtons.callCount, 2) - }) - }) -}) + assert.strictEqual(ButtonGroup.prototype.renderButtons.callCount, 1); + wrapper.instance().render(); + assert.strictEqual(ButtonGroup.prototype.renderButtons.callCount, 2); + }); + }); +}); diff --git a/ui/app/components/ui/button/button.component.js b/ui/app/components/ui/button/button.component.js index 52b267517b..a1af4da437 100644 --- a/ui/app/components/ui/button/button.component.js +++ b/ui/app/components/ui/button/button.component.js @@ -1,15 +1,15 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; -const CLASSNAME_DEFAULT = 'btn-default' -const CLASSNAME_PRIMARY = 'btn-primary' -const CLASSNAME_SECONDARY = 'btn-secondary' -const CLASSNAME_CONFIRM = 'btn-primary' -const CLASSNAME_RAISED = 'btn-raised' -const CLASSNAME_LARGE = 'btn--large' -const CLASSNAME_ROUNDED = 'btn--rounded' -const CLASSNAME_FIRST_TIME = 'btn--first-time' +const CLASSNAME_DEFAULT = 'btn-default'; +const CLASSNAME_PRIMARY = 'btn-primary'; +const CLASSNAME_SECONDARY = 'btn-secondary'; +const CLASSNAME_CONFIRM = 'btn-primary'; +const CLASSNAME_RAISED = 'btn-raised'; +const CLASSNAME_LARGE = 'btn--large'; +const CLASSNAME_ROUNDED = 'btn--rounded'; +const CLASSNAME_FIRST_TIME = 'btn--first-time'; const typeHash = { default: CLASSNAME_DEFAULT, @@ -23,7 +23,7 @@ const typeHash = { confirm: CLASSNAME_CONFIRM, raised: CLASSNAME_RAISED, 'first-time': CLASSNAME_FIRST_TIME, -} +}; const Button = ({ type, @@ -39,11 +39,11 @@ const Button = ({ // we swap the html tag we use to render this component and delete any buttonProps that // we know to be erroneous attributes for a link. We will likely want to extract Link // to its own component in the future. - let Tag = 'button' + let Tag = 'button'; if (type === 'link') { - Tag = 'a' + Tag = 'a'; } else if (submit) { - buttonProps.type = 'submit' + buttonProps.type = 'submit'; } return ( {icon}} {children} - ) -} + ); +}; Button.propTypes = { type: PropTypes.string, @@ -70,10 +70,10 @@ Button.propTypes = { className: PropTypes.string, children: PropTypes.node, icon: PropTypes.node, -} +}; Button.defaultProps = { submit: false, -} +}; -export default Button +export default Button; diff --git a/ui/app/components/ui/button/button.stories.js b/ui/app/components/ui/button/button.stories.js index d07b02e314..f2bfe38387 100644 --- a/ui/app/components/ui/button/button.stories.js +++ b/ui/app/components/ui/button/button.stories.js @@ -1,11 +1,11 @@ -import React from 'react' -import { action } from '@storybook/addon-actions' -import { text, boolean } from '@storybook/addon-knobs' -import Button from '.' +import React from 'react'; +import { action } from '@storybook/addon-actions'; +import { text, boolean } from '@storybook/addon-knobs'; +import Button from '.'; export default { title: 'Button', -} +}; export const primaryType = () => ( -) +); export const secondaryType = () => ( -) +); export const defaultType = () => ( -) +); export const warningType = () => ( -) +); export const dangerType = () => ( -) +); export const dangerPrimaryType = () => ( -) +); diff --git a/ui/app/components/ui/button/index.js b/ui/app/components/ui/button/index.js index 19702ed25f..0b6199739d 100644 --- a/ui/app/components/ui/button/index.js +++ b/ui/app/components/ui/button/index.js @@ -1,3 +1,3 @@ -import Button from './button.component' +import Button from './button.component'; -export default Button +export default Button; diff --git a/ui/app/components/ui/callout/callout.js b/ui/app/components/ui/callout/callout.js index bc9d4ba62a..7da13c2b92 100644 --- a/ui/app/components/ui/callout/callout.js +++ b/ui/app/components/ui/callout/callout.js @@ -1,8 +1,8 @@ -import React, { useEffect, useState } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import InfoIconInverted from '../icon/info-icon-inverted.component' -import { SEVERITIES } from '../../../helpers/constants/design-system' +import React, { useEffect, useState } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import InfoIconInverted from '../icon/info-icon-inverted.component'; +import { SEVERITIES } from '../../../helpers/constants/design-system'; export default function Callout({ severity, @@ -12,14 +12,14 @@ export default function Callout({ isLast, isMultiple, }) { - const [removed, setRemoved] = useState(false) + const [removed, setRemoved] = useState(false); const calloutClassName = classnames('callout', `callout--${severity}`, { 'callout--dismissed': removed === true, 'callout--multiple': isMultiple === true, 'callout--dismissible': Boolean(dismiss), 'callout--first': isFirst === true || isMultiple !== true, 'callout--last': isLast === true || isMultiple !== true, - }) + }); // Clicking the close button will set removed state, which will trigger this // effect to refire due to changing dependencies. When that happens, after a // half of a second we fire the dismiss method from the parent. The @@ -28,10 +28,10 @@ export default function Callout({ useEffect(() => { if (removed) { setTimeout(() => { - dismiss() - }, 500) + dismiss(); + }, 500); } - }, [removed, dismiss]) + }, [removed, dismiss]); return (
    @@ -39,11 +39,11 @@ export default function Callout({ {dismiss && ( { - setRemoved(true) + setRemoved(true); }} onKeyUp={(event) => { if (event.key === 'Enter') { - setRemoved(true) + setRemoved(true); } }} role="button" @@ -52,7 +52,7 @@ export default function Callout({ /> )}
    - ) + ); } Callout.propTypes = { @@ -62,4 +62,4 @@ Callout.propTypes = { isFirst: PropTypes.bool, isLast: PropTypes.bool, isMultiple: PropTypes.bool, -} +}; diff --git a/ui/app/components/ui/callout/callout.stories.js b/ui/app/components/ui/callout/callout.stories.js index 079d7d10ed..7e2a54691e 100644 --- a/ui/app/components/ui/callout/callout.stories.js +++ b/ui/app/components/ui/callout/callout.stories.js @@ -1,17 +1,17 @@ -import { select } from '@storybook/addon-knobs' -import React, { useState } from 'react' +import { select } from '@storybook/addon-knobs'; +import React, { useState } from 'react'; import { COLORS, SEVERITIES, TYPOGRAPHY, -} from '../../../helpers/constants/design-system' -import Box from '../box' -import Typography from '../typography' -import Callout from './callout' +} from '../../../helpers/constants/design-system'; +import Box from '../box'; +import Typography from '../typography'; +import Callout from './callout'; export default { title: 'Callout', -} +}; export const persistentCallout = () => ( @@ -25,10 +25,10 @@ export const persistentCallout = () => ( Always back up your private key! -) +); export const DismissibleCallout = () => { - const [dismissed, setDismissed] = useState(false) + const [dismissed, setDismissed] = useState(false); return ( @@ -49,8 +49,8 @@ export const DismissibleCallout = () => { )} - ) -} + ); +}; const MULTIPLE_CALLOUTS = { WARN: { @@ -63,10 +63,10 @@ const MULTIPLE_CALLOUTS = { content: 'Never give your private key out, it will lead to loss of funds!', dismissed: false, }, -} +}; export const MultipleDismissibleCallouts = () => { - const [calloutState, setCalloutState] = useState(MULTIPLE_CALLOUTS) + const [calloutState, setCalloutState] = useState(MULTIPLE_CALLOUTS); const dismiss = (id) => { setCalloutState((prevState) => ({ ...prevState, @@ -74,8 +74,8 @@ export const MultipleDismissibleCallouts = () => { ...prevState[id], dismissed: true, }, - })) - } + })); + }; return ( @@ -103,5 +103,5 @@ export const MultipleDismissibleCallouts = () => { ))} - ) -} + ); +}; diff --git a/ui/app/components/ui/callout/index.js b/ui/app/components/ui/callout/index.js index dc48ad1acc..a258baf65c 100644 --- a/ui/app/components/ui/callout/index.js +++ b/ui/app/components/ui/callout/index.js @@ -1 +1 @@ -export { default } from './callout' +export { default } from './callout'; diff --git a/ui/app/components/ui/card/card.component.js b/ui/app/components/ui/card/card.component.js index c4e96e5117..d75506b9aa 100644 --- a/ui/app/components/ui/card/card.component.js +++ b/ui/app/components/ui/card/card.component.js @@ -1,6 +1,6 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; export default class Card extends PureComponent { static propTypes = { @@ -8,16 +8,16 @@ export default class Card extends PureComponent { overrideClassName: PropTypes.bool, title: PropTypes.string, children: PropTypes.node, - } + }; render() { - const { className, overrideClassName, title } = this.props + const { className, overrideClassName, title } = this.props; return (
    {title}
    {this.props.children}
    - ) + ); } } diff --git a/ui/app/components/ui/card/index.js b/ui/app/components/ui/card/index.js index c3ca6e3f4f..643fad74d3 100644 --- a/ui/app/components/ui/card/index.js +++ b/ui/app/components/ui/card/index.js @@ -1 +1 @@ -export { default } from './card.component' +export { default } from './card.component'; diff --git a/ui/app/components/ui/card/tests/card.component.test.js b/ui/app/components/ui/card/tests/card.component.test.js index efd05e7277..2f1d4b43c5 100644 --- a/ui/app/components/ui/card/tests/card.component.test.js +++ b/ui/app/components/ui/card/tests/card.component.test.js @@ -1,7 +1,7 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import Card from '../card.component' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import Card from '../card.component'; describe('Card Component', function () { it('should render a card with a title and child element', function () { @@ -9,14 +9,14 @@ describe('Card Component', function () {
    Child
    , - ) + ); - assert.ok(wrapper.hasClass('card-test-class')) - const title = wrapper.find('.card__title') - assert.ok(title) - assert.strictEqual(title.text(), 'Test') - const child = wrapper.find('.child-test-class') - assert.ok(child) - assert.strictEqual(child.text(), 'Child') - }) -}) + assert.ok(wrapper.hasClass('card-test-class')); + const title = wrapper.find('.card__title'); + assert.ok(title); + assert.strictEqual(title.text(), 'Test'); + const child = wrapper.find('.child-test-class'); + assert.ok(child); + assert.strictEqual(child.text(), 'Child'); + }); +}); diff --git a/ui/app/components/ui/check-box/check-box.component.js b/ui/app/components/ui/check-box/check-box.component.js index 360787902b..825d2cc166 100644 --- a/ui/app/components/ui/check-box/check-box.component.js +++ b/ui/app/components/ui/check-box/check-box.component.js @@ -1,24 +1,24 @@ -import React, { useLayoutEffect, useRef } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React, { useLayoutEffect, useRef } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; const CHECKBOX_STATE = { CHECKED: 'CHECKED', INDETERMINATE: 'INDETERMINATE', UNCHECKED: 'UNCHECKED', -} +}; -export const { CHECKED, INDETERMINATE, UNCHECKED } = CHECKBOX_STATE +export const { CHECKED, INDETERMINATE, UNCHECKED } = CHECKBOX_STATE; const CheckBox = ({ className, disabled, id, onClick, checked, title }) => { if (typeof checked === 'boolean') { // eslint-disable-next-line no-param-reassign - checked = checked ? CHECKBOX_STATE.CHECKED : CHECKBOX_STATE.UNCHECKED + checked = checked ? CHECKBOX_STATE.CHECKED : CHECKBOX_STATE.UNCHECKED; } - const ref = useRef(null) + const ref = useRef(null); useLayoutEffect(() => { - ref.current.indeterminate = checked === CHECKBOX_STATE.INDETERMINATE - }, [checked]) + ref.current.indeterminate = checked === CHECKBOX_STATE.INDETERMINATE; + }, [checked]); return ( { onClick={ onClick ? (event) => { - event.preventDefault() - onClick() + event.preventDefault(); + onClick(); } : null } @@ -45,8 +45,8 @@ const CheckBox = ({ className, disabled, id, onClick, checked, title }) => { title={title} type="checkbox" /> - ) -} + ); +}; CheckBox.propTypes = { className: PropTypes.string, @@ -56,12 +56,12 @@ CheckBox.propTypes = { checked: PropTypes.oneOf([...Object.keys(CHECKBOX_STATE), true, false]) .isRequired, title: PropTypes.string, -} +}; CheckBox.defaultProps = { className: undefined, disabled: false, id: undefined, -} +}; -export default CheckBox +export default CheckBox; diff --git a/ui/app/components/ui/check-box/check-box.stories.js b/ui/app/components/ui/check-box/check-box.stories.js index 2fb7cdae75..65e8d72812 100644 --- a/ui/app/components/ui/check-box/check-box.stories.js +++ b/ui/app/components/ui/check-box/check-box.stories.js @@ -1,15 +1,15 @@ -import React from 'react' -import { action } from '@storybook/addon-actions' -import { boolean, select, text } from '@storybook/addon-knobs' +import React from 'react'; +import { action } from '@storybook/addon-actions'; +import { boolean, select, text } from '@storybook/addon-knobs'; import CheckBox, { CHECKED, INDETERMINATE, UNCHECKED, -} from './check-box.component' +} from './check-box.component'; export default { title: 'Check Box', -} +}; const checkboxOptions = { [CHECKED]: CHECKED, @@ -17,7 +17,7 @@ const checkboxOptions = { [UNCHECKED]: UNCHECKED, True: true, False: false, -} +}; export const primaryType = () => ( ( id={text('ID', 'checkboxId')} onClick={action('checkbox clicked')} /> -) +); diff --git a/ui/app/components/ui/check-box/index.js b/ui/app/components/ui/check-box/index.js index 9a7460d6a3..d8c0dd4217 100644 --- a/ui/app/components/ui/check-box/index.js +++ b/ui/app/components/ui/check-box/index.js @@ -3,4 +3,4 @@ export { CHECKED, INDETERMINATE, UNCHECKED, -} from './check-box.component' +} from './check-box.component'; diff --git a/ui/app/components/ui/chip/chip.js b/ui/app/components/ui/chip/chip.js index 691df480b6..1d4f82d2a8 100644 --- a/ui/app/components/ui/chip/chip.js +++ b/ui/app/components/ui/chip/chip.js @@ -1,9 +1,9 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { omit } from 'lodash' -import Typography from '../typography' -import { COLORS, TYPOGRAPHY } from '../../../helpers/constants/design-system' +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import { omit } from 'lodash'; +import Typography from '../typography'; +import { COLORS, TYPOGRAPHY } from '../../../helpers/constants/design-system'; export default function Chip({ className, @@ -17,9 +17,9 @@ export default function Chip({ }) { const onKeyPress = (event) => { if (event.key === 'Enter' && onClick) { - onClick(event) + onClick(event); } - } + }; return (
    {rightIcon}
    } - ) + ); } Chip.propTypes = { @@ -61,4 +61,4 @@ Chip.propTypes = { rightIcon: PropTypes.node, className: PropTypes.string, onClick: PropTypes.func, -} +}; diff --git a/ui/app/components/ui/chip/chip.stories.js b/ui/app/components/ui/chip/chip.stories.js index e2f3fd5df2..690d97172d 100644 --- a/ui/app/components/ui/chip/chip.stories.js +++ b/ui/app/components/ui/chip/chip.stories.js @@ -1,15 +1,15 @@ /* eslint-disable react/prop-types */ -import React from 'react' -import { select, text } from '@storybook/addon-knobs' -import { COLORS, TYPOGRAPHY } from '../../../helpers/constants/design-system' -import ApproveIcon from '../icon/approve-icon.component' -import Identicon from '../identicon/identicon.component' -import Chip from '.' +import React from 'react'; +import { select, text } from '@storybook/addon-knobs'; +import { COLORS, TYPOGRAPHY } from '../../../helpers/constants/design-system'; +import ApproveIcon from '../icon/approve-icon.component'; +import Identicon from '../identicon/identicon.component'; +import Chip from '.'; export default { title: 'Chip', -} +}; export const Plain = ({ leftIcon, @@ -28,7 +28,7 @@ export const Plain = ({ }} borderColor={select('borderColor', COLORS, borderColor)} /> -) +); export const WithLeftIcon = () => ( ( fontColor={COLORS.SUCCESS3} leftIcon={} /> -) +); export const WithRightIcon = () => ( ( /> } /> -) +); export const WithBothIcons = () => ( ( /> } /> -) +); diff --git a/ui/app/components/ui/chip/index.js b/ui/app/components/ui/chip/index.js index 54029bc485..144a7e75da 100644 --- a/ui/app/components/ui/chip/index.js +++ b/ui/app/components/ui/chip/index.js @@ -1 +1 @@ -export { default } from './chip' +export { default } from './chip'; diff --git a/ui/app/components/ui/circle-icon/circle-icon.component.js b/ui/app/components/ui/circle-icon/circle-icon.component.js index 179906673f..5229532868 100644 --- a/ui/app/components/ui/circle-icon/circle-icon.component.js +++ b/ui/app/components/ui/circle-icon/circle-icon.component.js @@ -1,5 +1,5 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; export default class CircleIcon extends PureComponent { static propTypes = { @@ -7,16 +7,16 @@ export default class CircleIcon extends PureComponent { circleClass: PropTypes.string, iconSource: PropTypes.string.isRequired, iconSize: PropTypes.string, - } + }; static defaultProps = { size: '56px', iconSize: '18px', circleClass: '', - } + }; render() { - const { size, circleClass, iconSize, iconSource } = this.props + const { size, circleClass, iconSize, iconSource } = this.props; return (
    - ) + ); } } diff --git a/ui/app/components/ui/circle-icon/circle-icon.stories.js b/ui/app/components/ui/circle-icon/circle-icon.stories.js index 230a2f8a32..45b95dbd7f 100644 --- a/ui/app/components/ui/circle-icon/circle-icon.stories.js +++ b/ui/app/components/ui/circle-icon/circle-icon.stories.js @@ -1,9 +1,9 @@ -import React from 'react' -import CircleIcon from './circle-icon.component' +import React from 'react'; +import CircleIcon from './circle-icon.component'; export default { title: 'CircleIcon', -} +}; export const basicCircleIcon = () => ( ( iconSize="42px" iconSource="images/eth_logo.svg" /> -) +); diff --git a/ui/app/components/ui/circle-icon/index.js b/ui/app/components/ui/circle-icon/index.js index d5cfd62c13..7a4964c71b 100644 --- a/ui/app/components/ui/circle-icon/index.js +++ b/ui/app/components/ui/circle-icon/index.js @@ -1 +1 @@ -export { default } from './circle-icon.component' +export { default } from './circle-icon.component'; diff --git a/ui/app/components/ui/color-indicator/color-indicator.js b/ui/app/components/ui/color-indicator/color-indicator.js index 22ef28c0cd..f34eef3d9e 100644 --- a/ui/app/components/ui/color-indicator/color-indicator.js +++ b/ui/app/components/ui/color-indicator/color-indicator.js @@ -1,7 +1,7 @@ -import React from 'react' -import classnames from 'classnames' -import PropTypes from 'prop-types' -import { COLORS, SIZES } from '../../../helpers/constants/design-system' +import React from 'react'; +import classnames from 'classnames'; +import PropTypes from 'prop-types'; +import { COLORS, SIZES } from '../../../helpers/constants/design-system'; export default function ColorIndicator({ size = 'small', @@ -16,7 +16,7 @@ export default function ColorIndicator({ [`color-indicator--border-color-${borderColor}`]: Boolean(borderColor), [`color-indicator--color-${color}`]: true, [`color-indicator--size-${size}`]: true, - }) + }); return (
    @@ -26,14 +26,14 @@ export default function ColorIndicator({ )}
    - ) + ); } ColorIndicator.TYPES = { FILLED: 'filled', PARTIAL: 'partial-filled', OUTLINE: 'outline', -} +}; ColorIndicator.propTypes = { color: PropTypes.oneOf(Object.values(COLORS)), @@ -41,4 +41,4 @@ ColorIndicator.propTypes = { size: PropTypes.oneOf(Object.values(SIZES)), iconClassName: PropTypes.string, type: PropTypes.oneOf(Object.values(ColorIndicator.TYPES)), -} +}; diff --git a/ui/app/components/ui/color-indicator/color-indicator.stories.js b/ui/app/components/ui/color-indicator/color-indicator.stories.js index 1c661869bd..81ab5f2606 100644 --- a/ui/app/components/ui/color-indicator/color-indicator.stories.js +++ b/ui/app/components/ui/color-indicator/color-indicator.stories.js @@ -1,11 +1,11 @@ -import React from 'react' -import { select } from '@storybook/addon-knobs' -import { COLORS, SIZES } from '../../../helpers/constants/design-system' -import ColorIndicator from './color-indicator' +import React from 'react'; +import { select } from '@storybook/addon-knobs'; +import { COLORS, SIZES } from '../../../helpers/constants/design-system'; +import ColorIndicator from './color-indicator'; export default { title: 'ColorIndicator', -} +}; export const colorIndicator = () => ( ( color={select('color', COLORS, COLORS.PRIMARY1)} borderColor={select('borderColor', { NONE: undefined, ...COLORS })} /> -) +); export const withIcon = () => ( ( iconClassName="fa fa-question" borderColor={select('borderColor', { NONE: undefined, ...COLORS })} /> -) +); diff --git a/ui/app/components/ui/color-indicator/index.js b/ui/app/components/ui/color-indicator/index.js index 257ecdc0b6..b73dde1257 100644 --- a/ui/app/components/ui/color-indicator/index.js +++ b/ui/app/components/ui/color-indicator/index.js @@ -1 +1 @@ -export { default } from './color-indicator' +export { default } from './color-indicator'; diff --git a/ui/app/components/ui/currency-display/currency-display.component.js b/ui/app/components/ui/currency-display/currency-display.component.js index 575fb73680..6310960af7 100644 --- a/ui/app/components/ui/currency-display/currency-display.component.js +++ b/ui/app/components/ui/currency-display/currency-display.component.js @@ -1,8 +1,8 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { GWEI } from '../../../helpers/constants/common' -import { useCurrencyDisplay } from '../../../hooks/useCurrencyDisplay' +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import { GWEI } from '../../../helpers/constants/common'; +import { useCurrencyDisplay } from '../../../hooks/useCurrencyDisplay'; export default function CurrencyDisplay({ value, @@ -27,7 +27,7 @@ export default function CurrencyDisplay({ denomination, currency, suffix, - }) + }); return (
    )}
    - ) + ); } CurrencyDisplay.propTypes = { @@ -63,4 +63,4 @@ CurrencyDisplay.propTypes = { style: PropTypes.object, suffix: PropTypes.string, value: PropTypes.string, -} +}; diff --git a/ui/app/components/ui/currency-display/index.js b/ui/app/components/ui/currency-display/index.js index f861bb91a3..f5b01c575a 100644 --- a/ui/app/components/ui/currency-display/index.js +++ b/ui/app/components/ui/currency-display/index.js @@ -1 +1 @@ -export { default } from './currency-display.component' +export { default } from './currency-display.component'; diff --git a/ui/app/components/ui/currency-display/tests/currency-display.component.test.js b/ui/app/components/ui/currency-display/tests/currency-display.component.test.js index 8fd0bb4bac..295d4c4632 100644 --- a/ui/app/components/ui/currency-display/tests/currency-display.component.test.js +++ b/ui/app/components/ui/currency-display/tests/currency-display.component.test.js @@ -1,19 +1,19 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import sinon from 'sinon' -import * as reactRedux from 'react-redux' -import CurrencyDisplay from '../currency-display.component' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import * as reactRedux from 'react-redux'; +import CurrencyDisplay from '../currency-display.component'; describe('CurrencyDisplay Component', function () { beforeEach(function () { - const stub = sinon.stub(reactRedux, 'useSelector') + const stub = sinon.stub(reactRedux, 'useSelector'); stub.callsFake(() => ({ currentCurrency: 'usd', nativeCurrency: 'ETH', conversionRate: 280.45, - })) - }) + })); + }); it('should render text with a className', function () { const wrapper = shallow( , - ) + ); - assert.ok(wrapper.hasClass('currency-display')) - assert.strictEqual(wrapper.text(), '$123.45') - }) + assert.ok(wrapper.hasClass('currency-display')); + assert.strictEqual(wrapper.text(), '$123.45'); + }); it('should render text with a prefix', function () { const wrapper = shallow( @@ -35,12 +35,12 @@ describe('CurrencyDisplay Component', function () { prefix="-" hideLabel />, - ) + ); - assert.ok(wrapper.hasClass('currency-display')) - assert.strictEqual(wrapper.text(), '-$123.45') - }) + assert.ok(wrapper.hasClass('currency-display')); + assert.strictEqual(wrapper.text(), '-$123.45'); + }); afterEach(function () { - sinon.restore() - }) -}) + sinon.restore(); + }); +}); diff --git a/ui/app/components/ui/currency-input/currency-input.component.js b/ui/app/components/ui/currency-input/currency-input.component.js index 0186051de7..e953d30901 100644 --- a/ui/app/components/ui/currency-input/currency-input.component.js +++ b/ui/app/components/ui/currency-input/currency-input.component.js @@ -1,12 +1,12 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import UnitInput from '../unit-input' -import CurrencyDisplay from '../currency-display' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import UnitInput from '../unit-input'; +import CurrencyDisplay from '../currency-display'; import { getValueFromWeiHex, getWeiHexFromDecimalValue, -} from '../../../helpers/utils/conversions.util' -import { ETH } from '../../../helpers/constants/common' +} from '../../../helpers/utils/conversions.util'; +import { ETH } from '../../../helpers/constants/common'; /** * Component that allows user to enter currency values as a number, and props receive a converted @@ -16,7 +16,7 @@ import { ETH } from '../../../helpers/constants/common' export default class CurrencyInput extends PureComponent { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { conversionRate: PropTypes.number, @@ -28,37 +28,37 @@ export default class CurrencyInput extends PureComponent { value: PropTypes.string, fiatSuffix: PropTypes.string, nativeSuffix: PropTypes.string, - } + }; constructor(props) { - super(props) + super(props); - const { value: hexValue } = props - const decimalValue = hexValue ? this.getDecimalValue(props) : 0 + const { value: hexValue } = props; + const decimalValue = hexValue ? this.getDecimalValue(props) : 0; this.state = { decimalValue, hexValue, isSwapped: false, - } + }; } componentDidUpdate(prevProps) { - const { value: prevPropsHexValue } = prevProps - const { value: propsHexValue } = this.props - const { hexValue: stateHexValue } = this.state + const { value: prevPropsHexValue } = prevProps; + const { value: propsHexValue } = this.props; + const { hexValue: stateHexValue } = this.state; if ( prevPropsHexValue !== propsHexValue && propsHexValue !== stateHexValue ) { - const decimalValue = this.getDecimalValue(this.props) - this.setState({ hexValue: propsHexValue, decimalValue }) + const decimalValue = this.getDecimalValue(this.props); + this.setState({ hexValue: propsHexValue, decimalValue }); } } getDecimalValue(props) { - const { value: hexValue, currentCurrency, conversionRate } = props + const { value: hexValue, currentCurrency, conversionRate } = props; const decimalValueString = this.shouldUseFiat() ? getValueFromWeiHex({ value: hexValue, @@ -70,35 +70,35 @@ export default class CurrencyInput extends PureComponent { value: hexValue, toCurrency: ETH, numberOfDecimals: 6, - }) + }); - return Number(decimalValueString) || 0 + return Number(decimalValueString) || 0; } shouldUseFiat = () => { - const { useFiat, hideFiat } = this.props - const { isSwapped } = this.state || {} + const { useFiat, hideFiat } = this.props; + const { isSwapped } = this.state || {}; if (hideFiat) { - return false + return false; } - return isSwapped ? !useFiat : useFiat - } + return isSwapped ? !useFiat : useFiat; + }; swap = () => { - const { isSwapped, decimalValue } = this.state + const { isSwapped, decimalValue } = this.state; this.setState({ isSwapped: !isSwapped }, () => { - this.handleChange(decimalValue) - }) - } + this.handleChange(decimalValue); + }); + }; handleChange = (decimalValue) => { const { currentCurrency: fromCurrency, conversionRate, onChange, - } = this.props + } = this.props; const hexValue = this.shouldUseFiat() ? getWeiHexFromDecimalValue({ @@ -112,33 +112,33 @@ export default class CurrencyInput extends PureComponent { fromCurrency: ETH, fromDenomination: ETH, conversionRate, - }) + }); - this.setState({ hexValue, decimalValue }) - onChange(hexValue) - } + this.setState({ hexValue, decimalValue }); + onChange(hexValue); + }; renderConversionComponent() { - const { currentCurrency, nativeCurrency, hideFiat } = this.props - const { hexValue } = this.state - let currency, numberOfDecimals + const { currentCurrency, nativeCurrency, hideFiat } = this.props; + const { hexValue } = this.state; + let currency, numberOfDecimals; if (hideFiat) { return (
    {this.context.t('noConversionRateAvailable')}
    - ) + ); } if (this.shouldUseFiat()) { // Display ETH - currency = nativeCurrency || ETH - numberOfDecimals = 6 + currency = nativeCurrency || ETH; + numberOfDecimals = 6; } else { // Display Fiat - currency = currentCurrency - numberOfDecimals = 2 + currency = currentCurrency; + numberOfDecimals = 2; } return ( @@ -148,12 +148,12 @@ export default class CurrencyInput extends PureComponent { value={hexValue} numberOfDecimals={numberOfDecimals} /> - ) + ); } render() { - const { fiatSuffix, nativeSuffix, ...restProps } = this.props - const { decimalValue } = this.state + const { fiatSuffix, nativeSuffix, ...restProps } = this.props; + const { decimalValue } = this.state; return ( {this.renderConversionComponent()} - ) + ); } } diff --git a/ui/app/components/ui/currency-input/currency-input.container.js b/ui/app/components/ui/currency-input/currency-input.container.js index e402a3defd..23d792838d 100644 --- a/ui/app/components/ui/currency-input/currency-input.container.js +++ b/ui/app/components/ui/currency-input/currency-input.container.js @@ -1,25 +1,25 @@ -import { connect } from 'react-redux' -import { ETH } from '../../../helpers/constants/common' -import { getIsMainnet, getPreferences } from '../../../selectors' -import CurrencyInput from './currency-input.component' +import { connect } from 'react-redux'; +import { ETH } from '../../../helpers/constants/common'; +import { getIsMainnet, getPreferences } from '../../../selectors'; +import CurrencyInput from './currency-input.component'; const mapStateToProps = (state) => { const { metamask: { nativeCurrency, currentCurrency, conversionRate }, - } = state - const { showFiatInTestnets } = getPreferences(state) - const isMainnet = getIsMainnet(state) + } = state; + const { showFiatInTestnets } = getPreferences(state); + const isMainnet = getIsMainnet(state); return { nativeCurrency, currentCurrency, conversionRate, hideFiat: !isMainnet && !showFiatInTestnets, - } -} + }; +}; const mergeProps = (stateProps, dispatchProps, ownProps) => { - const { nativeCurrency, currentCurrency } = stateProps + const { nativeCurrency, currentCurrency } = stateProps; return { ...stateProps, @@ -27,7 +27,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { ...ownProps, nativeSuffix: nativeCurrency || ETH, fiatSuffix: currentCurrency.toUpperCase(), - } -} + }; +}; -export default connect(mapStateToProps, null, mergeProps)(CurrencyInput) +export default connect(mapStateToProps, null, mergeProps)(CurrencyInput); diff --git a/ui/app/components/ui/currency-input/index.js b/ui/app/components/ui/currency-input/index.js index d8069fb671..4f3b7bedfe 100644 --- a/ui/app/components/ui/currency-input/index.js +++ b/ui/app/components/ui/currency-input/index.js @@ -1 +1 @@ -export { default } from './currency-input.container' +export { default } from './currency-input.container'; diff --git a/ui/app/components/ui/currency-input/tests/currency-input.component.test.js b/ui/app/components/ui/currency-input/tests/currency-input.component.test.js index e6e05a33bb..f47154b5c4 100644 --- a/ui/app/components/ui/currency-input/tests/currency-input.component.test.js +++ b/ui/app/components/ui/currency-input/tests/currency-input.component.test.js @@ -1,22 +1,22 @@ -import assert from 'assert' -import React from 'react' -import PropTypes from 'prop-types' -import { shallow, mount } from 'enzyme' -import sinon from 'sinon' -import { Provider } from 'react-redux' -import configureMockStore from 'redux-mock-store' -import CurrencyInput from '../currency-input.component' -import UnitInput from '../../unit-input' -import CurrencyDisplay from '../../currency-display' +import assert from 'assert'; +import React from 'react'; +import PropTypes from 'prop-types'; +import { shallow, mount } from 'enzyme'; +import sinon from 'sinon'; +import { Provider } from 'react-redux'; +import configureMockStore from 'redux-mock-store'; +import CurrencyInput from '../currency-input.component'; +import UnitInput from '../../unit-input'; +import CurrencyDisplay from '../../currency-display'; describe('CurrencyInput Component', function () { describe('rendering', function () { it('should render properly without a suffix', function () { - const wrapper = shallow() + const wrapper = shallow(); - assert.ok(wrapper) - assert.strictEqual(wrapper.find(UnitInput).length, 1) - }) + assert.ok(wrapper); + assert.strictEqual(wrapper.find(UnitInput).length, 1); + }); it('should render properly with a suffix', function () { const mockStore = { @@ -25,8 +25,8 @@ describe('CurrencyInput Component', function () { currentCurrency: 'usd', conversionRate: 231.06, }, - } - const store = configureMockStore()(mockStore) + }; + const store = configureMockStore()(mockStore); const wrapper = mount( @@ -36,13 +36,13 @@ describe('CurrencyInput Component', function () { nativeCurrency="ETH" /> , - ) + ); - assert.ok(wrapper) - assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) - assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ETH') - assert.strictEqual(wrapper.find(CurrencyDisplay).length, 1) - }) + assert.ok(wrapper); + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1); + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ETH'); + assert.strictEqual(wrapper.find(CurrencyDisplay).length, 1); + }); it('should render properly with an ETH value', function () { const mockStore = { @@ -51,8 +51,8 @@ describe('CurrencyInput Component', function () { currentCurrency: 'usd', conversionRate: 231.06, }, - } - const store = configureMockStore()(mockStore) + }; + const store = configureMockStore()(mockStore); const wrapper = mount( @@ -65,23 +65,26 @@ describe('CurrencyInput Component', function () { conversionRate={231.06} /> , - ) - - assert.ok(wrapper) - const currencyInputInstance = wrapper.find(CurrencyInput).at(0).instance() - assert.strictEqual(currencyInputInstance.state.decimalValue, 1) + ); + + assert.ok(wrapper); + const currencyInputInstance = wrapper + .find(CurrencyInput) + .at(0) + .instance(); + assert.strictEqual(currencyInputInstance.state.decimalValue, 1); assert.strictEqual( currencyInputInstance.state.hexValue, 'de0b6b3a7640000', - ) - assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) - assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ETH') - assert.strictEqual(wrapper.find('.unit-input__input').props().value, 1) + ); + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1); + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ETH'); + assert.strictEqual(wrapper.find('.unit-input__input').props().value, 1); assert.strictEqual( wrapper.find('.currency-display-component').text(), '$231.06USD', - ) - }) + ); + }); it('should render properly with a fiat value', function () { const mockStore = { @@ -90,8 +93,8 @@ describe('CurrencyInput Component', function () { currentCurrency: 'usd', conversionRate: 231.06, }, - } - const store = configureMockStore()(mockStore) + }; + const store = configureMockStore()(mockStore); const wrapper = mount( @@ -105,20 +108,23 @@ describe('CurrencyInput Component', function () { conversionRate={231.06} /> , - ) - - assert.ok(wrapper) - const currencyInputInstance = wrapper.find(CurrencyInput).at(0).instance() - assert.strictEqual(currencyInputInstance.state.decimalValue, 1) - assert.strictEqual(currencyInputInstance.state.hexValue, 'f602f2234d0ea') - assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) - assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'USD') - assert.strictEqual(wrapper.find('.unit-input__input').props().value, 1) + ); + + assert.ok(wrapper); + const currencyInputInstance = wrapper + .find(CurrencyInput) + .at(0) + .instance(); + assert.strictEqual(currencyInputInstance.state.decimalValue, 1); + assert.strictEqual(currencyInputInstance.state.hexValue, 'f602f2234d0ea'); + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1); + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'USD'); + assert.strictEqual(wrapper.find('.unit-input__input').props().value, 1); assert.strictEqual( wrapper.find('.currency-display-component').text(), '0.004328ETH', - ) - }) + ); + }); it('should render properly with a native value when hideFiat is true', function () { const mockStore = { @@ -127,8 +133,8 @@ describe('CurrencyInput Component', function () { currentCurrency: 'usd', conversionRate: 231.06, }, - } - const store = configureMockStore()(mockStore) + }; + const store = configureMockStore()(mockStore); const wrapper = mount( @@ -147,33 +153,36 @@ describe('CurrencyInput Component', function () { context: { t: (str) => `${str}_t` }, childContextTypes: { t: PropTypes.func }, }, - ) - - assert.ok(wrapper) - const currencyInputInstance = wrapper.find(CurrencyInput).at(0).instance() - assert.strictEqual(currencyInputInstance.state.decimalValue, 0.004328) - assert.strictEqual(currencyInputInstance.state.hexValue, 'f602f2234d0ea') - assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) - assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ETH') + ); + + assert.ok(wrapper); + const currencyInputInstance = wrapper + .find(CurrencyInput) + .at(0) + .instance(); + assert.strictEqual(currencyInputInstance.state.decimalValue, 0.004328); + assert.strictEqual(currencyInputInstance.state.hexValue, 'f602f2234d0ea'); + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1); + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ETH'); assert.strictEqual( wrapper.find('.unit-input__input').props().value, 0.004328, - ) + ); assert.strictEqual( wrapper.find('.currency-input__conversion-component').text(), 'noConversionRateAvailable_t', - ) - }) - }) + ); + }); + }); describe('handling actions', function () { - const handleChangeSpy = sinon.spy() - const handleBlurSpy = sinon.spy() + const handleChangeSpy = sinon.spy(); + const handleBlurSpy = sinon.spy(); afterEach(function () { - handleChangeSpy.resetHistory() - handleBlurSpy.resetHistory() - }) + handleChangeSpy.resetHistory(); + handleBlurSpy.resetHistory(); + }); it('should call onChange on input changes with the hex value for ETH', function () { const mockStore = { @@ -182,8 +191,8 @@ describe('CurrencyInput Component', function () { currentCurrency: 'usd', conversionRate: 231.06, }, - } - const store = configureMockStore()(mockStore) + }; + const store = configureMockStore()(mockStore); const wrapper = mount( , - ) - - assert.ok(wrapper) - assert.strictEqual(handleChangeSpy.callCount, 0) - assert.strictEqual(handleBlurSpy.callCount, 0) - - const currencyInputInstance = wrapper.find(CurrencyInput).at(0).instance() - assert.strictEqual(currencyInputInstance.state.decimalValue, 0) - assert.strictEqual(currencyInputInstance.state.hexValue, undefined) + ); + + assert.ok(wrapper); + assert.strictEqual(handleChangeSpy.callCount, 0); + assert.strictEqual(handleBlurSpy.callCount, 0); + + const currencyInputInstance = wrapper + .find(CurrencyInput) + .at(0) + .instance(); + assert.strictEqual(currencyInputInstance.state.decimalValue, 0); + assert.strictEqual(currencyInputInstance.state.hexValue, undefined); assert.strictEqual( wrapper.find('.currency-display-component').text(), '$0.00USD', - ) - const input = wrapper.find('input') - assert.strictEqual(input.props().value, 0) + ); + const input = wrapper.find('input'); + assert.strictEqual(input.props().value, 0); - input.simulate('change', { target: { value: 1 } }) - assert.strictEqual(handleChangeSpy.callCount, 1) - assert.ok(handleChangeSpy.calledWith('de0b6b3a7640000')) + input.simulate('change', { target: { value: 1 } }); + assert.strictEqual(handleChangeSpy.callCount, 1); + assert.ok(handleChangeSpy.calledWith('de0b6b3a7640000')); assert.strictEqual( wrapper.find('.currency-display-component').text(), '$231.06USD', - ) - assert.strictEqual(currencyInputInstance.state.decimalValue, 1) + ); + assert.strictEqual(currencyInputInstance.state.decimalValue, 1); assert.strictEqual( currencyInputInstance.state.hexValue, 'de0b6b3a7640000', - ) - }) + ); + }); it('should call onChange on input changes with the hex value for fiat', function () { const mockStore = { @@ -231,8 +243,8 @@ describe('CurrencyInput Component', function () { currentCurrency: 'usd', conversionRate: 231.06, }, - } - const store = configureMockStore()(mockStore) + }; + const store = configureMockStore()(mockStore); const wrapper = mount( , - ) - - assert.ok(wrapper) - assert.strictEqual(handleChangeSpy.callCount, 0) - assert.strictEqual(handleBlurSpy.callCount, 0) - - const currencyInputInstance = wrapper.find(CurrencyInput).at(0).instance() - assert.strictEqual(currencyInputInstance.state.decimalValue, 0) - assert.strictEqual(currencyInputInstance.state.hexValue, undefined) + ); + + assert.ok(wrapper); + assert.strictEqual(handleChangeSpy.callCount, 0); + assert.strictEqual(handleBlurSpy.callCount, 0); + + const currencyInputInstance = wrapper + .find(CurrencyInput) + .at(0) + .instance(); + assert.strictEqual(currencyInputInstance.state.decimalValue, 0); + assert.strictEqual(currencyInputInstance.state.hexValue, undefined); assert.strictEqual( wrapper.find('.currency-display-component').text(), '0ETH', - ) - const input = wrapper.find('input') - assert.strictEqual(input.props().value, 0) + ); + const input = wrapper.find('input'); + assert.strictEqual(input.props().value, 0); - input.simulate('change', { target: { value: 1 } }) - assert.strictEqual(handleChangeSpy.callCount, 1) - assert.ok(handleChangeSpy.calledWith('f602f2234d0ea')) + input.simulate('change', { target: { value: 1 } }); + assert.strictEqual(handleChangeSpy.callCount, 1); + assert.ok(handleChangeSpy.calledWith('f602f2234d0ea')); assert.strictEqual( wrapper.find('.currency-display-component').text(), '0.004328ETH', - ) - assert.strictEqual(currencyInputInstance.state.decimalValue, 1) - assert.strictEqual(currencyInputInstance.state.hexValue, 'f602f2234d0ea') - }) + ); + assert.strictEqual(currencyInputInstance.state.decimalValue, 1); + assert.strictEqual(currencyInputInstance.state.hexValue, 'f602f2234d0ea'); + }); it('should change the state and pass in a new decimalValue when props.value changes', function () { const mockStore = { @@ -278,8 +293,8 @@ describe('CurrencyInput Component', function () { currentCurrency: 'usd', conversionRate: 231.06, }, - } - const store = configureMockStore()(mockStore) + }; + const store = configureMockStore()(mockStore); const wrapper = shallow( , - ) + ); - assert.ok(wrapper) - const currencyInputInstance = wrapper.find(CurrencyInput).dive() - assert.strictEqual(currencyInputInstance.state('decimalValue'), 0) - assert.strictEqual(currencyInputInstance.state('hexValue'), undefined) - assert.strictEqual(currencyInputInstance.find(UnitInput).props().value, 0) + assert.ok(wrapper); + const currencyInputInstance = wrapper.find(CurrencyInput).dive(); + assert.strictEqual(currencyInputInstance.state('decimalValue'), 0); + assert.strictEqual(currencyInputInstance.state('hexValue'), undefined); + assert.strictEqual( + currencyInputInstance.find(UnitInput).props().value, + 0, + ); - currencyInputInstance.setProps({ value: '1ec05e43e72400' }) - currencyInputInstance.update() - assert.strictEqual(currencyInputInstance.state('decimalValue'), 2) + currencyInputInstance.setProps({ value: '1ec05e43e72400' }); + currencyInputInstance.update(); + assert.strictEqual(currencyInputInstance.state('decimalValue'), 2); assert.strictEqual( currencyInputInstance.state('hexValue'), '1ec05e43e72400', - ) - assert.strictEqual(currencyInputInstance.find(UnitInput).props().value, 2) - }) + ); + assert.strictEqual( + currencyInputInstance.find(UnitInput).props().value, + 2, + ); + }); it('should swap selected currency when swap icon is clicked', function () { const mockStore = { @@ -316,8 +337,8 @@ describe('CurrencyInput Component', function () { currentCurrency: 'usd', conversionRate: 231.06, }, - } - const store = configureMockStore()(mockStore) + }; + const store = configureMockStore()(mockStore); const wrapper = mount( , - ) - - assert.ok(wrapper) - assert.strictEqual(handleChangeSpy.callCount, 0) - assert.strictEqual(handleBlurSpy.callCount, 0) - - const currencyInputInstance = wrapper.find(CurrencyInput).at(0).instance() - assert.strictEqual(currencyInputInstance.state.decimalValue, 0) - assert.strictEqual(currencyInputInstance.state.hexValue, undefined) + ); + + assert.ok(wrapper); + assert.strictEqual(handleChangeSpy.callCount, 0); + assert.strictEqual(handleBlurSpy.callCount, 0); + + const currencyInputInstance = wrapper + .find(CurrencyInput) + .at(0) + .instance(); + assert.strictEqual(currencyInputInstance.state.decimalValue, 0); + assert.strictEqual(currencyInputInstance.state.hexValue, undefined); assert.strictEqual( wrapper.find('.currency-display-component').text(), '$0.00USD', - ) - const input = wrapper.find('input') - assert.strictEqual(input.props().value, 0) + ); + const input = wrapper.find('input'); + assert.strictEqual(input.props().value, 0); - input.simulate('change', { target: { value: 1 } }) - assert.strictEqual(handleChangeSpy.callCount, 1) - assert.ok(handleChangeSpy.calledWith('de0b6b3a7640000')) + input.simulate('change', { target: { value: 1 } }); + assert.strictEqual(handleChangeSpy.callCount, 1); + assert.ok(handleChangeSpy.calledWith('de0b6b3a7640000')); assert.strictEqual( wrapper.find('.currency-display-component').text(), '$231.06USD', - ) - assert.strictEqual(currencyInputInstance.state.decimalValue, 1) + ); + assert.strictEqual(currencyInputInstance.state.decimalValue, 1); assert.strictEqual( currencyInputInstance.state.hexValue, 'de0b6b3a7640000', - ) + ); - const swap = wrapper.find('.currency-input__swap-component') - swap.simulate('click') + const swap = wrapper.find('.currency-input__swap-component'); + swap.simulate('click'); assert.strictEqual( wrapper.find('.currency-display-component').text(), '0.004328ETH', - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/ui/app/components/ui/currency-input/tests/currency-input.container.test.js b/ui/app/components/ui/currency-input/tests/currency-input.container.test.js index 630e4cdc62..ccb5bb6d05 100644 --- a/ui/app/components/ui/currency-input/tests/currency-input.container.test.js +++ b/ui/app/components/ui/currency-input/tests/currency-input.container.test.js @@ -1,17 +1,17 @@ -import assert from 'assert' -import proxyquire from 'proxyquire' +import assert from 'assert'; +import proxyquire from 'proxyquire'; -let mapStateToProps, mergeProps +let mapStateToProps, mergeProps; proxyquire('../currency-input.container.js', { 'react-redux': { connect: (ms, _, mp) => { - mapStateToProps = ms - mergeProps = mp - return () => ({}) + mapStateToProps = ms; + mergeProps = mp; + return () => ({}); }, }, -}) +}); describe('CurrencyInput container', function () { describe('mapStateToProps()', function () { @@ -111,14 +111,14 @@ describe('CurrencyInput container', function () { hideFiat: false, }, }, - ] + ]; tests.forEach(({ mockState, expected, comment }) => { it(comment, function () { - return assert.deepStrictEqual(mapStateToProps(mockState), expected) - }) - }) - }) + return assert.deepStrictEqual(mapStateToProps(mockState), expected); + }); + }); + }); describe('mergeProps()', function () { const tests = [ @@ -164,7 +164,7 @@ describe('CurrencyInput container', function () { fiatSuffix: 'USD', }, }, - ] + ]; tests.forEach( ({ @@ -176,9 +176,9 @@ describe('CurrencyInput container', function () { assert.deepStrictEqual( mergeProps(stateProps, dispatchProps, ownProps), expected, - ) - }) + ); + }); }, - ) - }) -}) + ); + }); +}); diff --git a/ui/app/components/ui/definition-list/definition-list.js b/ui/app/components/ui/definition-list/definition-list.js index 8c46611eb9..50a11b7a17 100644 --- a/ui/app/components/ui/definition-list/definition-list.js +++ b/ui/app/components/ui/definition-list/definition-list.js @@ -1,14 +1,14 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { omit } from 'lodash' -import Typography from '../typography' +import React from 'react'; +import PropTypes from 'prop-types'; +import { omit } from 'lodash'; +import Typography from '../typography'; import { COLORS, SIZES, TYPOGRAPHY, FONT_WEIGHT, -} from '../../../helpers/constants/design-system' -import Tooltip from '../tooltip' +} from '../../../helpers/constants/design-system'; +import Tooltip from '../tooltip'; const MARGIN_MAP = { [SIZES.XS]: 0, @@ -16,7 +16,7 @@ const MARGIN_MAP = { [SIZES.MD]: 4, [SIZES.LG]: 6, [SIZES.XL]: 8, -} +}; export default function DefinitionList({ dictionary, @@ -67,7 +67,7 @@ export default function DefinitionList({ ))} - ) + ); } DefinitionList.propTypes = { @@ -82,4 +82,4 @@ DefinitionList.propTypes = { definitionTypography: PropTypes.shape({ ...omit(Typography.propTypes, ['tag', 'className', 'boxProps']), }), -} +}; diff --git a/ui/app/components/ui/definition-list/definition-list.stories.js b/ui/app/components/ui/definition-list/definition-list.stories.js index b833e71d36..5a5c3042cf 100644 --- a/ui/app/components/ui/definition-list/definition-list.stories.js +++ b/ui/app/components/ui/definition-list/definition-list.stories.js @@ -1,15 +1,15 @@ -import React from 'react' -import { object, select } from '@storybook/addon-knobs' +import React from 'react'; +import { object, select } from '@storybook/addon-knobs'; import { COLORS, SIZES, TYPOGRAPHY, -} from '../../../helpers/constants/design-system' -import DefinitionList from './definition-list' +} from '../../../helpers/constants/design-system'; +import DefinitionList from './definition-list'; export default { title: 'Definition List', -} +}; const basic = { term: @@ -19,26 +19,26 @@ const basic = { dl: 'HTML tag denoting a definition list', dt: 'HTML tag denoting a definition list term', dd: 'HTML tag denoting a definition list definition', -} +}; const advanced = { 'Network Name': 'Ethereum Mainnet', 'Chain ID': '1', Ticker: 'ETH', -} +}; const tooltips = { 'Network Name': 'The name that is associated with this network', 'Chain ID': 'The numeric value representing the ID of this network', Ticker: 'The currency symbol of the primary currency for this network', -} +}; export const definitionList = () => ( -) +); export const withTooltips = () => ( ( tooltips={object('tooltips', tooltips)} gapSize={select('gapSize', SIZES, SIZES.SM)} /> -) +); export const withTypographyControl = () => ( ( color: select('definitionTypography.color', COLORS, COLORS.BLACK), }} /> -) +); diff --git a/ui/app/components/ui/definition-list/index.js b/ui/app/components/ui/definition-list/index.js index a321da7a88..9316f4022c 100644 --- a/ui/app/components/ui/definition-list/index.js +++ b/ui/app/components/ui/definition-list/index.js @@ -1 +1 @@ -export { default } from './definition-list' +export { default } from './definition-list'; diff --git a/ui/app/components/ui/dialog/index.js b/ui/app/components/ui/dialog/index.js index 672d833377..457aa6a4d7 100644 --- a/ui/app/components/ui/dialog/index.js +++ b/ui/app/components/ui/dialog/index.js @@ -1,9 +1,9 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; export default function Dialog(props) { - const { children, type, className, onClick } = props + const { children, type, className, onClick } = props; return (
    {children}
    - ) + ); } Dialog.propTypes = { @@ -23,4 +23,4 @@ Dialog.propTypes = { children: PropTypes.node, type: PropTypes.oneOf(['message', 'error', 'warning']), onClick: PropTypes.func, -} +}; diff --git a/ui/app/components/ui/dropdown/dropdown.js b/ui/app/components/ui/dropdown/dropdown.js index db75be9229..ed207d7603 100644 --- a/ui/app/components/ui/dropdown/dropdown.js +++ b/ui/app/components/ui/dropdown/dropdown.js @@ -1,6 +1,6 @@ -import React, { useCallback } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React, { useCallback } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; const Dropdown = ({ className, @@ -13,12 +13,12 @@ const Dropdown = ({ }) => { const _onChange = useCallback( (event) => { - event.preventDefault() - event.stopPropagation() - onChange(event.target.value) + event.preventDefault(); + event.stopPropagation(); + onChange(event.target.value); }, [onChange], - ) + ); return ( - ) -} + ); +}; Dropdown.propTypes = { className: PropTypes.string, @@ -53,7 +53,7 @@ Dropdown.propTypes = { ).isRequired, selectedOption: PropTypes.string, style: PropTypes.object, -} +}; Dropdown.defaultProps = { className: undefined, @@ -61,6 +61,6 @@ Dropdown.defaultProps = { title: undefined, selectedOption: null, style: undefined, -} +}; -export default Dropdown +export default Dropdown; diff --git a/ui/app/components/ui/dropdown/dropdown.stories.js b/ui/app/components/ui/dropdown/dropdown.stories.js index b46358def1..d12354e204 100644 --- a/ui/app/components/ui/dropdown/dropdown.stories.js +++ b/ui/app/components/ui/dropdown/dropdown.stories.js @@ -1,26 +1,26 @@ -import React from 'react' -import { action } from '@storybook/addon-actions' -import { boolean, select, text } from '@storybook/addon-knobs' -import Dropdown from '.' +import React from 'react'; +import { action } from '@storybook/addon-actions'; +import { boolean, select, text } from '@storybook/addon-knobs'; +import Dropdown from '.'; export default { title: 'Dropdown', -} +}; const unnamedOptions = [...Array(10).keys()].map((index) => { - return { value: `option${index}` } -}) + return { value: `option${index}` }; +}); const namedOptions = unnamedOptions.map((option, index) => { - return { ...option, name: `Option ${index}` } -}) + return { ...option, name: `Option ${index}` }; +}); const namedOptionsWithVeryLongNames = unnamedOptions.map((option, index) => { return { ...option, name: `Option ${index} with a very${', very'.repeat(index)} long name`, - } -}) + }; +}); export const simple = () => ( ( namedOptions[0].value, )} /> -) +); export const optionsWithoutNames = () => ( ( unnamedOptions[0].value, )} /> -) +); export const optionsWithLongNames = () => ( ( namedOptionsWithVeryLongNames[0].value, )} /> -) +); export const optionsWithLongNamesAndShortWidth = () => ( ( )} style={{ width: '200px' }} /> -) +); diff --git a/ui/app/components/ui/dropdown/index.js b/ui/app/components/ui/dropdown/index.js index 8d23b57090..1ad5658edb 100644 --- a/ui/app/components/ui/dropdown/index.js +++ b/ui/app/components/ui/dropdown/index.js @@ -1 +1 @@ -export { default } from './dropdown' +export { default } from './dropdown'; diff --git a/ui/app/components/ui/editable-label/editable-label.js b/ui/app/components/ui/editable-label/editable-label.js index 12ce68a7b1..acda2400bb 100644 --- a/ui/app/components/ui/editable-label/editable-label.js +++ b/ui/app/components/ui/editable-label/editable-label.js @@ -1,33 +1,33 @@ -import classnames from 'classnames' -import PropTypes from 'prop-types' -import React, { Component } from 'react' +import classnames from 'classnames'; +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; class EditableLabel extends Component { static propTypes = { onSubmit: PropTypes.func.isRequired, defaultValue: PropTypes.string, className: PropTypes.string, - } + }; state = { isEditing: false, value: this.props.defaultValue || '', - } + }; handleSubmit() { - const { value } = this.state + const { value } = this.state; if (value === '') { - return + return; } Promise.resolve(this.props.onSubmit(value)).then(() => this.setState({ isEditing: false }), - ) + ); } renderEditing() { - const { value } = this.state + const { value } = this.state; return [ { if (event.key === 'Enter') { - this.handleSubmit() + this.handleSubmit(); } }} onChange={(event) => this.setState({ value: event.target.value })} @@ -54,7 +54,7 @@ class EditableLabel extends Component { > , - ] + ]; } renderReadonly() { @@ -69,19 +69,19 @@ class EditableLabel extends Component { > , - ] + ]; } render() { - const { isEditing } = this.state - const { className } = this.props + const { isEditing } = this.state; + const { className } = this.props; return (
    {isEditing ? this.renderEditing() : this.renderReadonly()}
    - ) + ); } } -export default EditableLabel +export default EditableLabel; diff --git a/ui/app/components/ui/editable-label/index.js b/ui/app/components/ui/editable-label/index.js index 43078e7f74..a70b6b8d78 100644 --- a/ui/app/components/ui/editable-label/index.js +++ b/ui/app/components/ui/editable-label/index.js @@ -1 +1 @@ -export { default } from './editable-label' +export { default } from './editable-label'; diff --git a/ui/app/components/ui/error-message/error-message.component.js b/ui/app/components/ui/error-message/error-message.component.js index fdb8b651f3..399c7c24c4 100644 --- a/ui/app/components/ui/error-message/error-message.component.js +++ b/ui/app/components/ui/error-message/error-message.component.js @@ -1,25 +1,25 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; const ErrorMessage = (props, context) => { - const { errorMessage, errorKey } = props - const error = errorKey ? context.t(errorKey) : errorMessage + const { errorMessage, errorKey } = props; + const error = errorKey ? context.t(errorKey) : errorMessage; return (
    {`ALERT: ${error}`}
    - ) -} + ); +}; ErrorMessage.propTypes = { errorMessage: PropTypes.string, errorKey: PropTypes.string, -} +}; ErrorMessage.contextTypes = { t: PropTypes.func, -} +}; -export default ErrorMessage +export default ErrorMessage; diff --git a/ui/app/components/ui/error-message/index.js b/ui/app/components/ui/error-message/index.js index 1c97a99556..d4ea3575ff 100644 --- a/ui/app/components/ui/error-message/index.js +++ b/ui/app/components/ui/error-message/index.js @@ -1 +1 @@ -export { default } from './error-message.component' +export { default } from './error-message.component'; diff --git a/ui/app/components/ui/error-message/tests/error-message.component.test.js b/ui/app/components/ui/error-message/tests/error-message.component.test.js index 884fe6565f..a6c2d4ac35 100644 --- a/ui/app/components/ui/error-message/tests/error-message.component.test.js +++ b/ui/app/components/ui/error-message/tests/error-message.component.test.js @@ -1,36 +1,36 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import ErrorMessage from '../error-message.component' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import ErrorMessage from '../error-message.component'; describe('ErrorMessage Component', function () { - const t = (key) => `translate ${key}` + const t = (key) => `translate ${key}`; it('should render a message from props.errorMessage', function () { const wrapper = shallow(, { context: { t }, - }) + }); - assert.ok(wrapper) - assert.strictEqual(wrapper.find('.error-message').length, 1) - assert.strictEqual(wrapper.find('.error-message__icon').length, 1) + assert.ok(wrapper); + assert.strictEqual(wrapper.find('.error-message').length, 1); + assert.strictEqual(wrapper.find('.error-message__icon').length, 1); assert.strictEqual( wrapper.find('.error-message__text').text(), 'ALERT: This is an error.', - ) - }) + ); + }); it('should render a message translated from props.errorKey', function () { const wrapper = shallow(, { context: { t }, - }) + }); - assert.ok(wrapper) - assert.strictEqual(wrapper.find('.error-message').length, 1) - assert.strictEqual(wrapper.find('.error-message__icon').length, 1) + assert.ok(wrapper); + assert.strictEqual(wrapper.find('.error-message').length, 1); + assert.strictEqual(wrapper.find('.error-message__icon').length, 1); assert.strictEqual( wrapper.find('.error-message__text').text(), 'ALERT: translate testKey', - ) - }) -}) + ); + }); +}); diff --git a/ui/app/components/ui/export-text-container/export-text-container.component.js b/ui/app/components/ui/export-text-container/export-text-container.component.js index 2afa205757..8eb56cf8be 100644 --- a/ui/app/components/ui/export-text-container/export-text-container.component.js +++ b/ui/app/components/ui/export-text-container/export-text-container.component.js @@ -1,13 +1,13 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { exportAsFile } from '../../../helpers/utils/util' -import Copy from '../icon/copy-icon.component' -import { useI18nContext } from '../../../hooks/useI18nContext' -import { useCopyToClipboard } from '../../../hooks/useCopyToClipboard' +import React from 'react'; +import PropTypes from 'prop-types'; +import { exportAsFile } from '../../../helpers/utils/util'; +import Copy from '../icon/copy-icon.component'; +import { useI18nContext } from '../../../hooks/useI18nContext'; +import { useCopyToClipboard } from '../../../hooks/useCopyToClipboard'; function ExportTextContainer({ text = '' }) { - const t = useI18nContext() - const [copied, handleCopy] = useCopyToClipboard() + const t = useI18nContext(); + const [copied, handleCopy] = useCopyToClipboard(); return (
    @@ -18,7 +18,7 @@ function ExportTextContainer({ text = '' }) {
    { - handleCopy(text) + handleCopy(text); }} > @@ -37,11 +37,11 @@ function ExportTextContainer({ text = '' }) {
    - ) + ); } ExportTextContainer.propTypes = { text: PropTypes.string, -} +}; -export default React.memo(ExportTextContainer) +export default React.memo(ExportTextContainer); diff --git a/ui/app/components/ui/export-text-container/index.js b/ui/app/components/ui/export-text-container/index.js index 3c610389f0..042e4ada7c 100644 --- a/ui/app/components/ui/export-text-container/index.js +++ b/ui/app/components/ui/export-text-container/index.js @@ -1,3 +1,3 @@ -import ExportTextContainer from './export-text-container.component' +import ExportTextContainer from './export-text-container.component'; -export default ExportTextContainer +export default ExportTextContainer; diff --git a/ui/app/components/ui/hex-to-decimal/hex-to-decimal.component.js b/ui/app/components/ui/hex-to-decimal/hex-to-decimal.component.js index 69ddea055b..762b7ccf0f 100644 --- a/ui/app/components/ui/hex-to-decimal/hex-to-decimal.component.js +++ b/ui/app/components/ui/hex-to-decimal/hex-to-decimal.component.js @@ -1,17 +1,17 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import { hexToDecimal } from '../../../helpers/utils/conversions.util' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { hexToDecimal } from '../../../helpers/utils/conversions.util'; export default class HexToDecimal extends PureComponent { static propTypes = { className: PropTypes.string, value: PropTypes.string, - } + }; render() { - const { className, value } = this.props - const decimalValue = hexToDecimal(value) + const { className, value } = this.props; + const decimalValue = hexToDecimal(value); - return
    {decimalValue}
    + return
    {decimalValue}
    ; } } diff --git a/ui/app/components/ui/hex-to-decimal/index.js b/ui/app/components/ui/hex-to-decimal/index.js index 6e8567ca9d..94f00781de 100644 --- a/ui/app/components/ui/hex-to-decimal/index.js +++ b/ui/app/components/ui/hex-to-decimal/index.js @@ -1 +1 @@ -export { default } from './hex-to-decimal.component' +export { default } from './hex-to-decimal.component'; diff --git a/ui/app/components/ui/hex-to-decimal/tests/hex-to-decimal.component.test.js b/ui/app/components/ui/hex-to-decimal/tests/hex-to-decimal.component.test.js index cb75bfd632..30bff9fcea 100644 --- a/ui/app/components/ui/hex-to-decimal/tests/hex-to-decimal.component.test.js +++ b/ui/app/components/ui/hex-to-decimal/tests/hex-to-decimal.component.test.js @@ -1,24 +1,24 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import HexToDecimal from '../hex-to-decimal.component' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import HexToDecimal from '../hex-to-decimal.component'; describe('HexToDecimal Component', function () { it('should render a prefixed hex as a decimal with a className', function () { const wrapper = shallow( , - ) + ); - assert.ok(wrapper.hasClass('hex-to-decimal')) - assert.strictEqual(wrapper.text(), '12345') - }) + assert.ok(wrapper.hasClass('hex-to-decimal')); + assert.strictEqual(wrapper.text(), '12345'); + }); it('should render an unprefixed hex as a decimal with a className', function () { const wrapper = shallow( , - ) + ); - assert.ok(wrapper.hasClass('hex-to-decimal')) - assert.strictEqual(wrapper.text(), '6789') - }) -}) + assert.ok(wrapper.hasClass('hex-to-decimal')); + assert.strictEqual(wrapper.text(), '6789'); + }); +}); diff --git a/ui/app/components/ui/icon-border/icon-border.js b/ui/app/components/ui/icon-border/icon-border.js index f320a04b86..5ef8186b61 100644 --- a/ui/app/components/ui/icon-border/icon-border.js +++ b/ui/app/components/ui/icon-border/icon-border.js @@ -1,16 +1,16 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; export default function IconBorder({ children, size }) { - const borderStyle = { height: `${size}px`, width: `${size}px` } + const borderStyle = { height: `${size}px`, width: `${size}px` }; return (
    {children}
    - ) + ); } IconBorder.propTypes = { children: PropTypes.node.isRequired, size: PropTypes.number.isRequired, -} +}; diff --git a/ui/app/components/ui/icon-border/index.js b/ui/app/components/ui/icon-border/index.js index dea3f116e3..adcb92af20 100644 --- a/ui/app/components/ui/icon-border/index.js +++ b/ui/app/components/ui/icon-border/index.js @@ -1 +1 @@ -export { default } from './icon-border' +export { default } from './icon-border'; diff --git a/ui/app/components/ui/icon-button/icon-button.js b/ui/app/components/ui/icon-button/icon-button.js index 7d95fa8d45..dacd1ef256 100644 --- a/ui/app/components/ui/icon-button/icon-button.js +++ b/ui/app/components/ui/icon-button/icon-button.js @@ -1,8 +1,8 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' +import React from 'react'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; -const defaultRender = (inner) => inner +const defaultRender = (inner) => inner; export default function IconButton({ onClick, @@ -13,7 +13,7 @@ export default function IconButton({ className, ...props }) { - const renderWrapper = tooltipRender ?? defaultRender + const renderWrapper = tooltipRender ?? defaultRender; return ( - ) + ); } IconButton.propTypes = { @@ -43,4 +43,4 @@ IconButton.propTypes = { tooltipRender: PropTypes.func, className: PropTypes.string, 'data-testid': PropTypes.string, -} +}; diff --git a/ui/app/components/ui/icon-button/index.js b/ui/app/components/ui/icon-button/index.js index 5e3ded37f6..06569218c7 100644 --- a/ui/app/components/ui/icon-button/index.js +++ b/ui/app/components/ui/icon-button/index.js @@ -1 +1 @@ -export { default } from './icon-button' +export { default } from './icon-button'; diff --git a/ui/app/components/ui/icon-with-fallback/icon-with-fallback.component.js b/ui/app/components/ui/icon-with-fallback/icon-with-fallback.component.js index 27e16d28e6..fec573cd08 100644 --- a/ui/app/components/ui/icon-with-fallback/icon-with-fallback.component.js +++ b/ui/app/components/ui/icon-with-fallback/icon-with-fallback.component.js @@ -1,6 +1,6 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; export default class IconWithFallback extends PureComponent { static propTypes = { @@ -9,20 +9,20 @@ export default class IconWithFallback extends PureComponent { size: PropTypes.number, className: PropTypes.string, fallbackClassName: PropTypes.string, - } + }; static defaultProps = { name: '', icon: null, - } + }; state = { iconError: false, - } + }; render() { - const { icon, name, size, className, fallbackClassName } = this.props - const style = size ? { height: `${size}px`, width: `${size}px` } : {} + const { icon, name, size, className, fallbackClassName } = this.props; + const style = size ? { height: `${size}px`, width: `${size}px` } : {}; return !this.state.iconError && icon ? ( {name.length ? name.charAt(0).toUpperCase() : ''}
    - ) + ); } } diff --git a/ui/app/components/ui/icon-with-fallback/index.js b/ui/app/components/ui/icon-with-fallback/index.js index 8c1f9a154b..ef51111078 100644 --- a/ui/app/components/ui/icon-with-fallback/index.js +++ b/ui/app/components/ui/icon-with-fallback/index.js @@ -1 +1 @@ -export { default } from './icon-with-fallback.component' +export { default } from './icon-with-fallback.component'; diff --git a/ui/app/components/ui/icon-with-label/icon-with-label.js b/ui/app/components/ui/icon-with-label/icon-with-label.js index 1cb69d66fa..3551d10a57 100644 --- a/ui/app/components/ui/icon-with-label/icon-with-label.js +++ b/ui/app/components/ui/icon-with-label/icon-with-label.js @@ -1,6 +1,6 @@ -import React from 'react' -import classnames from 'classnames' -import PropTypes from 'prop-types' +import React from 'react'; +import classnames from 'classnames'; +import PropTypes from 'prop-types'; export default function IconWithLabel({ icon, label, className }) { return ( @@ -8,11 +8,11 @@ export default function IconWithLabel({ icon, label, className }) { {icon} {label && {label}} - ) + ); } IconWithLabel.propTypes = { icon: PropTypes.node.isRequired, className: PropTypes.string, label: PropTypes.string, -} +}; diff --git a/ui/app/components/ui/icon-with-label/index.js b/ui/app/components/ui/icon-with-label/index.js index 10432ac8fe..3cadb2d129 100644 --- a/ui/app/components/ui/icon-with-label/index.js +++ b/ui/app/components/ui/icon-with-label/index.js @@ -1 +1 @@ -export { default } from './icon-with-label' +export { default } from './icon-with-label'; diff --git a/ui/app/components/ui/icon/approve-icon.component.js b/ui/app/components/ui/icon/approve-icon.component.js index 79127a85aa..e60d604da7 100644 --- a/ui/app/components/ui/icon/approve-icon.component.js +++ b/ui/app/components/ui/icon/approve-icon.component.js @@ -1,5 +1,5 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; const Approve = ({ className, size, color }) => ( ( fill={color} /> -) +); Approve.defaultProps = { className: undefined, -} +}; Approve.propTypes = { className: PropTypes.string, size: PropTypes.number.isRequired, color: PropTypes.string.isRequired, -} +}; -export default Approve +export default Approve; diff --git a/ui/app/components/ui/icon/copy-icon.component.js b/ui/app/components/ui/icon/copy-icon.component.js index dc0d4cd1cc..e9b2dc78c5 100644 --- a/ui/app/components/ui/icon/copy-icon.component.js +++ b/ui/app/components/ui/icon/copy-icon.component.js @@ -1,5 +1,5 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; const Copy = ({ className, size, color }) => ( ( fill={color} /> -) +); Copy.defaultProps = { className: undefined, -} +}; Copy.propTypes = { className: PropTypes.string, size: PropTypes.number.isRequired, color: PropTypes.string.isRequired, -} +}; -export default Copy +export default Copy; diff --git a/ui/app/components/ui/icon/icon.stories.js b/ui/app/components/ui/icon/icon.stories.js index ff750bc5d4..6f2e35ddf9 100644 --- a/ui/app/components/ui/icon/icon.stories.js +++ b/ui/app/components/ui/icon/icon.stories.js @@ -1,55 +1,55 @@ -import React from 'react' -import { color, number, select } from '@storybook/addon-knobs' -import { SEVERITIES } from '../../../helpers/constants/design-system' -import Approve from './approve-icon.component' -import Copy from './copy-icon.component' -import Interaction from './interaction-icon.component' -import Preloader from './preloader' -import Receive from './receive-icon.component' -import Send from './send-icon.component' -import InfoIcon from './info-icon.component' -import InfoIconInverted from './info-icon-inverted.component' +import React from 'react'; +import { color, number, select } from '@storybook/addon-knobs'; +import { SEVERITIES } from '../../../helpers/constants/design-system'; +import Approve from './approve-icon.component'; +import Copy from './copy-icon.component'; +import Interaction from './interaction-icon.component'; +import Preloader from './preloader'; +import Receive from './receive-icon.component'; +import Send from './send-icon.component'; +import InfoIcon from './info-icon.component'; +import InfoIconInverted from './info-icon-inverted.component'; export default { title: 'Icon', -} +}; export const copy = () => ( -) +); export const send = () => ( -) +); export const receive = () => ( -) +); export const siteInteraction = () => ( -) +); export const approveSpendLimit = () => ( -) +); -export const preloader = () => +export const preloader = () => ; export const PaperAirplane = () => ( -) +); export const info = () => ( -) +); export const infoInverted = () => ( -) +); diff --git a/ui/app/components/ui/icon/info-icon-inverted.component.js b/ui/app/components/ui/icon/info-icon-inverted.component.js index df057aa07f..3eef46cc00 100644 --- a/ui/app/components/ui/icon/info-icon-inverted.component.js +++ b/ui/app/components/ui/icon/info-icon-inverted.component.js @@ -1,7 +1,7 @@ -import React from 'react' -import classnames from 'classnames' -import PropTypes from 'prop-types' -import { SEVERITIES } from '../../../helpers/constants/design-system' +import React from 'react'; +import classnames from 'classnames'; +import PropTypes from 'prop-types'; +import { SEVERITIES } from '../../../helpers/constants/design-system'; export default function InfoIconInverted({ severity }) { const className = classnames('info-icon', { @@ -9,7 +9,7 @@ export default function InfoIconInverted({ severity }) { 'info-icon--warning': severity === SEVERITIES.WARNING, 'info-icon--danger': severity === SEVERITIES.DANGER, 'info-icon--info': severity === SEVERITIES.INFO, - }) + }); return ( - ) + ); } InfoIconInverted.propTypes = { severity: PropTypes.oneOf(Object.values(SEVERITIES)), -} +}; diff --git a/ui/app/components/ui/icon/info-icon.component.js b/ui/app/components/ui/icon/info-icon.component.js index 3d2ec7e7db..824a81a408 100644 --- a/ui/app/components/ui/icon/info-icon.component.js +++ b/ui/app/components/ui/icon/info-icon.component.js @@ -1,7 +1,7 @@ -import React from 'react' -import classnames from 'classnames' -import PropTypes from 'prop-types' -import { SEVERITIES } from '../../../helpers/constants/design-system' +import React from 'react'; +import classnames from 'classnames'; +import PropTypes from 'prop-types'; +import { SEVERITIES } from '../../../helpers/constants/design-system'; export default function InfoIcon({ severity }) { const className = classnames('info-icon', { @@ -9,7 +9,7 @@ export default function InfoIcon({ severity }) { 'info-icon--warning': severity === SEVERITIES.WARNING, 'info-icon--danger': severity === SEVERITIES.DANGER, 'info-icon--info': severity === SEVERITIES.INFO, - }) + }); return ( - ) + ); } InfoIcon.propTypes = { severity: PropTypes.oneOf(Object.values(SEVERITIES)), -} +}; diff --git a/ui/app/components/ui/icon/interaction-icon.component.js b/ui/app/components/ui/icon/interaction-icon.component.js index 0d96c87530..93ef6e08eb 100644 --- a/ui/app/components/ui/icon/interaction-icon.component.js +++ b/ui/app/components/ui/icon/interaction-icon.component.js @@ -1,5 +1,5 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; const Interaction = ({ className, size, color }) => ( ( fill={color} /> -) +); Interaction.defaultProps = { className: undefined, -} +}; Interaction.propTypes = { className: PropTypes.string, size: PropTypes.number.isRequired, color: PropTypes.string.isRequired, -} +}; -export default Interaction +export default Interaction; diff --git a/ui/app/components/ui/icon/overview-buy-icon.component.js b/ui/app/components/ui/icon/overview-buy-icon.component.js index aca33efb28..c7be24b954 100644 --- a/ui/app/components/ui/icon/overview-buy-icon.component.js +++ b/ui/app/components/ui/icon/overview-buy-icon.component.js @@ -1,5 +1,5 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; export default function BuyIcon({ width = '17', @@ -27,11 +27,11 @@ export default function BuyIcon({ fill="white" /> - ) + ); } BuyIcon.propTypes = { width: PropTypes.string, height: PropTypes.string, fill: PropTypes.string, -} +}; diff --git a/ui/app/components/ui/icon/overview-send-icon.component.js b/ui/app/components/ui/icon/overview-send-icon.component.js index 310e9ebeb3..05879ed2fd 100644 --- a/ui/app/components/ui/icon/overview-send-icon.component.js +++ b/ui/app/components/ui/icon/overview-send-icon.component.js @@ -1,5 +1,5 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; export default function SwapIcon({ width = '15', @@ -19,11 +19,11 @@ export default function SwapIcon({ fill={fill} /> - ) + ); } SwapIcon.propTypes = { width: PropTypes.string, height: PropTypes.string, fill: PropTypes.string, -} +}; diff --git a/ui/app/components/ui/icon/paper-airplane-icon.js b/ui/app/components/ui/icon/paper-airplane-icon.js index 0db6a424eb..5bd1567046 100644 --- a/ui/app/components/ui/icon/paper-airplane-icon.js +++ b/ui/app/components/ui/icon/paper-airplane-icon.js @@ -1,5 +1,5 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; export default function PaperAirplane({ size, className, color }) { return ( @@ -18,15 +18,15 @@ export default function PaperAirplane({ size, className, color }) { fill={color} /> - ) + ); } PaperAirplane.defaultProps = { color: '#FFFFFF', -} +}; PaperAirplane.propTypes = { className: PropTypes.string, size: PropTypes.number.isRequired, color: PropTypes.string, -} +}; diff --git a/ui/app/components/ui/icon/preloader/index.js b/ui/app/components/ui/icon/preloader/index.js index b8c7793d64..c9387865a5 100644 --- a/ui/app/components/ui/icon/preloader/index.js +++ b/ui/app/components/ui/icon/preloader/index.js @@ -1,3 +1,3 @@ -import preloader from './preloader-icon.component' +import preloader from './preloader-icon.component'; -export default preloader +export default preloader; diff --git a/ui/app/components/ui/icon/preloader/preloader-icon.component.js b/ui/app/components/ui/icon/preloader/preloader-icon.component.js index fc7cb5707b..87ca7f299f 100644 --- a/ui/app/components/ui/icon/preloader/preloader-icon.component.js +++ b/ui/app/components/ui/icon/preloader/preloader-icon.component.js @@ -1,6 +1,6 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; const Preloader = ({ className, size }) => ( ( /> -) +); Preloader.defaultProps = { className: undefined, -} +}; Preloader.propTypes = { className: PropTypes.string, size: PropTypes.number.isRequired, -} +}; -export default Preloader +export default Preloader; diff --git a/ui/app/components/ui/icon/receive-icon.component.js b/ui/app/components/ui/icon/receive-icon.component.js index 67317d7edc..530fd5170e 100644 --- a/ui/app/components/ui/icon/receive-icon.component.js +++ b/ui/app/components/ui/icon/receive-icon.component.js @@ -1,5 +1,5 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; const Receive = ({ className, size, color }) => ( ( fill={color} /> -) +); Receive.defaultProps = { className: undefined, -} +}; Receive.propTypes = { className: PropTypes.string, size: PropTypes.number.isRequired, color: PropTypes.string.isRequired, -} +}; -export default Receive +export default Receive; diff --git a/ui/app/components/ui/icon/send-icon.component.js b/ui/app/components/ui/icon/send-icon.component.js index c8ec227aea..d1ee9d24fa 100644 --- a/ui/app/components/ui/icon/send-icon.component.js +++ b/ui/app/components/ui/icon/send-icon.component.js @@ -1,5 +1,5 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; const Send = ({ className, size, color }) => ( ( fill={color} /> -) +); Send.defaultProps = { className: undefined, -} +}; Send.propTypes = { className: PropTypes.string, size: PropTypes.number.isRequired, color: PropTypes.string.isRequired, -} +}; -export default Send +export default Send; diff --git a/ui/app/components/ui/icon/sign-icon.component.js b/ui/app/components/ui/icon/sign-icon.component.js index f3bf6e2d7c..8870858263 100644 --- a/ui/app/components/ui/icon/sign-icon.component.js +++ b/ui/app/components/ui/icon/sign-icon.component.js @@ -1,5 +1,5 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; export default function Sign({ className, size, color }) { return ( @@ -24,11 +24,11 @@ export default function Sign({ className, size, color }) { fill={color} /> - ) + ); } Sign.propTypes = { className: PropTypes.string, size: PropTypes.number.isRequired, color: PropTypes.string.isRequired, -} +}; diff --git a/ui/app/components/ui/icon/sun-check-icon.component.js b/ui/app/components/ui/icon/sun-check-icon.component.js index c6029e37c2..31dd194044 100644 --- a/ui/app/components/ui/icon/sun-check-icon.component.js +++ b/ui/app/components/ui/icon/sun-check-icon.component.js @@ -1,9 +1,9 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; export default function SunCheck({ reverseColors }) { - const sunColor = reverseColors ? '#037DD6' : 'white' - const checkColor = reverseColors ? 'white' : '#037DD6' + const sunColor = reverseColors ? '#037DD6' : 'white'; + const checkColor = reverseColors ? 'white' : '#037DD6'; return ( - ) + ); } SunCheck.propTypes = { reverseColors: PropTypes.bool, -} +}; diff --git a/ui/app/components/ui/icon/swap-icon-for-list.component.js b/ui/app/components/ui/icon/swap-icon-for-list.component.js index 1e2d5453a1..5c20b51f59 100644 --- a/ui/app/components/ui/icon/swap-icon-for-list.component.js +++ b/ui/app/components/ui/icon/swap-icon-for-list.component.js @@ -1,5 +1,5 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; const Swap = ({ className, size, color }) => ( ( fill={color} /> -) +); Swap.defaultProps = { className: undefined, -} +}; Swap.propTypes = { className: PropTypes.string, size: PropTypes.number.isRequired, color: PropTypes.string.isRequired, -} +}; -export default Swap +export default Swap; diff --git a/ui/app/components/ui/icon/swap-icon.component.js b/ui/app/components/ui/icon/swap-icon.component.js index f8c147580f..32dd6f9163 100644 --- a/ui/app/components/ui/icon/swap-icon.component.js +++ b/ui/app/components/ui/icon/swap-icon.component.js @@ -1,5 +1,5 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; export default function SwapIcon({ width = '17', @@ -21,11 +21,11 @@ export default function SwapIcon({ strokeWidth="0.1" /> - ) + ); } SwapIcon.propTypes = { width: PropTypes.string, height: PropTypes.string, color: PropTypes.string, -} +}; diff --git a/ui/app/components/ui/identicon/blockieIdenticon/blockieIdenticon.component.js b/ui/app/components/ui/identicon/blockieIdenticon/blockieIdenticon.component.js index 05d201e224..341abe441b 100644 --- a/ui/app/components/ui/identicon/blockieIdenticon/blockieIdenticon.component.js +++ b/ui/app/components/ui/identicon/blockieIdenticon/blockieIdenticon.component.js @@ -1,33 +1,33 @@ -import React, { useEffect, useRef, useState } from 'react' -import PropTypes from 'prop-types' -import { renderIcon } from '@download/blockies' +import React, { useEffect, useRef, useState } from 'react'; +import PropTypes from 'prop-types'; +import { renderIcon } from '@download/blockies'; const BlockieIdenticon = ({ address, diameter, alt }) => { - const [dataUrl, setDataUrl] = useState(null) - const canvasRef = useRef(null) + const [dataUrl, setDataUrl] = useState(null); + const canvasRef = useRef(null); useEffect(() => { - const canvas = canvasRef.current - renderIcon({ seed: address.toLowerCase() }, canvas) - const updatedDataUrl = canvas.toDataURL() + const canvas = canvasRef.current; + renderIcon({ seed: address.toLowerCase() }, canvas); + const updatedDataUrl = canvas.toDataURL(); if (updatedDataUrl !== dataUrl) { - setDataUrl(updatedDataUrl) + setDataUrl(updatedDataUrl); } - }, [dataUrl, address]) + }, [dataUrl, address]); return ( <> {alt - ) -} + ); +}; BlockieIdenticon.propTypes = { address: PropTypes.string.isRequired, diameter: PropTypes.number.isRequired, alt: PropTypes.string, -} +}; -export default BlockieIdenticon +export default BlockieIdenticon; diff --git a/ui/app/components/ui/identicon/blockieIdenticon/index.js b/ui/app/components/ui/identicon/blockieIdenticon/index.js index a87ff93235..63c88d0648 100644 --- a/ui/app/components/ui/identicon/blockieIdenticon/index.js +++ b/ui/app/components/ui/identicon/blockieIdenticon/index.js @@ -1 +1 @@ -export { default } from './blockieIdenticon.component' +export { default } from './blockieIdenticon.component'; diff --git a/ui/app/components/ui/identicon/identicon.component.js b/ui/app/components/ui/identicon/identicon.component.js index 09a731ecad..91f3a11f55 100644 --- a/ui/app/components/ui/identicon/identicon.component.js +++ b/ui/app/components/ui/identicon/identicon.component.js @@ -1,17 +1,17 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import contractMap from '@metamask/contract-metadata' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import contractMap from '@metamask/contract-metadata'; -import { checksumAddress } from '../../../helpers/utils/util' -import Jazzicon from '../jazzicon' -import BlockieIdenticon from './blockieIdenticon' +import { checksumAddress } from '../../../helpers/utils/util'; +import Jazzicon from '../jazzicon'; +import BlockieIdenticon from './blockieIdenticon'; const getStyles = (diameter) => ({ height: diameter, width: diameter, borderRadius: diameter / 2, -}) +}); export default class Identicon extends PureComponent { static propTypes = { @@ -22,7 +22,7 @@ export default class Identicon extends PureComponent { image: PropTypes.string, useBlockie: PropTypes.bool, alt: PropTypes.string, - } + }; static defaultProps = { addBorder: false, @@ -32,10 +32,10 @@ export default class Identicon extends PureComponent { image: undefined, useBlockie: false, alt: '', - } + }; renderImage() { - const { className, diameter, image, alt } = this.props + const { className, diameter, image, alt } = this.props; return ( {alt} - ) + ); } renderJazzicon() { - const { address, className, diameter, alt } = this.props + const { address, className, diameter, alt } = this.props; return ( - ) + ); } renderBlockie() { - const { address, className, diameter, alt } = this.props + const { address, className, diameter, alt } = this.props; return (
    - ) + ); } render() { @@ -83,17 +83,17 @@ export default class Identicon extends PureComponent { useBlockie, addBorder, alt, - } = this.props + } = this.props; if (image) { - return this.renderImage() + return this.renderImage(); } if (address) { - const checksummedAddress = checksumAddress(address) + const checksummedAddress = checksumAddress(address); if (contractMap[checksummedAddress]?.logo) { - return this.renderJazzicon() + return this.renderJazzicon(); } return ( @@ -102,7 +102,7 @@ export default class Identicon extends PureComponent { > {useBlockie ? this.renderBlockie() : this.renderJazzicon()} - ) + ); } return ( @@ -112,6 +112,6 @@ export default class Identicon extends PureComponent { style={getStyles(diameter)} alt={alt} /> - ) + ); } } diff --git a/ui/app/components/ui/identicon/identicon.container.js b/ui/app/components/ui/identicon/identicon.container.js index 0ee6f7841c..2ed017abb5 100644 --- a/ui/app/components/ui/identicon/identicon.container.js +++ b/ui/app/components/ui/identicon/identicon.container.js @@ -1,14 +1,14 @@ -import { connect } from 'react-redux' -import Identicon from './identicon.component' +import { connect } from 'react-redux'; +import Identicon from './identicon.component'; const mapStateToProps = (state) => { const { metamask: { useBlockie }, - } = state + } = state; return { useBlockie, - } -} + }; +}; -export default connect(mapStateToProps)(Identicon) +export default connect(mapStateToProps)(Identicon); diff --git a/ui/app/components/ui/identicon/identicon.stories.js b/ui/app/components/ui/identicon/identicon.stories.js index 0dbefe0ff1..a71928bfdc 100644 --- a/ui/app/components/ui/identicon/identicon.stories.js +++ b/ui/app/components/ui/identicon/identicon.stories.js @@ -1,15 +1,15 @@ -import React from 'react' -import { text, boolean, number } from '@storybook/addon-knobs' -import Identicon from './identicon.component' +import React from 'react'; +import { text, boolean, number } from '@storybook/addon-knobs'; +import Identicon from './identicon.component'; -export default { title: 'Identicon' } +export default { title: 'Identicon' }; const diameterOptions = { range: true, min: 10, max: 200, step: 1, -} +}; export const standard = () => ( ( )} useBlockie={boolean('Use Blockie', Identicon.defaultProps.useBlockie)} /> -) +); -export const image = () => +export const image = () => ; export const blockie = () => ( -) +); // The border size is hard-coded in CSS, and was designed with this size identicon in mind -const withBorderDiameter = 32 +const withBorderDiameter = 32; export const withBorder = () => ( ( address={text('Address', '0x5CfE73b6021E818B776b421B1c4Db2474086a7e1')} diameter={number('Diameter', withBorderDiameter, diameterOptions)} /> -) +); diff --git a/ui/app/components/ui/identicon/index.js b/ui/app/components/ui/identicon/index.js index 799c886f25..5bc3a42858 100644 --- a/ui/app/components/ui/identicon/index.js +++ b/ui/app/components/ui/identicon/index.js @@ -1 +1 @@ -export { default } from './identicon.container' +export { default } from './identicon.container'; diff --git a/ui/app/components/ui/identicon/tests/identicon.component.test.js b/ui/app/components/ui/identicon/tests/identicon.component.test.js index c938657ab4..3d33397ea9 100644 --- a/ui/app/components/ui/identicon/tests/identicon.component.test.js +++ b/ui/app/components/ui/identicon/tests/identicon.component.test.js @@ -1,50 +1,53 @@ -import assert from 'assert' -import React from 'react' -import thunk from 'redux-thunk' -import configureMockStore from 'redux-mock-store' -import { mount } from 'enzyme' -import Identicon from '../identicon.component' +import assert from 'assert'; +import React from 'react'; +import thunk from 'redux-thunk'; +import configureMockStore from 'redux-mock-store'; +import { mount } from 'enzyme'; +import Identicon from '../identicon.component'; describe('Identicon', function () { const state = { metamask: { useBlockie: false, }, - } + }; - const middlewares = [thunk] - const mockStore = configureMockStore(middlewares) - const store = mockStore(state) + const middlewares = [thunk]; + const mockStore = configureMockStore(middlewares); + const store = mockStore(state); it('renders default eth_logo identicon with no props', function () { - const wrapper = mount() + const wrapper = mount(); assert.strictEqual( wrapper.find('img.identicon__eth-logo').prop('src'), './images/eth_logo.svg', - ) - }) + ); + }); it('renders custom image and add className props', function () { const wrapper = mount( , - ) + ); assert.strictEqual( wrapper.find('img.test-image').prop('className'), 'identicon test-image', - ) - assert.strictEqual(wrapper.find('img.test-image').prop('src'), 'test-image') - }) + ); + assert.strictEqual( + wrapper.find('img.test-image').prop('src'), + 'test-image', + ); + }); it('renders div with address prop', function () { const wrapper = mount( , - ) + ); assert.strictEqual( wrapper.find('div.test-address').prop('className'), 'identicon test-address', - ) - }) -}) + ); + }); +}); diff --git a/ui/app/components/ui/info-tooltip/index.js b/ui/app/components/ui/info-tooltip/index.js index 2fe0f2786e..87014d15c2 100644 --- a/ui/app/components/ui/info-tooltip/index.js +++ b/ui/app/components/ui/info-tooltip/index.js @@ -1 +1 @@ -export { default } from './info-tooltip' +export { default } from './info-tooltip'; diff --git a/ui/app/components/ui/info-tooltip/info-tooltip.js b/ui/app/components/ui/info-tooltip/info-tooltip.js index af2537f0ce..4c67eefd02 100644 --- a/ui/app/components/ui/info-tooltip/info-tooltip.js +++ b/ui/app/components/ui/info-tooltip/info-tooltip.js @@ -1,14 +1,14 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import Tooltip from '../tooltip' +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import Tooltip from '../tooltip'; const positionArrowClassMap = { top: 'info-tooltip__top-tooltip-arrow', bottom: 'info-tooltip__bottom-tooltip-arrow', left: 'info-tooltip__left-tooltip-arrow', right: 'info-tooltip__right-tooltip-arrow', -} +}; export default function InfoTooltip({ contentText = '', @@ -35,7 +35,7 @@ export default function InfoTooltip({ - ) + ); } InfoTooltip.propTypes = { @@ -44,4 +44,4 @@ InfoTooltip.propTypes = { wide: PropTypes.bool, containerClassName: PropTypes.string, wrapperClassName: PropTypes.string, -} +}; diff --git a/ui/app/components/ui/info-tooltip/info-tooltip.stories.js b/ui/app/components/ui/info-tooltip/info-tooltip.stories.js index dfe44e2cf5..77756f9b32 100644 --- a/ui/app/components/ui/info-tooltip/info-tooltip.stories.js +++ b/ui/app/components/ui/info-tooltip/info-tooltip.stories.js @@ -1,10 +1,10 @@ -import React from 'react' -import { text } from '@storybook/addon-knobs' -import InfoTooltip from './info-tooltip' +import React from 'react'; +import { text } from '@storybook/addon-knobs'; +import InfoTooltip from './info-tooltip'; export default { title: 'InfoTooltip', -} +}; export const Top = () => ( ( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut gravida dictum diam et sagittis. Sed lorem arcu, consectetur consectetur et, lacinia hendrerit sapien.', )} /> -) +); export const Bottom = () => ( ( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut gravida dictum diam et sagittis. Sed lorem arcu, consectetur consectetur et, lacinia hendrerit sapien.', )} /> -) +); export const Left = () => ( ( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut gravida dictum diam et sagittis. Sed lorem arcu, consectetur consectetur et, lacinia hendrerit sapien.', )} /> -) +); export const Right = () => ( ( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut gravida dictum diam et sagittis. Sed lorem arcu, consectetur consectetur et, lacinia hendrerit sapien.', )} /> -) +); diff --git a/ui/app/components/ui/jazzicon/index.js b/ui/app/components/ui/jazzicon/index.js index bea900ab9a..0ded7d4372 100644 --- a/ui/app/components/ui/jazzicon/index.js +++ b/ui/app/components/ui/jazzicon/index.js @@ -1 +1 @@ -export { default } from './jazzicon.component' +export { default } from './jazzicon.component'; diff --git a/ui/app/components/ui/jazzicon/jazzicon.component.js b/ui/app/components/ui/jazzicon/jazzicon.component.js index 098b085077..5d19530099 100644 --- a/ui/app/components/ui/jazzicon/jazzicon.component.js +++ b/ui/app/components/ui/jazzicon/jazzicon.component.js @@ -1,9 +1,9 @@ -import React, { createRef, PureComponent } from 'react' -import PropTypes from 'prop-types' -import jazzicon from '@metamask/jazzicon' -import iconFactoryGenerator from '../../../../lib/icon-factory' +import React, { createRef, PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import jazzicon from '@metamask/jazzicon'; +import iconFactoryGenerator from '../../../../lib/icon-factory'; -const iconFactory = iconFactoryGenerator(jazzicon) +const iconFactory = iconFactoryGenerator(jazzicon); /** * Wrapper around the jazzicon library to return a React component, as the library returns an @@ -15,45 +15,45 @@ export default class Jazzicon extends PureComponent { className: PropTypes.string, diameter: PropTypes.number, style: PropTypes.object, - } + }; static defaultProps = { diameter: 46, - } + }; - container = createRef() + container = createRef(); componentDidMount() { - this.appendJazzicon() + this.appendJazzicon(); } componentDidUpdate(prevProps) { - const { address: prevAddress, diameter: prevDiameter } = prevProps - const { address, diameter } = this.props + const { address: prevAddress, diameter: prevDiameter } = prevProps; + const { address, diameter } = this.props; if (address !== prevAddress || diameter !== prevDiameter) { - this.removeExistingChildren() - this.appendJazzicon() + this.removeExistingChildren(); + this.appendJazzicon(); } } removeExistingChildren() { - const { children } = this.container.current + const { children } = this.container.current; for (let i = 0; i < children.length; i++) { - this.container.current.removeChild(children[i]) + this.container.current.removeChild(children[i]); } } appendJazzicon() { - const { address, diameter } = this.props - const image = iconFactory.iconForAddress(address, diameter) - this.container.current.appendChild(image) + const { address, diameter } = this.props; + const image = iconFactory.iconForAddress(address, diameter); + this.container.current.appendChild(image); } render() { - const { className, style } = this.props + const { className, style } = this.props; - return
    + return
    ; } } diff --git a/ui/app/components/ui/list-item/index.js b/ui/app/components/ui/list-item/index.js index 867edb4dfd..c76dfda2f5 100644 --- a/ui/app/components/ui/list-item/index.js +++ b/ui/app/components/ui/list-item/index.js @@ -1 +1 @@ -export { default } from './list-item.component' +export { default } from './list-item.component'; diff --git a/ui/app/components/ui/list-item/list-item.component.js b/ui/app/components/ui/list-item/list-item.component.js index 8ac979dd59..79649d672d 100644 --- a/ui/app/components/ui/list-item/list-item.component.js +++ b/ui/app/components/ui/list-item/list-item.component.js @@ -1,6 +1,6 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; export default function ListItem({ title, @@ -14,7 +14,7 @@ export default function ListItem({ className, 'data-testid': dataTestId, }) { - const primaryClassName = classnames('list-item', className) + const primaryClassName = classnames('list-item', className); return (
    {rightContent}
    )}
    - ) + ); } ListItem.propTypes = { @@ -56,4 +56,4 @@ ListItem.propTypes = { className: PropTypes.string, onClick: PropTypes.func, 'data-testid': PropTypes.string, -} +}; diff --git a/ui/app/components/ui/list-item/list-item.stories.js b/ui/app/components/ui/list-item/list-item.stories.js index ce9f3d4af0..93054a2670 100644 --- a/ui/app/components/ui/list-item/list-item.stories.js +++ b/ui/app/components/ui/list-item/list-item.stories.js @@ -1,17 +1,17 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { text } from '@storybook/addon-knobs' -import Send from '../icon/send-icon.component' -import Interaction from '../icon/interaction-icon.component' -import Approve from '../icon/approve-icon.component' -import Receive from '../icon/receive-icon.component' -import Preloader from '../icon/preloader' -import Button from '../button' -import ListItem from './list-item.component' +import React from 'react'; +import PropTypes from 'prop-types'; +import { text } from '@storybook/addon-knobs'; +import Send from '../icon/send-icon.component'; +import Interaction from '../icon/interaction-icon.component'; +import Approve from '../icon/approve-icon.component'; +import Receive from '../icon/receive-icon.component'; +import Preloader from '../icon/preloader'; +import Button from '../button'; +import ListItem from './list-item.component'; export default { title: 'ListItem', -} +}; function Currencies({ primary, secondary }) { return ( @@ -19,16 +19,16 @@ function Currencies({ primary, secondary }) {
    {primary}
    {secondary}
    - ) + ); } Currencies.propTypes = { primary: PropTypes.string, secondary: PropTypes.string, -} +}; -const okColor = '#2F80ED' -const failColor = '#D73A49' +const okColor = '#2F80ED'; +const failColor = '#D73A49'; export const send = () => ( ( -) +); export const pending = () => ( ( /> } /> -) +); export const approve = () => ( ( /> } /> -) +); export const receive = () => ( ( /> } /> -) +); diff --git a/ui/app/components/ui/list-item/tests/list-item.test.js b/ui/app/components/ui/list-item/tests/list-item.test.js index 6f9e132cd2..488ee9039c 100644 --- a/ui/app/components/ui/list-item/tests/list-item.test.js +++ b/ui/app/components/ui/list-item/tests/list-item.test.js @@ -1,23 +1,23 @@ -import assert from 'assert' -import { shallow } from 'enzyme' -import React from 'react' -import Sinon from 'sinon' -import ListItem from '../list-item.component' -import Preloader from '../../icon/preloader/preloader-icon.component' -import Send from '../../icon/send-icon.component' +import assert from 'assert'; +import { shallow } from 'enzyme'; +import React from 'react'; +import Sinon from 'sinon'; +import ListItem from '../list-item.component'; +import Preloader from '../../icon/preloader/preloader-icon.component'; +import Send from '../../icon/send-icon.component'; -const TITLE = 'Hello World' -const SUBTITLE =

    I am a list item

    -const CLASSNAME = 'list-item-test' -const RIGHT_CONTENT =

    Content rendered to the right

    -const CHILDREN = -const MID_CONTENT =

    Content rendered in the middle

    +const TITLE = 'Hello World'; +const SUBTITLE =

    I am a list item

    ; +const CLASSNAME = 'list-item-test'; +const RIGHT_CONTENT =

    Content rendered to the right

    ; +const CHILDREN = ; +const MID_CONTENT =

    Content rendered in the middle

    ; describe('ListItem', function () { - let wrapper - let clickHandler + let wrapper; + let clickHandler; before(function () { - clickHandler = Sinon.fake() + clickHandler = Sinon.fake(); wrapper = shallow( {CHILDREN} , - ) - }) + ); + }); it('includes the data-testid', function () { - assert.strictEqual(wrapper.props()['data-testid'], 'test-id') - }) + assert.strictEqual(wrapper.props()['data-testid'], 'test-id'); + }); it(`renders "${TITLE}" title`, function () { - assert.strictEqual(wrapper.find('.list-item__heading h2').text(), TITLE) - }) + assert.strictEqual(wrapper.find('.list-item__heading h2').text(), TITLE); + }); it(`renders "I am a list item" subtitle`, function () { assert.strictEqual( wrapper.find('.list-item__subheading').text(), 'I am a list item', - ) - }) + ); + }); it('attaches external className', function () { - assert(wrapper.props().className.includes(CLASSNAME)) - }) + assert(wrapper.props().className.includes(CLASSNAME)); + }); it('renders content on the right side of the list item', function () { assert.strictEqual( wrapper.find('.list-item__right-content p').text(), 'Content rendered to the right', - ) - }) + ); + }); it('renders content in the middle of the list item', function () { assert.strictEqual( wrapper.find('.list-item__mid-content p').text(), 'Content rendered in the middle', - ) - }) + ); + }); it('renders list item actions', function () { assert.strictEqual( wrapper.find('.list-item__actions button').text(), 'I am a button', - ) - }) + ); + }); it('renders the title icon', function () { - assert(wrapper.find(Preloader)) - }) + assert(wrapper.find(Preloader)); + }); it('renders the list item icon', function () { - assert(wrapper.find(Send)) - }) + assert(wrapper.find(Send)); + }); it('handles click action and fires onClick', function () { - wrapper.simulate('click') - assert.strictEqual(clickHandler.callCount, 1) - }) + wrapper.simulate('click'); + assert.strictEqual(clickHandler.callCount, 1); + }); after(function () { - Sinon.restore() - }) -}) + Sinon.restore(); + }); +}); diff --git a/ui/app/components/ui/loading-indicator/index.js b/ui/app/components/ui/loading-indicator/index.js index 69b932c0f9..a11357e30c 100644 --- a/ui/app/components/ui/loading-indicator/index.js +++ b/ui/app/components/ui/loading-indicator/index.js @@ -1 +1 @@ -export { default } from './loading-indicator' +export { default } from './loading-indicator'; diff --git a/ui/app/components/ui/loading-indicator/loading-indicator.js b/ui/app/components/ui/loading-indicator/loading-indicator.js index f5e81d76ee..6654399875 100644 --- a/ui/app/components/ui/loading-indicator/loading-indicator.js +++ b/ui/app/components/ui/loading-indicator/loading-indicator.js @@ -1,5 +1,5 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; export default function LoadingIndicator({ alt, @@ -18,7 +18,7 @@ export default function LoadingIndicator({ ) : ( children - ) + ); } LoadingIndicator.propTypes = { @@ -26,4 +26,4 @@ LoadingIndicator.propTypes = { alt: PropTypes.string.isRequired, title: PropTypes.string.isRequired, children: PropTypes.node, -} +}; diff --git a/ui/app/components/ui/loading-screen/index.js b/ui/app/components/ui/loading-screen/index.js index e6ea29114d..c5ea452895 100644 --- a/ui/app/components/ui/loading-screen/index.js +++ b/ui/app/components/ui/loading-screen/index.js @@ -1,3 +1,3 @@ -import LoadingScreen from './loading-screen.component' +import LoadingScreen from './loading-screen.component'; -export default LoadingScreen +export default LoadingScreen; diff --git a/ui/app/components/ui/loading-screen/loading-screen.component.js b/ui/app/components/ui/loading-screen/loading-screen.component.js index 279d54c124..2940f8c623 100644 --- a/ui/app/components/ui/loading-screen/loading-screen.component.js +++ b/ui/app/components/ui/loading-screen/loading-screen.component.js @@ -1,31 +1,31 @@ -import React, { Component, isValidElement } from 'react' -import PropTypes from 'prop-types' -import Spinner from '../spinner' +import React, { Component, isValidElement } from 'react'; +import PropTypes from 'prop-types'; +import Spinner from '../spinner'; class LoadingScreen extends Component { static defaultProps = { loadingMessage: null, showLoadingSpinner: true, - } + }; static propTypes = { loadingMessage: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), showLoadingSpinner: PropTypes.bool, header: PropTypes.element, - } + }; renderMessage() { - const { loadingMessage } = this.props + const { loadingMessage } = this.props; if (!loadingMessage) { - return null + return null; } return isValidElement(loadingMessage) ? ( loadingMessage ) : ( {loadingMessage} - ) + ); } render() { @@ -39,8 +39,8 @@ class LoadingScreen extends Component { {this.renderMessage()} - ) + ); } } -export default LoadingScreen +export default LoadingScreen; diff --git a/ui/app/components/ui/lock-icon/index.js b/ui/app/components/ui/lock-icon/index.js index 6b4df0e58f..8ab512f5ba 100644 --- a/ui/app/components/ui/lock-icon/index.js +++ b/ui/app/components/ui/lock-icon/index.js @@ -1 +1 @@ -export { default } from './lock-icon.component' +export { default } from './lock-icon.component'; diff --git a/ui/app/components/ui/lock-icon/lock-icon.component.js b/ui/app/components/ui/lock-icon/lock-icon.component.js index bc8828e203..472d8d7bae 100644 --- a/ui/app/components/ui/lock-icon/lock-icon.component.js +++ b/ui/app/components/ui/lock-icon/lock-icon.component.js @@ -1,4 +1,4 @@ -import React from 'react' +import React from 'react'; export default function LockIcon(props) { return ( @@ -28,5 +28,5 @@ export default function LockIcon(props) { /> - ) + ); } diff --git a/ui/app/components/ui/mascot/index.js b/ui/app/components/ui/mascot/index.js index ad6ece3313..9a263ffa1b 100644 --- a/ui/app/components/ui/mascot/index.js +++ b/ui/app/components/ui/mascot/index.js @@ -1 +1 @@ -export { default } from './mascot.component' +export { default } from './mascot.component'; diff --git a/ui/app/components/ui/mascot/mascot.component.js b/ui/app/components/ui/mascot/mascot.component.js index dcffdc247c..2002f15e6c 100644 --- a/ui/app/components/ui/mascot/mascot.component.js +++ b/ui/app/components/ui/mascot/mascot.component.js @@ -1,19 +1,19 @@ -import PropTypes from 'prop-types' -import React, { createRef, Component } from 'react' -import MetaMaskLogo from '@metamask/logo' -import { debounce } from 'lodash' +import PropTypes from 'prop-types'; +import React, { createRef, Component } from 'react'; +import MetaMaskLogo from '@metamask/logo'; +import { debounce } from 'lodash'; const directionTargetGenerator = ({ top, left, height, width }) => { - const horizontalMiddle = left + width / 2 - const verticalMiddle = top + height / 2 + const horizontalMiddle = left + width / 2; + const verticalMiddle = top + height / 2; return { up: { x: horizontalMiddle, y: top - height }, down: { x: horizontalMiddle, y: top + height * 2 }, left: { x: left - width, y: verticalMiddle }, right: { x: left + width * 2, y: verticalMiddle }, middle: { x: horizontalMiddle, y: verticalMiddle }, - } -} + }; +}; export default class Mascot extends Component { static propTypes = { @@ -23,7 +23,7 @@ export default class Mascot extends Component { followMouse: PropTypes.bool, lookAtTarget: PropTypes.object, lookAtDirection: PropTypes.oneOf(['up', 'down', 'left', 'right', 'middle']), - } + }; static defaultProps = { width: '200', @@ -31,60 +31,60 @@ export default class Mascot extends Component { followMouse: true, lookAtTarget: {}, lookAtDirection: null, - } + }; constructor(props) { - super(props) + super(props); - const { width, height, followMouse } = props + const { width, height, followMouse } = props; this.logo = MetaMaskLogo({ followMouse, pxNotRatio: true, width, height, - }) + }); - this.mascotContainer = createRef() + this.mascotContainer = createRef(); this.refollowMouse = debounce( this.logo.setFollowMouse.bind(this.logo, true), 1000, - ) - this.unfollowMouse = this.logo.setFollowMouse.bind(this.logo, false) + ); + this.unfollowMouse = this.logo.setFollowMouse.bind(this.logo, false); } handleAnimationEvents() { // only setup listeners once if (this.animations) { - return + return; } - this.animations = this.props.animationEventEmitter - this.animations.on('point', this.lookAt.bind(this)) + this.animations = this.props.animationEventEmitter; + this.animations.on('point', this.lookAt.bind(this)); this.animations.on( 'setFollowMouse', this.logo.setFollowMouse.bind(this.logo), - ) + ); } lookAt(target) { - this.unfollowMouse() - this.logo.lookAt(target) - this.refollowMouse() + this.unfollowMouse(); + this.logo.lookAt(target); + this.refollowMouse(); } componentDidMount() { - this.mascotContainer.current.appendChild(this.logo.container) + this.mascotContainer.current.appendChild(this.logo.container); this.directionTargetMap = directionTargetGenerator( this.mascotContainer.current.getBoundingClientRect(), - ) + ); - const { lookAtTarget, lookAtDirection } = this.props + const { lookAtTarget, lookAtDirection } = this.props; if (lookAtTarget?.x && lookAtTarget?.y) { - this.logo.lookAtAndRender(lookAtTarget) + this.logo.lookAtAndRender(lookAtTarget); } else if (lookAtDirection) { - this.logo.lookAtAndRender(this.directionTargetMap[lookAtDirection]) + this.logo.lookAtAndRender(this.directionTargetMap[lookAtDirection]); } } @@ -93,35 +93,35 @@ export default class Mascot extends Component { lookAtTarget: prevTarget = {}, lookAtDirection: prevDirection = null, followMouse: prevFollowMouse, - } = prevProps - const { lookAtTarget = {}, followMouse, lookAtDirection } = this.props + } = prevProps; + const { lookAtTarget = {}, followMouse, lookAtDirection } = this.props; if (lookAtDirection && prevDirection !== lookAtDirection) { - this.logo.lookAtAndRender(this.directionTargetMap[lookAtDirection]) + this.logo.lookAtAndRender(this.directionTargetMap[lookAtDirection]); } else if ( lookAtTarget?.x !== prevTarget?.x || lookAtTarget?.y !== prevTarget?.y ) { - this.logo.lookAtAndRender(lookAtTarget) + this.logo.lookAtAndRender(lookAtTarget); } if (prevFollowMouse !== followMouse) { - this.unfollowMouse() - followMouse && this.refollowMouse() + this.unfollowMouse(); + followMouse && this.refollowMouse(); } } componentWillUnmount() { - this.animations = this.props.animationEventEmitter - this.animations.removeAllListeners() - this.logo.container.remove() - this.logo.stopAnimation() + this.animations = this.props.animationEventEmitter; + this.animations.removeAllListeners(); + this.logo.container.remove(); + this.logo.stopAnimation(); } render() { // this is a bit hacky // the event emitter is on `this.props` // and we dont get that until render - this.handleAnimationEvents() - return
    + this.handleAnimationEvents(); + return
    ; } } diff --git a/ui/app/components/ui/mascot/mascot.stories.js b/ui/app/components/ui/mascot/mascot.stories.js index ad698370b3..aae108b05b 100644 --- a/ui/app/components/ui/mascot/mascot.stories.js +++ b/ui/app/components/ui/mascot/mascot.stories.js @@ -1,10 +1,10 @@ -import EventEmitter from 'events' -import React, { useState } from 'react' -import Button from '../button' -import ButtonGroup from '../button-group' -import Mascot from './mascot.component' +import EventEmitter from 'events'; +import React, { useState } from 'react'; +import Button from '../button'; +import ButtonGroup from '../button-group'; +import Mascot from './mascot.component'; -const animationEventEmitter = new EventEmitter() +const animationEventEmitter = new EventEmitter(); const containerStyle = { height: '600px', @@ -14,27 +14,27 @@ const containerStyle = { flexFlow: 'column', justifyContent: 'center', alignItems: 'center', -} +}; const buttonStyle = { marginTop: '16px', -} +}; export default { title: 'Mascot', -} +}; export function Demo() { - const [lookAtDirection, setLookAtDirection] = useState(null) - const [followMouseMode, setFollowMouseMode] = useState(false) - const [clickToLookMode, setClickToLookMode] = useState(false) - const [clickedTarget, setClickedTarget] = useState(null) + const [lookAtDirection, setLookAtDirection] = useState(null); + const [followMouseMode, setFollowMouseMode] = useState(false); + const [clickToLookMode, setClickToLookMode] = useState(false); + const [clickedTarget, setClickedTarget] = useState(null); const createDirectionOnClick = (direction) => () => { - setFollowMouseMode(false) - setClickToLookMode(false) - setLookAtDirection(direction) - } + setFollowMouseMode(false); + setClickToLookMode(false); + setLookAtDirection(direction); + }; return (
    { const isButtonClick = event.target.classList.contains( 'button-group__button', - ) + ); if (clickToLookMode && !isButtonClick) { - setLookAtDirection(null) - setClickedTarget({ x: event.clientX, y: event.clientY }) + setLookAtDirection(null); + setClickedTarget({ x: event.clientX, y: event.clientY }); } }} > @@ -69,16 +69,16 @@ export function Demo() {
    - ) + ); } diff --git a/ui/app/components/ui/menu/index.js b/ui/app/components/ui/menu/index.js index 2d624ff68c..4032224fb6 100644 --- a/ui/app/components/ui/menu/index.js +++ b/ui/app/components/ui/menu/index.js @@ -1,2 +1,2 @@ -export { default as Menu } from './menu' -export { default as MenuItem } from './menu-item' +export { default as Menu } from './menu'; +export { default as MenuItem } from './menu-item'; diff --git a/ui/app/components/ui/menu/menu-item.js b/ui/app/components/ui/menu/menu-item.js index db84f7a1c8..f62c76ba92 100644 --- a/ui/app/components/ui/menu/menu-item.js +++ b/ui/app/components/ui/menu/menu-item.js @@ -1,6 +1,6 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; const MenuItem = ({ children, @@ -21,7 +21,7 @@ const MenuItem = ({ {children} {subtitle} -) +); MenuItem.propTypes = { children: PropTypes.node.isRequired, @@ -30,7 +30,7 @@ MenuItem.propTypes = { iconClassName: PropTypes.string, onClick: PropTypes.func, subtitle: PropTypes.node, -} +}; MenuItem.defaultProps = { className: undefined, @@ -38,6 +38,6 @@ MenuItem.defaultProps = { iconClassName: undefined, onClick: undefined, subtitle: undefined, -} +}; -export default MenuItem +export default MenuItem; diff --git a/ui/app/components/ui/menu/menu.js b/ui/app/components/ui/menu/menu.js index c093cf80c8..b76771ac9a 100644 --- a/ui/app/components/ui/menu/menu.js +++ b/ui/app/components/ui/menu/menu.js @@ -1,8 +1,8 @@ -import PropTypes from 'prop-types' -import React, { useRef, useState } from 'react' -import { createPortal } from 'react-dom' -import { usePopper } from 'react-popper' -import classnames from 'classnames' +import PropTypes from 'prop-types'; +import React, { useRef, useState } from 'react'; +import { createPortal } from 'react-dom'; +import { usePopper } from 'react-popper'; +import classnames from 'classnames'; const Menu = ({ anchorElement, @@ -11,16 +11,16 @@ const Menu = ({ onHide, popperOptions, }) => { - const [popperElement, setPopperElement] = useState(null) + const [popperElement, setPopperElement] = useState(null); const popoverContainerElement = useRef( document.getElementById('popover-content'), - ) + ); const { attributes, styles } = usePopper( anchorElement, popperElement, popperOptions, - ) + ); return createPortal( <> @@ -35,8 +35,8 @@ const Menu = ({
    , popoverContainerElement.current, - ) -} + ); +}; Menu.propTypes = { anchorElement: PropTypes.instanceOf(window.Element), @@ -44,12 +44,12 @@ Menu.propTypes = { className: PropTypes.string, onHide: PropTypes.func.isRequired, popperOptions: PropTypes.object, -} +}; Menu.defaultProps = { anchorElement: undefined, className: undefined, popperOptions: undefined, -} +}; -export default Menu +export default Menu; diff --git a/ui/app/components/ui/menu/menu.stories.js b/ui/app/components/ui/menu/menu.stories.js index 59b73b701f..e067e29d44 100644 --- a/ui/app/components/ui/menu/menu.stories.js +++ b/ui/app/components/ui/menu/menu.stories.js @@ -1,10 +1,10 @@ -import React, { useState } from 'react' -import { action } from '@storybook/addon-actions' -import { Menu, MenuItem } from '.' +import React, { useState } from 'react'; +import { action } from '@storybook/addon-actions'; +import { Menu, MenuItem } from '.'; export default { title: 'Menu', -} +}; export const Basic = () => { return ( @@ -17,11 +17,11 @@ export const Basic = () => { Menu Item 3 - ) -} + ); +}; export const Anchored = () => { - const [anchorElement, setAnchorElement] = useState(null) + const [anchorElement, setAnchorElement] = useState(null); return ( <> @@ -38,5 +38,5 @@ export const Anchored = () => { - ) -} + ); +}; diff --git a/ui/app/components/ui/metafox-logo/index.js b/ui/app/components/ui/metafox-logo/index.js index 0aeaed7436..7c00c523f8 100644 --- a/ui/app/components/ui/metafox-logo/index.js +++ b/ui/app/components/ui/metafox-logo/index.js @@ -1 +1 @@ -export { default } from './metafox-logo.component' +export { default } from './metafox-logo.component'; diff --git a/ui/app/components/ui/metafox-logo/metafox-logo.component.js b/ui/app/components/ui/metafox-logo/metafox-logo.component.js index faae1eb8e1..363bf422c8 100644 --- a/ui/app/components/ui/metafox-logo/metafox-logo.component.js +++ b/ui/app/components/ui/metafox-logo/metafox-logo.component.js @@ -1,20 +1,20 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; export default class MetaFoxLogo extends PureComponent { static propTypes = { onClick: PropTypes.func, unsetIconHeight: PropTypes.bool, - } + }; static defaultProps = { onClick: undefined, - } + }; render() { - const { onClick, unsetIconHeight } = this.props - const iconProps = unsetIconHeight ? {} : { height: 42, width: 42 } + const { onClick, unsetIconHeight } = this.props; + const iconProps = unsetIconHeight ? {} : { height: 42, width: 42 }; return (
    - ) + ); } } diff --git a/ui/app/components/ui/metafox-logo/tests/metafox-logo.component.test.js b/ui/app/components/ui/metafox-logo/tests/metafox-logo.component.test.js index 5ea89c620a..3c0f725a4b 100644 --- a/ui/app/components/ui/metafox-logo/tests/metafox-logo.component.test.js +++ b/ui/app/components/ui/metafox-logo/tests/metafox-logo.component.test.js @@ -1,32 +1,32 @@ -import assert from 'assert' -import React from 'react' -import { mount } from 'enzyme' -import MetaFoxLogo from '..' +import assert from 'assert'; +import React from 'react'; +import { mount } from 'enzyme'; +import MetaFoxLogo from '..'; describe('MetaFoxLogo', function () { it('sets icon height and width to 42 by default', function () { - const wrapper = mount() + const wrapper = mount(); assert.strictEqual( wrapper.find('img.app-header__metafox-logo--icon').prop('width'), 42, - ) + ); assert.strictEqual( wrapper.find('img.app-header__metafox-logo--icon').prop('height'), 42, - ) - }) + ); + }); it('does not set icon height and width when unsetIconHeight is true', function () { - const wrapper = mount() + const wrapper = mount(); assert.strictEqual( wrapper.find('img.app-header__metafox-logo--icon').prop('width'), undefined, - ) + ); assert.strictEqual( wrapper.find('img.app-header__metafox-logo--icon').prop('height'), undefined, - ) - }) -}) + ); + }); +}); diff --git a/ui/app/components/ui/page-container/index.js b/ui/app/components/ui/page-container/index.js index 1c423e8701..18a34048de 100644 --- a/ui/app/components/ui/page-container/index.js +++ b/ui/app/components/ui/page-container/index.js @@ -1,5 +1,5 @@ -import PageContainerHeader from './page-container-header' -import PageContainerFooter from './page-container-footer' +import PageContainerHeader from './page-container-header'; +import PageContainerFooter from './page-container-footer'; -export { default } from './page-container.component' -export { PageContainerHeader, PageContainerFooter } +export { default } from './page-container.component'; +export { PageContainerHeader, PageContainerFooter }; diff --git a/ui/app/components/ui/page-container/page-container-content.component.js b/ui/app/components/ui/page-container/page-container-content.component.js index c833c76bfa..bb1279e588 100644 --- a/ui/app/components/ui/page-container/page-container-content.component.js +++ b/ui/app/components/ui/page-container/page-container-content.component.js @@ -1,12 +1,12 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; export default class PageContainerContent extends Component { static propTypes = { children: PropTypes.node.isRequired, - } + }; render() { - return
    {this.props.children}
    + return
    {this.props.children}
    ; } } diff --git a/ui/app/components/ui/page-container/page-container-footer/index.js b/ui/app/components/ui/page-container/page-container-footer/index.js index 7825c45209..b082804993 100644 --- a/ui/app/components/ui/page-container/page-container-footer/index.js +++ b/ui/app/components/ui/page-container/page-container-footer/index.js @@ -1 +1 @@ -export { default } from './page-container-footer.component' +export { default } from './page-container-footer.component'; diff --git a/ui/app/components/ui/page-container/page-container-footer/page-container-footer.component.js b/ui/app/components/ui/page-container/page-container-footer/page-container-footer.component.js index 9278f4e257..cc53848173 100644 --- a/ui/app/components/ui/page-container/page-container-footer/page-container-footer.component.js +++ b/ui/app/components/ui/page-container/page-container-footer/page-container-footer.component.js @@ -1,7 +1,7 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import Button from '../../button' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import Button from '../../button'; export default class PageContainerFooter extends Component { static propTypes = { @@ -17,11 +17,11 @@ export default class PageContainerFooter extends Component { buttonSizeLarge: PropTypes.bool, footerClassName: PropTypes.string, footerButtonClassName: PropTypes.string, - } + }; static contextTypes = { t: PropTypes.func, - } + }; render() { const { @@ -37,7 +37,7 @@ export default class PageContainerFooter extends Component { buttonSizeLarge = false, footerClassName, footerButtonClassName, - } = this.props + } = this.props; return (
    @@ -76,6 +76,6 @@ export default class PageContainerFooter extends Component {
    {children}
    )}
    - ) + ); } } diff --git a/ui/app/components/ui/page-container/page-container-footer/tests/page-container-footer.component.test.js b/ui/app/components/ui/page-container/page-container-footer/tests/page-container-footer.component.test.js index 4fd9b039ca..56c798f651 100644 --- a/ui/app/components/ui/page-container/page-container-footer/tests/page-container-footer.component.test.js +++ b/ui/app/components/ui/page-container/page-container-footer/tests/page-container-footer.component.test.js @@ -1,14 +1,14 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import sinon from 'sinon' -import Button from '../../../button' -import PageFooter from '../page-container-footer.component' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import Button from '../../../button'; +import PageFooter from '../page-container-footer.component'; describe('Page Footer', function () { - let wrapper - const onCancel = sinon.spy() - const onSubmit = sinon.spy() + let wrapper; + const onCancel = sinon.spy(); + const onSubmit = sinon.spy(); beforeEach(function () { wrapper = shallow( @@ -20,12 +20,12 @@ describe('Page Footer', function () { disabled={false} submitButtonType="Test Type" />, - ) - }) + ); + }); it('renders page container footer', function () { - assert.strictEqual(wrapper.find('.page-container__footer').length, 1) - }) + assert.strictEqual(wrapper.find('.page-container__footer').length, 1); + }); it('should render a secondary footer inside page-container__footer when given children', function () { wrapper = shallow( @@ -33,64 +33,64 @@ describe('Page Footer', function () {
    Works
    , { context: { t: sinon.spy((k) => `[${k}]`) } }, - ) + ); assert.strictEqual( wrapper.find('.page-container__footer-secondary').length, 1, - ) - }) + ); + }); it('renders two button components', function () { - assert.strictEqual(wrapper.find(Button).length, 2) - }) + assert.strictEqual(wrapper.find(Button).length, 2); + }); describe('Cancel Button', function () { it('has button type of default', function () { assert.strictEqual( wrapper.find('.page-container__footer-button').first().prop('type'), 'default', - ) - }) + ); + }); it('has children text of Cancel', function () { assert.strictEqual( wrapper.find('.page-container__footer-button').first().prop('children'), 'Cancel', - ) - }) + ); + }); it('should call cancel when click is simulated', function () { - wrapper.find('.page-container__footer-button').first().prop('onClick')() - assert.strictEqual(onCancel.callCount, 1) - }) - }) + wrapper.find('.page-container__footer-button').first().prop('onClick')(); + assert.strictEqual(onCancel.callCount, 1); + }); + }); describe('Submit Button', function () { it('assigns button type based on props', function () { assert.strictEqual( wrapper.find('.page-container__footer-button').last().prop('type'), 'Test Type', - ) - }) + ); + }); it('has disabled prop', function () { assert.strictEqual( wrapper.find('.page-container__footer-button').last().prop('disabled'), false, - ) - }) + ); + }); it('has children text when submitText prop exists', function () { assert.strictEqual( wrapper.find('.page-container__footer-button').last().prop('children'), 'Submit', - ) - }) + ); + }); it('should call submit when click is simulated', function () { - wrapper.find('.page-container__footer-button').last().prop('onClick')() - assert.strictEqual(onSubmit.callCount, 1) - }) - }) -}) + wrapper.find('.page-container__footer-button').last().prop('onClick')(); + assert.strictEqual(onSubmit.callCount, 1); + }); + }); +}); diff --git a/ui/app/components/ui/page-container/page-container-header/index.js b/ui/app/components/ui/page-container/page-container-header/index.js index b194af057e..14f4c01c2a 100644 --- a/ui/app/components/ui/page-container/page-container-header/index.js +++ b/ui/app/components/ui/page-container/page-container-header/index.js @@ -1 +1 @@ -export { default } from './page-container-header.component' +export { default } from './page-container-header.component'; diff --git a/ui/app/components/ui/page-container/page-container-header/page-container-header.component.js b/ui/app/components/ui/page-container/page-container-header/page-container-header.component.js index 0f715a0279..3717b74501 100644 --- a/ui/app/components/ui/page-container/page-container-header/page-container-header.component.js +++ b/ui/app/components/ui/page-container/page-container-header/page-container-header.component.js @@ -1,7 +1,7 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import Button from '../../button' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import Button from '../../button'; export default class PageContainerHeader extends Component { static propTypes = { @@ -15,12 +15,12 @@ export default class PageContainerHeader extends Component { tabs: PropTypes.node, headerCloseText: PropTypes.string, className: PropTypes.string, - } + }; renderTabs() { - const { tabs } = this.props + const { tabs } = this.props; - return tabs &&
      {tabs}
    + return tabs &&
      {tabs}
    ; } renderHeaderRow() { @@ -29,7 +29,7 @@ export default class PageContainerHeader extends Component { onBackButtonClick, backButtonStyles, backButtonString, - } = this.props + } = this.props; return ( showBackButton && ( @@ -43,7 +43,7 @@ export default class PageContainerHeader extends Component { ) - ) + ); } render() { @@ -54,7 +54,7 @@ export default class PageContainerHeader extends Component { tabs, headerCloseText, className, - } = this.props + } = this.props; return (
    - ) + ); } } diff --git a/ui/app/components/ui/page-container/page-container-header/tests/page-container-header.component.test.js b/ui/app/components/ui/page-container/page-container-header/tests/page-container-header.component.test.js index c686e34902..1c96ee0e5b 100644 --- a/ui/app/components/ui/page-container/page-container-header/tests/page-container-header.component.test.js +++ b/ui/app/components/ui/page-container/page-container-header/tests/page-container-header.component.test.js @@ -1,16 +1,16 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import sinon from 'sinon' -import PageContainerHeader from '../page-container-header.component' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import PageContainerHeader from '../page-container-header.component'; describe('Page Container Header', function () { - let wrapper, style, onBackButtonClick, onClose + let wrapper, style, onBackButtonClick, onClose; beforeEach(function () { - style = { test: 'style' } - onBackButtonClick = sinon.spy() - onClose = sinon.spy() + style = { test: 'style' }; + onBackButtonClick = sinon.spy(); + onClose = sinon.spy(); wrapper = shallow( , - ) - }) + ); + }); describe('Render Header Row', function () { it('renders back button', function () { - assert.strictEqual(wrapper.find('.page-container__back-button').length, 1) + assert.strictEqual( + wrapper.find('.page-container__back-button').length, + 1, + ); assert.strictEqual( wrapper.find('.page-container__back-button').text(), 'Back', - ) - }) + ); + }); it('ensures style prop', function () { assert.strictEqual( wrapper.find('.page-container__back-button').props().style, style, - ) - }) + ); + }); it('should call back button when click is simulated', function () { - wrapper.find('.page-container__back-button').prop('onClick')() - assert.strictEqual(onBackButtonClick.callCount, 1) - }) - }) + wrapper.find('.page-container__back-button').prop('onClick')(); + assert.strictEqual(onBackButtonClick.callCount, 1); + }); + }); describe('Render', function () { - let header, headerRow, pageTitle, pageSubtitle, pageClose, pageTab + let header, headerRow, pageTitle, pageSubtitle, pageClose, pageTab; beforeEach(function () { - header = wrapper.find('.page-container__header--no-padding-bottom') - headerRow = wrapper.find('.page-container__header-row') - pageTitle = wrapper.find('.page-container__title') - pageSubtitle = wrapper.find('.page-container__subtitle') - pageClose = wrapper.find('.page-container__header-close') - pageTab = wrapper.find('.page-container__tabs') - }) + header = wrapper.find('.page-container__header--no-padding-bottom'); + headerRow = wrapper.find('.page-container__header-row'); + pageTitle = wrapper.find('.page-container__title'); + pageSubtitle = wrapper.find('.page-container__subtitle'); + pageClose = wrapper.find('.page-container__header-close'); + pageTab = wrapper.find('.page-container__tabs'); + }); it('renders page container', function () { - assert.strictEqual(header.length, 1) - assert.strictEqual(headerRow.length, 1) - assert.strictEqual(pageTitle.length, 1) - assert.strictEqual(pageSubtitle.length, 1) - assert.strictEqual(pageClose.length, 1) - assert.strictEqual(pageTab.length, 1) - }) + assert.strictEqual(header.length, 1); + assert.strictEqual(headerRow.length, 1); + assert.strictEqual(pageTitle.length, 1); + assert.strictEqual(pageSubtitle.length, 1); + assert.strictEqual(pageClose.length, 1); + assert.strictEqual(pageTab.length, 1); + }); it('renders title', function () { - assert.strictEqual(pageTitle.text(), 'Test Title') - }) + assert.strictEqual(pageTitle.text(), 'Test Title'); + }); it('renders subtitle', function () { - assert.strictEqual(pageSubtitle.text(), 'Test Subtitle') - }) + assert.strictEqual(pageSubtitle.text(), 'Test Subtitle'); + }); it('renders tabs', function () { - assert.strictEqual(pageTab.text(), 'Test Tab') - }) + assert.strictEqual(pageTab.text(), 'Test Tab'); + }); it('should call close when click is simulated', function () { - pageClose.prop('onClick')() - assert.strictEqual(onClose.callCount, 1) - }) - }) -}) + pageClose.prop('onClick')(); + assert.strictEqual(onClose.callCount, 1); + }); + }); +}); diff --git a/ui/app/components/ui/page-container/page-container.component.js b/ui/app/components/ui/page-container/page-container.component.js index 79126e4540..3cefb2273c 100644 --- a/ui/app/components/ui/page-container/page-container.component.js +++ b/ui/app/components/ui/page-container/page-container.component.js @@ -1,8 +1,8 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; -import PageContainerHeader from './page-container-header' -import PageContainerFooter from './page-container-footer' +import PageContainerHeader from './page-container-header'; +import PageContainerFooter from './page-container-footer'; export default class PageContainer extends PureComponent { static propTypes = { @@ -27,24 +27,24 @@ export default class PageContainer extends PureComponent { onCancel: PropTypes.func, onSubmit: PropTypes.func, submitText: PropTypes.string, - } + }; state = { activeTabIndex: this.props.defaultActiveTabIndex || 0, - } + }; handleTabClick(activeTabIndex) { - this.setState({ activeTabIndex }) + this.setState({ activeTabIndex }); } renderTabs() { - const { tabsComponent } = this.props + const { tabsComponent } = this.props; if (!tabsComponent) { - return null + return null; } - const numberOfTabs = React.Children.count(tabsComponent.props.children) + const numberOfTabs = React.Children.count(tabsComponent.props.children); return React.Children.map( tabsComponent.props.children, @@ -59,31 +59,31 @@ export default class PageContainer extends PureComponent { key: tabIndex, className: 'page-container__tab', }) - ) + ); }, - ) + ); } renderActiveTabContent() { - const { tabsComponent } = this.props - let { children } = tabsComponent.props - children = children.filter(Boolean) - const { activeTabIndex } = this.state + const { tabsComponent } = this.props; + let { children } = tabsComponent.props; + children = children.filter(Boolean); + const { activeTabIndex } = this.state; return children[activeTabIndex] ? children[activeTabIndex].props.children - : children.props.children + : children.props.children; } renderContent() { - const { contentComponent, tabsComponent } = this.props + const { contentComponent, tabsComponent } = this.props; if (contentComponent) { - return contentComponent + return contentComponent; } else if (tabsComponent) { - return this.renderActiveTabContent() + return this.renderActiveTabContent(); } - return null + return null; } render() { @@ -102,7 +102,7 @@ export default class PageContainer extends PureComponent { disabled, headerCloseText, hideCancel, - } = this.props + } = this.props; return (
    @@ -129,6 +129,6 @@ export default class PageContainer extends PureComponent { />
    - ) + ); } } diff --git a/ui/app/components/ui/popover/index.js b/ui/app/components/ui/popover/index.js index 416fee51a6..6c51559ddb 100644 --- a/ui/app/components/ui/popover/index.js +++ b/ui/app/components/ui/popover/index.js @@ -1,3 +1,3 @@ -import Item from './popover.component' +import Item from './popover.component'; -export default Item +export default Item; diff --git a/ui/app/components/ui/popover/popover.component.js b/ui/app/components/ui/popover/popover.component.js index 43d95449d6..0f93c71838 100644 --- a/ui/app/components/ui/popover/popover.component.js +++ b/ui/app/components/ui/popover/popover.component.js @@ -1,8 +1,8 @@ -import React, { PureComponent } from 'react' -import ReactDOM from 'react-dom' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { useI18nContext } from '../../../hooks/useI18nContext' +import React, { PureComponent } from 'react'; +import ReactDOM from 'react-dom'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import { useI18nContext } from '../../../hooks/useI18nContext'; const Popover = ({ title, @@ -17,7 +17,7 @@ const Popover = ({ showArrow, CustomBackground, }) => { - const t = useI18nContext() + const t = useI18nContext(); return (
    {CustomBackground ? ( @@ -61,8 +61,8 @@ const Popover = ({ ) : null}
    - ) -} + ); +}; Popover.propTypes = { title: PropTypes.string.isRequired, @@ -76,35 +76,35 @@ Popover.propTypes = { contentClassName: PropTypes.string, className: PropTypes.string, showArrow: PropTypes.bool, -} +}; export default class PopoverPortal extends PureComponent { - static propTypes = Popover.propTypes + static propTypes = Popover.propTypes; - rootNode = document.getElementById('popover-content') + rootNode = document.getElementById('popover-content'); - instanceNode = document.createElement('div') + instanceNode = document.createElement('div'); componentDidMount() { if (!this.rootNode) { - return + return; } - this.rootNode.appendChild(this.instanceNode) + this.rootNode.appendChild(this.instanceNode); } componentWillUnmount() { if (!this.rootNode) { - return + return; } - this.rootNode.removeChild(this.instanceNode) + this.rootNode.removeChild(this.instanceNode); } render() { - const children = + const children = ; return this.rootNode ? ReactDOM.createPortal(children, this.instanceNode) - : children + : children; } } diff --git a/ui/app/components/ui/popover/popover.stories.js b/ui/app/components/ui/popover/popover.stories.js index be713f0dc8..e7029d17f6 100644 --- a/ui/app/components/ui/popover/popover.stories.js +++ b/ui/app/components/ui/popover/popover.stories.js @@ -1,22 +1,22 @@ -import React from 'react' -import { text } from '@storybook/addon-knobs' -import { action } from '@storybook/addon-actions' -import Popover from './popover.component' +import React from 'react'; +import { text } from '@storybook/addon-knobs'; +import { action } from '@storybook/addon-actions'; +import Popover from './popover.component'; const containerStyle = { width: 800, height: 600, background: 'pink', position: 'relative', -} +}; const mainWrapperStyle = { padding: '0 24px 24px', -} +}; export default { title: 'Popover', -} +}; export const approve = () => (
    @@ -61,4 +61,4 @@ export const approve = () => (
    -) +); diff --git a/ui/app/components/ui/pulse-loader/index.js b/ui/app/components/ui/pulse-loader/index.js index 1fad53e562..b626bdda49 100644 --- a/ui/app/components/ui/pulse-loader/index.js +++ b/ui/app/components/ui/pulse-loader/index.js @@ -1 +1 @@ -export { default } from './pulse-loader' +export { default } from './pulse-loader'; diff --git a/ui/app/components/ui/pulse-loader/pulse-loader.js b/ui/app/components/ui/pulse-loader/pulse-loader.js index afc8af89d6..d4d542d71c 100644 --- a/ui/app/components/ui/pulse-loader/pulse-loader.js +++ b/ui/app/components/ui/pulse-loader/pulse-loader.js @@ -1,4 +1,4 @@ -import React from 'react' +import React from 'react'; export default function PulseLoader() { return ( @@ -7,5 +7,5 @@ export default function PulseLoader() {
    - ) + ); } diff --git a/ui/app/components/ui/pulse-loader/pulse-loader.stories.js b/ui/app/components/ui/pulse-loader/pulse-loader.stories.js index 6adb4f4412..a3878d27d5 100644 --- a/ui/app/components/ui/pulse-loader/pulse-loader.stories.js +++ b/ui/app/components/ui/pulse-loader/pulse-loader.stories.js @@ -1,8 +1,8 @@ -import React from 'react' -import PulseLoader from '.' +import React from 'react'; +import PulseLoader from '.'; export default { title: 'PulseLoader', -} +}; -export const common = () => +export const common = () => ; diff --git a/ui/app/components/ui/qr-code/index.js b/ui/app/components/ui/qr-code/index.js index f638ae4fb3..632ac037fc 100644 --- a/ui/app/components/ui/qr-code/index.js +++ b/ui/app/components/ui/qr-code/index.js @@ -1 +1 @@ -export { default } from './qr-code' +export { default } from './qr-code'; diff --git a/ui/app/components/ui/qr-code/qr-code.js b/ui/app/components/ui/qr-code/qr-code.js index b8990186ef..6c00f33fc2 100644 --- a/ui/app/components/ui/qr-code/qr-code.js +++ b/ui/app/components/ui/qr-code/qr-code.js @@ -1,31 +1,31 @@ -import PropTypes from 'prop-types' -import React from 'react' -import qrCode from 'qrcode-generator' -import { connect } from 'react-redux' -import { isHexPrefixed } from 'ethereumjs-util' -import ReadOnlyInput from '../readonly-input/readonly-input' -import { checksumAddress } from '../../../helpers/utils/util' +import PropTypes from 'prop-types'; +import React from 'react'; +import qrCode from 'qrcode-generator'; +import { connect } from 'react-redux'; +import { isHexPrefixed } from 'ethereumjs-util'; +import ReadOnlyInput from '../readonly-input/readonly-input'; +import { checksumAddress } from '../../../helpers/utils/util'; -export default connect(mapStateToProps)(QrCodeView) +export default connect(mapStateToProps)(QrCodeView); function mapStateToProps(state) { - const { buyView, warning } = state.appState + const { buyView, warning } = state.appState; return { // Qr code is not fetched from state. 'message' and 'data' props are passed instead. buyView, warning, - } + }; } function QrCodeView(props) { - const { Qr, warning } = props - const { message, data } = Qr + const { Qr, warning } = props; + const { message, data } = Qr; const address = `${isHexPrefixed(data) ? 'ethereum:' : ''}${checksumAddress( data, - )}` - const qrImage = qrCode(4, 'M') - qrImage.addData(address) - qrImage.make() + )}`; + const qrImage = qrCode(4, 'M'); + qrImage.addData(address); + qrImage.make(); return (
    @@ -53,7 +53,7 @@ function QrCodeView(props) { value={checksumAddress(data)} />
    - ) + ); } QrCodeView.propTypes = { @@ -65,4 +65,4 @@ QrCodeView.propTypes = { ]), data: PropTypes.string.isRequired, }).isRequired, -} +}; diff --git a/ui/app/components/ui/readonly-input/index.js b/ui/app/components/ui/readonly-input/index.js index 151a02ee87..f944d6a89f 100644 --- a/ui/app/components/ui/readonly-input/index.js +++ b/ui/app/components/ui/readonly-input/index.js @@ -1 +1 @@ -export { default } from './readonly-input' +export { default } from './readonly-input'; diff --git a/ui/app/components/ui/readonly-input/readonly-input.js b/ui/app/components/ui/readonly-input/readonly-input.js index a64aaf0545..30fbce0e25 100644 --- a/ui/app/components/ui/readonly-input/readonly-input.js +++ b/ui/app/components/ui/readonly-input/readonly-input.js @@ -1,6 +1,6 @@ -import PropTypes from 'prop-types' -import React from 'react' -import classnames from 'classnames' +import PropTypes from 'prop-types'; +import React from 'react'; +import classnames from 'classnames'; export default function ReadOnlyInput(props) { const { @@ -10,9 +10,9 @@ export default function ReadOnlyInput(props) { textarea, onClick, autoFocus = false, - } = props + } = props; - const InputType = textarea ? 'textarea' : 'input' + const InputType = textarea ? 'textarea' : 'input'; return (
    @@ -25,7 +25,7 @@ export default function ReadOnlyInput(props) { autoFocus={autoFocus} />
    - ) + ); } ReadOnlyInput.propTypes = { @@ -35,4 +35,4 @@ ReadOnlyInput.propTypes = { textarea: PropTypes.bool, onClick: PropTypes.func, autoFocus: PropTypes.bool, -} +}; diff --git a/ui/app/components/ui/search-icon/index.js b/ui/app/components/ui/search-icon/index.js index f6078b7be4..7583cbf6b4 100644 --- a/ui/app/components/ui/search-icon/index.js +++ b/ui/app/components/ui/search-icon/index.js @@ -1 +1 @@ -export { default } from './search-icon.component' +export { default } from './search-icon.component'; diff --git a/ui/app/components/ui/search-icon/search-icon.component.js b/ui/app/components/ui/search-icon/search-icon.component.js index a0bf8aa54e..957c499bf6 100644 --- a/ui/app/components/ui/search-icon/search-icon.component.js +++ b/ui/app/components/ui/search-icon/search-icon.component.js @@ -1,4 +1,4 @@ -import React from 'react' +import React from 'react'; export default function SearchIcon() { return ( @@ -13,5 +13,5 @@ export default function SearchIcon() { - ) + ); } diff --git a/ui/app/components/ui/sender-to-recipient/index.js b/ui/app/components/ui/sender-to-recipient/index.js index f515c4ac41..b19de3f809 100644 --- a/ui/app/components/ui/sender-to-recipient/index.js +++ b/ui/app/components/ui/sender-to-recipient/index.js @@ -1 +1 @@ -export { default } from './sender-to-recipient.component' +export { default } from './sender-to-recipient.component'; diff --git a/ui/app/components/ui/sender-to-recipient/sender-to-recipient.component.js b/ui/app/components/ui/sender-to-recipient/sender-to-recipient.component.js index 5c4ae79913..00e099e24a 100644 --- a/ui/app/components/ui/sender-to-recipient/sender-to-recipient.component.js +++ b/ui/app/components/ui/sender-to-recipient/sender-to-recipient.component.js @@ -1,23 +1,23 @@ -import React, { useState } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import copyToClipboard from 'copy-to-clipboard' -import Tooltip from '../tooltip' -import Identicon from '../identicon' -import { checksumAddress, shortenAddress } from '../../../helpers/utils/util' -import AccountMismatchWarning from '../account-mismatch-warning/account-mismatch-warning.component' -import { useI18nContext } from '../../../hooks/useI18nContext' +import React, { useState } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import copyToClipboard from 'copy-to-clipboard'; +import Tooltip from '../tooltip'; +import Identicon from '../identicon'; +import { checksumAddress, shortenAddress } from '../../../helpers/utils/util'; +import AccountMismatchWarning from '../account-mismatch-warning/account-mismatch-warning.component'; +import { useI18nContext } from '../../../hooks/useI18nContext'; import { DEFAULT_VARIANT, CARDS_VARIANT, FLAT_VARIANT, -} from './sender-to-recipient.constants' +} from './sender-to-recipient.constants'; const variantHash = { [DEFAULT_VARIANT]: 'sender-to-recipient--default', [CARDS_VARIANT]: 'sender-to-recipient--cards', [FLAT_VARIANT]: 'sender-to-recipient--flat', -} +}; function SenderAddress({ addressOnly, @@ -27,9 +27,9 @@ function SenderAddress({ senderAddress, warnUserOnAccountMismatch, }) { - const t = useI18nContext() - const [addressCopied, setAddressCopied] = useState(false) - let tooltipHtml =

    {t('copiedExclamation')}

    + const t = useI18nContext(); + const [addressCopied, setAddressCopied] = useState(false); + let tooltipHtml =

    {t('copiedExclamation')}

    ; if (!addressCopied) { tooltipHtml = addressOnly ? (

    {t('copyAddress')}

    @@ -39,7 +39,7 @@ function SenderAddress({
    {t('copyAddress')}

    - ) + ); } return (
    { - setAddressCopied(true) - copyToClipboard(checksummedSenderAddress) + setAddressCopied(true); + copyToClipboard(checksummedSenderAddress); if (onSenderClick) { - onSenderClick() + onSenderClick(); } }} > @@ -80,7 +80,7 @@ function SenderAddress({ )}
    - ) + ); } SenderAddress.propTypes = { @@ -90,7 +90,7 @@ SenderAddress.propTypes = { senderAddress: PropTypes.string, onSenderClick: PropTypes.func, warnUserOnAccountMismatch: PropTypes.bool, -} +}; function RecipientWithAddress({ checksummedRecipientAddress, @@ -101,13 +101,13 @@ function RecipientWithAddress({ recipientEns, recipientName, }) { - const t = useI18nContext() - const [addressCopied, setAddressCopied] = useState(false) + const t = useI18nContext(); + const [addressCopied, setAddressCopied] = useState(false); - let tooltipHtml =

    {t('copiedExclamation')}

    + let tooltipHtml =

    {t('copiedExclamation')}

    ; if (!addressCopied) { if (addressOnly && !recipientNickname && !recipientEns) { - tooltipHtml =

    {t('copyAddress')}

    + tooltipHtml =

    {t('copyAddress')}

    ; } else { tooltipHtml = (

    @@ -115,17 +115,17 @@ function RecipientWithAddress({
    {t('copyAddress')}

    - ) + ); } } return (
    { - setAddressCopied(true) - copyToClipboard(checksummedRecipientAddress) + setAddressCopied(true); + copyToClipboard(checksummedRecipientAddress); if (onRecipientClick) { - onRecipientClick() + onRecipientClick(); } }} > @@ -157,7 +157,7 @@ function RecipientWithAddress({
    - ) + ); } RecipientWithAddress.propTypes = { @@ -168,7 +168,7 @@ RecipientWithAddress.propTypes = { addressOnly: PropTypes.bool, assetImage: PropTypes.string, onRecipientClick: PropTypes.func, -} +}; function Arrow({ variant }) { return variant === DEFAULT_VARIANT ? ( @@ -181,12 +181,12 @@ function Arrow({ variant }) {
    - ) + ); } Arrow.propTypes = { variant: PropTypes.oneOf([DEFAULT_VARIANT, CARDS_VARIANT, FLAT_VARIANT]), -} +}; export default function SenderToRecipient({ senderAddress, @@ -202,9 +202,9 @@ export default function SenderToRecipient({ variant, warnUserOnAccountMismatch, }) { - const t = useI18nContext() - const checksummedSenderAddress = checksumAddress(senderAddress) - const checksummedRecipientAddress = checksumAddress(recipientAddress) + const t = useI18nContext(); + const checksummedSenderAddress = checksumAddress(senderAddress); + const checksummedRecipientAddress = checksumAddress(recipientAddress); return (
    @@ -234,13 +234,13 @@ export default function SenderToRecipient({
    )} - ) + ); } SenderToRecipient.defaultProps = { variant: DEFAULT_VARIANT, warnUserOnAccountMismatch: true, -} +}; SenderToRecipient.propTypes = { senderName: PropTypes.string, @@ -255,4 +255,4 @@ SenderToRecipient.propTypes = { onRecipientClick: PropTypes.func, onSenderClick: PropTypes.func, warnUserOnAccountMismatch: PropTypes.bool, -} +}; diff --git a/ui/app/components/ui/sender-to-recipient/sender-to-recipient.constants.js b/ui/app/components/ui/sender-to-recipient/sender-to-recipient.constants.js index f53a5115d4..5b7b53f460 100644 --- a/ui/app/components/ui/sender-to-recipient/sender-to-recipient.constants.js +++ b/ui/app/components/ui/sender-to-recipient/sender-to-recipient.constants.js @@ -1,4 +1,4 @@ // Component design variants -export const DEFAULT_VARIANT = 'DEFAULT_VARIANT' -export const CARDS_VARIANT = 'CARDS_VARIANT' -export const FLAT_VARIANT = 'FLAT_VARIANT' +export const DEFAULT_VARIANT = 'DEFAULT_VARIANT'; +export const CARDS_VARIANT = 'CARDS_VARIANT'; +export const FLAT_VARIANT = 'FLAT_VARIANT'; diff --git a/ui/app/components/ui/site-icon/index.js b/ui/app/components/ui/site-icon/index.js index a68d9779dc..1097b3c64e 100644 --- a/ui/app/components/ui/site-icon/index.js +++ b/ui/app/components/ui/site-icon/index.js @@ -1 +1 @@ -export { default } from './site-icon' +export { default } from './site-icon'; diff --git a/ui/app/components/ui/site-icon/site-icon.js b/ui/app/components/ui/site-icon/site-icon.js index e0a690c6e8..4101b7b300 100644 --- a/ui/app/components/ui/site-icon/site-icon.js +++ b/ui/app/components/ui/site-icon/site-icon.js @@ -1,24 +1,24 @@ -import React from 'react' -import PropTypes from 'prop-types' -import IconBorder from '../icon-border' -import IconWithFallback from '../icon-with-fallback' +import React from 'react'; +import PropTypes from 'prop-types'; +import IconBorder from '../icon-border'; +import IconWithFallback from '../icon-with-fallback'; export default function SiteIcon({ icon, name, size }) { - const iconSize = Math.floor(size * 0.75) + const iconSize = Math.floor(size * 0.75); return ( - ) + ); } SiteIcon.propTypes = { icon: PropTypes.string, name: PropTypes.string, size: PropTypes.number.isRequired, -} +}; SiteIcon.defaultProps = { icon: undefined, name: undefined, -} +}; diff --git a/ui/app/components/ui/snackbar/index.js b/ui/app/components/ui/snackbar/index.js index 3d3e0394dd..3fe5015d64 100644 --- a/ui/app/components/ui/snackbar/index.js +++ b/ui/app/components/ui/snackbar/index.js @@ -1 +1 @@ -export { default } from './snackbar.component' +export { default } from './snackbar.component'; diff --git a/ui/app/components/ui/snackbar/snackbar.component.js b/ui/app/components/ui/snackbar/snackbar.component.js index c9da15dba7..87fa7c003b 100644 --- a/ui/app/components/ui/snackbar/snackbar.component.js +++ b/ui/app/components/ui/snackbar/snackbar.component.js @@ -1,14 +1,14 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; const Snackbar = ({ className = '', content }) => { - return
    {content}
    -} + return
    {content}
    ; +}; Snackbar.propTypes = { className: PropTypes.string, content: PropTypes.string.isRequired, -} +}; -export default Snackbar +export default Snackbar; diff --git a/ui/app/components/ui/spinner/index.js b/ui/app/components/ui/spinner/index.js index d302d535b7..ce78e9c960 100644 --- a/ui/app/components/ui/spinner/index.js +++ b/ui/app/components/ui/spinner/index.js @@ -1,3 +1,3 @@ -import Spinner from './spinner.component' +import Spinner from './spinner.component'; -export default Spinner +export default Spinner; diff --git a/ui/app/components/ui/spinner/spinner.component.js b/ui/app/components/ui/spinner/spinner.component.js index 4e002bfb25..6343988234 100644 --- a/ui/app/components/ui/spinner/spinner.component.js +++ b/ui/app/components/ui/spinner/spinner.component.js @@ -1,5 +1,5 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; const Spinner = ({ className = '', color = '#000000' }) => { return ( @@ -148,12 +148,12 @@ const Spinner = ({ className = '', color = '#000000' }) => { - ) -} + ); +}; Spinner.propTypes = { className: PropTypes.string, color: PropTypes.string, -} +}; -export default Spinner +export default Spinner; diff --git a/ui/app/components/ui/tabs/index.js b/ui/app/components/ui/tabs/index.js index 46f0b18a5f..43366ec6f7 100644 --- a/ui/app/components/ui/tabs/index.js +++ b/ui/app/components/ui/tabs/index.js @@ -1,4 +1,4 @@ -import Tabs from './tabs.component' -import Tab from './tab' +import Tabs from './tabs.component'; +import Tab from './tab'; -export { Tabs, Tab } +export { Tabs, Tab }; diff --git a/ui/app/components/ui/tabs/tab/index.js b/ui/app/components/ui/tabs/tab/index.js index c6ef9bb68b..06ffef1a5c 100644 --- a/ui/app/components/ui/tabs/tab/index.js +++ b/ui/app/components/ui/tabs/tab/index.js @@ -1,3 +1,3 @@ -import Tab from './tab.component' +import Tab from './tab.component'; -export default Tab +export default Tab; diff --git a/ui/app/components/ui/tabs/tab/tab.component.js b/ui/app/components/ui/tabs/tab/tab.component.js index e88deaca49..63325c0251 100644 --- a/ui/app/components/ui/tabs/tab/tab.component.js +++ b/ui/app/components/ui/tabs/tab/tab.component.js @@ -1,6 +1,6 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; const Tab = (props) => { const { @@ -11,7 +11,7 @@ const Tab = (props) => { name, onClick, tabIndex, - } = props + } = props; return (
  • { })} data-testid={dataTestId} onClick={(event) => { - event.preventDefault() - onClick(tabIndex) + event.preventDefault(); + onClick(tabIndex); }} >
  • - ) -} + ); +}; Tab.propTypes = { activeClassName: PropTypes.string, @@ -38,12 +38,12 @@ Tab.propTypes = { name: PropTypes.string.isRequired, onClick: PropTypes.func, tabIndex: PropTypes.number, // required, but added using React.cloneElement -} +}; Tab.defaultProps = { activeClassName: undefined, className: undefined, onClick: undefined, -} +}; -export default Tab +export default Tab; diff --git a/ui/app/components/ui/tabs/tabs.component.js b/ui/app/components/ui/tabs/tabs.component.js index 2f1f7583ec..6c091e5a25 100644 --- a/ui/app/components/ui/tabs/tabs.component.js +++ b/ui/app/components/ui/tabs/tabs.component.js @@ -1,31 +1,31 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; export default class Tabs extends Component { static defaultProps = { defaultActiveTabName: null, onTabClick: null, tabsClassName: undefined, - } + }; static propTypes = { defaultActiveTabName: PropTypes.string, onTabClick: PropTypes.func, children: PropTypes.node.isRequired, tabsClassName: PropTypes.string, - } + }; state = { activeTabIndex: Math.max( this._findChildByName(this.props.defaultActiveTabName), 0, ), - } + }; handleTabClick(tabIndex, tabName) { - const { onTabClick } = this.props - const { activeTabIndex } = this.state + const { onTabClick } = this.props; + const { activeTabIndex } = this.state; if (tabIndex !== activeTabIndex) { this.setState( @@ -34,18 +34,18 @@ export default class Tabs extends Component { }, () => { if (onTabClick) { - onTabClick(tabName) + onTabClick(tabName); } }, - ) + ); } } renderTabs() { - const numberOfTabs = React.Children.count(this.props.children) + const numberOfTabs = React.Children.count(this.props.children); return React.Children.map(this.props.children, (child, index) => { - const tabName = child?.props.name + const tabName = child?.props.name; return ( child && React.cloneElement(child, { @@ -53,28 +53,28 @@ export default class Tabs extends Component { tabIndex: index, isActive: numberOfTabs > 1 && index === this.state.activeTabIndex, }) - ) - }) + ); + }); } renderActiveTabContent() { - const { children } = this.props - const { activeTabIndex } = this.state + const { children } = this.props; + const { activeTabIndex } = this.state; if ( (Array.isArray(children) && !children[activeTabIndex]) || (!Array.isArray(children) && activeTabIndex !== 0) ) { - throw new Error(`Tab at index '${activeTabIndex}' does not exist`) + throw new Error(`Tab at index '${activeTabIndex}' does not exist`); } return children[activeTabIndex] ? children[activeTabIndex].props.children - : children.props.children + : children.props.children; } render() { - const { tabsClassName } = this.props + const { tabsClassName } = this.props; return (
      @@ -82,7 +82,7 @@ export default class Tabs extends Component {
    {this.renderActiveTabContent()}
    - ) + ); } /** @@ -94,6 +94,6 @@ export default class Tabs extends Component { _findChildByName(name) { return React.Children.toArray(this.props.children).findIndex( (c) => c?.props.name === name, - ) + ); } } diff --git a/ui/app/components/ui/tabs/tabs.stories.js b/ui/app/components/ui/tabs/tabs.stories.js index 1cdc9044c4..ee656845d7 100644 --- a/ui/app/components/ui/tabs/tabs.stories.js +++ b/ui/app/components/ui/tabs/tabs.stories.js @@ -1,27 +1,27 @@ -import React from 'react' -import { text } from '@storybook/addon-knobs' -import Tab from './tab/tab.component' -import Tabs from './tabs.component' +import React from 'react'; +import { text } from '@storybook/addon-knobs'; +import Tab from './tab/tab.component'; +import Tabs from './tabs.component'; export default { title: 'Tabs', -} +}; function renderTab(id) { return ( {text(`Tab ${id} Contents`, `Contents of Tab ${id}`)} - ) + ); } export const twoTabs = () => { - return {['A', 'B'].map(renderTab)} -} + return {['A', 'B'].map(renderTab)}; +}; export const manyTabs = () => { - return {['A', 'B', 'C', 'D', 'E'].map(renderTab)} -} + return {['A', 'B', 'C', 'D', 'E'].map(renderTab)}; +}; export const singleTab = () => { return ( @@ -30,5 +30,5 @@ export const singleTab = () => { {text('Contents', 'Contents of tab')} - ) -} + ); +}; diff --git a/ui/app/components/ui/text-field/index.js b/ui/app/components/ui/text-field/index.js index adc0669b82..262be3c0e2 100644 --- a/ui/app/components/ui/text-field/index.js +++ b/ui/app/components/ui/text-field/index.js @@ -1,3 +1,3 @@ -import TextField from './text-field.component' +import TextField from './text-field.component'; -export default TextField +export default TextField; diff --git a/ui/app/components/ui/text-field/text-field.component.js b/ui/app/components/ui/text-field/text-field.component.js index 88d51d6e61..49e6ca785e 100644 --- a/ui/app/components/ui/text-field/text-field.component.js +++ b/ui/app/components/ui/text-field/text-field.component.js @@ -1,14 +1,14 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { withStyles } from '@material-ui/core/styles' -import MaterialTextField from '@material-ui/core/TextField' +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import MaterialTextField from '@material-ui/core/TextField'; const inputLabelBase = { transform: 'none', transition: 'none', position: 'initial', color: '#5b5b5b', -} +}; const styles = { materialLabel: { @@ -82,7 +82,7 @@ const styles = { inputMultiline: { lineHeight: 'initial !important', }, -} +}; const getMaterialThemeInputProps = ({ dir, @@ -105,7 +105,7 @@ const getMaterialThemeInputProps = ({ dir, }, }, -}) +}); const getMaterialWhitePaddedThemeInputProps = ({ dir, @@ -129,7 +129,7 @@ const getMaterialWhitePaddedThemeInputProps = ({ dir, }, }, -}) +}); const getBorderedThemeInputProps = ({ dir, @@ -167,13 +167,13 @@ const getBorderedThemeInputProps = ({ dir, }, }, -}) +}); const themeToInputProps = { material: getMaterialThemeInputProps, bordered: getBorderedThemeInputProps, 'material-white-padded': getMaterialWhitePaddedThemeInputProps, -} +}; const TextField = ({ error, @@ -189,7 +189,7 @@ const TextField = ({ startAdornment, largeLabel, dir, - }) + }); return ( - ) -} + ); +}; TextField.defaultProps = { error: null, dir: 'auto', theme: 'bordered', -} +}; TextField.propTypes = { error: PropTypes.string, @@ -214,6 +214,6 @@ TextField.propTypes = { theme: PropTypes.oneOf(['bordered', 'material', 'material-white-padded']), startAdornment: PropTypes.element, largeLabel: PropTypes.bool, -} +}; -export default withStyles(styles)(TextField) +export default withStyles(styles)(TextField); diff --git a/ui/app/components/ui/text-field/text-field.stories.js b/ui/app/components/ui/text-field/text-field.stories.js index ed905163dc..2b5cb30187 100644 --- a/ui/app/components/ui/text-field/text-field.stories.js +++ b/ui/app/components/ui/text-field/text-field.stories.js @@ -1,30 +1,30 @@ -import React from 'react' -import TextField from '.' +import React from 'react'; +import TextField from '.'; export default { title: 'TextField', -} +}; -export const text = () => +export const text = () => ; -export const password = () => +export const password = () => ; export const error = () => ( -) +); export const mascaraText = () => ( -) +); export const materialText = () => ( -) +); export const materialPassword = () => ( -) +); export const materialError = () => ( -) +); diff --git a/ui/app/components/ui/toggle-button/index.js b/ui/app/components/ui/toggle-button/index.js index b0c4141e7a..445c963ce5 100644 --- a/ui/app/components/ui/toggle-button/index.js +++ b/ui/app/components/ui/toggle-button/index.js @@ -1,3 +1,3 @@ -import ToggleButton from './toggle-button.component' +import ToggleButton from './toggle-button.component'; -export default ToggleButton +export default ToggleButton; diff --git a/ui/app/components/ui/toggle-button/toggle-button.component.js b/ui/app/components/ui/toggle-button/toggle-button.component.js index 3809b78776..86e6074f18 100644 --- a/ui/app/components/ui/toggle-button/toggle-button.component.js +++ b/ui/app/components/ui/toggle-button/toggle-button.component.js @@ -1,6 +1,6 @@ -import React from 'react' -import PropTypes from 'prop-types' -import ReactToggleButton from 'react-toggle-button' +import React from 'react'; +import PropTypes from 'prop-types'; +import ReactToggleButton from 'react-toggle-button'; const trackStyle = { width: '40px', @@ -11,12 +11,12 @@ const trackStyle = { display: 'flex', alignItems: 'center', justifyContent: 'center', -} +}; const offTrackStyle = { ...trackStyle, border: '2px solid #8E8E8E', -} +}; const thumbStyle = { width: '18px', @@ -26,7 +26,7 @@ const thumbStyle = { alignSelf: 'center', borderRadius: '50%', position: 'relative', -} +}; const colors = { activeThumb: { @@ -43,12 +43,12 @@ const colors = { base: '#DADADA', hover: '#DADADA', }, -} +}; const ToggleButton = (props) => { - const { value, onToggle, offLabel, onLabel } = props + const { value, onToggle, offLabel, onLabel } = props; - const modifier = value ? 'on' : 'off' + const modifier = value ? 'on' : 'off'; return (
    @@ -67,14 +67,14 @@ const ToggleButton = (props) => { {onLabel}
    - ) -} + ); +}; ToggleButton.propTypes = { value: PropTypes.bool, onToggle: PropTypes.func, offLabel: PropTypes.string, onLabel: PropTypes.string, -} +}; -export default ToggleButton +export default ToggleButton; diff --git a/ui/app/components/ui/token-balance/index.js b/ui/app/components/ui/token-balance/index.js index 97bc9bbc2a..e18b4653f9 100644 --- a/ui/app/components/ui/token-balance/index.js +++ b/ui/app/components/ui/token-balance/index.js @@ -1 +1 @@ -export { default } from './token-balance' +export { default } from './token-balance'; diff --git a/ui/app/components/ui/token-balance/token-balance.js b/ui/app/components/ui/token-balance/token-balance.js index dcb7aaa99e..2a972a7f30 100644 --- a/ui/app/components/ui/token-balance/token-balance.js +++ b/ui/app/components/ui/token-balance/token-balance.js @@ -1,19 +1,19 @@ -import React from 'react' -import PropTypes from 'prop-types' -import CurrencyDisplay from '../currency-display' -import { useTokenTracker } from '../../../hooks/useTokenTracker' +import React from 'react'; +import PropTypes from 'prop-types'; +import CurrencyDisplay from '../currency-display'; +import { useTokenTracker } from '../../../hooks/useTokenTracker'; export default function TokenBalance({ className, token }) { - const { tokensWithBalances } = useTokenTracker([token]) + const { tokensWithBalances } = useTokenTracker([token]); - const { string, symbol } = tokensWithBalances[0] || {} + const { string, symbol } = tokensWithBalances[0] || {}; return ( - ) + ); } TokenBalance.propTypes = { @@ -23,8 +23,8 @@ TokenBalance.propTypes = { decimals: PropTypes.number, symbol: PropTypes.string, }).isRequired, -} +}; TokenBalance.defaultProps = { className: undefined, -} +}; diff --git a/ui/app/components/ui/token-currency-display/index.js b/ui/app/components/ui/token-currency-display/index.js index 6065cae1f0..c4c28291ad 100644 --- a/ui/app/components/ui/token-currency-display/index.js +++ b/ui/app/components/ui/token-currency-display/index.js @@ -1 +1 @@ -export { default } from './token-currency-display.component' +export { default } from './token-currency-display.component'; diff --git a/ui/app/components/ui/token-currency-display/token-currency-display.component.js b/ui/app/components/ui/token-currency-display/token-currency-display.component.js index 69a314e474..4d9cb01d09 100644 --- a/ui/app/components/ui/token-currency-display/token-currency-display.component.js +++ b/ui/app/components/ui/token-currency-display/token-currency-display.component.js @@ -1,7 +1,7 @@ -import React from 'react' -import PropTypes from 'prop-types' -import CurrencyDisplay from '../currency-display' -import { useTokenDisplayValue } from '../../../hooks/useTokenDisplayValue' +import React from 'react'; +import PropTypes from 'prop-types'; +import CurrencyDisplay from '../currency-display'; +import { useTokenDisplayValue } from '../../../hooks/useTokenDisplayValue'; export default function TokenCurrencyDisplay({ className, @@ -9,7 +9,7 @@ export default function TokenCurrencyDisplay({ token, prefix, }) { - const displayValue = useTokenDisplayValue(transactionData, token) + const displayValue = useTokenDisplayValue(transactionData, token); return ( - ) + ); } TokenCurrencyDisplay.propTypes = { @@ -26,4 +26,4 @@ TokenCurrencyDisplay.propTypes = { transactionData: PropTypes.string, token: PropTypes.object, prefix: PropTypes.string, -} +}; diff --git a/ui/app/components/ui/token-input/index.js b/ui/app/components/ui/token-input/index.js index 22c06111ee..fb5bafb906 100644 --- a/ui/app/components/ui/token-input/index.js +++ b/ui/app/components/ui/token-input/index.js @@ -1 +1 @@ -export { default } from './token-input.container' +export { default } from './token-input.container'; diff --git a/ui/app/components/ui/token-input/tests/token-input.component.test.js b/ui/app/components/ui/token-input/tests/token-input.component.test.js index e6542b3e28..479d63b0e1 100644 --- a/ui/app/components/ui/token-input/tests/token-input.component.test.js +++ b/ui/app/components/ui/token-input/tests/token-input.component.test.js @@ -1,16 +1,16 @@ -import assert from 'assert' -import React from 'react' -import PropTypes from 'prop-types' -import { shallow, mount } from 'enzyme' -import sinon from 'sinon' -import { Provider } from 'react-redux' -import configureMockStore from 'redux-mock-store' -import TokenInput from '../token-input.component' -import UnitInput from '../../unit-input' -import CurrencyDisplay from '../../currency-display' +import assert from 'assert'; +import React from 'react'; +import PropTypes from 'prop-types'; +import { shallow, mount } from 'enzyme'; +import sinon from 'sinon'; +import { Provider } from 'react-redux'; +import configureMockStore from 'redux-mock-store'; +import TokenInput from '../token-input.component'; +import UnitInput from '../../unit-input'; +import CurrencyDisplay from '../../currency-display'; describe('TokenInput Component', function () { - const t = (key) => `translate ${key}` + const t = (key) => `translate ${key}`; describe('rendering', function () { it('should render properly', function () { @@ -19,8 +19,8 @@ describe('TokenInput Component', function () { currentCurrency: 'usd', conversionRate: 231.06, }, - } - const store = configureMockStore()(mockStore) + }; + const store = configureMockStore()(mockStore); const wrapper = mount( @@ -38,20 +38,20 @@ describe('TokenInput Component', function () { t: PropTypes.func, }, }, - ) + ); - assert.ok(wrapper) - assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) - assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ABC') + assert.ok(wrapper); + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1); + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ABC'); assert.strictEqual( wrapper.find('.currency-input__conversion-component').length, 1, - ) + ); assert.strictEqual( wrapper.find('.currency-input__conversion-component').text(), 'translate noConversionRateAvailable', - ) - }) + ); + }); it('should render properly with tokenExchangeRates', function () { const mockStore = { @@ -59,8 +59,8 @@ describe('TokenInput Component', function () { currentCurrency: 'usd', conversionRate: 231.06, }, - } - const store = configureMockStore()(mockStore) + }; + const store = configureMockStore()(mockStore); const wrapper = mount( @@ -79,13 +79,13 @@ describe('TokenInput Component', function () { t: PropTypes.func, }, }, - ) + ); - assert.ok(wrapper) - assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) - assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ABC') - assert.strictEqual(wrapper.find(CurrencyDisplay).length, 1) - }) + assert.ok(wrapper); + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1); + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ABC'); + assert.strictEqual(wrapper.find(CurrencyDisplay).length, 1); + }); it('should render properly with a token value for ETH', function () { const mockStore = { @@ -93,8 +93,8 @@ describe('TokenInput Component', function () { currentCurrency: 'usd', conversionRate: 231.06, }, - } - const store = configureMockStore()(mockStore) + }; + const store = configureMockStore()(mockStore); const wrapper = mount( @@ -108,20 +108,20 @@ describe('TokenInput Component', function () { tokenExchangeRates={{ '0x1': 2 }} /> , - ) + ); - assert.ok(wrapper) - const tokenInputInstance = wrapper.find(TokenInput).at(0).instance() - assert.strictEqual(tokenInputInstance.state.decimalValue, '1') - assert.strictEqual(tokenInputInstance.state.hexValue, '2710') - assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) - assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ABC') - assert.strictEqual(wrapper.find('.unit-input__input').props().value, '1') + assert.ok(wrapper); + const tokenInputInstance = wrapper.find(TokenInput).at(0).instance(); + assert.strictEqual(tokenInputInstance.state.decimalValue, '1'); + assert.strictEqual(tokenInputInstance.state.hexValue, '2710'); + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1); + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ABC'); + assert.strictEqual(wrapper.find('.unit-input__input').props().value, '1'); assert.strictEqual( wrapper.find('.currency-display-component').text(), '2ETH', - ) - }) + ); + }); it('should render properly with a token value for fiat', function () { const mockStore = { @@ -129,8 +129,8 @@ describe('TokenInput Component', function () { currentCurrency: 'usd', conversionRate: 231.06, }, - } - const store = configureMockStore()(mockStore) + }; + const store = configureMockStore()(mockStore); const wrapper = mount( @@ -145,20 +145,20 @@ describe('TokenInput Component', function () { showFiat /> , - ) + ); - assert.ok(wrapper) - const tokenInputInstance = wrapper.find(TokenInput).at(0).instance() - assert.strictEqual(tokenInputInstance.state.decimalValue, '1') - assert.strictEqual(tokenInputInstance.state.hexValue, '2710') - assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) - assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ABC') - assert.strictEqual(wrapper.find('.unit-input__input').props().value, '1') + assert.ok(wrapper); + const tokenInputInstance = wrapper.find(TokenInput).at(0).instance(); + assert.strictEqual(tokenInputInstance.state.decimalValue, '1'); + assert.strictEqual(tokenInputInstance.state.hexValue, '2710'); + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1); + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ABC'); + assert.strictEqual(wrapper.find('.unit-input__input').props().value, '1'); assert.strictEqual( wrapper.find('.currency-display-component').text(), '$462.12USD', - ) - }) + ); + }); it('should render properly with a token value for fiat, but hideConversion is true', function () { const mockStore = { @@ -166,8 +166,8 @@ describe('TokenInput Component', function () { currentCurrency: 'usd', conversionRate: 231.06, }, - } - const store = configureMockStore()(mockStore) + }; + const store = configureMockStore()(mockStore); const wrapper = mount( @@ -189,30 +189,30 @@ describe('TokenInput Component', function () { t: PropTypes.func, }, }, - ) + ); - assert.ok(wrapper) - const tokenInputInstance = wrapper.find(TokenInput).at(0).instance() - assert.strictEqual(tokenInputInstance.state.decimalValue, '1') - assert.strictEqual(tokenInputInstance.state.hexValue, '2710') - assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) - assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ABC') - assert.strictEqual(wrapper.find('.unit-input__input').props().value, '1') + assert.ok(wrapper); + const tokenInputInstance = wrapper.find(TokenInput).at(0).instance(); + assert.strictEqual(tokenInputInstance.state.decimalValue, '1'); + assert.strictEqual(tokenInputInstance.state.hexValue, '2710'); + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1); + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ABC'); + assert.strictEqual(wrapper.find('.unit-input__input').props().value, '1'); assert.strictEqual( wrapper.find('.currency-input__conversion-component').text(), 'translate noConversionRateAvailable', - ) - }) - }) + ); + }); + }); describe('handling actions', function () { - const handleChangeSpy = sinon.spy() - const handleBlurSpy = sinon.spy() + const handleChangeSpy = sinon.spy(); + const handleBlurSpy = sinon.spy(); afterEach(function () { - handleChangeSpy.resetHistory() - handleBlurSpy.resetHistory() - }) + handleChangeSpy.resetHistory(); + handleBlurSpy.resetHistory(); + }); it('should call onChange on input changes with the hex value for ETH', function () { const mockStore = { @@ -220,8 +220,8 @@ describe('TokenInput Component', function () { currentCurrency: 'usd', conversionRate: 231.06, }, - } - const store = configureMockStore()(mockStore) + }; + const store = configureMockStore()(mockStore); const wrapper = mount( , - ) + ); - assert.ok(wrapper) - assert.strictEqual(handleChangeSpy.callCount, 0) - assert.strictEqual(handleBlurSpy.callCount, 0) + assert.ok(wrapper); + assert.strictEqual(handleChangeSpy.callCount, 0); + assert.strictEqual(handleBlurSpy.callCount, 0); - const tokenInputInstance = wrapper.find(TokenInput).at(0).instance() - assert.strictEqual(tokenInputInstance.state.decimalValue, 0) - assert.strictEqual(tokenInputInstance.state.hexValue, undefined) + const tokenInputInstance = wrapper.find(TokenInput).at(0).instance(); + assert.strictEqual(tokenInputInstance.state.decimalValue, 0); + assert.strictEqual(tokenInputInstance.state.hexValue, undefined); assert.strictEqual( wrapper.find('.currency-display-component').text(), '0ETH', - ) - const input = wrapper.find('input') - assert.strictEqual(input.props().value, 0) + ); + const input = wrapper.find('input'); + assert.strictEqual(input.props().value, 0); - input.simulate('change', { target: { value: 1 } }) - assert.strictEqual(handleChangeSpy.callCount, 1) - assert.ok(handleChangeSpy.calledWith('2710')) + input.simulate('change', { target: { value: 1 } }); + assert.strictEqual(handleChangeSpy.callCount, 1); + assert.ok(handleChangeSpy.calledWith('2710')); assert.strictEqual( wrapper.find('.currency-display-component').text(), '2ETH', - ) - assert.strictEqual(tokenInputInstance.state.decimalValue, 1) - assert.strictEqual(tokenInputInstance.state.hexValue, '2710') - }) + ); + assert.strictEqual(tokenInputInstance.state.decimalValue, 1); + assert.strictEqual(tokenInputInstance.state.hexValue, '2710'); + }); it('should call onChange on input changes with the hex value for fiat', function () { const mockStore = { @@ -267,8 +267,8 @@ describe('TokenInput Component', function () { currentCurrency: 'usd', conversionRate: 231.06, }, - } - const store = configureMockStore()(mockStore) + }; + const store = configureMockStore()(mockStore); const wrapper = mount( , - ) + ); - assert.ok(wrapper) - assert.strictEqual(handleChangeSpy.callCount, 0) - assert.strictEqual(handleBlurSpy.callCount, 0) + assert.ok(wrapper); + assert.strictEqual(handleChangeSpy.callCount, 0); + assert.strictEqual(handleBlurSpy.callCount, 0); - const tokenInputInstance = wrapper.find(TokenInput).at(0).instance() - assert.strictEqual(tokenInputInstance.state.decimalValue, 0) - assert.strictEqual(tokenInputInstance.state.hexValue, undefined) + const tokenInputInstance = wrapper.find(TokenInput).at(0).instance(); + assert.strictEqual(tokenInputInstance.state.decimalValue, 0); + assert.strictEqual(tokenInputInstance.state.hexValue, undefined); assert.strictEqual( wrapper.find('.currency-display-component').text(), '$0.00USD', - ) - const input = wrapper.find('input') - assert.strictEqual(input.props().value, 0) + ); + const input = wrapper.find('input'); + assert.strictEqual(input.props().value, 0); - input.simulate('change', { target: { value: 1 } }) - assert.strictEqual(handleChangeSpy.callCount, 1) - assert.ok(handleChangeSpy.calledWith('2710')) + input.simulate('change', { target: { value: 1 } }); + assert.strictEqual(handleChangeSpy.callCount, 1); + assert.ok(handleChangeSpy.calledWith('2710')); assert.strictEqual( wrapper.find('.currency-display-component').text(), '$462.12USD', - ) - assert.strictEqual(tokenInputInstance.state.decimalValue, 1) - assert.strictEqual(tokenInputInstance.state.hexValue, '2710') - }) + ); + assert.strictEqual(tokenInputInstance.state.decimalValue, 1); + assert.strictEqual(tokenInputInstance.state.hexValue, '2710'); + }); it('should change the state and pass in a new decimalValue when props.value changes', function () { const mockStore = { @@ -315,8 +315,8 @@ describe('TokenInput Component', function () { currentCurrency: 'usd', conversionRate: 231.06, }, - } - const store = configureMockStore()(mockStore) + }; + const store = configureMockStore()(mockStore); const wrapper = shallow( , - ) + ); - assert.ok(wrapper) - const tokenInputInstance = wrapper.find(TokenInput).dive() - assert.strictEqual(tokenInputInstance.state('decimalValue'), 0) - assert.strictEqual(tokenInputInstance.state('hexValue'), undefined) - assert.strictEqual(tokenInputInstance.find(UnitInput).props().value, 0) + assert.ok(wrapper); + const tokenInputInstance = wrapper.find(TokenInput).dive(); + assert.strictEqual(tokenInputInstance.state('decimalValue'), 0); + assert.strictEqual(tokenInputInstance.state('hexValue'), undefined); + assert.strictEqual(tokenInputInstance.find(UnitInput).props().value, 0); - tokenInputInstance.setProps({ value: '2710' }) - tokenInputInstance.update() - assert.strictEqual(tokenInputInstance.state('decimalValue'), '1') - assert.strictEqual(tokenInputInstance.state('hexValue'), '2710') - assert.strictEqual(tokenInputInstance.find(UnitInput).props().value, '1') - }) - }) -}) + tokenInputInstance.setProps({ value: '2710' }); + tokenInputInstance.update(); + assert.strictEqual(tokenInputInstance.state('decimalValue'), '1'); + assert.strictEqual(tokenInputInstance.state('hexValue'), '2710'); + assert.strictEqual(tokenInputInstance.find(UnitInput).props().value, '1'); + }); + }); +}); diff --git a/ui/app/components/ui/token-input/token-input.component.js b/ui/app/components/ui/token-input/token-input.component.js index 4d85ed4a5a..fe7001d4fe 100644 --- a/ui/app/components/ui/token-input/token-input.component.js +++ b/ui/app/components/ui/token-input/token-input.component.js @@ -1,14 +1,14 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import UnitInput from '../unit-input' -import CurrencyDisplay from '../currency-display' -import { getWeiHexFromDecimalValue } from '../../../helpers/utils/conversions.util' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import UnitInput from '../unit-input'; +import CurrencyDisplay from '../currency-display'; +import { getWeiHexFromDecimalValue } from '../../../helpers/utils/conversions.util'; import { conversionUtil, multiplyCurrencies, -} from '../../../helpers/utils/conversion-util' -import { ETH } from '../../../helpers/constants/common' -import { addHexPrefix } from '../../../../../app/scripts/lib/util' +} from '../../../helpers/utils/conversion-util'; +import { ETH } from '../../../helpers/constants/common'; +import { addHexPrefix } from '../../../../../app/scripts/lib/util'; /** * Component that allows user to enter token values as a number, and props receive a converted @@ -18,7 +18,7 @@ import { addHexPrefix } from '../../../../../app/scripts/lib/util' export default class TokenInput extends PureComponent { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { currentCurrency: PropTypes.string, @@ -32,62 +32,62 @@ export default class TokenInput extends PureComponent { symbol: PropTypes.string, }).isRequired, tokenExchangeRates: PropTypes.object, - } + }; constructor(props) { - super(props) + super(props); - const { value: hexValue } = props - const decimalValue = hexValue ? this.getValue(props) : 0 + const { value: hexValue } = props; + const decimalValue = hexValue ? this.getValue(props) : 0; this.state = { decimalValue, hexValue, - } + }; } componentDidUpdate(prevProps) { - const { value: prevPropsHexValue } = prevProps - const { value: propsHexValue } = this.props - const { hexValue: stateHexValue } = this.state + const { value: prevPropsHexValue } = prevProps; + const { value: propsHexValue } = this.props; + const { hexValue: stateHexValue } = this.state; if ( prevPropsHexValue !== propsHexValue && propsHexValue !== stateHexValue ) { - const decimalValue = this.getValue(this.props) - this.setState({ hexValue: propsHexValue, decimalValue }) + const decimalValue = this.getValue(this.props); + this.setState({ hexValue: propsHexValue, decimalValue }); } } getValue(props) { - const { value: hexValue, token: { decimals, symbol } = {} } = props + const { value: hexValue, token: { decimals, symbol } = {} } = props; - const multiplier = Math.pow(10, Number(decimals || 0)) + const multiplier = Math.pow(10, Number(decimals || 0)); const decimalValueString = conversionUtil(addHexPrefix(hexValue), { fromNumericBase: 'hex', toNumericBase: 'dec', toCurrency: symbol, conversionRate: multiplier, invertConversionRate: true, - }) + }); - return Number(decimalValueString) ? decimalValueString : '' + return Number(decimalValueString) ? decimalValueString : ''; } handleChange = (decimalValue) => { - const { token: { decimals } = {}, onChange } = this.props + const { token: { decimals } = {}, onChange } = this.props; - const multiplier = Math.pow(10, Number(decimals || 0)) + const multiplier = Math.pow(10, Number(decimals || 0)); const hexValue = multiplyCurrencies(decimalValue || 0, multiplier, { multiplicandBase: 10, multiplierBase: 10, toNumericBase: 'hex', - }) + }); - this.setState({ hexValue, decimalValue }) - onChange(hexValue) - } + this.setState({ hexValue, decimalValue }); + onChange(hexValue); + }; renderConversionComponent() { const { @@ -96,36 +96,36 @@ export default class TokenInput extends PureComponent { currentCurrency, hideConversion, token, - } = this.props - const { decimalValue } = this.state + } = this.props; + const { decimalValue } = this.state; - const tokenExchangeRate = tokenExchangeRates?.[token.address] || 0 - let currency, numberOfDecimals + const tokenExchangeRate = tokenExchangeRates?.[token.address] || 0; + let currency, numberOfDecimals; if (hideConversion) { return (
    {this.context.t('noConversionRateAvailable')}
    - ) + ); } if (showFiat) { // Display Fiat - currency = currentCurrency - numberOfDecimals = 2 + currency = currentCurrency; + numberOfDecimals = 2; } else { // Display ETH - currency = ETH - numberOfDecimals = 6 + currency = ETH; + numberOfDecimals = 6; } - const decimalEthValue = decimalValue * tokenExchangeRate || 0 + const decimalEthValue = decimalValue * tokenExchangeRate || 0; const hexWeiValue = getWeiHexFromDecimalValue({ value: decimalEthValue, fromCurrency: ETH, fromDenomination: ETH, - }) + }); return tokenExchangeRate ? ( {this.context.t('noConversionRateAvailable')} - ) + ); } render() { - const { token, ...restProps } = this.props - const { decimalValue } = this.state + const { token, ...restProps } = this.props; + const { decimalValue } = this.state; return ( {this.renderConversionComponent()} - ) + ); } } diff --git a/ui/app/components/ui/token-input/token-input.container.js b/ui/app/components/ui/token-input/token-input.container.js index eac410000c..a34c2d247b 100644 --- a/ui/app/components/ui/token-input/token-input.container.js +++ b/ui/app/components/ui/token-input/token-input.container.js @@ -1,27 +1,27 @@ -import { connect } from 'react-redux' -import PropTypes from 'prop-types' +import { connect } from 'react-redux'; +import PropTypes from 'prop-types'; import { getIsMainnet, getTokenExchangeRates, getPreferences, -} from '../../../selectors' -import TokenInput from './token-input.component' +} from '../../../selectors'; +import TokenInput from './token-input.component'; const mapStateToProps = (state) => { const { metamask: { currentCurrency }, - } = state - const { showFiatInTestnets } = getPreferences(state) - const isMainnet = getIsMainnet(state) + } = state; + const { showFiatInTestnets } = getPreferences(state); + const isMainnet = getIsMainnet(state); return { currentCurrency, tokenExchangeRates: getTokenExchangeRates(state), hideConversion: !isMainnet && !showFiatInTestnets, - } -} + }; +}; -const TokenInputContainer = connect(mapStateToProps)(TokenInput) +const TokenInputContainer = connect(mapStateToProps)(TokenInput); TokenInputContainer.propTypes = { token: PropTypes.shape({ @@ -29,6 +29,6 @@ TokenInputContainer.propTypes = { decimals: PropTypes.number, symbol: PropTypes.string, }).isRequired, -} +}; -export default TokenInputContainer +export default TokenInputContainer; diff --git a/ui/app/components/ui/tooltip/index.js b/ui/app/components/ui/tooltip/index.js index 00a8d178af..bb106e2074 100644 --- a/ui/app/components/ui/tooltip/index.js +++ b/ui/app/components/ui/tooltip/index.js @@ -1 +1 @@ -export { default } from './tooltip' +export { default } from './tooltip'; diff --git a/ui/app/components/ui/tooltip/tooltip.js b/ui/app/components/ui/tooltip/tooltip.js index b9319f1668..4c01eaadec 100644 --- a/ui/app/components/ui/tooltip/tooltip.js +++ b/ui/app/components/ui/tooltip/tooltip.js @@ -1,6 +1,6 @@ -import PropTypes from 'prop-types' -import React, { PureComponent } from 'react' -import { Tooltip as ReactTippy } from 'react-tippy' +import PropTypes from 'prop-types'; +import React, { PureComponent } from 'react'; +import { Tooltip as ReactTippy } from 'react-tippy'; export default class Tooltip extends PureComponent { static defaultProps = { @@ -17,7 +17,7 @@ export default class Tooltip extends PureComponent { trigger: 'mouseenter', wrapperClassName: undefined, theme: '', - } + }; static propTypes = { arrow: PropTypes.bool, @@ -35,7 +35,7 @@ export default class Tooltip extends PureComponent { wrapperClassName: PropTypes.string, style: PropTypes.object, theme: PropTypes.string, - } + }; render() { const { @@ -54,10 +54,10 @@ export default class Tooltip extends PureComponent { wrapperClassName, style, theme, - } = this.props + } = this.props; if (!title && !html) { - return
    {children}
    + return
    {children}
    ; } return ( @@ -81,6 +81,6 @@ export default class Tooltip extends PureComponent { {children} - ) + ); } } diff --git a/ui/app/components/ui/truncated-definition-list/index.js b/ui/app/components/ui/truncated-definition-list/index.js index 427109d63f..cabe7da11a 100644 --- a/ui/app/components/ui/truncated-definition-list/index.js +++ b/ui/app/components/ui/truncated-definition-list/index.js @@ -1 +1 @@ -export { default } from './truncated-definition-list' +export { default } from './truncated-definition-list'; diff --git a/ui/app/components/ui/truncated-definition-list/truncated-definition-list.js b/ui/app/components/ui/truncated-definition-list/truncated-definition-list.js index 356f1aed14..2382b045b3 100644 --- a/ui/app/components/ui/truncated-definition-list/truncated-definition-list.js +++ b/ui/app/components/ui/truncated-definition-list/truncated-definition-list.js @@ -1,12 +1,12 @@ -import { pick } from 'lodash' -import React, { useState } from 'react' -import PropTypes from 'prop-types' -import { COLORS, SIZES } from '../../../helpers/constants/design-system' -import Box from '../box' -import Button from '../button' -import DefinitionList from '../definition-list/definition-list' -import Popover from '../popover' -import { useI18nContext } from '../../../hooks/useI18nContext' +import { pick } from 'lodash'; +import React, { useState } from 'react'; +import PropTypes from 'prop-types'; +import { COLORS, SIZES } from '../../../helpers/constants/design-system'; +import Box from '../box'; +import Button from '../button'; +import DefinitionList from '../definition-list/definition-list'; +import Popover from '../popover'; +import { useI18nContext } from '../../../hooks/useI18nContext'; export default function TruncatedDefinitionList({ dictionary, @@ -14,8 +14,8 @@ export default function TruncatedDefinitionList({ prefaceKeys, title, }) { - const [isPopoverOpen, setIsPopoverOpen] = useState(false) - const t = useI18nContext() + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const t = useI18nContext(); return ( <> @@ -67,7 +67,7 @@ export default function TruncatedDefinitionList({
    )} - ) + ); } TruncatedDefinitionList.propTypes = { @@ -75,4 +75,4 @@ TruncatedDefinitionList.propTypes = { tooltips: DefinitionList.propTypes.dictionary, title: PropTypes.string, prefaceKeys: PropTypes.arrayOf(PropTypes.string), -} +}; diff --git a/ui/app/components/ui/truncated-definition-list/truncated-definition-list.stories.js b/ui/app/components/ui/truncated-definition-list/truncated-definition-list.stories.js index 68101ef0de..01c9977e12 100644 --- a/ui/app/components/ui/truncated-definition-list/truncated-definition-list.stories.js +++ b/ui/app/components/ui/truncated-definition-list/truncated-definition-list.stories.js @@ -1,11 +1,11 @@ -import React from 'react' -import { object, text } from '@storybook/addon-knobs' +import React from 'react'; +import { object, text } from '@storybook/addon-knobs'; -import TruncatedDefinitionList from './truncated-definition-list' +import TruncatedDefinitionList from './truncated-definition-list'; export default { title: 'Truncated Definition List', -} +}; const basic = { term: @@ -15,19 +15,19 @@ const basic = { dl: 'HTML tag denoting a definition list', dt: 'HTML tag denoting a definition list term', dd: 'HTML tag denoting a definition list definition', -} +}; const advanced = { 'Network Name': 'Ethereum Mainnet', 'Chain ID': '1', Ticker: 'ETH', -} +}; const tooltips = { 'Network Name': 'The name that is associated with this network', 'Chain ID': 'The numeric value representing the ID of this network', Ticker: 'The currency symbol of the primary currency for this network', -} +}; export const truncatedDefinitionList = () => ( ( title={text('title', 'Basic definitions')} prefaceKeys={object('prefaceKeys', ['term', 'definition'])} /> -) +); export const withTooltips = () => ( ( tooltips={object('tooltips', tooltips)} prefaceKeys={object('prefaceKeys', ['Chain ID'])} /> -) +); diff --git a/ui/app/components/ui/typography/index.js b/ui/app/components/ui/typography/index.js index 648ce1725b..ad5e11bde5 100644 --- a/ui/app/components/ui/typography/index.js +++ b/ui/app/components/ui/typography/index.js @@ -1 +1 @@ -export { default } from './typography' +export { default } from './typography'; diff --git a/ui/app/components/ui/typography/typography.js b/ui/app/components/ui/typography/typography.js index c6ca4afe84..b18b53debe 100644 --- a/ui/app/components/ui/typography/typography.js +++ b/ui/app/components/ui/typography/typography.js @@ -1,15 +1,15 @@ -import React from 'react' -import classnames from 'classnames' -import PropTypes from 'prop-types' +import React from 'react'; +import classnames from 'classnames'; +import PropTypes from 'prop-types'; import { COLORS, FONT_WEIGHT, TEXT_ALIGN, TYPOGRAPHY, -} from '../../../helpers/constants/design-system' -import Box from '../box' +} from '../../../helpers/constants/design-system'; +import Box from '../box'; -const { H6, H7, H8, H9 } = TYPOGRAPHY +const { H6, H7, H8, H9 } = TYPOGRAPHY; export default function Typography({ variant = TYPOGRAPHY.Paragraph, @@ -28,14 +28,14 @@ export default function Typography({ `typography--align-${align}`, `typography--color-${color}`, `typography--weight-${fontWeight}`, - ) + ); - let Tag = tag ?? variant + let Tag = tag ?? variant; if (Tag === TYPOGRAPHY.Paragraph) { - Tag = 'p' + Tag = 'p'; } else if ([H7, H8, H9].includes(Tag)) { - Tag = H6 + Tag = H6; } return ( @@ -46,7 +46,7 @@ export default function Typography({ )}
    - ) + ); } Typography.propTypes = { @@ -72,4 +72,4 @@ Typography.propTypes = { 'dt', 'dd', ]), -} +}; diff --git a/ui/app/components/ui/typography/typography.stories.js b/ui/app/components/ui/typography/typography.stories.js index 0d0d486b80..bd39982a40 100644 --- a/ui/app/components/ui/typography/typography.stories.js +++ b/ui/app/components/ui/typography/typography.stories.js @@ -1,16 +1,16 @@ -import React from 'react' -import { number, select, text } from '@storybook/addon-knobs' +import React from 'react'; +import { number, select, text } from '@storybook/addon-knobs'; import { COLORS, FONT_WEIGHT, TEXT_ALIGN, TYPOGRAPHY, -} from '../../../helpers/constants/design-system' -import Typography from '.' +} from '../../../helpers/constants/design-system'; +import Typography from '.'; export default { title: 'Typography', -} +}; export const list = () => (
    @@ -32,7 +32,7 @@ export const list = () => (
    ))} -) +); export const TheQuickOrangeFox = () => (
    @@ -48,4 +48,4 @@ export const TheQuickOrangeFox = () => (
    -) +); diff --git a/ui/app/components/ui/unit-input/index.js b/ui/app/components/ui/unit-input/index.js index 7c33c9e5c5..4eaa920b38 100644 --- a/ui/app/components/ui/unit-input/index.js +++ b/ui/app/components/ui/unit-input/index.js @@ -1 +1 @@ -export { default } from './unit-input.component' +export { default } from './unit-input.component'; diff --git a/ui/app/components/ui/unit-input/tests/unit-input.component.test.js b/ui/app/components/ui/unit-input/tests/unit-input.component.test.js index 47fdfafded..032b9b76e6 100644 --- a/ui/app/components/ui/unit-input/tests/unit-input.component.test.js +++ b/ui/app/components/ui/unit-input/tests/unit-input.component.test.js @@ -1,99 +1,99 @@ -import assert from 'assert' -import React from 'react' -import { shallow, mount } from 'enzyme' -import sinon from 'sinon' -import UnitInput from '../unit-input.component' +import assert from 'assert'; +import React from 'react'; +import { shallow, mount } from 'enzyme'; +import sinon from 'sinon'; +import UnitInput from '../unit-input.component'; describe('UnitInput Component', function () { describe('rendering', function () { it('should render properly without a suffix', function () { - const wrapper = shallow() + const wrapper = shallow(); - assert.ok(wrapper) - assert.strictEqual(wrapper.find('.unit-input__suffix').length, 0) - }) + assert.ok(wrapper); + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 0); + }); it('should render properly with a suffix', function () { - const wrapper = shallow() + const wrapper = shallow(); - assert.ok(wrapper) - assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) - assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ETH') - }) + assert.ok(wrapper); + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1); + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ETH'); + }); it('should render properly with a child component', function () { const wrapper = shallow(
    TESTCOMPONENT
    , - ) + ); - assert.ok(wrapper) - assert.strictEqual(wrapper.find('.testing').length, 1) - assert.strictEqual(wrapper.find('.testing').text(), 'TESTCOMPONENT') - }) + assert.ok(wrapper); + assert.strictEqual(wrapper.find('.testing').length, 1); + assert.strictEqual(wrapper.find('.testing').text(), 'TESTCOMPONENT'); + }); it('should render with an error class when props.error === true', function () { - const wrapper = shallow() + const wrapper = shallow(); - assert.ok(wrapper) - assert.strictEqual(wrapper.find('.unit-input--error').length, 1) - }) - }) + assert.ok(wrapper); + assert.strictEqual(wrapper.find('.unit-input--error').length, 1); + }); + }); describe('handling actions', function () { - const handleChangeSpy = sinon.spy() - const handleBlurSpy = sinon.spy() + const handleChangeSpy = sinon.spy(); + const handleBlurSpy = sinon.spy(); afterEach(function () { - handleChangeSpy.resetHistory() - handleBlurSpy.resetHistory() - }) + handleChangeSpy.resetHistory(); + handleBlurSpy.resetHistory(); + }); it('should focus the input on component click', function () { - const wrapper = mount() + const wrapper = mount(); - assert.ok(wrapper) - const handleFocusSpy = sinon.spy(wrapper.instance(), 'handleFocus') - wrapper.instance().forceUpdate() - wrapper.update() - assert.strictEqual(handleFocusSpy.callCount, 0) - wrapper.find('.unit-input').simulate('click') - assert.strictEqual(handleFocusSpy.callCount, 1) - }) + assert.ok(wrapper); + const handleFocusSpy = sinon.spy(wrapper.instance(), 'handleFocus'); + wrapper.instance().forceUpdate(); + wrapper.update(); + assert.strictEqual(handleFocusSpy.callCount, 0); + wrapper.find('.unit-input').simulate('click'); + assert.strictEqual(handleFocusSpy.callCount, 1); + }); it('should call onChange on input changes with the value', function () { - const wrapper = mount() + const wrapper = mount(); - assert.ok(wrapper) - assert.strictEqual(handleChangeSpy.callCount, 0) - const input = wrapper.find('input') - input.simulate('change', { target: { value: 123 } }) - assert.strictEqual(handleChangeSpy.callCount, 1) - assert.ok(handleChangeSpy.calledWith(123)) - assert.strictEqual(wrapper.state('value'), 123) - }) + assert.ok(wrapper); + assert.strictEqual(handleChangeSpy.callCount, 0); + const input = wrapper.find('input'); + input.simulate('change', { target: { value: 123 } }); + assert.strictEqual(handleChangeSpy.callCount, 1); + assert.ok(handleChangeSpy.calledWith(123)); + assert.strictEqual(wrapper.state('value'), 123); + }); it('should set the component state value with props.value', function () { - const wrapper = mount() + const wrapper = mount(); - assert.ok(wrapper) - assert.strictEqual(wrapper.state('value'), 123) - }) + assert.ok(wrapper); + assert.strictEqual(wrapper.state('value'), 123); + }); it('should update the component state value with props.value', function () { - const wrapper = mount() - - assert.ok(wrapper) - assert.strictEqual(handleChangeSpy.callCount, 0) - const input = wrapper.find('input') - input.simulate('change', { target: { value: 123 } }) - assert.strictEqual(wrapper.state('value'), 123) - assert.strictEqual(handleChangeSpy.callCount, 1) - assert.ok(handleChangeSpy.calledWith(123)) - wrapper.setProps({ value: 456 }) - assert.strictEqual(wrapper.state('value'), 456) - assert.strictEqual(handleChangeSpy.callCount, 1) - }) - }) -}) + const wrapper = mount(); + + assert.ok(wrapper); + assert.strictEqual(handleChangeSpy.callCount, 0); + const input = wrapper.find('input'); + input.simulate('change', { target: { value: 123 } }); + assert.strictEqual(wrapper.state('value'), 123); + assert.strictEqual(handleChangeSpy.callCount, 1); + assert.ok(handleChangeSpy.calledWith(123)); + wrapper.setProps({ value: 456 }); + assert.strictEqual(wrapper.state('value'), 456); + assert.strictEqual(handleChangeSpy.callCount, 1); + }); + }); +}); diff --git a/ui/app/components/ui/unit-input/unit-input.component.js b/ui/app/components/ui/unit-input/unit-input.component.js index 8155e242b1..8eeb39e1bb 100644 --- a/ui/app/components/ui/unit-input/unit-input.component.js +++ b/ui/app/components/ui/unit-input/unit-input.component.js @@ -1,7 +1,7 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { removeLeadingZeroes } from '../../../pages/send/send.utils' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import { removeLeadingZeroes } from '../../../pages/send/send.utils'; /** * Component that attaches a suffix or unit of measurement trailing user input, ex. 'ETH'. Also @@ -17,53 +17,59 @@ export default class UnitInput extends PureComponent { placeholder: PropTypes.string, suffix: PropTypes.string, value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - } + }; static defaultProps = { value: '', placeholder: '0', - } + }; state = { value: this.props.value, - } + }; componentDidUpdate(prevProps) { - const { value: prevPropsValue } = prevProps - const { value: propsValue } = this.props - const { value: stateValue } = this.state + const { value: prevPropsValue } = prevProps; + const { value: propsValue } = this.props; + const { value: stateValue } = this.state; if (prevPropsValue !== propsValue && propsValue !== stateValue) { - this.setState({ value: propsValue }) + this.setState({ value: propsValue }); } } handleFocus = () => { - this.unitInput.focus() - } + this.unitInput.focus(); + }; handleChange = (event) => { - const { value: userInput } = event.target - let value = userInput + const { value: userInput } = event.target; + let value = userInput; if (userInput.length && userInput.length > 1) { - value = removeLeadingZeroes(userInput) + value = removeLeadingZeroes(userInput); } - this.setState({ value }) - this.props.onChange(value) - } + this.setState({ value }); + this.props.onChange(value); + }; getInputWidth(value) { - const valueString = String(value) - const valueLength = valueString.length || 1 - const decimalPointDeficit = valueString.match(/\./u) ? -0.5 : 0 - return `${valueLength + decimalPointDeficit + 0.5}ch` + const valueString = String(value); + const valueLength = valueString.length || 1; + const decimalPointDeficit = valueString.match(/\./u) ? -0.5 : 0; + return `${valueLength + decimalPointDeficit + 0.5}ch`; } render() { - const { error, placeholder, suffix, actionComponent, children } = this.props - const { value } = this.state + const { + error, + placeholder, + suffix, + actionComponent, + children, + } = this.props; + const { value } = this.state; return (
    { - this.unitInput = ref + this.unitInput = ref; }} /> {suffix &&
    {suffix}
    } @@ -90,6 +96,6 @@ export default class UnitInput extends PureComponent {
    {actionComponent} - ) + ); } } diff --git a/ui/app/components/ui/url-icon/index.js b/ui/app/components/ui/url-icon/index.js index c1bfd9fd7a..6211d9f075 100644 --- a/ui/app/components/ui/url-icon/index.js +++ b/ui/app/components/ui/url-icon/index.js @@ -1 +1 @@ -export { default } from './url-icon' +export { default } from './url-icon'; diff --git a/ui/app/components/ui/url-icon/url-icon.js b/ui/app/components/ui/url-icon/url-icon.js index 115eb5fe1c..b8381fd873 100644 --- a/ui/app/components/ui/url-icon/url-icon.js +++ b/ui/app/components/ui/url-icon/url-icon.js @@ -1,7 +1,7 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import IconWithFallback from '../icon-with-fallback' +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import IconWithFallback from '../icon-with-fallback'; export default function UrlIcon({ url, className, name, fallbackClassName }) { return ( @@ -11,7 +11,7 @@ export default function UrlIcon({ url, className, name, fallbackClassName }) { name={name} fallbackClassName={classnames('url-icon__fallback', fallbackClassName)} /> - ) + ); } UrlIcon.propTypes = { @@ -19,4 +19,4 @@ UrlIcon.propTypes = { className: PropTypes.string, name: PropTypes.string, fallbackClassName: PropTypes.string, -} +}; diff --git a/ui/app/contexts/i18n.js b/ui/app/contexts/i18n.js index 86abd3fa0c..0c64815aa4 100644 --- a/ui/app/contexts/i18n.js +++ b/ui/app/contexts/i18n.js @@ -1,59 +1,61 @@ -import React, { Component, createContext, useMemo } from 'react' -import PropTypes from 'prop-types' -import { useSelector } from 'react-redux' -import { getMessage } from '../helpers/utils/i18n-helper' -import { getCurrentLocale } from '../ducks/metamask/metamask' +import React, { Component, createContext, useMemo } from 'react'; +import PropTypes from 'prop-types'; +import { useSelector } from 'react-redux'; +import { getMessage } from '../helpers/utils/i18n-helper'; +import { getCurrentLocale } from '../ducks/metamask/metamask'; import { getCurrentLocaleMessages, getEnLocaleMessages, -} from '../ducks/locale/locale' +} from '../ducks/locale/locale'; -export const I18nContext = createContext((key) => `[${key}]`) +export const I18nContext = createContext((key) => `[${key}]`); export const I18nProvider = (props) => { - const currentLocale = useSelector(getCurrentLocale) - const current = useSelector(getCurrentLocaleMessages) - const en = useSelector(getEnLocaleMessages) + const currentLocale = useSelector(getCurrentLocale); + const current = useSelector(getCurrentLocaleMessages); + const en = useSelector(getEnLocaleMessages); const t = useMemo(() => { return (key, ...args) => getMessage(currentLocale, current, key, ...args) || - getMessage(currentLocale, en, key, ...args) - }, [currentLocale, current, en]) + getMessage(currentLocale, en, key, ...args); + }, [currentLocale, current, en]); - return {props.children} -} + return ( + {props.children} + ); +}; I18nProvider.propTypes = { children: PropTypes.node, -} +}; I18nProvider.defaultProps = { children: undefined, -} +}; export class LegacyI18nProvider extends Component { static propTypes = { children: PropTypes.node, - } + }; static defaultProps = { children: undefined, - } + }; - static contextType = I18nContext + static contextType = I18nContext; static childContextTypes = { t: PropTypes.func, - } + }; getChildContext() { return { t: this.context, - } + }; } render() { - return this.props.children + return this.props.children; } } diff --git a/ui/app/contexts/metametrics.js b/ui/app/contexts/metametrics.js index 80d383a548..5940f1088c 100644 --- a/ui/app/contexts/metametrics.js +++ b/ui/app/contexts/metametrics.js @@ -4,45 +4,45 @@ import React, { useEffect, useCallback, useState, -} from 'react' -import { useSelector } from 'react-redux' -import PropTypes from 'prop-types' -import { useHistory } from 'react-router-dom' -import { captureException } from '@sentry/browser' +} from 'react'; +import { useSelector } from 'react-redux'; +import PropTypes from 'prop-types'; +import { useHistory } from 'react-router-dom'; +import { captureException } from '@sentry/browser'; import { getAccountType, getNumberOfAccounts, getNumberOfTokens, -} from '../selectors/selectors' -import { getSendToken } from '../selectors/send' -import { txDataSelector } from '../selectors/confirm-transaction' -import { getEnvironmentType } from '../../../app/scripts/lib/util' -import { trackMetaMetricsEvent } from '../store/actions' +} from '../selectors/selectors'; +import { getSendToken } from '../selectors/send'; +import { txDataSelector } from '../selectors/confirm-transaction'; +import { getEnvironmentType } from '../../../app/scripts/lib/util'; +import { trackMetaMetricsEvent } from '../store/actions'; export const MetaMetricsContext = createContext(() => { captureException( Error( `MetaMetrics context function was called from a react node that is not a descendant of a MetaMetrics context provider`, ), - ) -}) + ); +}); export function MetaMetricsProvider({ children }) { - const txData = useSelector(txDataSelector) || {} - const environmentType = getEnvironmentType() - const activeCurrency = useSelector(getSendToken)?.symbol - const accountType = useSelector(getAccountType) - const confirmTransactionOrigin = txData.origin - const numberOfTokens = useSelector(getNumberOfTokens) - const numberOfAccounts = useSelector(getNumberOfAccounts) - const history = useHistory() + const txData = useSelector(txDataSelector) || {}; + const environmentType = getEnvironmentType(); + const activeCurrency = useSelector(getSendToken)?.symbol; + const accountType = useSelector(getAccountType); + const confirmTransactionOrigin = txData.origin; + const numberOfTokens = useSelector(getNumberOfTokens); + const numberOfAccounts = useSelector(getNumberOfAccounts); + const history = useHistory(); const [state, setState] = useState(() => ({ currentPath: new URL(window.location.href).pathname, previousPath: '', - })) + })); - const { currentPath } = state + const { currentPath } = state; useEffect(() => { const unlisten = history.listen(() => @@ -50,20 +50,20 @@ export function MetaMetricsProvider({ children }) { currentPath: new URL(window.location.href).pathname, previousPath: prevState.currentPath, })), - ) + ); // remove this listener if the component is no longer mounted - return unlisten - }, [history]) + return unlisten; + }, [history]); const metricsEvent = useCallback( (config = {}, overrides = {}) => { - const { eventOpts = {} } = config + const { eventOpts = {} } = config; const referrer = confirmTransactionOrigin ? { url: confirmTransactionOrigin } - : undefined + : undefined; const page = { path: currentPath, - } + }; return trackMetaMetricsEvent( { event: eventOpts.name, @@ -96,7 +96,7 @@ export function MetaMetricsProvider({ children }) { matomoEvent: true, flushImmediately: config.flushImmediately, }, - ) + ); }, [ accountType, @@ -107,39 +107,39 @@ export function MetaMetricsProvider({ children }) { numberOfAccounts, environmentType, ], - ) + ); return ( {children} - ) + ); } -MetaMetricsProvider.propTypes = { children: PropTypes.node } +MetaMetricsProvider.propTypes = { children: PropTypes.node }; export class LegacyMetaMetricsProvider extends Component { static propTypes = { children: PropTypes.node, - } + }; static defaultProps = { children: undefined, - } + }; - static contextType = MetaMetricsContext + static contextType = MetaMetricsContext; static childContextTypes = { metricsEvent: PropTypes.func, - } + }; getChildContext() { return { metricsEvent: this.context, - } + }; } render() { - return this.props.children + return this.props.children; } } diff --git a/ui/app/contexts/metametrics.new.js b/ui/app/contexts/metametrics.new.js index ca39df1009..e46638c131 100644 --- a/ui/app/contexts/metametrics.new.js +++ b/ui/app/contexts/metametrics.new.js @@ -9,18 +9,18 @@ import React, { useEffect, useRef, useCallback, -} from 'react' -import { useSelector } from 'react-redux' -import PropTypes from 'prop-types' -import { matchPath, useLocation, useRouteMatch } from 'react-router-dom' -import { captureException, captureMessage } from '@sentry/browser' +} from 'react'; +import { useSelector } from 'react-redux'; +import PropTypes from 'prop-types'; +import { matchPath, useLocation, useRouteMatch } from 'react-router-dom'; +import { captureException, captureMessage } from '@sentry/browser'; -import { omit } from 'lodash' -import { getEnvironmentType } from '../../../app/scripts/lib/util' -import { PATH_NAME_MAP } from '../helpers/constants/routes' -import { txDataSelector } from '../selectors' +import { omit } from 'lodash'; +import { getEnvironmentType } from '../../../app/scripts/lib/util'; +import { PATH_NAME_MAP } from '../helpers/constants/routes'; +import { txDataSelector } from '../selectors'; -import { trackMetaMetricsEvent, trackMetaMetricsPage } from '../store/actions' +import { trackMetaMetricsEvent, trackMetaMetricsPage } from '../store/actions'; // type imports /** @@ -49,10 +49,10 @@ export const MetaMetricsContext = createContext(() => { Error( `MetaMetrics context function was called from a react node that is not a descendant of a MetaMetrics context provider`, ), - ) -}) + ); +}); -const PATHS_TO_CHECK = Object.keys(PATH_NAME_MAP) +const PATHS_TO_CHECK = Object.keys(PATH_NAME_MAP); /** * Returns the current page if it matches out route map, as well as the origin @@ -67,15 +67,15 @@ function useSegmentContext() { path: PATHS_TO_CHECK, exact: true, strict: true, - }) - const txData = useSelector(txDataSelector) || {} - const confirmTransactionOrigin = txData.origin + }); + const txData = useSelector(txDataSelector) || {}; + const confirmTransactionOrigin = txData.origin; const referrer = confirmTransactionOrigin ? { url: confirmTransactionOrigin, } - : undefined + : undefined; const page = match ? { @@ -83,17 +83,17 @@ function useSegmentContext() { title: PATH_NAME_MAP[match.path], url: match.path, } - : undefined + : undefined; return { page, referrer, - } + }; } export function MetaMetricsProvider({ children }) { - const location = useLocation() - const context = useSegmentContext() + const location = useLocation(); + const context = useSegmentContext(); /** * @type {UITrackEventMethod} @@ -107,13 +107,13 @@ export function MetaMetricsProvider({ children }) { ...context, }, options, - ) + ); }, [context], - ) + ); // Used to prevent double tracking page calls - const previousMatch = useRef() + const previousMatch = useRef(); /** * Anytime the location changes, track a page change with segment. @@ -122,12 +122,12 @@ export function MetaMetricsProvider({ children }) { * which page the user is on and their navigation path. */ useEffect(() => { - const environmentType = getEnvironmentType() + const environmentType = getEnvironmentType(); const match = matchPath(location.pathname, { path: PATHS_TO_CHECK, exact: true, strict: true, - }) + }); // Start by checking for a missing match route. If this falls through to // the else if, then we know we have a matched route for tracking. if (!match) { @@ -136,7 +136,7 @@ export function MetaMetricsProvider({ children }) { previousMatch, currentPath: location.pathname, }, - }) + }); } else if ( previousMatch.current !== match.path && !( @@ -150,8 +150,8 @@ export function MetaMetricsProvider({ children }) { // this we keep track of the previousMatch, and we skip the event track // in the event that we are dealing with the initial load of the // homepage - const { path, params } = match - const name = PATH_NAME_MAP[path] + const { path, params } = match; + const name = PATH_NAME_MAP[path]; trackMetaMetricsPage( { name, @@ -165,45 +165,45 @@ export function MetaMetricsProvider({ children }) { { isOptInPath: location.pathname.startsWith('/initialize'), }, - ) + ); } - previousMatch.current = match?.path - }, [location, context]) + previousMatch.current = match?.path; + }, [location, context]); return ( {children} - ) + ); } -MetaMetricsProvider.propTypes = { children: PropTypes.node } +MetaMetricsProvider.propTypes = { children: PropTypes.node }; export class LegacyMetaMetricsProvider extends Component { static propTypes = { children: PropTypes.node, - } + }; static defaultProps = { children: undefined, - } + }; - static contextType = MetaMetricsContext + static contextType = MetaMetricsContext; static childContextTypes = { // This has to be different than the type name for the old metametrics file // using the same name would result in whichever was lower in the tree to be // used. trackEvent: PropTypes.func, - } + }; getChildContext() { return { trackEvent: this.context, - } + }; } render() { - return this.props.children + return this.props.children; } } diff --git a/ui/app/ducks/alerts/enums.js b/ui/app/ducks/alerts/enums.js index 9a2267e520..b9192d8464 100644 --- a/ui/app/ducks/alerts/enums.js +++ b/ui/app/ducks/alerts/enums.js @@ -3,4 +3,4 @@ export const ALERT_STATE = { ERROR: 'ERROR', LOADING: 'LOADING', OPEN: 'OPEN', -} +}; diff --git a/ui/app/ducks/alerts/index.js b/ui/app/ducks/alerts/index.js index d7387326b9..28dd8c8976 100644 --- a/ui/app/ducks/alerts/index.js +++ b/ui/app/ducks/alerts/index.js @@ -1,4 +1,4 @@ -export { default as unconnectedAccount } from './unconnected-account' -export { default as invalidCustomNetwork } from './invalid-custom-network' +export { default as unconnectedAccount } from './unconnected-account'; +export { default as invalidCustomNetwork } from './invalid-custom-network'; -export { ALERT_STATE } from './enums' +export { ALERT_STATE } from './enums'; diff --git a/ui/app/ducks/alerts/invalid-custom-network.js b/ui/app/ducks/alerts/invalid-custom-network.js index be2aa20e18..ab033ed463 100644 --- a/ui/app/ducks/alerts/invalid-custom-network.js +++ b/ui/app/ducks/alerts/invalid-custom-network.js @@ -1,16 +1,16 @@ -import { createSlice } from '@reduxjs/toolkit' +import { createSlice } from '@reduxjs/toolkit'; -import { ALERT_TYPES } from '../../../../shared/constants/alerts' -import { ALERT_STATE } from './enums' +import { ALERT_TYPES } from '../../../../shared/constants/alerts'; +import { ALERT_STATE } from './enums'; // Constants -const name = ALERT_TYPES.invalidCustomNetwork +const name = ALERT_TYPES.invalidCustomNetwork; const initialState = { state: ALERT_STATE.CLOSED, networkName: '', -} +}; // Slice (reducer plus auto-generated actions and action creators) @@ -19,30 +19,30 @@ const slice = createSlice({ initialState, reducers: { openAlert: (state, action) => { - state.state = ALERT_STATE.OPEN - state.networkName = action.payload + state.state = ALERT_STATE.OPEN; + state.networkName = action.payload; }, dismissAlert: (state) => { - state.state = ALERT_STATE.CLOSED - state.networkName = '' + state.state = ALERT_STATE.CLOSED; + state.networkName = ''; }, }, -}) +}); -const { actions, reducer } = slice +const { actions, reducer } = slice; -export default reducer +export default reducer; // Selectors -export const getAlertState = (state) => state[name].state +export const getAlertState = (state) => state[name].state; -export const getNetworkName = (state) => state[name].networkName +export const getNetworkName = (state) => state[name].networkName; -export const alertIsOpen = (state) => state[name].state !== ALERT_STATE.CLOSED +export const alertIsOpen = (state) => state[name].state !== ALERT_STATE.CLOSED; // Actions / action-creators -const { openAlert, dismissAlert } = actions +const { openAlert, dismissAlert } = actions; -export { openAlert, dismissAlert } +export { openAlert, dismissAlert }; diff --git a/ui/app/ducks/alerts/unconnected-account.js b/ui/app/ducks/alerts/unconnected-account.js index 563af43d25..2020def25e 100644 --- a/ui/app/ducks/alerts/unconnected-account.js +++ b/ui/app/ducks/alerts/unconnected-account.js @@ -1,23 +1,23 @@ -import { createSlice } from '@reduxjs/toolkit' -import { captureException } from '@sentry/browser' +import { createSlice } from '@reduxjs/toolkit'; +import { captureException } from '@sentry/browser'; -import { ALERT_TYPES } from '../../../../shared/constants/alerts' -import * as actionConstants from '../../store/actionConstants' +import { ALERT_TYPES } from '../../../../shared/constants/alerts'; +import * as actionConstants from '../../store/actionConstants'; import { addPermittedAccount, setAlertEnabledness, setSelectedAddress, -} from '../../store/actions' -import { getOriginOfCurrentTab, getSelectedAddress } from '../../selectors' -import { ALERT_STATE } from './enums' +} from '../../store/actions'; +import { getOriginOfCurrentTab, getSelectedAddress } from '../../selectors'; +import { ALERT_STATE } from './enums'; // Constants -const name = ALERT_TYPES.unconnectedAccount +const name = ALERT_TYPES.unconnectedAccount; const initialState = { state: ALERT_STATE.CLOSED, -} +}; // Slice (reducer plus auto-generated actions and action creators) @@ -26,58 +26,58 @@ const slice = createSlice({ initialState, reducers: { connectAccountFailed: (state) => { - state.state = ALERT_STATE.ERROR + state.state = ALERT_STATE.ERROR; }, connectAccountRequested: (state) => { - state.state = ALERT_STATE.LOADING + state.state = ALERT_STATE.LOADING; }, connectAccountSucceeded: (state) => { - state.state = ALERT_STATE.CLOSED + state.state = ALERT_STATE.CLOSED; }, disableAlertFailed: (state) => { - state.state = ALERT_STATE.ERROR + state.state = ALERT_STATE.ERROR; }, disableAlertRequested: (state) => { - state.state = ALERT_STATE.LOADING + state.state = ALERT_STATE.LOADING; }, disableAlertSucceeded: (state) => { - state.state = ALERT_STATE.CLOSED + state.state = ALERT_STATE.CLOSED; }, dismissAlert: (state) => { - state.state = ALERT_STATE.CLOSED + state.state = ALERT_STATE.CLOSED; }, switchAccountFailed: (state) => { - state.state = ALERT_STATE.ERROR + state.state = ALERT_STATE.ERROR; }, switchAccountRequested: (state) => { - state.state = ALERT_STATE.LOADING + state.state = ALERT_STATE.LOADING; }, switchAccountSucceeded: (state) => { - state.state = ALERT_STATE.CLOSED + state.state = ALERT_STATE.CLOSED; }, switchedToUnconnectedAccount: (state) => { - state.state = ALERT_STATE.OPEN + state.state = ALERT_STATE.OPEN; }, }, extraReducers: { [actionConstants.SELECTED_ADDRESS_CHANGED]: (state) => { // close the alert if the account is switched while it's open if (state.state === ALERT_STATE.OPEN) { - state.state = ALERT_STATE.CLOSED + state.state = ALERT_STATE.CLOSED; } }, }, -}) +}); -const { actions, reducer } = slice +const { actions, reducer } = slice; -export default reducer +export default reducer; // Selectors -export const getAlertState = (state) => state[name].state +export const getAlertState = (state) => state[name].state; -export const alertIsOpen = (state) => state[name].state !== ALERT_STATE.CLOSED +export const alertIsOpen = (state) => state[name].state !== ALERT_STATE.CLOSED; // Actions / action-creators @@ -93,51 +93,51 @@ const { switchAccountRequested, switchAccountSucceeded, switchedToUnconnectedAccount, -} = actions +} = actions; -export { dismissAlert, switchedToUnconnectedAccount } +export { dismissAlert, switchedToUnconnectedAccount }; export const dismissAndDisableAlert = () => { return async (dispatch) => { try { - await dispatch(disableAlertRequested()) - await setAlertEnabledness(name, false) - await dispatch(disableAlertSucceeded()) + await dispatch(disableAlertRequested()); + await setAlertEnabledness(name, false); + await dispatch(disableAlertSucceeded()); } catch (error) { - console.error(error) - captureException(error) - await dispatch(disableAlertFailed()) + console.error(error); + captureException(error); + await dispatch(disableAlertFailed()); } - } -} + }; +}; export const switchToAccount = (address) => { return async (dispatch) => { try { - await dispatch(switchAccountRequested()) - await dispatch(setSelectedAddress(address)) - await dispatch(switchAccountSucceeded()) + await dispatch(switchAccountRequested()); + await dispatch(setSelectedAddress(address)); + await dispatch(switchAccountSucceeded()); } catch (error) { - console.error(error) - captureException(error) - await dispatch(switchAccountFailed()) + console.error(error); + captureException(error); + await dispatch(switchAccountFailed()); } - } -} + }; +}; export const connectAccount = () => { return async (dispatch, getState) => { - const state = getState() - const selectedAddress = getSelectedAddress(state) - const origin = getOriginOfCurrentTab(state) + const state = getState(); + const selectedAddress = getSelectedAddress(state); + const origin = getOriginOfCurrentTab(state); try { - await dispatch(connectAccountRequested()) - await dispatch(addPermittedAccount(origin, selectedAddress)) - await dispatch(connectAccountSucceeded()) + await dispatch(connectAccountRequested()); + await dispatch(addPermittedAccount(origin, selectedAddress)); + await dispatch(connectAccountSucceeded()); } catch (error) { - console.error(error) - captureException(error) - await dispatch(connectAccountFailed()) + console.error(error); + captureException(error); + await dispatch(connectAccountFailed()); } - } -} + }; +}; diff --git a/ui/app/ducks/app/app.js b/ui/app/ducks/app/app.js index 06f194a174..c927e70c98 100644 --- a/ui/app/ducks/app/app.js +++ b/ui/app/ducks/app/app.js @@ -1,7 +1,7 @@ -import * as actionConstants from '../../store/actionConstants' +import * as actionConstants from '../../store/actionConstants'; // actionConstants -const SET_THREEBOX_LAST_UPDATED = 'metamask/app/SET_THREEBOX_LAST_UPDATED' +const SET_THREEBOX_LAST_UPDATED = 'metamask/app/SET_THREEBOX_LAST_UPDATED'; export default function reduceApp(state = {}, action) { // default state @@ -51,7 +51,7 @@ export default function reduceApp(state = {}, action) { openMetaMaskTabs: {}, currentWindowTab: {}, ...state, - } + }; switch (action.type) { // dropdown methods @@ -59,13 +59,13 @@ export default function reduceApp(state = {}, action) { return { ...appState, networkDropdownOpen: true, - } + }; case actionConstants.NETWORK_DROPDOWN_CLOSE: return { ...appState, networkDropdownOpen: false, - } + }; // sidebar methods case actionConstants.SIDEBAR_OPEN: @@ -75,7 +75,7 @@ export default function reduceApp(state = {}, action) { ...action.value, isOpen: true, }, - } + }; case actionConstants.SIDEBAR_CLOSE: return { @@ -84,7 +84,7 @@ export default function reduceApp(state = {}, action) { ...appState.sidebar, isOpen: false, }, - } + }; // alert methods case actionConstants.ALERT_OPEN: @@ -92,25 +92,25 @@ export default function reduceApp(state = {}, action) { ...appState, alertOpen: true, alertMessage: action.value, - } + }; case actionConstants.ALERT_CLOSE: return { ...appState, alertOpen: false, alertMessage: null, - } + }; // qr scanner methods case actionConstants.QR_CODE_DETECTED: return { ...appState, qrCodeData: action.value, - } + }; // modal methods: case actionConstants.MODAL_OPEN: { - const { name, ...modalProps } = action.payload + const { name, ...modalProps } = action.payload; return { ...appState, @@ -122,7 +122,7 @@ export default function reduceApp(state = {}, action) { }, previousModalState: { ...appState.modal.modalState }, }, - } + }; } case actionConstants.MODAL_CLOSE: @@ -134,31 +134,31 @@ export default function reduceApp(state = {}, action) { { modalState: { name: null, props: {} } }, { previousModalState: appState.modal.modalState }, ), - } + }; case actionConstants.CLEAR_ACCOUNT_DETAILS: return { ...appState, accountDetail: {}, - } + }; case actionConstants.FORGOT_PASSWORD: return { ...appState, forgottenPassword: action.value, - } + }; case actionConstants.SHOW_SEND_TOKEN_PAGE: return { ...appState, warning: null, - } + }; case actionConstants.LOCK_METAMASK: return { ...appState, warning: null, - } + }; // accounts @@ -171,7 +171,7 @@ export default function reduceApp(state = {}, action) { privateKey: '', }, warning: null, - } + }; case actionConstants.SHOW_ACCOUNT_DETAIL: return { @@ -184,7 +184,7 @@ export default function reduceApp(state = {}, action) { accountExport: 'none', privateKey: '', }, - } + }; case actionConstants.SHOW_ACCOUNTS_PAGE: return { @@ -193,7 +193,7 @@ export default function reduceApp(state = {}, action) { warning: null, scrollToBottom: false, forgottenPassword: false, - } + }; case actionConstants.SHOW_CONF_TX_PAGE: return { @@ -201,7 +201,7 @@ export default function reduceApp(state = {}, action) { txId: action.id, warning: null, isLoading: false, - } + }; case actionConstants.COMPLETED_TX: if (action.value.unconfirmedActionsCount > 0) { @@ -209,7 +209,7 @@ export default function reduceApp(state = {}, action) { ...appState, txId: null, warning: null, - } + }; } return { ...appState, @@ -220,34 +220,34 @@ export default function reduceApp(state = {}, action) { accountDetail: { subview: 'transactions', }, - } + }; case actionConstants.TRANSACTION_ERROR: return { ...appState, - } + }; case actionConstants.UNLOCK_FAILED: return { ...appState, warning: action.value || 'Incorrect password. Try again.', - } + }; case actionConstants.UNLOCK_SUCCEEDED: return { ...appState, warning: '', - } + }; case actionConstants.SET_HARDWARE_WALLET_DEFAULT_HD_PATH: { - const { device, path } = action.value - const newDefaults = { ...appState.defaultHdPaths } - newDefaults[device] = path + const { device, path } = action.value; + const newDefaults = { ...appState.defaultHdPaths }; + newDefaults[device] = path; return { ...appState, defaultHdPaths: newDefaults, - } + }; } case actionConstants.SHOW_LOADING: @@ -255,26 +255,26 @@ export default function reduceApp(state = {}, action) { ...appState, isLoading: true, loadingMessage: action.value, - } + }; case actionConstants.HIDE_LOADING: return { ...appState, isLoading: false, - } + }; case actionConstants.DISPLAY_WARNING: return { ...appState, warning: action.value, isLoading: false, - } + }; case actionConstants.HIDE_WARNING: return { ...appState, warning: undefined, - } + }; case actionConstants.SHOW_PRIVATE_KEY: return { @@ -284,76 +284,76 @@ export default function reduceApp(state = {}, action) { accountExport: 'completed', privateKey: action.value, }, - } + }; case actionConstants.SET_MOUSE_USER_STATE: return { ...appState, isMouseUser: action.value, - } + }; case actionConstants.GAS_LOADING_STARTED: return { ...appState, gasIsLoading: true, - } + }; case actionConstants.GAS_LOADING_FINISHED: return { ...appState, gasIsLoading: false, - } + }; case actionConstants.SET_SELECTED_SETTINGS_RPC_URL: return { ...appState, networksTabSelectedRpcUrl: action.value, - } + }; case actionConstants.SET_NETWORKS_TAB_ADD_MODE: return { ...appState, networksTabIsInAddMode: action.value, - } + }; case actionConstants.LOADING_METHOD_DATA_STARTED: return { ...appState, loadingMethodData: true, - } + }; case actionConstants.LOADING_METHOD_DATA_FINISHED: return { ...appState, loadingMethodData: false, - } + }; case SET_THREEBOX_LAST_UPDATED: return { ...appState, threeBoxLastUpdated: action.value, - } + }; case actionConstants.SET_REQUEST_ACCOUNT_TABS: return { ...appState, requestAccountTabs: action.value, - } + }; case actionConstants.SET_OPEN_METAMASK_TAB_IDS: return { ...appState, openMetaMaskTabs: action.value, - } + }; case actionConstants.SET_CURRENT_WINDOW_TAB: return { ...appState, currentWindowTab: action.value, - } + }; default: - return appState + return appState; } } @@ -362,5 +362,5 @@ export function setThreeBoxLastUpdated(lastUpdated) { return { type: SET_THREEBOX_LAST_UPDATED, value: lastUpdated, - } + }; } diff --git a/ui/app/ducks/confirm-transaction/confirm-transaction.duck.js b/ui/app/ducks/confirm-transaction/confirm-transaction.duck.js index 5125f17d98..a89eeae36a 100644 --- a/ui/app/ducks/confirm-transaction/confirm-transaction.duck.js +++ b/ui/app/ducks/confirm-transaction/confirm-transaction.duck.js @@ -1,10 +1,10 @@ -import { addHexPrefix } from '../../../../app/scripts/lib/util' +import { addHexPrefix } from '../../../../app/scripts/lib/util'; import { conversionRateSelector, currentCurrencySelector, unconfirmedTransactionsHashSelector, getNativeCurrency, -} from '../../selectors' +} from '../../selectors'; import { getValueFromWeiHex, @@ -14,32 +14,32 @@ import { addEth, increaseLastGasPrice, hexGreaterThan, -} from '../../helpers/utils/confirm-tx.util' +} from '../../helpers/utils/confirm-tx.util'; -import { getTokenData, sumHexes } from '../../helpers/utils/transactions.util' +import { getTokenData, sumHexes } from '../../helpers/utils/transactions.util'; -import { conversionUtil } from '../../helpers/utils/conversion-util' +import { conversionUtil } from '../../helpers/utils/conversion-util'; // Actions -const createActionType = (action) => `metamask/confirm-transaction/${action}` - -const UPDATE_TX_DATA = createActionType('UPDATE_TX_DATA') -const CLEAR_TX_DATA = createActionType('CLEAR_TX_DATA') -const UPDATE_TOKEN_DATA = createActionType('UPDATE_TOKEN_DATA') -const CLEAR_TOKEN_DATA = createActionType('CLEAR_TOKEN_DATA') -const UPDATE_METHOD_DATA = createActionType('UPDATE_METHOD_DATA') -const CLEAR_METHOD_DATA = createActionType('CLEAR_METHOD_DATA') -const CLEAR_CONFIRM_TRANSACTION = createActionType('CLEAR_CONFIRM_TRANSACTION') +const createActionType = (action) => `metamask/confirm-transaction/${action}`; + +const UPDATE_TX_DATA = createActionType('UPDATE_TX_DATA'); +const CLEAR_TX_DATA = createActionType('CLEAR_TX_DATA'); +const UPDATE_TOKEN_DATA = createActionType('UPDATE_TOKEN_DATA'); +const CLEAR_TOKEN_DATA = createActionType('CLEAR_TOKEN_DATA'); +const UPDATE_METHOD_DATA = createActionType('UPDATE_METHOD_DATA'); +const CLEAR_METHOD_DATA = createActionType('CLEAR_METHOD_DATA'); +const CLEAR_CONFIRM_TRANSACTION = createActionType('CLEAR_CONFIRM_TRANSACTION'); const UPDATE_TRANSACTION_AMOUNTS = createActionType( 'UPDATE_TRANSACTION_AMOUNTS', -) -const UPDATE_TRANSACTION_FEES = createActionType('UPDATE_TRANSACTION_FEES') -const UPDATE_TRANSACTION_TOTALS = createActionType('UPDATE_TRANSACTION_TOTALS') -const UPDATE_TOKEN_PROPS = createActionType('UPDATE_TOKEN_PROPS') -const UPDATE_NONCE = createActionType('UPDATE_NONCE') -const UPDATE_TO_SMART_CONTRACT = createActionType('UPDATE_TO_SMART_CONTRACT') -const FETCH_DATA_START = createActionType('FETCH_DATA_START') -const FETCH_DATA_END = createActionType('FETCH_DATA_END') +); +const UPDATE_TRANSACTION_FEES = createActionType('UPDATE_TRANSACTION_FEES'); +const UPDATE_TRANSACTION_TOTALS = createActionType('UPDATE_TRANSACTION_TOTALS'); +const UPDATE_TOKEN_PROPS = createActionType('UPDATE_TOKEN_PROPS'); +const UPDATE_NONCE = createActionType('UPDATE_NONCE'); +const UPDATE_TO_SMART_CONTRACT = createActionType('UPDATE_TO_SMART_CONTRACT'); +const FETCH_DATA_START = createActionType('FETCH_DATA_START'); +const FETCH_DATA_END = createActionType('FETCH_DATA_END'); // Initial state const initState = { @@ -62,7 +62,7 @@ const initState = { nonce: '', toSmartContract: false, fetchingData: false, -} +}; // Reducer export default function reducer(state = initState, action = {}) { @@ -73,42 +73,42 @@ export default function reducer(state = initState, action = {}) { txData: { ...action.payload, }, - } + }; case CLEAR_TX_DATA: return { ...state, txData: {}, - } + }; case UPDATE_TOKEN_DATA: return { ...state, tokenData: { ...action.payload, }, - } + }; case CLEAR_TOKEN_DATA: return { ...state, tokenData: {}, - } + }; case UPDATE_METHOD_DATA: return { ...state, methodData: { ...action.payload, }, - } + }; case CLEAR_METHOD_DATA: return { ...state, methodData: {}, - } + }; case UPDATE_TRANSACTION_AMOUNTS: { const { fiatTransactionAmount, ethTransactionAmount, hexTransactionAmount, - } = action.payload + } = action.payload; return { ...state, fiatTransactionAmount: @@ -117,37 +117,37 @@ export default function reducer(state = initState, action = {}) { ethTransactionAmount || state.ethTransactionAmount, hexTransactionAmount: hexTransactionAmount || state.hexTransactionAmount, - } + }; } case UPDATE_TRANSACTION_FEES: { const { fiatTransactionFee, ethTransactionFee, hexTransactionFee, - } = action.payload + } = action.payload; return { ...state, fiatTransactionFee: fiatTransactionFee || state.fiatTransactionFee, ethTransactionFee: ethTransactionFee || state.ethTransactionFee, hexTransactionFee: hexTransactionFee || state.hexTransactionFee, - } + }; } case UPDATE_TRANSACTION_TOTALS: { const { fiatTransactionTotal, ethTransactionTotal, hexTransactionTotal, - } = action.payload + } = action.payload; return { ...state, fiatTransactionTotal: fiatTransactionTotal || state.fiatTransactionTotal, ethTransactionTotal: ethTransactionTotal || state.ethTransactionTotal, hexTransactionTotal: hexTransactionTotal || state.hexTransactionTotal, - } + }; } case UPDATE_TOKEN_PROPS: { - const { tokenSymbol = '', tokenDecimals = '' } = action.payload + const { tokenSymbol = '', tokenDecimals = '' } = action.payload; return { ...state, tokenProps: { @@ -155,32 +155,32 @@ export default function reducer(state = initState, action = {}) { tokenSymbol, tokenDecimals, }, - } + }; } case UPDATE_NONCE: return { ...state, nonce: action.payload, - } + }; case UPDATE_TO_SMART_CONTRACT: return { ...state, toSmartContract: action.payload, - } + }; case FETCH_DATA_START: return { ...state, fetchingData: true, - } + }; case FETCH_DATA_END: return { ...state, fetchingData: false, - } + }; case CLEAR_CONFIRM_TRANSACTION: - return initState + return initState; default: - return state + return state; } } @@ -189,94 +189,94 @@ export function updateTxData(txData) { return { type: UPDATE_TX_DATA, payload: txData, - } + }; } export function clearTxData() { return { type: CLEAR_TX_DATA, - } + }; } export function updateTokenData(tokenData) { return { type: UPDATE_TOKEN_DATA, payload: tokenData, - } + }; } export function clearTokenData() { return { type: CLEAR_TOKEN_DATA, - } + }; } export function updateMethodData(methodData) { return { type: UPDATE_METHOD_DATA, payload: methodData, - } + }; } export function clearMethodData() { return { type: CLEAR_METHOD_DATA, - } + }; } export function updateTransactionAmounts(amounts) { return { type: UPDATE_TRANSACTION_AMOUNTS, payload: amounts, - } + }; } export function updateTransactionFees(fees) { return { type: UPDATE_TRANSACTION_FEES, payload: fees, - } + }; } export function updateTransactionTotals(totals) { return { type: UPDATE_TRANSACTION_TOTALS, payload: totals, - } + }; } export function updateTokenProps(tokenProps) { return { type: UPDATE_TOKEN_PROPS, payload: tokenProps, - } + }; } export function updateNonce(nonce) { return { type: UPDATE_NONCE, payload: nonce, - } + }; } export function updateToSmartContract(toSmartContract) { return { type: UPDATE_TO_SMART_CONTRACT, payload: toSmartContract, - } + }; } export function setFetchingData(isFetching) { return { type: isFetching ? FETCH_DATA_START : FETCH_DATA_END, - } + }; } export function updateGasAndCalculate({ gasLimit, gasPrice }) { return (dispatch, getState) => { const { confirmTransaction: { txData }, - } = getState() + } = getState(); const newTxData = { ...txData, txParams: { @@ -284,22 +284,28 @@ export function updateGasAndCalculate({ gasLimit, gasPrice }) { gas: addHexPrefix(gasLimit), gasPrice: addHexPrefix(gasPrice), }, - } + }; - dispatch(updateTxDataAndCalculate(newTxData)) - } + dispatch(updateTxDataAndCalculate(newTxData)); + }; } function increaseFromLastGasPrice(txData) { - const { lastGasPrice, txParams: { gasPrice: previousGasPrice } = {} } = txData + const { + lastGasPrice, + txParams: { gasPrice: previousGasPrice } = {}, + } = txData; // Set the minimum to a 10% increase from the lastGasPrice. - const minimumGasPrice = increaseLastGasPrice(lastGasPrice) - const gasPriceBelowMinimum = hexGreaterThan(minimumGasPrice, previousGasPrice) + const minimumGasPrice = increaseLastGasPrice(lastGasPrice); + const gasPriceBelowMinimum = hexGreaterThan( + minimumGasPrice, + previousGasPrice, + ); const gasPrice = !previousGasPrice || gasPriceBelowMinimum ? minimumGasPrice - : previousGasPrice + : previousGasPrice; return { ...txData, @@ -307,21 +313,21 @@ function increaseFromLastGasPrice(txData) { ...txData.txParams, gasPrice, }, - } + }; } export function updateTxDataAndCalculate(txData) { return (dispatch, getState) => { - const state = getState() - const currentCurrency = currentCurrencySelector(state) - const conversionRate = conversionRateSelector(state) - const nativeCurrency = getNativeCurrency(state) + const state = getState(); + const currentCurrency = currentCurrencySelector(state); + const conversionRate = conversionRateSelector(state); + const nativeCurrency = getNativeCurrency(state); - dispatch(updateTxData(txData)) + dispatch(updateTxData(txData)); const { txParams: { value = '0x0', gas: gasLimit = '0x0', gasPrice = '0x0' } = {}, - } = txData + } = txData; const fiatTransactionAmount = getValueFromWeiHex({ value, @@ -329,14 +335,14 @@ export function updateTxDataAndCalculate(txData) { toCurrency: currentCurrency, conversionRate, numberOfDecimals: 2, - }) + }); const ethTransactionAmount = getValueFromWeiHex({ value, fromCurrency: nativeCurrency, toCurrency: nativeCurrency, conversionRate, numberOfDecimals: 6, - }) + }); dispatch( updateTransactionAmounts({ @@ -344,9 +350,9 @@ export function updateTxDataAndCalculate(txData) { ethTransactionAmount, hexTransactionAmount: value, }), - ) + ); - const hexTransactionFee = getHexGasTotal({ gasLimit, gasPrice }) + const hexTransactionFee = getHexGasTotal({ gasLimit, gasPrice }); const fiatTransactionFee = getTransactionFee({ value: hexTransactionFee, @@ -354,14 +360,14 @@ export function updateTxDataAndCalculate(txData) { toCurrency: currentCurrency, numberOfDecimals: 2, conversionRate, - }) + }); const ethTransactionFee = getTransactionFee({ value: hexTransactionFee, fromCurrency: nativeCurrency, toCurrency: nativeCurrency, numberOfDecimals: 6, conversionRate, - }) + }); dispatch( updateTransactionFees({ @@ -369,14 +375,14 @@ export function updateTxDataAndCalculate(txData) { ethTransactionFee, hexTransactionFee, }), - ) + ); const fiatTransactionTotal = addFiat( fiatTransactionFee, fiatTransactionAmount, - ) - const ethTransactionTotal = addEth(ethTransactionFee, ethTransactionAmount) - const hexTransactionTotal = sumHexes(value, hexTransactionFee) + ); + const ethTransactionTotal = addEth(ethTransactionFee, ethTransactionAmount); + const hexTransactionTotal = sumHexes(value, hexTransactionFee); dispatch( updateTransactionTotals({ @@ -384,55 +390,55 @@ export function updateTxDataAndCalculate(txData) { ethTransactionTotal, hexTransactionTotal, }), - ) - } + ); + }; } export function setTransactionToConfirm(transactionId) { return (dispatch, getState) => { - const state = getState() + const state = getState(); const unconfirmedTransactionsHash = unconfirmedTransactionsHashSelector( state, - ) - const transaction = unconfirmedTransactionsHash[transactionId] + ); + const transaction = unconfirmedTransactionsHash[transactionId]; if (!transaction) { - console.error(`Transaction with id ${transactionId} not found`) - return + console.error(`Transaction with id ${transactionId} not found`); + return; } if (transaction.txParams) { - const { lastGasPrice } = transaction + const { lastGasPrice } = transaction; const txData = lastGasPrice ? increaseFromLastGasPrice(transaction) - : transaction - dispatch(updateTxDataAndCalculate(txData)) + : transaction; + dispatch(updateTxDataAndCalculate(txData)); - const { txParams } = transaction + const { txParams } = transaction; if (txParams.data) { - const { data } = txParams + const { data } = txParams; - const tokenData = getTokenData(data) - dispatch(updateTokenData(tokenData)) + const tokenData = getTokenData(data); + dispatch(updateTokenData(tokenData)); } if (txParams.nonce) { const nonce = conversionUtil(txParams.nonce, { fromNumericBase: 'hex', toNumericBase: 'dec', - }) + }); - dispatch(updateNonce(nonce)) + dispatch(updateNonce(nonce)); } } else { - dispatch(updateTxData(transaction)) + dispatch(updateTxData(transaction)); } - } + }; } export function clearConfirmTransaction() { return { type: CLEAR_CONFIRM_TRANSACTION, - } + }; } diff --git a/ui/app/ducks/confirm-transaction/confirm-transaction.duck.test.js b/ui/app/ducks/confirm-transaction/confirm-transaction.duck.test.js index f5edaa67fd..6f512a7033 100644 --- a/ui/app/ducks/confirm-transaction/confirm-transaction.duck.test.js +++ b/ui/app/ducks/confirm-transaction/confirm-transaction.duck.test.js @@ -1,13 +1,13 @@ -import assert from 'assert' -import configureMockStore from 'redux-mock-store' -import thunk from 'redux-thunk' -import sinon from 'sinon' +import assert from 'assert'; +import configureMockStore from 'redux-mock-store'; +import thunk from 'redux-thunk'; +import sinon from 'sinon'; import { TRANSACTION_CATEGORIES, TRANSACTION_STATUSES, -} from '../../../../shared/constants/transaction' +} from '../../../../shared/constants/transaction'; -import ConfirmTransactionReducer, * as actions from './confirm-transaction.duck' +import ConfirmTransactionReducer, * as actions from './confirm-transaction.duck'; const initialState = { txData: {}, @@ -29,28 +29,28 @@ const initialState = { nonce: '', toSmartContract: false, fetchingData: false, -} - -const UPDATE_TX_DATA = 'metamask/confirm-transaction/UPDATE_TX_DATA' -const CLEAR_TX_DATA = 'metamask/confirm-transaction/CLEAR_TX_DATA' -const UPDATE_TOKEN_DATA = 'metamask/confirm-transaction/UPDATE_TOKEN_DATA' -const CLEAR_TOKEN_DATA = 'metamask/confirm-transaction/CLEAR_TOKEN_DATA' -const UPDATE_METHOD_DATA = 'metamask/confirm-transaction/UPDATE_METHOD_DATA' -const CLEAR_METHOD_DATA = 'metamask/confirm-transaction/CLEAR_METHOD_DATA' +}; + +const UPDATE_TX_DATA = 'metamask/confirm-transaction/UPDATE_TX_DATA'; +const CLEAR_TX_DATA = 'metamask/confirm-transaction/CLEAR_TX_DATA'; +const UPDATE_TOKEN_DATA = 'metamask/confirm-transaction/UPDATE_TOKEN_DATA'; +const CLEAR_TOKEN_DATA = 'metamask/confirm-transaction/CLEAR_TOKEN_DATA'; +const UPDATE_METHOD_DATA = 'metamask/confirm-transaction/UPDATE_METHOD_DATA'; +const CLEAR_METHOD_DATA = 'metamask/confirm-transaction/CLEAR_METHOD_DATA'; const UPDATE_TRANSACTION_AMOUNTS = - 'metamask/confirm-transaction/UPDATE_TRANSACTION_AMOUNTS' + 'metamask/confirm-transaction/UPDATE_TRANSACTION_AMOUNTS'; const UPDATE_TRANSACTION_FEES = - 'metamask/confirm-transaction/UPDATE_TRANSACTION_FEES' + 'metamask/confirm-transaction/UPDATE_TRANSACTION_FEES'; const UPDATE_TRANSACTION_TOTALS = - 'metamask/confirm-transaction/UPDATE_TRANSACTION_TOTALS' -const UPDATE_TOKEN_PROPS = 'metamask/confirm-transaction/UPDATE_TOKEN_PROPS' -const UPDATE_NONCE = 'metamask/confirm-transaction/UPDATE_NONCE' + 'metamask/confirm-transaction/UPDATE_TRANSACTION_TOTALS'; +const UPDATE_TOKEN_PROPS = 'metamask/confirm-transaction/UPDATE_TOKEN_PROPS'; +const UPDATE_NONCE = 'metamask/confirm-transaction/UPDATE_NONCE'; const UPDATE_TO_SMART_CONTRACT = - 'metamask/confirm-transaction/UPDATE_TO_SMART_CONTRACT' -const FETCH_DATA_START = 'metamask/confirm-transaction/FETCH_DATA_START' -const FETCH_DATA_END = 'metamask/confirm-transaction/FETCH_DATA_END' + 'metamask/confirm-transaction/UPDATE_TO_SMART_CONTRACT'; +const FETCH_DATA_START = 'metamask/confirm-transaction/FETCH_DATA_START'; +const FETCH_DATA_END = 'metamask/confirm-transaction/FETCH_DATA_END'; const CLEAR_CONFIRM_TRANSACTION = - 'metamask/confirm-transaction/CLEAR_CONFIRM_TRANSACTION' + 'metamask/confirm-transaction/CLEAR_CONFIRM_TRANSACTION'; describe('Confirm Transaction Duck', function () { describe('State changes', function () { @@ -80,14 +80,14 @@ describe('Confirm Transaction Duck', function () { nonce: '0x0', toSmartContract: false, fetchingData: false, - } + }; it('should initialize state', function () { assert.deepStrictEqual( ConfirmTransactionReducer(undefined, {}), initialState, - ) - }) + ); + }); it('should return state unchanged if it does not match a dispatched actions type', function () { assert.deepStrictEqual( @@ -96,8 +96,8 @@ describe('Confirm Transaction Duck', function () { value: 'someValue', }), { ...mockState }, - ) - }) + ); + }); it('should set txData when receiving a UPDATE_TX_DATA action', function () { assert.deepStrictEqual( @@ -114,8 +114,8 @@ describe('Confirm Transaction Duck', function () { id: 2, }, }, - ) - }) + ); + }); it('should clear txData when receiving a CLEAR_TX_DATA action', function () { assert.deepStrictEqual( @@ -126,8 +126,8 @@ describe('Confirm Transaction Duck', function () { ...mockState, txData: {}, }, - ) - }) + ); + }); it('should set tokenData when receiving a UPDATE_TOKEN_DATA action', function () { assert.deepStrictEqual( @@ -144,8 +144,8 @@ describe('Confirm Transaction Duck', function () { name: 'defToken', }, }, - ) - }) + ); + }); it('should clear tokenData when receiving a CLEAR_TOKEN_DATA action', function () { assert.deepStrictEqual( @@ -156,8 +156,8 @@ describe('Confirm Transaction Duck', function () { ...mockState, tokenData: {}, }, - ) - }) + ); + }); it('should set methodData when receiving a UPDATE_METHOD_DATA action', function () { assert.deepStrictEqual( @@ -174,8 +174,8 @@ describe('Confirm Transaction Duck', function () { name: 'transferFrom', }, }, - ) - }) + ); + }); it('should clear methodData when receiving a CLEAR_METHOD_DATA action', function () { assert.deepStrictEqual( @@ -186,8 +186,8 @@ describe('Confirm Transaction Duck', function () { ...mockState, methodData: {}, }, - ) - }) + ); + }); it('should update transaction amounts when receiving an UPDATE_TRANSACTION_AMOUNTS action', function () { assert.deepStrictEqual( @@ -205,8 +205,8 @@ describe('Confirm Transaction Duck', function () { ethTransactionAmount: '.5', hexTransactionAmount: '0x1', }, - ) - }) + ); + }); it('should update transaction fees when receiving an UPDATE_TRANSACTION_FEES action', function () { assert.deepStrictEqual( @@ -224,8 +224,8 @@ describe('Confirm Transaction Duck', function () { ethTransactionFee: '.5', hexTransactionFee: '0x1', }, - ) - }) + ); + }); it('should update transaction totals when receiving an UPDATE_TRANSACTION_TOTALS action', function () { assert.deepStrictEqual( @@ -243,8 +243,8 @@ describe('Confirm Transaction Duck', function () { ethTransactionTotal: '.5', hexTransactionTotal: '0x1', }, - ) - }) + ); + }); it('should update tokenProps when receiving an UPDATE_TOKEN_PROPS action', function () { assert.deepStrictEqual( @@ -262,8 +262,8 @@ describe('Confirm Transaction Duck', function () { tokenDecimals: '1', }, }, - ) - }) + ); + }); it('should update nonce when receiving an UPDATE_NONCE action', function () { assert.deepStrictEqual( @@ -275,8 +275,8 @@ describe('Confirm Transaction Duck', function () { ...mockState, nonce: '0x1', }, - ) - }) + ); + }); it('should update nonce when receiving an UPDATE_TO_SMART_CONTRACT action', function () { assert.deepStrictEqual( @@ -288,8 +288,8 @@ describe('Confirm Transaction Duck', function () { ...mockState, toSmartContract: true, }, - ) - }) + ); + }); it('should set fetchingData to true when receiving a FETCH_DATA_START action', function () { assert.deepStrictEqual( @@ -300,8 +300,8 @@ describe('Confirm Transaction Duck', function () { ...mockState, fetchingData: true, }, - ) - }) + ); + }); it('should set fetchingData to false when receiving a FETCH_DATA_END action', function () { assert.deepStrictEqual( @@ -310,8 +310,8 @@ describe('Confirm Transaction Duck', function () { { type: FETCH_DATA_END }, ), { fetchingData: false }, - ) - }) + ); + }); it('should clear confirmTransaction when receiving a FETCH_DATA_END action', function () { assert.deepStrictEqual( @@ -319,157 +319,160 @@ describe('Confirm Transaction Duck', function () { type: CLEAR_CONFIRM_TRANSACTION, }), initialState, - ) - }) - }) + ); + }); + }); describe('Single actions', function () { it('should create an action to update txData', function () { - const txData = { test: 123 } + const txData = { test: 123 }; const expectedAction = { type: UPDATE_TX_DATA, payload: txData, - } + }; - assert.deepStrictEqual(actions.updateTxData(txData), expectedAction) - }) + assert.deepStrictEqual(actions.updateTxData(txData), expectedAction); + }); it('should create an action to clear txData', function () { const expectedAction = { type: CLEAR_TX_DATA, - } + }; - assert.deepStrictEqual(actions.clearTxData(), expectedAction) - }) + assert.deepStrictEqual(actions.clearTxData(), expectedAction); + }); it('should create an action to update tokenData', function () { - const tokenData = { test: 123 } + const tokenData = { test: 123 }; const expectedAction = { type: UPDATE_TOKEN_DATA, payload: tokenData, - } + }; - assert.deepStrictEqual(actions.updateTokenData(tokenData), expectedAction) - }) + assert.deepStrictEqual( + actions.updateTokenData(tokenData), + expectedAction, + ); + }); it('should create an action to clear tokenData', function () { const expectedAction = { type: CLEAR_TOKEN_DATA, - } + }; - assert.deepStrictEqual(actions.clearTokenData(), expectedAction) - }) + assert.deepStrictEqual(actions.clearTokenData(), expectedAction); + }); it('should create an action to update methodData', function () { - const methodData = { test: 123 } + const methodData = { test: 123 }; const expectedAction = { type: UPDATE_METHOD_DATA, payload: methodData, - } + }; assert.deepStrictEqual( actions.updateMethodData(methodData), expectedAction, - ) - }) + ); + }); it('should create an action to clear methodData', function () { const expectedAction = { type: CLEAR_METHOD_DATA, - } + }; - assert.deepStrictEqual(actions.clearMethodData(), expectedAction) - }) + assert.deepStrictEqual(actions.clearMethodData(), expectedAction); + }); it('should create an action to update transaction amounts', function () { - const transactionAmounts = { test: 123 } + const transactionAmounts = { test: 123 }; const expectedAction = { type: UPDATE_TRANSACTION_AMOUNTS, payload: transactionAmounts, - } + }; assert.deepStrictEqual( actions.updateTransactionAmounts(transactionAmounts), expectedAction, - ) - }) + ); + }); it('should create an action to update transaction fees', function () { - const transactionFees = { test: 123 } + const transactionFees = { test: 123 }; const expectedAction = { type: UPDATE_TRANSACTION_FEES, payload: transactionFees, - } + }; assert.deepStrictEqual( actions.updateTransactionFees(transactionFees), expectedAction, - ) - }) + ); + }); it('should create an action to update transaction totals', function () { - const transactionTotals = { test: 123 } + const transactionTotals = { test: 123 }; const expectedAction = { type: UPDATE_TRANSACTION_TOTALS, payload: transactionTotals, - } + }; assert.deepStrictEqual( actions.updateTransactionTotals(transactionTotals), expectedAction, - ) - }) + ); + }); it('should create an action to update tokenProps', function () { const tokenProps = { tokenDecimals: '1', tokenSymbol: 'abc', - } + }; const expectedAction = { type: UPDATE_TOKEN_PROPS, payload: tokenProps, - } + }; assert.deepStrictEqual( actions.updateTokenProps(tokenProps), expectedAction, - ) - }) + ); + }); it('should create an action to update nonce', function () { - const nonce = '0x1' + const nonce = '0x1'; const expectedAction = { type: UPDATE_NONCE, payload: nonce, - } + }; - assert.deepStrictEqual(actions.updateNonce(nonce), expectedAction) - }) + assert.deepStrictEqual(actions.updateNonce(nonce), expectedAction); + }); it('should create an action to set fetchingData to true', function () { const expectedAction = { type: FETCH_DATA_START, - } + }; - assert.deepStrictEqual(actions.setFetchingData(true), expectedAction) - }) + assert.deepStrictEqual(actions.setFetchingData(true), expectedAction); + }); it('should create an action to set fetchingData to false', function () { const expectedAction = { type: FETCH_DATA_END, - } + }; - assert.deepStrictEqual(actions.setFetchingData(false), expectedAction) - }) + assert.deepStrictEqual(actions.setFetchingData(false), expectedAction); + }); it('should create an action to clear confirmTransaction', function () { const expectedAction = { type: CLEAR_CONFIRM_TRANSACTION, - } + }; - assert.deepStrictEqual(actions.clearConfirmTransaction(), expectedAction) - }) - }) + assert.deepStrictEqual(actions.clearConfirmTransaction(), expectedAction); + }); + }); describe('Thunk actions', function () { beforeEach(function () { @@ -479,12 +482,12 @@ describe('Confirm Transaction Duck', function () { .callsFake((address) => Promise.resolve(address?.match(/isContract/u) ? 'not-0x' : '0x'), ), - } - }) + }; + }); afterEach(function () { - global.eth.getCode.resetHistory() - }) + global.eth.getCode.resetHistory(); + }); it('updates txData and gas on an existing transaction in confirmTransaction', function () { const mockState = { @@ -518,28 +521,28 @@ describe('Confirm Transaction Duck', function () { time: 1530838113716, }, }, - } + }; - const middlewares = [thunk] - const mockStore = configureMockStore(middlewares) - const store = mockStore(mockState) + const middlewares = [thunk]; + const mockStore = configureMockStore(middlewares); + const store = mockStore(mockState); const expectedActions = [ 'metamask/confirm-transaction/UPDATE_TX_DATA', 'metamask/confirm-transaction/UPDATE_TRANSACTION_AMOUNTS', 'metamask/confirm-transaction/UPDATE_TRANSACTION_FEES', 'metamask/confirm-transaction/UPDATE_TRANSACTION_TOTALS', - ] + ]; store.dispatch( actions.updateGasAndCalculate({ gasLimit: '0x2', gasPrice: '0x25' }), - ) + ); - const storeActions = store.getActions() - assert.strictEqual(storeActions.length, expectedActions.length) + const storeActions = store.getActions(); + assert.strictEqual(storeActions.length, expectedActions.length); storeActions.forEach((action, index) => assert.strictEqual(action.type, expectedActions[index]), - ) - }) + ); + }); it('updates txData and updates gas values in confirmTransaction', function () { const txData = { @@ -557,7 +560,7 @@ describe('Confirm Transaction Duck', function () { to: '0x81b7e08f65bdf5648606c89998a9cc8164397647', value: '0xde0b6b3a7640000', }, - } + }; const mockState = { metamask: { conversionRate: 468.58, @@ -586,26 +589,26 @@ describe('Confirm Transaction Duck', function () { }, }, }, - } + }; - const middlewares = [thunk] - const mockStore = configureMockStore(middlewares) - const store = mockStore(mockState) + const middlewares = [thunk]; + const mockStore = configureMockStore(middlewares); + const store = mockStore(mockState); const expectedActions = [ 'metamask/confirm-transaction/UPDATE_TX_DATA', 'metamask/confirm-transaction/UPDATE_TRANSACTION_AMOUNTS', 'metamask/confirm-transaction/UPDATE_TRANSACTION_FEES', 'metamask/confirm-transaction/UPDATE_TRANSACTION_TOTALS', - ] + ]; - store.dispatch(actions.updateTxDataAndCalculate(txData)) + store.dispatch(actions.updateTxDataAndCalculate(txData)); - const storeActions = store.getActions() - assert.strictEqual(storeActions.length, expectedActions.length) + const storeActions = store.getActions(); + assert.strictEqual(storeActions.length, expectedActions.length); storeActions.forEach((action, index) => assert.strictEqual(action.type, expectedActions[index]), - ) - }) + ); + }); it('updates confirmTransaction transaction', function () { const mockState = { @@ -633,25 +636,25 @@ describe('Confirm Transaction Duck', function () { }, }, confirmTransaction: {}, - } + }; - const middlewares = [thunk] - const mockStore = configureMockStore(middlewares) - const store = mockStore(mockState) + const middlewares = [thunk]; + const mockStore = configureMockStore(middlewares); + const store = mockStore(mockState); const expectedActions = [ 'metamask/confirm-transaction/UPDATE_TX_DATA', 'metamask/confirm-transaction/UPDATE_TRANSACTION_AMOUNTS', 'metamask/confirm-transaction/UPDATE_TRANSACTION_FEES', 'metamask/confirm-transaction/UPDATE_TRANSACTION_TOTALS', - ] + ]; - store.dispatch(actions.setTransactionToConfirm(2603411941761054)) - const storeActions = store.getActions() - assert.strictEqual(storeActions.length, expectedActions.length) + store.dispatch(actions.setTransactionToConfirm(2603411941761054)); + const storeActions = store.getActions(); + assert.strictEqual(storeActions.length, expectedActions.length); storeActions.forEach((action, index) => assert.strictEqual(action.type, expectedActions[index]), - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/ui/app/ducks/gas/gas-duck.test.js b/ui/app/ducks/gas/gas-duck.test.js index 913fb1168e..4e7be79560 100644 --- a/ui/app/ducks/gas/gas-duck.test.js +++ b/ui/app/ducks/gas/gas-duck.test.js @@ -1,13 +1,13 @@ -import assert from 'assert' -import nock from 'nock' -import sinon from 'sinon' -import proxyquire from 'proxyquire' +import assert from 'assert'; +import nock from 'nock'; +import sinon from 'sinon'; +import proxyquire from 'proxyquire'; -const fakeStorage = {} +const fakeStorage = {}; const GasDuck = proxyquire('./gas.duck.js', { '../../../lib/storage-helpers': fakeStorage, -}) +}); const { basicGasEstimatesLoadingStarted, @@ -17,34 +17,34 @@ const { setCustomGasLimit, resetCustomGasState, fetchBasicGasEstimates, -} = GasDuck -const GasReducer = GasDuck.default +} = GasDuck; +const GasReducer = GasDuck.default; describe('Gas Duck', function () { - let tempDateNow + let tempDateNow; const mockGasPriceApiResponse = { SafeGasPrice: 10, ProposeGasPrice: 20, FastGasPrice: 30, - } + }; beforeEach(function () { - tempDateNow = global.Date.now + tempDateNow = global.Date.now; - fakeStorage.getStorageItem = sinon.stub() - fakeStorage.setStorageItem = sinon.spy() - global.Date.now = () => 2000000 - }) + fakeStorage.getStorageItem = sinon.stub(); + fakeStorage.setStorageItem = sinon.spy(); + global.Date.now = () => 2000000; + }); afterEach(function () { - sinon.restore() + sinon.restore(); - global.Date.now = tempDateNow - }) + global.Date.now = tempDateNow; + }); const mockState = { mockProp: 123, - } + }; const initState = { customData: { price: null, @@ -57,22 +57,23 @@ describe('Gas Duck', function () { }, basicEstimateIsLoading: true, basicPriceEstimatesLastRetrieved: 0, - } + }; const BASIC_GAS_ESTIMATE_LOADING_FINISHED = - 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_FINISHED' + 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_FINISHED'; const BASIC_GAS_ESTIMATE_LOADING_STARTED = - 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_STARTED' - const RESET_CUSTOM_GAS_STATE = 'metamask/gas/RESET_CUSTOM_GAS_STATE' - const SET_BASIC_GAS_ESTIMATE_DATA = 'metamask/gas/SET_BASIC_GAS_ESTIMATE_DATA' - const SET_CUSTOM_GAS_LIMIT = 'metamask/gas/SET_CUSTOM_GAS_LIMIT' - const SET_CUSTOM_GAS_PRICE = 'metamask/gas/SET_CUSTOM_GAS_PRICE' + 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_STARTED'; + const RESET_CUSTOM_GAS_STATE = 'metamask/gas/RESET_CUSTOM_GAS_STATE'; + const SET_BASIC_GAS_ESTIMATE_DATA = + 'metamask/gas/SET_BASIC_GAS_ESTIMATE_DATA'; + const SET_CUSTOM_GAS_LIMIT = 'metamask/gas/SET_CUSTOM_GAS_LIMIT'; + const SET_CUSTOM_GAS_PRICE = 'metamask/gas/SET_CUSTOM_GAS_PRICE'; const SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED = - 'metamask/gas/SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED' + 'metamask/gas/SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED'; describe('GasReducer()', function () { it('should initialize state', function () { - assert.deepStrictEqual(GasReducer(undefined, {}), initState) - }) + assert.deepStrictEqual(GasReducer(undefined, {}), initState); + }); it('should return state unchanged if it does not match a dispatched actions type', function () { assert.deepStrictEqual( @@ -81,22 +82,22 @@ describe('Gas Duck', function () { value: 'someValue', }), mockState, - ) - }) + ); + }); it('should set basicEstimateIsLoading to true when receiving a BASIC_GAS_ESTIMATE_LOADING_STARTED action', function () { assert.deepStrictEqual( GasReducer(mockState, { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }), { basicEstimateIsLoading: true, ...mockState }, - ) - }) + ); + }); it('should set basicEstimateIsLoading to false when receiving a BASIC_GAS_ESTIMATE_LOADING_FINISHED action', function () { assert.deepStrictEqual( GasReducer(mockState, { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }), { basicEstimateIsLoading: false, ...mockState }, - ) - }) + ); + }); it('should set basicEstimates when receiving a SET_BASIC_GAS_ESTIMATE_DATA action', function () { assert.deepStrictEqual( @@ -105,8 +106,8 @@ describe('Gas Duck', function () { value: { someProp: 'someData123' }, }), { basicEstimates: { someProp: 'someData123' }, ...mockState }, - ) - }) + ); + }); it('should set customData.price when receiving a SET_CUSTOM_GAS_PRICE action', function () { assert.deepStrictEqual( @@ -115,8 +116,8 @@ describe('Gas Duck', function () { value: 4321, }), { customData: { price: 4321 }, ...mockState }, - ) - }) + ); + }); it('should set customData.limit when receiving a SET_CUSTOM_GAS_LIMIT action', function () { assert.deepStrictEqual( @@ -125,58 +126,58 @@ describe('Gas Duck', function () { value: 9876, }), { customData: { limit: 9876 }, ...mockState }, - ) - }) + ); + }); it('should return the initial state in response to a RESET_CUSTOM_GAS_STATE action', function () { assert.deepStrictEqual( GasReducer(mockState, { type: RESET_CUSTOM_GAS_STATE }), initState, - ) - }) - }) + ); + }); + }); describe('basicGasEstimatesLoadingStarted', function () { it('should create the correct action', function () { assert.deepStrictEqual(basicGasEstimatesLoadingStarted(), { type: BASIC_GAS_ESTIMATE_LOADING_STARTED, - }) - }) - }) + }); + }); + }); describe('basicGasEstimatesLoadingFinished', function () { it('should create the correct action', function () { assert.deepStrictEqual(basicGasEstimatesLoadingFinished(), { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED, - }) - }) - }) + }); + }); + }); describe('fetchBasicGasEstimates', function () { it('should call fetch with the expected params', async function () { - const mockDistpatch = sinon.spy() + const mockDistpatch = sinon.spy(); - const windowFetchSpy = sinon.spy(window, 'fetch') + const windowFetchSpy = sinon.spy(window, 'fetch'); nock('https://api.metaswap.codefi.network') .get('/gasPrices') - .reply(200, mockGasPriceApiResponse) + .reply(200, mockGasPriceApiResponse); await fetchBasicGasEstimates()(mockDistpatch, () => ({ gas: { ...initState, basicPriceAEstimatesLastRetrieved: 1000000 }, - })) + })); assert.deepStrictEqual(mockDistpatch.getCall(0).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, - ]) + ]); assert.ok( windowFetchSpy .getCall(0) .args[0].startsWith('https://api.metaswap.codefi.network/gasPrices'), 'should fetch metaswap /gasPrices', - ) + ); assert.deepStrictEqual(mockDistpatch.getCall(1).args, [ { type: SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED, value: 2000000 }, - ]) + ]); assert.deepStrictEqual(mockDistpatch.getCall(2).args, [ { type: SET_BASIC_GAS_ESTIMATE_DATA, @@ -186,33 +187,33 @@ describe('Gas Duck', function () { safeLow: 10, }, }, - ]) + ]); assert.deepStrictEqual(mockDistpatch.getCall(3).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }, - ]) - }) + ]); + }); it('should fetch recently retrieved estimates from storage', async function () { - const mockDistpatch = sinon.spy() + const mockDistpatch = sinon.spy(); - const windowFetchSpy = sinon.spy(window, 'fetch') + const windowFetchSpy = sinon.spy(window, 'fetch'); fakeStorage.getStorageItem .withArgs('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED') - .returns(2000000 - 1) // one second ago from "now" + .returns(2000000 - 1); // one second ago from "now" fakeStorage.getStorageItem.withArgs('BASIC_PRICE_ESTIMATES').returns({ average: 25, fast: 35, safeLow: 15, - }) + }); await fetchBasicGasEstimates()(mockDistpatch, () => ({ gas: { ...initState }, - })) + })); assert.deepStrictEqual(mockDistpatch.getCall(0).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, - ]) - assert.ok(windowFetchSpy.notCalled) + ]); + assert.ok(windowFetchSpy.notCalled); assert.deepStrictEqual(mockDistpatch.getCall(1).args, [ { type: SET_BASIC_GAS_ESTIMATE_DATA, @@ -222,41 +223,41 @@ describe('Gas Duck', function () { safeLow: 15, }, }, - ]) + ]); assert.deepStrictEqual(mockDistpatch.getCall(2).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }, - ]) - }) + ]); + }); it('should fallback to network if retrieving estimates from storage fails', async function () { - const mockDistpatch = sinon.spy() + const mockDistpatch = sinon.spy(); - const windowFetchSpy = sinon.spy(window, 'fetch') + const windowFetchSpy = sinon.spy(window, 'fetch'); nock('https://api.metaswap.codefi.network') .get('/gasPrices') - .reply(200, mockGasPriceApiResponse) + .reply(200, mockGasPriceApiResponse); fakeStorage.getStorageItem .withArgs('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED') - .returns(2000000 - 1) // one second ago from "now" + .returns(2000000 - 1); // one second ago from "now" await fetchBasicGasEstimates()(mockDistpatch, () => ({ gas: { ...initState }, - })) + })); assert.deepStrictEqual(mockDistpatch.getCall(0).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, - ]) + ]); assert.ok( windowFetchSpy .getCall(0) .args[0].startsWith('https://api.metaswap.codefi.network/gasPrices'), 'should fetch metaswap /gasPrices', - ) + ); assert.deepStrictEqual(mockDistpatch.getCall(1).args, [ { type: SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED, value: 2000000 }, - ]) + ]); assert.deepStrictEqual(mockDistpatch.getCall(2).args, [ { type: SET_BASIC_GAS_ESTIMATE_DATA, @@ -266,45 +267,45 @@ describe('Gas Duck', function () { fast: 30, }, }, - ]) + ]); assert.deepStrictEqual(mockDistpatch.getCall(3).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }, - ]) - }) - }) + ]); + }); + }); describe('setBasicGasEstimateData', function () { it('should create the correct action', function () { assert.deepStrictEqual(setBasicGasEstimateData('mockBasicEstimatData'), { type: SET_BASIC_GAS_ESTIMATE_DATA, value: 'mockBasicEstimatData', - }) - }) - }) + }); + }); + }); describe('setCustomGasPrice', function () { it('should create the correct action', function () { assert.deepStrictEqual(setCustomGasPrice('mockCustomGasPrice'), { type: SET_CUSTOM_GAS_PRICE, value: 'mockCustomGasPrice', - }) - }) - }) + }); + }); + }); describe('setCustomGasLimit', function () { it('should create the correct action', function () { assert.deepStrictEqual(setCustomGasLimit('mockCustomGasLimit'), { type: SET_CUSTOM_GAS_LIMIT, value: 'mockCustomGasLimit', - }) - }) - }) + }); + }); + }); describe('resetCustomGasState', function () { it('should create the correct action', function () { assert.deepStrictEqual(resetCustomGasState(), { type: RESET_CUSTOM_GAS_STATE, - }) - }) - }) -}) + }); + }); + }); +}); diff --git a/ui/app/ducks/gas/gas.duck.js b/ui/app/ducks/gas/gas.duck.js index 1bcc5d417f..73a621f8f8 100644 --- a/ui/app/ducks/gas/gas.duck.js +++ b/ui/app/ducks/gas/gas.duck.js @@ -1,23 +1,23 @@ -import { cloneDeep } from 'lodash' -import BigNumber from 'bignumber.js' -import { getStorageItem, setStorageItem } from '../../../lib/storage-helpers' -import { decGWEIToHexWEI } from '../../helpers/utils/conversions.util' -import getFetchWithTimeout from '../../../../shared/modules/fetch-with-timeout' +import { cloneDeep } from 'lodash'; +import BigNumber from 'bignumber.js'; +import { getStorageItem, setStorageItem } from '../../../lib/storage-helpers'; +import { decGWEIToHexWEI } from '../../helpers/utils/conversions.util'; +import getFetchWithTimeout from '../../../../shared/modules/fetch-with-timeout'; -const fetchWithTimeout = getFetchWithTimeout(30000) +const fetchWithTimeout = getFetchWithTimeout(30000); // Actions const BASIC_GAS_ESTIMATE_LOADING_FINISHED = - 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_FINISHED' + 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_FINISHED'; const BASIC_GAS_ESTIMATE_LOADING_STARTED = - 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_STARTED' -const RESET_CUSTOM_GAS_STATE = 'metamask/gas/RESET_CUSTOM_GAS_STATE' -const RESET_CUSTOM_DATA = 'metamask/gas/RESET_CUSTOM_DATA' -const SET_BASIC_GAS_ESTIMATE_DATA = 'metamask/gas/SET_BASIC_GAS_ESTIMATE_DATA' -const SET_CUSTOM_GAS_LIMIT = 'metamask/gas/SET_CUSTOM_GAS_LIMIT' -const SET_CUSTOM_GAS_PRICE = 'metamask/gas/SET_CUSTOM_GAS_PRICE' + 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_STARTED'; +const RESET_CUSTOM_GAS_STATE = 'metamask/gas/RESET_CUSTOM_GAS_STATE'; +const RESET_CUSTOM_DATA = 'metamask/gas/RESET_CUSTOM_DATA'; +const SET_BASIC_GAS_ESTIMATE_DATA = 'metamask/gas/SET_BASIC_GAS_ESTIMATE_DATA'; +const SET_CUSTOM_GAS_LIMIT = 'metamask/gas/SET_CUSTOM_GAS_LIMIT'; +const SET_CUSTOM_GAS_PRICE = 'metamask/gas/SET_CUSTOM_GAS_PRICE'; const SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED = - 'metamask/gas/SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED' + 'metamask/gas/SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED'; const initState = { customData: { @@ -31,7 +31,7 @@ const initState = { }, basicEstimateIsLoading: true, basicPriceEstimatesLastRetrieved: 0, -} +}; // Reducer export default function reducer(state = initState, action) { @@ -40,17 +40,17 @@ export default function reducer(state = initState, action) { return { ...state, basicEstimateIsLoading: true, - } + }; case BASIC_GAS_ESTIMATE_LOADING_FINISHED: return { ...state, basicEstimateIsLoading: false, - } + }; case SET_BASIC_GAS_ESTIMATE_DATA: return { ...state, basicEstimates: action.value, - } + }; case SET_CUSTOM_GAS_PRICE: return { ...state, @@ -58,7 +58,7 @@ export default function reducer(state = initState, action) { ...state.customData, price: action.value, }, - } + }; case SET_CUSTOM_GAS_LIMIT: return { ...state, @@ -66,21 +66,21 @@ export default function reducer(state = initState, action) { ...state.customData, limit: action.value, }, - } + }; case SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED: return { ...state, basicPriceEstimatesLastRetrieved: action.value, - } + }; case RESET_CUSTOM_DATA: return { ...state, customData: cloneDeep(initState.customData), - } + }; case RESET_CUSTOM_GAS_STATE: - return cloneDeep(initState) + return cloneDeep(initState); default: - return state + return state; } } @@ -88,17 +88,17 @@ export default function reducer(state = initState, action) { export function basicGasEstimatesLoadingStarted() { return { type: BASIC_GAS_ESTIMATE_LOADING_STARTED, - } + }; } export function basicGasEstimatesLoadingFinished() { return { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED, - } + }; } async function basicGasPriceQuery() { - const url = `https://api.metaswap.codefi.network/gasPrices` + const url = `https://api.metaswap.codefi.network/gasPrices`; return await fetchWithTimeout(url, { headers: {}, referrer: 'https://api.metaswap.codefi.network/gasPrices', @@ -106,105 +106,108 @@ async function basicGasPriceQuery() { body: null, method: 'GET', mode: 'cors', - }) + }); } export function fetchBasicGasEstimates() { return async (dispatch, getState) => { - const { basicPriceEstimatesLastRetrieved } = getState().gas + const { basicPriceEstimatesLastRetrieved } = getState().gas; const timeLastRetrieved = basicPriceEstimatesLastRetrieved || (await getStorageItem('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED')) || - 0 + 0; - dispatch(basicGasEstimatesLoadingStarted()) + dispatch(basicGasEstimatesLoadingStarted()); - let basicEstimates + let basicEstimates; if (Date.now() - timeLastRetrieved > 75000) { - basicEstimates = await fetchExternalBasicGasEstimates(dispatch) + basicEstimates = await fetchExternalBasicGasEstimates(dispatch); } else { - const cachedBasicEstimates = await getStorageItem('BASIC_PRICE_ESTIMATES') + const cachedBasicEstimates = await getStorageItem( + 'BASIC_PRICE_ESTIMATES', + ); basicEstimates = - cachedBasicEstimates || (await fetchExternalBasicGasEstimates(dispatch)) + cachedBasicEstimates || + (await fetchExternalBasicGasEstimates(dispatch)); } - dispatch(setBasicGasEstimateData(basicEstimates)) - dispatch(basicGasEstimatesLoadingFinished()) + dispatch(setBasicGasEstimateData(basicEstimates)); + dispatch(basicGasEstimatesLoadingFinished()); - return basicEstimates - } + return basicEstimates; + }; } async function fetchExternalBasicGasEstimates(dispatch) { - const response = await basicGasPriceQuery() + const response = await basicGasPriceQuery(); - const { SafeGasPrice, ProposeGasPrice, FastGasPrice } = await response.json() + const { SafeGasPrice, ProposeGasPrice, FastGasPrice } = await response.json(); const [safeLow, average, fast] = [ SafeGasPrice, ProposeGasPrice, FastGasPrice, - ].map((price) => new BigNumber(price, 10).toNumber()) + ].map((price) => new BigNumber(price, 10).toNumber()); const basicEstimates = { safeLow, average, fast, - } + }; - const timeRetrieved = Date.now() + const timeRetrieved = Date.now(); await Promise.all([ setStorageItem('BASIC_PRICE_ESTIMATES', basicEstimates), setStorageItem('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED', timeRetrieved), - ]) - dispatch(setBasicPriceEstimatesLastRetrieved(timeRetrieved)) + ]); + dispatch(setBasicPriceEstimatesLastRetrieved(timeRetrieved)); - return basicEstimates + return basicEstimates; } export function setCustomGasPriceForRetry(newPrice) { return async (dispatch) => { if (newPrice === '0x0') { - const { fast } = await getStorageItem('BASIC_PRICE_ESTIMATES') - dispatch(setCustomGasPrice(decGWEIToHexWEI(fast))) + const { fast } = await getStorageItem('BASIC_PRICE_ESTIMATES'); + dispatch(setCustomGasPrice(decGWEIToHexWEI(fast))); } else { - dispatch(setCustomGasPrice(newPrice)) + dispatch(setCustomGasPrice(newPrice)); } - } + }; } export function setBasicGasEstimateData(basicGasEstimateData) { return { type: SET_BASIC_GAS_ESTIMATE_DATA, value: basicGasEstimateData, - } + }; } export function setCustomGasPrice(newPrice) { return { type: SET_CUSTOM_GAS_PRICE, value: newPrice, - } + }; } export function setCustomGasLimit(newLimit) { return { type: SET_CUSTOM_GAS_LIMIT, value: newLimit, - } + }; } export function setBasicPriceEstimatesLastRetrieved(retrievalTime) { return { type: SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED, value: retrievalTime, - } + }; } export function resetCustomGasState() { - return { type: RESET_CUSTOM_GAS_STATE } + return { type: RESET_CUSTOM_GAS_STATE }; } export function resetCustomData() { - return { type: RESET_CUSTOM_DATA } + return { type: RESET_CUSTOM_DATA }; } diff --git a/ui/app/ducks/history/history.js b/ui/app/ducks/history/history.js index e74576f7f9..87fabe2043 100644 --- a/ui/app/ducks/history/history.js +++ b/ui/app/ducks/history/history.js @@ -1,14 +1,14 @@ -import { createSlice } from '@reduxjs/toolkit' +import { createSlice } from '@reduxjs/toolkit'; -import { ASSET_ROUTE, DEFAULT_ROUTE } from '../../helpers/constants/routes' +import { ASSET_ROUTE, DEFAULT_ROUTE } from '../../helpers/constants/routes'; // Constants const initialState = { mostRecentOverviewPage: DEFAULT_ROUTE, -} +}; -const name = 'history' +const name = 'history'; // Slice (reducer plus auto-generated actions and action creators) @@ -17,23 +17,23 @@ const slice = createSlice({ initialState, reducers: { pageChanged: (state, action) => { - const path = action.payload + const path = action.payload; if (path === DEFAULT_ROUTE || path.startsWith(ASSET_ROUTE)) { - state.mostRecentOverviewPage = path + state.mostRecentOverviewPage = path; } }, }, -}) +}); -const { actions, reducer } = slice +const { actions, reducer } = slice; -export default reducer +export default reducer; // Selectors export const getMostRecentOverviewPage = (state) => - state[name].mostRecentOverviewPage + state[name].mostRecentOverviewPage; // Actions / action-creators -export const { pageChanged } = actions +export const { pageChanged } = actions; diff --git a/ui/app/ducks/index.js b/ui/app/ducks/index.js index 42fccab069..4782acc487 100644 --- a/ui/app/ducks/index.js +++ b/ui/app/ducks/index.js @@ -1,14 +1,14 @@ -import { combineReducers } from 'redux' -import { ALERT_TYPES } from '../../../shared/constants/alerts' -import metamaskReducer from './metamask/metamask' -import localeMessagesReducer from './locale/locale' -import sendReducer from './send/send.duck' -import appStateReducer from './app/app' -import confirmTransactionReducer from './confirm-transaction/confirm-transaction.duck' -import gasReducer from './gas/gas.duck' -import { invalidCustomNetwork, unconnectedAccount } from './alerts' -import swapsReducer from './swaps/swaps' -import historyReducer from './history/history' +import { combineReducers } from 'redux'; +import { ALERT_TYPES } from '../../../shared/constants/alerts'; +import metamaskReducer from './metamask/metamask'; +import localeMessagesReducer from './locale/locale'; +import sendReducer from './send/send.duck'; +import appStateReducer from './app/app'; +import confirmTransactionReducer from './confirm-transaction/confirm-transaction.duck'; +import gasReducer from './gas/gas.duck'; +import { invalidCustomNetwork, unconnectedAccount } from './alerts'; +import swapsReducer from './swaps/swaps'; +import historyReducer from './history/history'; export default combineReducers({ [ALERT_TYPES.invalidCustomNetwork]: invalidCustomNetwork, @@ -22,4 +22,4 @@ export default combineReducers({ swaps: swapsReducer, gas: gasReducer, localeMessages: localeMessagesReducer, -}) +}); diff --git a/ui/app/ducks/locale/locale.js b/ui/app/ducks/locale/locale.js index e7f14c40a5..88976e62f6 100644 --- a/ui/app/ducks/locale/locale.js +++ b/ui/app/ducks/locale/locale.js @@ -1,4 +1,4 @@ -import * as actionConstants from '../../store/actionConstants' +import * as actionConstants from '../../store/actionConstants'; export default function reduceLocaleMessages(state = {}, { type, value }) { switch (type) { @@ -6,12 +6,12 @@ export default function reduceLocaleMessages(state = {}, { type, value }) { return { ...state, current: value.messages, - } + }; default: - return state + return state; } } -export const getCurrentLocaleMessages = (state) => state.localeMessages.current +export const getCurrentLocaleMessages = (state) => state.localeMessages.current; -export const getEnLocaleMessages = (state) => state.localeMessages.en +export const getEnLocaleMessages = (state) => state.localeMessages.en; diff --git a/ui/app/ducks/metamask/metamask.js b/ui/app/ducks/metamask/metamask.js index cdc644a021..31c8088772 100644 --- a/ui/app/ducks/metamask/metamask.js +++ b/ui/app/ducks/metamask/metamask.js @@ -1,6 +1,6 @@ -import * as actionConstants from '../../store/actionConstants' -import { ALERT_TYPES } from '../../../../shared/constants/alerts' -import { NETWORK_TYPE_RPC } from '../../../../shared/constants/network' +import * as actionConstants from '../../store/actionConstants'; +import { ALERT_TYPES } from '../../../../shared/constants/alerts'; +import { NETWORK_TYPE_RPC } from '../../../../shared/constants/network'; export default function reduceMetamask(state = {}, action) { const metamaskState = { @@ -48,17 +48,17 @@ export default function reduceMetamask(state = {}, action) { metaMetricsSendCount: 0, nextNonce: null, ...state, - } + }; switch (action.type) { case actionConstants.UPDATE_METAMASK_STATE: - return { ...metamaskState, ...action.value } + return { ...metamaskState, ...action.value }; case actionConstants.LOCK_METAMASK: return { ...metamaskState, isUnlocked: false, - } + }; case actionConstants.SET_RPC_TARGET: return { @@ -67,7 +67,7 @@ export default function reduceMetamask(state = {}, action) { type: NETWORK_TYPE_RPC, rpcUrl: action.value, }, - } + }; case actionConstants.SET_PROVIDER_TYPE: return { @@ -75,7 +75,7 @@ export default function reduceMetamask(state = {}, action) { provider: { type: action.value, }, - } + }; case actionConstants.SHOW_ACCOUNT_DETAIL: return { @@ -83,15 +83,15 @@ export default function reduceMetamask(state = {}, action) { isUnlocked: true, isInitialized: true, selectedAddress: action.value, - } + }; case actionConstants.SET_ACCOUNT_LABEL: { - const { account } = action.value - const name = action.value.label - const id = {} - id[account] = { ...metamaskState.identities[account], name } - const identities = { ...metamaskState.identities, ...id } - return Object.assign(metamaskState, { identities }) + const { account } = action.value; + const name = action.value.label; + const id = {}; + id[account] = { ...metamaskState.identities[account], name }; + const identities = { ...metamaskState.identities, ...id }; + return Object.assign(metamaskState, { identities }); } case actionConstants.SET_CURRENT_FIAT: @@ -99,13 +99,13 @@ export default function reduceMetamask(state = {}, action) { currentCurrency: action.value.currentCurrency, conversionRate: action.value.conversionRate, conversionDate: action.value.conversionDate, - }) + }); case actionConstants.UPDATE_TOKENS: return { ...metamaskState, tokens: action.newTokens, - } + }; // metamask.send case actionConstants.UPDATE_GAS_LIMIT: @@ -115,12 +115,12 @@ export default function reduceMetamask(state = {}, action) { ...metamaskState.send, gasLimit: action.value, }, - } + }; case actionConstants.UPDATE_CUSTOM_NONCE: return { ...metamaskState, customNonceValue: action.value, - } + }; case actionConstants.UPDATE_GAS_PRICE: return { ...metamaskState, @@ -128,13 +128,13 @@ export default function reduceMetamask(state = {}, action) { ...metamaskState.send, gasPrice: action.value, }, - } + }; case actionConstants.TOGGLE_ACCOUNT_MENU: return { ...metamaskState, isAccountMenuOpen: !metamaskState.isAccountMenuOpen, - } + }; case actionConstants.UPDATE_GAS_TOTAL: return { @@ -143,7 +143,7 @@ export default function reduceMetamask(state = {}, action) { ...metamaskState.send, gasTotal: action.value, }, - } + }; case actionConstants.UPDATE_SEND_TOKEN_BALANCE: return { @@ -152,7 +152,7 @@ export default function reduceMetamask(state = {}, action) { ...metamaskState.send, tokenBalance: action.value, }, - } + }; case actionConstants.UPDATE_SEND_HEX_DATA: return { @@ -161,7 +161,7 @@ export default function reduceMetamask(state = {}, action) { ...metamaskState.send, data: action.value, }, - } + }; case actionConstants.UPDATE_SEND_TO: return { @@ -171,7 +171,7 @@ export default function reduceMetamask(state = {}, action) { to: action.value.to, toNickname: action.value.nickname, }, - } + }; case actionConstants.UPDATE_SEND_AMOUNT: return { @@ -180,7 +180,7 @@ export default function reduceMetamask(state = {}, action) { ...metamaskState.send, amount: action.value, }, - } + }; case actionConstants.UPDATE_MAX_MODE: return { @@ -189,7 +189,7 @@ export default function reduceMetamask(state = {}, action) { ...metamaskState.send, maxModeOn: action.value, }, - } + }; case actionConstants.UPDATE_SEND: return Object.assign(metamaskState, { @@ -197,18 +197,18 @@ export default function reduceMetamask(state = {}, action) { ...metamaskState.send, ...action.value, }, - }) + }); case actionConstants.UPDATE_SEND_TOKEN: { const newSend = { ...metamaskState.send, token: action.value, - } + }; // erase token-related state when switching back to native currency if (newSend.editingTransactionId && !newSend.token) { const unapprovedTx = - newSend?.unapprovedTxs?.[newSend.editingTransactionId] || {} - const txParams = unapprovedTx.txParams || {} + newSend?.unapprovedTxs?.[newSend.editingTransactionId] || {}; + const txParams = unapprovedTx.txParams || {}; Object.assign(newSend, { tokenBalance: null, balance: '0', @@ -223,11 +223,11 @@ export default function reduceMetamask(state = {}, action) { }, }, }, - }) + }); } return Object.assign(metamaskState, { send: newSend, - }) + }); } case actionConstants.UPDATE_SEND_ENS_RESOLUTION: @@ -238,7 +238,7 @@ export default function reduceMetamask(state = {}, action) { ensResolution: action.payload, ensResolutionError: '', }, - } + }; case actionConstants.UPDATE_SEND_ENS_RESOLUTION_ERROR: return { @@ -248,7 +248,7 @@ export default function reduceMetamask(state = {}, action) { ensResolution: null, ensResolutionError: action.payload, }, - } + }; case actionConstants.CLEAR_SEND: return { @@ -267,73 +267,73 @@ export default function reduceMetamask(state = {}, action) { editingTransactionId: null, toNickname: '', }, - } + }; case actionConstants.UPDATE_TRANSACTION_PARAMS: { - const { id: txId, value } = action - let { currentNetworkTxList } = metamaskState + const { id: txId, value } = action; + let { currentNetworkTxList } = metamaskState; currentNetworkTxList = currentNetworkTxList.map((tx) => { if (tx.id === txId) { - const newTx = { ...tx } - newTx.txParams = value - return newTx + const newTx = { ...tx }; + newTx.txParams = value; + return newTx; } - return tx - }) + return tx; + }); return { ...metamaskState, currentNetworkTxList, - } + }; } case actionConstants.SET_PARTICIPATE_IN_METAMETRICS: return { ...metamaskState, participateInMetaMetrics: action.value, - } + }; case actionConstants.SET_METAMETRICS_SEND_COUNT: return { ...metamaskState, metaMetricsSendCount: action.value, - } + }; case actionConstants.SET_USE_BLOCKIE: return { ...metamaskState, useBlockie: action.value, - } + }; case actionConstants.UPDATE_FEATURE_FLAGS: return { ...metamaskState, featureFlags: action.value, - } + }; case actionConstants.CLOSE_WELCOME_SCREEN: return { ...metamaskState, welcomeScreenSeen: true, - } + }; case actionConstants.SET_CURRENT_LOCALE: return { ...metamaskState, currentLocale: action.value.locale, - } + }; case actionConstants.SET_PENDING_TOKENS: return { ...metamaskState, pendingTokens: { ...action.payload }, - } + }; case actionConstants.CLEAR_PENDING_TOKENS: { return { ...metamaskState, pendingTokens: {}, - } + }; } case actionConstants.UPDATE_PREFERENCES: { @@ -343,46 +343,46 @@ export default function reduceMetamask(state = {}, action) { ...metamaskState.preferences, ...action.payload, }, - } + }; } case actionConstants.COMPLETE_ONBOARDING: { return { ...metamaskState, completedOnboarding: true, - } + }; } case actionConstants.SET_FIRST_TIME_FLOW_TYPE: { return { ...metamaskState, firstTimeFlowType: action.value, - } + }; } case actionConstants.SET_NEXT_NONCE: { return { ...metamaskState, nextNonce: action.value, - } + }; } default: - return metamaskState + return metamaskState; } } -export const getCurrentLocale = (state) => state.metamask.currentLocale +export const getCurrentLocale = (state) => state.metamask.currentLocale; -export const getAlertEnabledness = (state) => state.metamask.alertEnabledness +export const getAlertEnabledness = (state) => state.metamask.alertEnabledness; export const getUnconnectedAccountAlertEnabledness = (state) => - getAlertEnabledness(state)[ALERT_TYPES.unconnectedAccount] + getAlertEnabledness(state)[ALERT_TYPES.unconnectedAccount]; export const getWeb3ShimUsageAlertEnabledness = (state) => - getAlertEnabledness(state)[ALERT_TYPES.web3ShimUsage] + getAlertEnabledness(state)[ALERT_TYPES.web3ShimUsage]; export const getUnconnectedAccountAlertShown = (state) => - state.metamask.unconnectedAccountAlertShownOrigins + state.metamask.unconnectedAccountAlertShownOrigins; -export const getTokens = (state) => state.metamask.tokens +export const getTokens = (state) => state.metamask.tokens; diff --git a/ui/app/ducks/send/send-duck.test.js b/ui/app/ducks/send/send-duck.test.js index 2d123fb019..3f24b7ece6 100644 --- a/ui/app/ducks/send/send-duck.test.js +++ b/ui/app/ducks/send/send-duck.test.js @@ -1,4 +1,4 @@ -import assert from 'assert' +import assert from 'assert'; import SendReducer, { openToDropdown, @@ -6,28 +6,28 @@ import SendReducer, { updateSendErrors, showGasButtonGroup, hideGasButtonGroup, -} from './send.duck' +} from './send.duck'; describe('Send Duck', function () { const mockState = { mockProp: 123, - } + }; const initState = { toDropdownOpen: false, errors: {}, gasButtonGroupShown: true, - } - const OPEN_TO_DROPDOWN = 'metamask/send/OPEN_TO_DROPDOWN' - const CLOSE_TO_DROPDOWN = 'metamask/send/CLOSE_TO_DROPDOWN' - const UPDATE_SEND_ERRORS = 'metamask/send/UPDATE_SEND_ERRORS' - const RESET_SEND_STATE = 'metamask/send/RESET_SEND_STATE' - const SHOW_GAS_BUTTON_GROUP = 'metamask/send/SHOW_GAS_BUTTON_GROUP' - const HIDE_GAS_BUTTON_GROUP = 'metamask/send/HIDE_GAS_BUTTON_GROUP' + }; + const OPEN_TO_DROPDOWN = 'metamask/send/OPEN_TO_DROPDOWN'; + const CLOSE_TO_DROPDOWN = 'metamask/send/CLOSE_TO_DROPDOWN'; + const UPDATE_SEND_ERRORS = 'metamask/send/UPDATE_SEND_ERRORS'; + const RESET_SEND_STATE = 'metamask/send/RESET_SEND_STATE'; + const SHOW_GAS_BUTTON_GROUP = 'metamask/send/SHOW_GAS_BUTTON_GROUP'; + const HIDE_GAS_BUTTON_GROUP = 'metamask/send/HIDE_GAS_BUTTON_GROUP'; describe('SendReducer()', function () { it('should initialize state', function () { - assert.deepStrictEqual(SendReducer(undefined, {}), initState) - }) + assert.deepStrictEqual(SendReducer(undefined, {}), initState); + }); it('should return state unchanged if it does not match a dispatched actions type', function () { assert.deepStrictEqual( @@ -36,8 +36,8 @@ describe('Send Duck', function () { value: 'someValue', }), mockState, - ) - }) + ); + }); it('should set toDropdownOpen to true when receiving a OPEN_TO_DROPDOWN action', function () { assert.deepStrictEqual( @@ -45,8 +45,8 @@ describe('Send Duck', function () { type: OPEN_TO_DROPDOWN, }), { toDropdownOpen: true, ...mockState }, - ) - }) + ); + }); it('should set toDropdownOpen to false when receiving a CLOSE_TO_DROPDOWN action', function () { assert.deepStrictEqual( @@ -54,8 +54,8 @@ describe('Send Duck', function () { type: CLOSE_TO_DROPDOWN, }), { toDropdownOpen: false, ...mockState }, - ) - }) + ); + }); it('should set gasButtonGroupShown to true when receiving a SHOW_GAS_BUTTON_GROUP action', function () { assert.deepStrictEqual( @@ -64,15 +64,15 @@ describe('Send Duck', function () { { type: SHOW_GAS_BUTTON_GROUP }, ), { gasButtonGroupShown: true, ...mockState }, - ) - }) + ); + }); it('should set gasButtonGroupShown to false when receiving a HIDE_GAS_BUTTON_GROUP action', function () { assert.deepStrictEqual( SendReducer(mockState, { type: HIDE_GAS_BUTTON_GROUP }), { gasButtonGroupShown: false, ...mockState }, - ) - }) + ); + }); it('should extend send.errors with the value of a UPDATE_SEND_ERRORS action', function () { const modifiedMockState = { @@ -80,7 +80,7 @@ describe('Send Duck', function () { errors: { someError: false, }, - } + }; assert.deepStrictEqual( SendReducer(modifiedMockState, { type: UPDATE_SEND_ERRORS, @@ -93,8 +93,8 @@ describe('Send Duck', function () { someOtherError: true, }, }, - ) - }) + ); + }); it('should return the initial state in response to a RESET_SEND_STATE action', function () { assert.deepStrictEqual( @@ -102,34 +102,34 @@ describe('Send Duck', function () { type: RESET_SEND_STATE, }), initState, - ) - }) - }) + ); + }); + }); describe('openToDropdown', function () { - assert.deepStrictEqual(openToDropdown(), { type: OPEN_TO_DROPDOWN }) - }) + assert.deepStrictEqual(openToDropdown(), { type: OPEN_TO_DROPDOWN }); + }); describe('closeToDropdown', function () { - assert.deepStrictEqual(closeToDropdown(), { type: CLOSE_TO_DROPDOWN }) - }) + assert.deepStrictEqual(closeToDropdown(), { type: CLOSE_TO_DROPDOWN }); + }); describe('showGasButtonGroup', function () { assert.deepStrictEqual(showGasButtonGroup(), { type: SHOW_GAS_BUTTON_GROUP, - }) - }) + }); + }); describe('hideGasButtonGroup', function () { assert.deepStrictEqual(hideGasButtonGroup(), { type: HIDE_GAS_BUTTON_GROUP, - }) - }) + }); + }); describe('updateSendErrors', function () { assert.deepStrictEqual(updateSendErrors('mockErrorObject'), { type: UPDATE_SEND_ERRORS, value: 'mockErrorObject', - }) - }) -}) + }); + }); +}); diff --git a/ui/app/ducks/send/send.duck.js b/ui/app/ducks/send/send.duck.js index c5202d442d..b8d9744575 100644 --- a/ui/app/ducks/send/send.duck.js +++ b/ui/app/ducks/send/send.duck.js @@ -1,16 +1,16 @@ // Actions -const OPEN_TO_DROPDOWN = 'metamask/send/OPEN_TO_DROPDOWN' -const CLOSE_TO_DROPDOWN = 'metamask/send/CLOSE_TO_DROPDOWN' -const UPDATE_SEND_ERRORS = 'metamask/send/UPDATE_SEND_ERRORS' -const RESET_SEND_STATE = 'metamask/send/RESET_SEND_STATE' -const SHOW_GAS_BUTTON_GROUP = 'metamask/send/SHOW_GAS_BUTTON_GROUP' -const HIDE_GAS_BUTTON_GROUP = 'metamask/send/HIDE_GAS_BUTTON_GROUP' +const OPEN_TO_DROPDOWN = 'metamask/send/OPEN_TO_DROPDOWN'; +const CLOSE_TO_DROPDOWN = 'metamask/send/CLOSE_TO_DROPDOWN'; +const UPDATE_SEND_ERRORS = 'metamask/send/UPDATE_SEND_ERRORS'; +const RESET_SEND_STATE = 'metamask/send/RESET_SEND_STATE'; +const SHOW_GAS_BUTTON_GROUP = 'metamask/send/SHOW_GAS_BUTTON_GROUP'; +const HIDE_GAS_BUTTON_GROUP = 'metamask/send/HIDE_GAS_BUTTON_GROUP'; const initState = { toDropdownOpen: false, gasButtonGroupShown: true, errors: {}, -} +}; // Reducer export default function reducer(state = initState, action) { @@ -19,12 +19,12 @@ export default function reducer(state = initState, action) { return { ...state, toDropdownOpen: true, - } + }; case CLOSE_TO_DROPDOWN: return { ...state, toDropdownOpen: false, - } + }; case UPDATE_SEND_ERRORS: return { ...state, @@ -32,48 +32,48 @@ export default function reducer(state = initState, action) { ...state.errors, ...action.value, }, - } + }; case SHOW_GAS_BUTTON_GROUP: return { ...state, gasButtonGroupShown: true, - } + }; case HIDE_GAS_BUTTON_GROUP: return { ...state, gasButtonGroupShown: false, - } + }; case RESET_SEND_STATE: - return { ...initState } + return { ...initState }; default: - return state + return state; } } // Action Creators export function openToDropdown() { - return { type: OPEN_TO_DROPDOWN } + return { type: OPEN_TO_DROPDOWN }; } export function closeToDropdown() { - return { type: CLOSE_TO_DROPDOWN } + return { type: CLOSE_TO_DROPDOWN }; } export function showGasButtonGroup() { - return { type: SHOW_GAS_BUTTON_GROUP } + return { type: SHOW_GAS_BUTTON_GROUP }; } export function hideGasButtonGroup() { - return { type: HIDE_GAS_BUTTON_GROUP } + return { type: HIDE_GAS_BUTTON_GROUP }; } export function updateSendErrors(errorObject) { return { type: UPDATE_SEND_ERRORS, value: errorObject, - } + }; } export function resetSendState() { - return { type: RESET_SEND_STATE } + return { type: RESET_SEND_STATE }; } diff --git a/ui/app/ducks/swaps/swaps.js b/ui/app/ducks/swaps/swaps.js index d67e8c994b..f59f20639b 100644 --- a/ui/app/ducks/swaps/swaps.js +++ b/ui/app/ducks/swaps/swaps.js @@ -1,8 +1,8 @@ -import { createSlice } from '@reduxjs/toolkit' -import BigNumber from 'bignumber.js' -import log from 'loglevel' +import { createSlice } from '@reduxjs/toolkit'; +import BigNumber from 'bignumber.js'; +import log from 'loglevel'; -import { getStorageItem, setStorageItem } from '../../../lib/storage-helpers' +import { getStorageItem, setStorageItem } from '../../../lib/storage-helpers'; import { addToken, @@ -24,50 +24,50 @@ import { setSelectedQuoteAggId, setSwapsTxGasLimit, cancelTx, -} from '../../store/actions' +} from '../../store/actions'; import { AWAITING_SWAP_ROUTE, BUILD_QUOTE_ROUTE, LOADING_QUOTES_ROUTE, SWAPS_ERROR_ROUTE, SWAPS_MAINTENANCE_ROUTE, -} from '../../helpers/constants/routes' +} from '../../helpers/constants/routes'; import { fetchSwapsFeatureLiveness, fetchSwapsGasPrices, -} from '../../pages/swaps/swaps.util' -import { calcGasTotal } from '../../pages/send/send.utils' +} from '../../pages/swaps/swaps.util'; +import { calcGasTotal } from '../../pages/send/send.utils'; import { decimalToHex, getValueFromWeiHex, decGWEIToHexWEI, hexToDecimal, hexWEIToDecGWEI, -} from '../../helpers/utils/conversions.util' -import { conversionLessThan } from '../../helpers/utils/conversion-util' -import { calcTokenAmount } from '../../helpers/utils/token-util' +} from '../../helpers/utils/conversions.util'; +import { conversionLessThan } from '../../helpers/utils/conversion-util'; +import { calcTokenAmount } from '../../helpers/utils/token-util'; import { getSelectedAccount, getTokenExchangeRates, getUSDConversionRate, -} from '../../selectors' +} from '../../selectors'; import { ERROR_FETCHING_QUOTES, QUOTES_NOT_AVAILABLE_ERROR, ETH_SWAPS_TOKEN_OBJECT, SWAP_FAILED_ERROR, SWAPS_FETCH_ORDER_CONFLICT, -} from '../../helpers/constants/swaps' -import { TRANSACTION_CATEGORIES } from '../../../../shared/constants/transaction' +} from '../../helpers/constants/swaps'; +import { TRANSACTION_CATEGORIES } from '../../../../shared/constants/transaction'; const GAS_PRICES_LOADING_STATES = { INITIAL: 'INITIAL', LOADING: 'LOADING', FAILED: 'FAILED', COMPLETED: 'COMPLETED', -} +}; -export const FALLBACK_GAS_MULTIPLIER = 1.5 +export const FALLBACK_GAS_MULTIPLIER = 1.5; const initialState = { aggregatorMetadata: null, @@ -86,7 +86,7 @@ const initialState = { priceEstimatesLastRetrieved: 0, fallBackPrice: null, }, -} +}; const slice = createSlice({ name: 'swaps', @@ -94,115 +94,115 @@ const slice = createSlice({ reducers: { clearSwapsState: () => initialState, navigatedBackToBuildQuote: (state) => { - state.approveTxId = null - state.balanceError = false - state.fetchingQuotes = false - state.customGas.limit = null - state.customGas.price = null + state.approveTxId = null; + state.balanceError = false; + state.fetchingQuotes = false; + state.customGas.limit = null; + state.customGas.price = null; }, retriedGetQuotes: (state) => { - state.approveTxId = null - state.balanceError = false - state.fetchingQuotes = false + state.approveTxId = null; + state.balanceError = false; + state.fetchingQuotes = false; }, setAggregatorMetadata: (state, action) => { - state.aggregatorMetadata = action.payload + state.aggregatorMetadata = action.payload; }, setBalanceError: (state, action) => { - state.balanceError = action.payload + state.balanceError = action.payload; }, setFetchingQuotes: (state, action) => { - state.fetchingQuotes = action.payload + state.fetchingQuotes = action.payload; }, setFromToken: (state, action) => { - state.fromToken = action.payload + state.fromToken = action.payload; }, setQuotesFetchStartTime: (state, action) => { - state.quotesFetchStartTime = action.payload + state.quotesFetchStartTime = action.payload; }, setTopAssets: (state, action) => { - state.topAssets = action.payload + state.topAssets = action.payload; }, setToToken: (state, action) => { - state.toToken = action.payload + state.toToken = action.payload; }, swapCustomGasModalClosed: (state) => { - state.customGas.price = null - state.customGas.limit = null + state.customGas.price = null; + state.customGas.limit = null; }, swapCustomGasModalPriceEdited: (state, action) => { - state.customGas.price = action.payload + state.customGas.price = action.payload; }, swapCustomGasModalLimitEdited: (state, action) => { - state.customGas.limit = action.payload + state.customGas.limit = action.payload; }, swapGasPriceEstimatesFetchStarted: (state) => { - state.customGas.loading = GAS_PRICES_LOADING_STATES.LOADING + state.customGas.loading = GAS_PRICES_LOADING_STATES.LOADING; }, swapGasPriceEstimatesFetchFailed: (state) => { - state.customGas.loading = GAS_PRICES_LOADING_STATES.FAILED + state.customGas.loading = GAS_PRICES_LOADING_STATES.FAILED; }, swapGasPriceEstimatesFetchCompleted: (state, action) => { - state.customGas.priceEstimates = action.payload.priceEstimates - state.customGas.loading = GAS_PRICES_LOADING_STATES.COMPLETED + state.customGas.priceEstimates = action.payload.priceEstimates; + state.customGas.loading = GAS_PRICES_LOADING_STATES.COMPLETED; state.customGas.priceEstimatesLastRetrieved = - action.payload.priceEstimatesLastRetrieved + action.payload.priceEstimatesLastRetrieved; }, retrievedFallbackSwapsGasPrice: (state, action) => { - state.customGas.fallBackPrice = action.payload + state.customGas.fallBackPrice = action.payload; }, }, -}) +}); -const { actions, reducer } = slice +const { actions, reducer } = slice; -export default reducer +export default reducer; // Selectors -export const getAggregatorMetadata = (state) => state.swaps.aggregatorMetadata +export const getAggregatorMetadata = (state) => state.swaps.aggregatorMetadata; -export const getBalanceError = (state) => state.swaps.balanceError +export const getBalanceError = (state) => state.swaps.balanceError; -export const getFromToken = (state) => state.swaps.fromToken +export const getFromToken = (state) => state.swaps.fromToken; -export const getTopAssets = (state) => state.swaps.topAssets +export const getTopAssets = (state) => state.swaps.topAssets; -export const getToToken = (state) => state.swaps.toToken +export const getToToken = (state) => state.swaps.toToken; -export const getFetchingQuotes = (state) => state.swaps.fetchingQuotes +export const getFetchingQuotes = (state) => state.swaps.fetchingQuotes; export const getQuotesFetchStartTime = (state) => - state.swaps.quotesFetchStartTime + state.swaps.quotesFetchStartTime; export const getSwapsCustomizationModalPrice = (state) => - state.swaps.customGas.price + state.swaps.customGas.price; export const getSwapsCustomizationModalLimit = (state) => - state.swaps.customGas.limit + state.swaps.customGas.limit; export const swapGasPriceEstimateIsLoading = (state) => - state.swaps.customGas.loading === GAS_PRICES_LOADING_STATES.LOADING + state.swaps.customGas.loading === GAS_PRICES_LOADING_STATES.LOADING; export const swapGasEstimateLoadingHasFailed = (state) => - state.swaps.customGas.loading === GAS_PRICES_LOADING_STATES.INITIAL + state.swaps.customGas.loading === GAS_PRICES_LOADING_STATES.INITIAL; export const getSwapGasPriceEstimateData = (state) => - state.swaps.customGas.priceEstimates + state.swaps.customGas.priceEstimates; export const getSwapsPriceEstimatesLastRetrieved = (state) => - state.swaps.customGas.priceEstimatesLastRetrieved + state.swaps.customGas.priceEstimatesLastRetrieved; export const getSwapsFallbackGasPrice = (state) => - state.swaps.customGas.fallBackPrice + state.swaps.customGas.fallBackPrice; export function shouldShowCustomPriceTooLowWarning(state) { - const { average } = getSwapGasPriceEstimateData(state) + const { average } = getSwapGasPriceEstimateData(state); - const customGasPrice = getSwapsCustomizationModalPrice(state) + const customGasPrice = getSwapsCustomizationModalPrice(state); if (!customGasPrice || average === undefined) { - return false + return false; } const customPriceRisksSwapFailure = conversionLessThan( @@ -213,83 +213,84 @@ export function shouldShowCustomPriceTooLowWarning(state) { toDenomination: 'GWEI', }, { value: average, fromNumericBase: 'dec' }, - ) + ); - return customPriceRisksSwapFailure + return customPriceRisksSwapFailure; } // Background selectors -const getSwapsState = (state) => state.metamask.swapsState +const getSwapsState = (state) => state.metamask.swapsState; export const getSwapsFeatureLiveness = (state) => - state.metamask.swapsState.swapsFeatureIsLive + state.metamask.swapsState.swapsFeatureIsLive; export const getSwapsQuoteRefreshTime = (state) => - state.metamask.swapsState.swapsQuoteRefreshTime + state.metamask.swapsState.swapsQuoteRefreshTime; export const getBackgroundSwapRouteState = (state) => - state.metamask.swapsState.routeState + state.metamask.swapsState.routeState; export const getCustomSwapsGas = (state) => - state.metamask.swapsState.customMaxGas + state.metamask.swapsState.customMaxGas; export const getCustomSwapsGasPrice = (state) => - state.metamask.swapsState.customGasPrice + state.metamask.swapsState.customGasPrice; -export const getFetchParams = (state) => state.metamask.swapsState.fetchParams +export const getFetchParams = (state) => state.metamask.swapsState.fetchParams; -export const getQuotes = (state) => state.metamask.swapsState.quotes +export const getQuotes = (state) => state.metamask.swapsState.quotes; export const getQuotesLastFetched = (state) => - state.metamask.swapsState.quotesLastFetched + state.metamask.swapsState.quotesLastFetched; export const getSelectedQuote = (state) => { - const { selectedAggId, quotes } = getSwapsState(state) - return quotes[selectedAggId] -} + const { selectedAggId, quotes } = getSwapsState(state); + return quotes[selectedAggId]; +}; -export const getSwapsErrorKey = (state) => getSwapsState(state)?.errorKey +export const getSwapsErrorKey = (state) => getSwapsState(state)?.errorKey; export const getShowQuoteLoadingScreen = (state) => - state.swaps.showQuoteLoadingScreen + state.swaps.showQuoteLoadingScreen; -export const getSwapsTokens = (state) => state.metamask.swapsState.tokens +export const getSwapsTokens = (state) => state.metamask.swapsState.tokens; export const getSwapsWelcomeMessageSeenStatus = (state) => - state.metamask.swapsWelcomeMessageHasBeenShown + state.metamask.swapsWelcomeMessageHasBeenShown; export const getTopQuote = (state) => { - const { topAggId, quotes } = getSwapsState(state) - return quotes[topAggId] -} + const { topAggId, quotes } = getSwapsState(state); + return quotes[topAggId]; +}; -export const getApproveTxId = (state) => state.metamask.swapsState.approveTxId +export const getApproveTxId = (state) => state.metamask.swapsState.approveTxId; -export const getTradeTxId = (state) => state.metamask.swapsState.tradeTxId +export const getTradeTxId = (state) => state.metamask.swapsState.tradeTxId; export const getUsedQuote = (state) => - getSelectedQuote(state) || getTopQuote(state) + getSelectedQuote(state) || getTopQuote(state); // Compound selectors export const getDestinationTokenInfo = (state) => - getFetchParams(state)?.metaData?.destinationTokenInfo + getFetchParams(state)?.metaData?.destinationTokenInfo; export const getUsedSwapsGasPrice = (state) => - getCustomSwapsGasPrice(state) || getSwapsFallbackGasPrice(state) + getCustomSwapsGasPrice(state) || getSwapsFallbackGasPrice(state); export const getApproveTxParams = (state) => { - const { approvalNeeded } = getSelectedQuote(state) || getTopQuote(state) || {} + const { approvalNeeded } = + getSelectedQuote(state) || getTopQuote(state) || {}; if (!approvalNeeded) { - return null + return null; } - const data = getSwapsState(state)?.customApproveTxData || approvalNeeded.data + const data = getSwapsState(state)?.customApproveTxData || approvalNeeded.data; - const gasPrice = getCustomSwapsGasPrice(state) || approvalNeeded.gasPrice - return { ...approvalNeeded, gasPrice, data } -} + const gasPrice = getCustomSwapsGasPrice(state) || approvalNeeded.gasPrice; + return { ...approvalNeeded, gasPrice, data }; +}; // Actions / action-creators @@ -311,7 +312,7 @@ const { swapCustomGasModalLimitEdited, retrievedFallbackSwapsGasPrice, swapCustomGasModalClosed, -} = actions +} = actions; export { clearSwapsState, @@ -325,49 +326,49 @@ export { swapCustomGasModalPriceEdited, swapCustomGasModalLimitEdited, swapCustomGasModalClosed, -} +}; export const navigateBackToBuildQuote = (history) => { return async (dispatch) => { // TODO: Ensure any fetch in progress is cancelled - await dispatch(setBackgroundSwapRouteState('')) - dispatch(navigatedBackToBuildQuote()) - history.push(BUILD_QUOTE_ROUTE) - } -} + await dispatch(setBackgroundSwapRouteState('')); + dispatch(navigatedBackToBuildQuote()); + history.push(BUILD_QUOTE_ROUTE); + }; +}; export const prepareForRetryGetQuotes = () => { return async (dispatch) => { // TODO: Ensure any fetch in progress is cancelled - await dispatch(resetSwapsPostFetchState()) - dispatch(retriedGetQuotes()) - } -} + await dispatch(resetSwapsPostFetchState()); + dispatch(retriedGetQuotes()); + }; +}; export const prepareToLeaveSwaps = () => { return async (dispatch) => { - dispatch(clearSwapsState()) - await dispatch(resetBackgroundSwapsState()) - } -} + dispatch(clearSwapsState()); + await dispatch(resetBackgroundSwapsState()); + }; +}; export const swapsQuoteSelected = (aggId) => { return (dispatch) => { - dispatch(swapCustomGasModalLimitEdited(null)) - dispatch(setSelectedQuoteAggId(aggId)) - dispatch(setSwapsTxGasLimit('')) - } -} + dispatch(swapCustomGasModalLimitEdited(null)); + dispatch(setSelectedQuoteAggId(aggId)); + dispatch(setSwapsTxGasLimit('')); + }; +}; export const fetchAndSetSwapsGasPriceInfo = () => { return async (dispatch) => { - const basicEstimates = await dispatch(fetchMetaSwapsGasPriceEstimates()) + const basicEstimates = await dispatch(fetchMetaSwapsGasPriceEstimates()); if (basicEstimates?.fast) { - dispatch(setSwapsTxGasPrice(decGWEIToHexWEI(basicEstimates.fast))) + dispatch(setSwapsTxGasPrice(decGWEIToHexWEI(basicEstimates.fast))); } - } -} + }; +}; export const fetchQuotesAndSetQuoteState = ( history, @@ -376,23 +377,23 @@ export const fetchQuotesAndSetQuoteState = ( metaMetricsEvent, ) => { return async (dispatch, getState) => { - let swapsFeatureIsLive = false + let swapsFeatureIsLive = false; try { - swapsFeatureIsLive = await fetchSwapsFeatureLiveness() + swapsFeatureIsLive = await fetchSwapsFeatureLiveness(); } catch (error) { - log.error('Failed to fetch Swaps liveness, defaulting to false.', error) + log.error('Failed to fetch Swaps liveness, defaulting to false.', error); } - await dispatch(setSwapsLiveness(swapsFeatureIsLive)) + await dispatch(setSwapsLiveness(swapsFeatureIsLive)); if (!swapsFeatureIsLive) { - await history.push(SWAPS_MAINTENANCE_ROUTE) - return + await history.push(SWAPS_MAINTENANCE_ROUTE); + return; } - const state = getState() - const fetchParams = getFetchParams(state) - const selectedAccount = getSelectedAccount(state) - const balanceError = getBalanceError(state) + const state = getState(); + const fetchParams = getFetchParams(state); + const selectedAccount = getSelectedAccount(state); + const balanceError = getBalanceError(state); const fetchParamsFromToken = fetchParams?.metaData?.sourceTokenInfo?.symbol === 'ETH' ? { @@ -404,32 +405,32 @@ export const fetchQuotesAndSetQuoteState = ( }), balance: hexToDecimal(selectedAccount.balance), } - : fetchParams?.metaData?.sourceTokenInfo - const selectedFromToken = getFromToken(state) || fetchParamsFromToken || {} + : fetchParams?.metaData?.sourceTokenInfo; + const selectedFromToken = getFromToken(state) || fetchParamsFromToken || {}; const selectedToToken = - getToToken(state) || fetchParams?.metaData?.destinationTokenInfo || {} + getToToken(state) || fetchParams?.metaData?.destinationTokenInfo || {}; const { address: fromTokenAddress, symbol: fromTokenSymbol, decimals: fromTokenDecimals, iconUrl: fromTokenIconUrl, balance: fromTokenBalance, - } = selectedFromToken + } = selectedFromToken; const { address: toTokenAddress, symbol: toTokenSymbol, decimals: toTokenDecimals, iconUrl: toTokenIconUrl, - } = selectedToToken - await dispatch(setBackgroundSwapRouteState('loading')) - history.push(LOADING_QUOTES_ROUTE) - dispatch(setFetchingQuotes(true)) + } = selectedToToken; + await dispatch(setBackgroundSwapRouteState('loading')); + history.push(LOADING_QUOTES_ROUTE); + dispatch(setFetchingQuotes(true)); - const contractExchangeRates = getTokenExchangeRates(state) + const contractExchangeRates = getTokenExchangeRates(state); - let destinationTokenAddedForSwap = false + let destinationTokenAddedForSwap = false; if (toTokenSymbol !== 'ETH' && !contractExchangeRates[toTokenAddress]) { - destinationTokenAddedForSwap = true + destinationTokenAddedForSwap = true; await dispatch( addToken( toTokenAddress, @@ -438,7 +439,7 @@ export const fetchQuotesAndSetQuoteState = ( toTokenIconUrl, true, ), - ) + ); } if ( fromTokenSymbol !== 'ETH' && @@ -454,19 +455,19 @@ export const fetchQuotesAndSetQuoteState = ( fromTokenIconUrl, true, ), - ) + ); } - const swapsTokens = getSwapsTokens(state) + const swapsTokens = getSwapsTokens(state); const sourceTokenInfo = swapsTokens?.find(({ address }) => address === fromTokenAddress) || - selectedFromToken + selectedFromToken; const destinationTokenInfo = swapsTokens?.find(({ address }) => address === toTokenAddress) || - selectedToToken + selectedToToken; - dispatch(setFromToken(selectedFromToken)) + dispatch(setFromToken(selectedFromToken)); metaMetricsEvent({ event: 'Quotes Requested', @@ -480,11 +481,11 @@ export const fetchQuotesAndSetQuoteState = ( custom_slippage: maxSlippage !== 2, anonymizedData: true, }, - }) + }); try { - const fetchStartTime = Date.now() - dispatch(setQuotesFetchStartTime(fetchStartTime)) + const fetchStartTime = Date.now(); + dispatch(setQuotesFetchStartTime(fetchStartTime)); const fetchAndSetQuotesPromise = dispatch( fetchAndSetQuotes( @@ -504,14 +505,14 @@ export const fetchQuotesAndSetQuoteState = ( accountBalance: selectedAccount.balance, }, ), - ) + ); - const gasPriceFetchPromise = dispatch(fetchAndSetSwapsGasPriceInfo()) + const gasPriceFetchPromise = dispatch(fetchAndSetSwapsGasPriceInfo()); const [[fetchedQuotes, selectedAggId]] = await Promise.all([ fetchAndSetQuotesPromise, gasPriceFetchPromise, - ]) + ]); if (Object.values(fetchedQuotes)?.length === 0) { metaMetricsEvent({ @@ -525,10 +526,10 @@ export const fetchQuotesAndSetQuoteState = ( slippage: maxSlippage, custom_slippage: maxSlippage !== 2, }, - }) - dispatch(setSwapsErrorKey(QUOTES_NOT_AVAILABLE_ERROR)) + }); + dispatch(setSwapsErrorKey(QUOTES_NOT_AVAILABLE_ERROR)); } else { - const newSelectedQuote = fetchedQuotes[selectedAggId] + const newSelectedQuote = fetchedQuotes[selectedAggId]; metaMetricsEvent({ event: 'Quotes Received', @@ -549,87 +550,90 @@ export const fetchQuotesAndSetQuoteState = ( available_quotes: Object.values(fetchedQuotes)?.length, anonymizedData: true, }, - }) + }); - dispatch(setInitialGasEstimate(selectedAggId)) + dispatch(setInitialGasEstimate(selectedAggId)); } } catch (e) { // A newer swap request is running, so simply bail and let the newer request respond if (e.message === SWAPS_FETCH_ORDER_CONFLICT) { - log.debug(`Swap fetch order conflict detected; ignoring older request`) - return + log.debug(`Swap fetch order conflict detected; ignoring older request`); + return; } // TODO: Check for any errors we should expect to occur in production, and report others to Sentry - log.error(`Error fetching quotes: `, e) + log.error(`Error fetching quotes: `, e); - dispatch(setSwapsErrorKey(ERROR_FETCHING_QUOTES)) + dispatch(setSwapsErrorKey(ERROR_FETCHING_QUOTES)); } - dispatch(setFetchingQuotes(false)) - } -} + dispatch(setFetchingQuotes(false)); + }; +}; export const signAndSendTransactions = (history, metaMetricsEvent) => { return async (dispatch, getState) => { - let swapsFeatureIsLive = false + let swapsFeatureIsLive = false; try { - swapsFeatureIsLive = await fetchSwapsFeatureLiveness() + swapsFeatureIsLive = await fetchSwapsFeatureLiveness(); } catch (error) { - log.error('Failed to fetch Swaps liveness, defaulting to false.', error) + log.error('Failed to fetch Swaps liveness, defaulting to false.', error); } - await dispatch(setSwapsLiveness(swapsFeatureIsLive)) + await dispatch(setSwapsLiveness(swapsFeatureIsLive)); if (!swapsFeatureIsLive) { - await history.push(SWAPS_MAINTENANCE_ROUTE) - return + await history.push(SWAPS_MAINTENANCE_ROUTE); + return; } - const state = getState() - const customSwapsGas = getCustomSwapsGas(state) - const fetchParams = getFetchParams(state) - const { metaData, value: swapTokenValue, slippage } = fetchParams - const { sourceTokenInfo = {}, destinationTokenInfo = {} } = metaData - await dispatch(setBackgroundSwapRouteState('awaiting')) - await dispatch(stopPollingForQuotes()) - history.push(AWAITING_SWAP_ROUTE) + const state = getState(); + const customSwapsGas = getCustomSwapsGas(state); + const fetchParams = getFetchParams(state); + const { metaData, value: swapTokenValue, slippage } = fetchParams; + const { sourceTokenInfo = {}, destinationTokenInfo = {} } = metaData; + await dispatch(setBackgroundSwapRouteState('awaiting')); + await dispatch(stopPollingForQuotes()); + history.push(AWAITING_SWAP_ROUTE); - const { fast: fastGasEstimate } = getSwapGasPriceEstimateData(state) + const { fast: fastGasEstimate } = getSwapGasPriceEstimateData(state); - const usedQuote = getUsedQuote(state) - const usedTradeTxParams = usedQuote.trade + const usedQuote = getUsedQuote(state); + const usedTradeTxParams = usedQuote.trade; - const estimatedGasLimit = new BigNumber(usedQuote?.gasEstimate || `0x0`, 16) + const estimatedGasLimit = new BigNumber( + usedQuote?.gasEstimate || `0x0`, + 16, + ); const estimatedGasLimitWithMultiplier = estimatedGasLimit .times(usedQuote?.gasMultiplier || FALLBACK_GAS_MULTIPLIER, 10) .round(0) - .toString(16) + .toString(16); const maxGasLimit = customSwapsGas || (usedQuote?.gasEstimate ? estimatedGasLimitWithMultiplier - : `0x${decimalToHex(usedQuote?.maxGas || 0)}`) + : `0x${decimalToHex(usedQuote?.maxGas || 0)}`); - const usedGasPrice = getUsedSwapsGasPrice(state) - usedTradeTxParams.gas = maxGasLimit - usedTradeTxParams.gasPrice = usedGasPrice + const usedGasPrice = getUsedSwapsGasPrice(state); + usedTradeTxParams.gas = maxGasLimit; + usedTradeTxParams.gasPrice = usedGasPrice; - const usdConversionRate = getUSDConversionRate(state) + const usdConversionRate = getUSDConversionRate(state); const destinationValue = calcTokenAmount( usedQuote.destinationAmount, destinationTokenInfo.decimals || 18, - ).toPrecision(8) + ).toPrecision(8); const usedGasLimitEstimate = usedQuote?.gasEstimateWithRefund || - `0x${decimalToHex(usedQuote?.averageGas || 0)}` + `0x${decimalToHex(usedQuote?.averageGas || 0)}`; const totalGasLimitEstimate = new BigNumber(usedGasLimitEstimate, 16) .plus(usedQuote.approvalNeeded?.gas || '0x0', 16) - .toString(16) + .toString(16); const gasEstimateTotalInUSD = getValueFromWeiHex({ value: calcGasTotal(totalGasLimitEstimate, usedGasPrice), toCurrency: 'usd', conversionRate: usdConversionRate, numberOfDecimals: 6, - }) + }); const swapMetaData = { token_from: sourceTokenInfo.symbol, @@ -654,24 +658,24 @@ export const signAndSendTransactions = (history, metaMetricsEvent) => { performance_savings: usedQuote.savings?.performance, fee_savings: usedQuote.savings?.fee, median_metamask_fee: usedQuote.savings?.medianMetaMaskFee, - } + }; metaMetricsEvent({ event: 'Swap Started', category: 'swaps', sensitiveProperties: swapMetaData, - }) + }); - let finalApproveTxMeta - const approveTxParams = getApproveTxParams(state) + let finalApproveTxMeta; + const approveTxParams = getApproveTxParams(state); if (approveTxParams) { const approveTxMeta = await dispatch( addUnapprovedTransaction( { ...approveTxParams, amount: '0x0' }, 'metamask', ), - ) - await dispatch(setApproveTxId(approveTxMeta.id)) + ); + await dispatch(setApproveTxId(approveTxMeta.id)); finalApproveTxMeta = await dispatch( updateTransaction( { @@ -681,20 +685,20 @@ export const signAndSendTransactions = (history, metaMetricsEvent) => { }, true, ), - ) + ); try { - await dispatch(updateAndApproveTx(finalApproveTxMeta, true)) + await dispatch(updateAndApproveTx(finalApproveTxMeta, true)); } catch (e) { - await dispatch(setSwapsErrorKey(SWAP_FAILED_ERROR)) - history.push(SWAPS_ERROR_ROUTE) - return + await dispatch(setSwapsErrorKey(SWAP_FAILED_ERROR)); + history.push(SWAPS_ERROR_ROUTE); + return; } } const tradeTxMeta = await dispatch( addUnapprovedTransaction(usedTradeTxParams, 'metamask'), - ) - dispatch(setTradeTxId(tradeTxMeta.id)) + ); + dispatch(setTradeTxId(tradeTxMeta.id)); // The simulationFails property is added during the transaction controllers // addUnapprovedTransaction call if the estimateGas call fails. In cases @@ -706,10 +710,10 @@ export const signAndSendTransactions = (history, metaMetricsEvent) => { // transactions that get published to the blockchain only to fail and thereby // waste the user's funds on gas. if (!approveTxParams && tradeTxMeta.simulationFails) { - await dispatch(cancelTx(tradeTxMeta, false)) - await dispatch(setSwapsErrorKey(SWAP_FAILED_ERROR)) - history.push(SWAPS_ERROR_ROUTE) - return + await dispatch(cancelTx(tradeTxMeta, false)); + await dispatch(setSwapsErrorKey(SWAP_FAILED_ERROR)); + history.push(SWAPS_ERROR_ROUTE); + return; } const finalTradeTxMeta = await dispatch( updateTransaction( @@ -726,67 +730,67 @@ export const signAndSendTransactions = (history, metaMetricsEvent) => { }, true, ), - ) + ); try { - await dispatch(updateAndApproveTx(finalTradeTxMeta, true)) + await dispatch(updateAndApproveTx(finalTradeTxMeta, true)); } catch (e) { - await dispatch(setSwapsErrorKey(SWAP_FAILED_ERROR)) - history.push(SWAPS_ERROR_ROUTE) - return + await dispatch(setSwapsErrorKey(SWAP_FAILED_ERROR)); + history.push(SWAPS_ERROR_ROUTE); + return; } - await forceUpdateMetamaskState(dispatch) - } -} + await forceUpdateMetamaskState(dispatch); + }; +}; export function fetchMetaSwapsGasPriceEstimates() { return async (dispatch, getState) => { - const state = getState() + const state = getState(); const priceEstimatesLastRetrieved = getSwapsPriceEstimatesLastRetrieved( state, - ) + ); const timeLastRetrieved = priceEstimatesLastRetrieved || (await getStorageItem('METASWAP_GAS_PRICE_ESTIMATES_LAST_RETRIEVED')) || - 0 + 0; - dispatch(swapGasPriceEstimatesFetchStarted()) + dispatch(swapGasPriceEstimatesFetchStarted()); - let priceEstimates + let priceEstimates; try { if (Date.now() - timeLastRetrieved > 30000) { - priceEstimates = await fetchSwapsGasPrices() + priceEstimates = await fetchSwapsGasPrices(); } else { const cachedPriceEstimates = await getStorageItem( 'METASWAP_GAS_PRICE_ESTIMATES', - ) - priceEstimates = cachedPriceEstimates || (await fetchSwapsGasPrices()) + ); + priceEstimates = cachedPriceEstimates || (await fetchSwapsGasPrices()); } } catch (e) { - log.warn('Fetching swaps gas prices failed:', e) + log.warn('Fetching swaps gas prices failed:', e); if (!e.message?.match(/NetworkError|Fetch failed with status:/u)) { - throw e + throw e; } - dispatch(swapGasPriceEstimatesFetchFailed()) + dispatch(swapGasPriceEstimatesFetchFailed()); try { - const gasPrice = await global.ethQuery.gasPrice() - const gasPriceInDecGWEI = hexWEIToDecGWEI(gasPrice.toString(10)) + const gasPrice = await global.ethQuery.gasPrice(); + const gasPriceInDecGWEI = hexWEIToDecGWEI(gasPrice.toString(10)); - dispatch(retrievedFallbackSwapsGasPrice(gasPriceInDecGWEI)) - return null + dispatch(retrievedFallbackSwapsGasPrice(gasPriceInDecGWEI)); + return null; } catch (networkGasPriceError) { console.error( `Failed to retrieve fallback gas price: `, networkGasPriceError, - ) - return null + ); + return null; } } - const timeRetrieved = Date.now() + const timeRetrieved = Date.now(); await Promise.all([ setStorageItem('METASWAP_GAS_PRICE_ESTIMATES', priceEstimates), @@ -794,14 +798,14 @@ export function fetchMetaSwapsGasPriceEstimates() { 'METASWAP_GAS_PRICE_ESTIMATES_LAST_RETRIEVED', timeRetrieved, ), - ]) + ]); dispatch( swapGasPriceEstimatesFetchCompleted({ priceEstimates, priceEstimatesLastRetrieved: timeRetrieved, }), - ) - return priceEstimates - } + ); + return priceEstimates; + }; } diff --git a/ui/app/helpers/constants/common.js b/ui/app/helpers/constants/common.js index 7a0503112d..c2e8f9bb5c 100644 --- a/ui/app/helpers/constants/common.js +++ b/ui/app/helpers/constants/common.js @@ -1,13 +1,13 @@ -export const ETH = 'ETH' -export const GWEI = 'GWEI' -export const WEI = 'WEI' +export const ETH = 'ETH'; +export const GWEI = 'GWEI'; +export const WEI = 'WEI'; -export const PRIMARY = 'PRIMARY' -export const SECONDARY = 'SECONDARY' +export const PRIMARY = 'PRIMARY'; +export const SECONDARY = 'SECONDARY'; export const GAS_ESTIMATE_TYPES = { SLOW: 'SLOW', AVERAGE: 'AVERAGE', FAST: 'FAST', FASTEST: 'FASTEST', -} +}; diff --git a/ui/app/helpers/constants/connected-sites.js b/ui/app/helpers/constants/connected-sites.js index 717460f297..2a5579fcda 100644 --- a/ui/app/helpers/constants/connected-sites.js +++ b/ui/app/helpers/constants/connected-sites.js @@ -1,4 +1,4 @@ -export const STATUS_CONNECTED = 'STATUS_CONNECTED' +export const STATUS_CONNECTED = 'STATUS_CONNECTED'; export const STATUS_CONNECTED_TO_ANOTHER_ACCOUNT = - 'STATUS_CONNECTED_TO_ANOTHER_ACCOUNT' -export const STATUS_NOT_CONNECTED = 'STATUS_NOT_CONNECTED' + 'STATUS_CONNECTED_TO_ANOTHER_ACCOUNT'; +export const STATUS_NOT_CONNECTED = 'STATUS_NOT_CONNECTED'; diff --git a/ui/app/helpers/constants/design-system.js b/ui/app/helpers/constants/design-system.js index 6caef4414f..070ea2748d 100644 --- a/ui/app/helpers/constants/design-system.js +++ b/ui/app/helpers/constants/design-system.js @@ -32,7 +32,7 @@ export const COLORS = { RINKEBY: 'rinkeby', GOERLI: 'goerli', TRANSPARENT: 'transparent', -} +}; export const TYPOGRAPHY = { H1: 'h1', @@ -45,9 +45,9 @@ export const TYPOGRAPHY = { H8: 'h8', H9: 'h9', Paragraph: 'paragraph', -} +}; -const NONE = 'none' +const NONE = 'none'; export const SIZES = { XS: 'xs', @@ -56,7 +56,7 @@ export const SIZES = { LG: 'lg', XL: 'xl', NONE, -} +}; export const BORDER_STYLE = { DASHED: 'dashed', @@ -64,11 +64,11 @@ export const BORDER_STYLE = { DOTTED: 'dotted', DOUBLE: 'double', NONE, -} +}; -const FLEX_END = 'flex-end' -const FLEX_START = 'flex-start' -const CENTER = 'center' +const FLEX_END = 'flex-end'; +const FLEX_START = 'flex-start'; +const CENTER = 'center'; export const ALIGN_ITEMS = { FLEX_START, @@ -76,7 +76,7 @@ export const ALIGN_ITEMS = { CENTER, BASELINE: 'baseline', STRETCH: 'stretch', -} +}; export const JUSTIFY_CONTENT = { FLEX_START, @@ -85,7 +85,7 @@ export const JUSTIFY_CONTENT = { SPACE_AROUND: 'space-around', SPACE_BETWEEN: 'space-between', SPACE_EVENLY: 'space-evenly', -} +}; export const DISPLAY = { BLOCK: 'block', @@ -95,7 +95,7 @@ export const DISPLAY = { INLINE_FLEX: 'inline-flex', INLINE_GRID: 'inline-grid', LIST_ITEM: 'list-item', -} +}; const FRACTIONS = { HALF: '1/2', @@ -124,7 +124,7 @@ const FRACTIONS = { NINE_TWELFTHS: '9/12', TEN_TWELFTHS: '10/12', ELEVEN_TWELFTHS: '11/12', -} +}; export const BLOCK_SIZES = { ...FRACTIONS, @@ -132,14 +132,14 @@ export const BLOCK_SIZES = { MAX: 'max', MIN: 'min', FULL: 'full', -} +}; export const TEXT_ALIGN = { LEFT: 'left', CENTER: 'center', RIGHT: 'right', JUSTIFY: 'justify', -} +}; export const FONT_WEIGHT = { BOLD: 'bold', @@ -153,11 +153,11 @@ export const FONT_WEIGHT = { 700: 700, 800: 800, 900: 900, -} +}; export const SEVERITIES = { DANGER: 'danger', WARNING: 'warning', INFO: 'info', SUCCESS: 'success', -} +}; diff --git a/ui/app/helpers/constants/error-keys.js b/ui/app/helpers/constants/error-keys.js index 704064c964..85ce13d7df 100644 --- a/ui/app/helpers/constants/error-keys.js +++ b/ui/app/helpers/constants/error-keys.js @@ -1,4 +1,4 @@ -export const INSUFFICIENT_FUNDS_ERROR_KEY = 'insufficientFunds' -export const GAS_LIMIT_TOO_LOW_ERROR_KEY = 'gasLimitTooLow' -export const TRANSACTION_ERROR_KEY = 'transactionError' -export const TRANSACTION_NO_CONTRACT_ERROR_KEY = 'transactionErrorNoContract' +export const INSUFFICIENT_FUNDS_ERROR_KEY = 'insufficientFunds'; +export const GAS_LIMIT_TOO_LOW_ERROR_KEY = 'gasLimitTooLow'; +export const TRANSACTION_ERROR_KEY = 'transactionError'; +export const TRANSACTION_NO_CONTRACT_ERROR_KEY = 'transactionErrorNoContract'; diff --git a/ui/app/helpers/constants/routes.js b/ui/app/helpers/constants/routes.js index d3b5904c5c..5b92c3fd59 100644 --- a/ui/app/helpers/constants/routes.js +++ b/ui/app/helpers/constants/routes.js @@ -1,67 +1,69 @@ -const DEFAULT_ROUTE = '/' -const UNLOCK_ROUTE = '/unlock' -const LOCK_ROUTE = '/lock' -const ASSET_ROUTE = '/asset' -const SETTINGS_ROUTE = '/settings' -const GENERAL_ROUTE = '/settings/general' -const ADVANCED_ROUTE = '/settings/advanced' -const SECURITY_ROUTE = '/settings/security' -const ABOUT_US_ROUTE = '/settings/about-us' -const ALERTS_ROUTE = '/settings/alerts' -const NETWORKS_ROUTE = '/settings/networks' -const NETWORKS_FORM_ROUTE = '/settings/networks/form' -const CONTACT_LIST_ROUTE = '/settings/contact-list' -const CONTACT_EDIT_ROUTE = '/settings/contact-list/edit-contact' -const CONTACT_ADD_ROUTE = '/settings/contact-list/add-contact' -const CONTACT_VIEW_ROUTE = '/settings/contact-list/view-contact' -const CONTACT_MY_ACCOUNTS_ROUTE = '/settings/contact-list/my-accounts' -const CONTACT_MY_ACCOUNTS_VIEW_ROUTE = '/settings/contact-list/my-accounts/view' -const CONTACT_MY_ACCOUNTS_EDIT_ROUTE = '/settings/contact-list/my-accounts/edit' -const REVEAL_SEED_ROUTE = '/seed' -const MOBILE_SYNC_ROUTE = '/mobile-sync' -const RESTORE_VAULT_ROUTE = '/restore-vault' -const ADD_TOKEN_ROUTE = '/add-token' -const CONFIRM_ADD_TOKEN_ROUTE = '/confirm-add-token' -const CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE = '/confirm-add-suggested-token' -const NEW_ACCOUNT_ROUTE = '/new-account' -const IMPORT_ACCOUNT_ROUTE = '/new-account/import' -const CONNECT_HARDWARE_ROUTE = '/new-account/connect' -const SEND_ROUTE = '/send' -const CONNECT_ROUTE = '/connect' -const CONNECT_CONFIRM_PERMISSIONS_ROUTE = '/confirm-permissions' -const CONNECTED_ROUTE = '/connected' -const CONNECTED_ACCOUNTS_ROUTE = '/connected/accounts' -const SWAPS_ROUTE = '/swaps' -const BUILD_QUOTE_ROUTE = '/swaps/build-quote' -const VIEW_QUOTE_ROUTE = '/swaps/view-quote' -const LOADING_QUOTES_ROUTE = '/swaps/loading-quotes' -const AWAITING_SWAP_ROUTE = '/swaps/awaiting-swap' -const SWAPS_ERROR_ROUTE = '/swaps/swaps-error' -const SWAPS_MAINTENANCE_ROUTE = '/swaps/maintenance' +const DEFAULT_ROUTE = '/'; +const UNLOCK_ROUTE = '/unlock'; +const LOCK_ROUTE = '/lock'; +const ASSET_ROUTE = '/asset'; +const SETTINGS_ROUTE = '/settings'; +const GENERAL_ROUTE = '/settings/general'; +const ADVANCED_ROUTE = '/settings/advanced'; +const SECURITY_ROUTE = '/settings/security'; +const ABOUT_US_ROUTE = '/settings/about-us'; +const ALERTS_ROUTE = '/settings/alerts'; +const NETWORKS_ROUTE = '/settings/networks'; +const NETWORKS_FORM_ROUTE = '/settings/networks/form'; +const CONTACT_LIST_ROUTE = '/settings/contact-list'; +const CONTACT_EDIT_ROUTE = '/settings/contact-list/edit-contact'; +const CONTACT_ADD_ROUTE = '/settings/contact-list/add-contact'; +const CONTACT_VIEW_ROUTE = '/settings/contact-list/view-contact'; +const CONTACT_MY_ACCOUNTS_ROUTE = '/settings/contact-list/my-accounts'; +const CONTACT_MY_ACCOUNTS_VIEW_ROUTE = + '/settings/contact-list/my-accounts/view'; +const CONTACT_MY_ACCOUNTS_EDIT_ROUTE = + '/settings/contact-list/my-accounts/edit'; +const REVEAL_SEED_ROUTE = '/seed'; +const MOBILE_SYNC_ROUTE = '/mobile-sync'; +const RESTORE_VAULT_ROUTE = '/restore-vault'; +const ADD_TOKEN_ROUTE = '/add-token'; +const CONFIRM_ADD_TOKEN_ROUTE = '/confirm-add-token'; +const CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE = '/confirm-add-suggested-token'; +const NEW_ACCOUNT_ROUTE = '/new-account'; +const IMPORT_ACCOUNT_ROUTE = '/new-account/import'; +const CONNECT_HARDWARE_ROUTE = '/new-account/connect'; +const SEND_ROUTE = '/send'; +const CONNECT_ROUTE = '/connect'; +const CONNECT_CONFIRM_PERMISSIONS_ROUTE = '/confirm-permissions'; +const CONNECTED_ROUTE = '/connected'; +const CONNECTED_ACCOUNTS_ROUTE = '/connected/accounts'; +const SWAPS_ROUTE = '/swaps'; +const BUILD_QUOTE_ROUTE = '/swaps/build-quote'; +const VIEW_QUOTE_ROUTE = '/swaps/view-quote'; +const LOADING_QUOTES_ROUTE = '/swaps/loading-quotes'; +const AWAITING_SWAP_ROUTE = '/swaps/awaiting-swap'; +const SWAPS_ERROR_ROUTE = '/swaps/swaps-error'; +const SWAPS_MAINTENANCE_ROUTE = '/swaps/maintenance'; -const INITIALIZE_ROUTE = '/initialize' -const INITIALIZE_WELCOME_ROUTE = '/initialize/welcome' -const INITIALIZE_UNLOCK_ROUTE = '/initialize/unlock' -const INITIALIZE_CREATE_PASSWORD_ROUTE = '/initialize/create-password' +const INITIALIZE_ROUTE = '/initialize'; +const INITIALIZE_WELCOME_ROUTE = '/initialize/welcome'; +const INITIALIZE_UNLOCK_ROUTE = '/initialize/unlock'; +const INITIALIZE_CREATE_PASSWORD_ROUTE = '/initialize/create-password'; const INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE = - '/initialize/create-password/import-with-seed-phrase' -const INITIALIZE_SELECT_ACTION_ROUTE = '/initialize/select-action' -const INITIALIZE_SEED_PHRASE_ROUTE = '/initialize/seed-phrase' -const INITIALIZE_BACKUP_SEED_PHRASE_ROUTE = '/initialize/backup-seed-phrase' -const INITIALIZE_END_OF_FLOW_ROUTE = '/initialize/end-of-flow' -const INITIALIZE_CONFIRM_SEED_PHRASE_ROUTE = '/initialize/seed-phrase/confirm' -const INITIALIZE_METAMETRICS_OPT_IN_ROUTE = '/initialize/metametrics-opt-in' + '/initialize/create-password/import-with-seed-phrase'; +const INITIALIZE_SELECT_ACTION_ROUTE = '/initialize/select-action'; +const INITIALIZE_SEED_PHRASE_ROUTE = '/initialize/seed-phrase'; +const INITIALIZE_BACKUP_SEED_PHRASE_ROUTE = '/initialize/backup-seed-phrase'; +const INITIALIZE_END_OF_FLOW_ROUTE = '/initialize/end-of-flow'; +const INITIALIZE_CONFIRM_SEED_PHRASE_ROUTE = '/initialize/seed-phrase/confirm'; +const INITIALIZE_METAMETRICS_OPT_IN_ROUTE = '/initialize/metametrics-opt-in'; -const CONFIRM_TRANSACTION_ROUTE = '/confirm-transaction' -const CONFIRM_SEND_ETHER_PATH = '/send-ether' -const CONFIRM_SEND_TOKEN_PATH = '/send-token' -const CONFIRM_DEPLOY_CONTRACT_PATH = '/deploy-contract' -const CONFIRM_APPROVE_PATH = '/approve' -const CONFIRM_TRANSFER_FROM_PATH = '/transfer-from' -const CONFIRM_TOKEN_METHOD_PATH = '/token-method' -const SIGNATURE_REQUEST_PATH = '/signature-request' -const DECRYPT_MESSAGE_REQUEST_PATH = '/decrypt-message-request' -const ENCRYPTION_PUBLIC_KEY_REQUEST_PATH = '/encryption-public-key-request' +const CONFIRM_TRANSACTION_ROUTE = '/confirm-transaction'; +const CONFIRM_SEND_ETHER_PATH = '/send-ether'; +const CONFIRM_SEND_TOKEN_PATH = '/send-token'; +const CONFIRM_DEPLOY_CONTRACT_PATH = '/deploy-contract'; +const CONFIRM_APPROVE_PATH = '/approve'; +const CONFIRM_TRANSFER_FROM_PATH = '/transfer-from'; +const CONFIRM_TOKEN_METHOD_PATH = '/token-method'; +const SIGNATURE_REQUEST_PATH = '/signature-request'; +const DECRYPT_MESSAGE_REQUEST_PATH = '/decrypt-message-request'; +const ENCRYPTION_PUBLIC_KEY_REQUEST_PATH = '/encryption-public-key-request'; // Used to pull a convenient name for analytics tracking events. The key must // be react-router ready path, and can include params such as :id for popup windows @@ -130,7 +132,7 @@ const PATH_NAME_MAP = { [LOADING_QUOTES_ROUTE]: 'Swaps Loading Quotes Page', [AWAITING_SWAP_ROUTE]: 'Swaps Awaiting Swaps Page', [SWAPS_ERROR_ROUTE]: 'Swaps Error Page', -} +}; export { DEFAULT_ROUTE, @@ -195,4 +197,4 @@ export { AWAITING_SWAP_ROUTE, SWAPS_ERROR_ROUTE, SWAPS_MAINTENANCE_ROUTE, -} +}; diff --git a/ui/app/helpers/constants/swaps.js b/ui/app/helpers/constants/swaps.js index af22f84eae..1011306a8f 100644 --- a/ui/app/helpers/constants/swaps.js +++ b/ui/app/helpers/constants/swaps.js @@ -1,6 +1,6 @@ // An address that the metaswap-api recognizes as ETH, in place of the token address that ERC-20 tokens have export const ETH_SWAPS_TOKEN_ADDRESS = - '0x0000000000000000000000000000000000000000' + '0x0000000000000000000000000000000000000000'; export const ETH_SWAPS_TOKEN_OBJECT = { symbol: 'ETH', @@ -8,17 +8,17 @@ export const ETH_SWAPS_TOKEN_OBJECT = { address: ETH_SWAPS_TOKEN_ADDRESS, decimals: 18, iconUrl: 'images/black-eth-logo.svg', -} +}; -export const QUOTES_EXPIRED_ERROR = 'quotes-expired' -export const SWAP_FAILED_ERROR = 'swap-failed-error' -export const ERROR_FETCHING_QUOTES = 'error-fetching-quotes' -export const QUOTES_NOT_AVAILABLE_ERROR = 'quotes-not-avilable' -export const OFFLINE_FOR_MAINTENANCE = 'offline-for-maintenance' -export const SWAPS_FETCH_ORDER_CONFLICT = 'swaps-fetch-order-conflict' +export const QUOTES_EXPIRED_ERROR = 'quotes-expired'; +export const SWAP_FAILED_ERROR = 'swap-failed-error'; +export const ERROR_FETCHING_QUOTES = 'error-fetching-quotes'; +export const QUOTES_NOT_AVAILABLE_ERROR = 'quotes-not-avilable'; +export const OFFLINE_FOR_MAINTENANCE = 'offline-for-maintenance'; +export const SWAPS_FETCH_ORDER_CONFLICT = 'swaps-fetch-order-conflict'; // A gas value for ERC20 approve calls that should be sufficient for all ERC20 approve implementations -export const DEFAULT_ERC20_APPROVE_GAS = '0x1d4c0' +export const DEFAULT_ERC20_APPROVE_GAS = '0x1d4c0'; export const SWAPS_CONTRACT_ADDRESS = - '0x881d40237659c251811cec9c364ef91dc08d300c' + '0x881d40237659c251811cec9c364ef91dc08d300c'; diff --git a/ui/app/helpers/constants/transactions.js b/ui/app/helpers/constants/transactions.js index e344587ba1..f349b3ae6e 100644 --- a/ui/app/helpers/constants/transactions.js +++ b/ui/app/helpers/constants/transactions.js @@ -1,21 +1,21 @@ import { TRANSACTION_CATEGORIES, TRANSACTION_STATUSES, -} from '../../../../shared/constants/transaction' +} from '../../../../shared/constants/transaction'; export const PENDING_STATUS_HASH = { [TRANSACTION_STATUSES.UNAPPROVED]: true, [TRANSACTION_STATUSES.APPROVED]: true, [TRANSACTION_STATUSES.SUBMITTED]: true, -} +}; export const PRIORITY_STATUS_HASH = { ...PENDING_STATUS_HASH, [TRANSACTION_STATUSES.CONFIRMED]: true, -} +}; export const TOKEN_CATEGORY_HASH = { [TRANSACTION_CATEGORIES.TOKEN_METHOD_APPROVE]: true, [TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER]: true, [TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER_FROM]: true, -} +}; diff --git a/ui/app/helpers/higher-order-components/authenticated/authenticated.component.js b/ui/app/helpers/higher-order-components/authenticated/authenticated.component.js index 585e34707f..2feebfdb0e 100644 --- a/ui/app/helpers/higher-order-components/authenticated/authenticated.component.js +++ b/ui/app/helpers/higher-order-components/authenticated/authenticated.component.js @@ -1,22 +1,22 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { Redirect, Route } from 'react-router-dom' -import { UNLOCK_ROUTE, INITIALIZE_ROUTE } from '../../constants/routes' +import React from 'react'; +import PropTypes from 'prop-types'; +import { Redirect, Route } from 'react-router-dom'; +import { UNLOCK_ROUTE, INITIALIZE_ROUTE } from '../../constants/routes'; export default function Authenticated(props) { - const { isUnlocked, completedOnboarding } = props + const { isUnlocked, completedOnboarding } = props; switch (true) { case isUnlocked && completedOnboarding: - return + return ; case !completedOnboarding: - return + return ; default: - return + return ; } } Authenticated.propTypes = { isUnlocked: PropTypes.bool, completedOnboarding: PropTypes.bool, -} +}; diff --git a/ui/app/helpers/higher-order-components/authenticated/authenticated.container.js b/ui/app/helpers/higher-order-components/authenticated/authenticated.container.js index 1f956957b1..6b0d735d18 100644 --- a/ui/app/helpers/higher-order-components/authenticated/authenticated.container.js +++ b/ui/app/helpers/higher-order-components/authenticated/authenticated.container.js @@ -1,15 +1,15 @@ -import { connect } from 'react-redux' -import Authenticated from './authenticated.component' +import { connect } from 'react-redux'; +import Authenticated from './authenticated.component'; const mapStateToProps = (state) => { const { metamask: { isUnlocked, completedOnboarding }, - } = state + } = state; return { isUnlocked, completedOnboarding, - } -} + }; +}; -export default connect(mapStateToProps)(Authenticated) +export default connect(mapStateToProps)(Authenticated); diff --git a/ui/app/helpers/higher-order-components/authenticated/index.js b/ui/app/helpers/higher-order-components/authenticated/index.js index 05632ed21c..bd53f11163 100644 --- a/ui/app/helpers/higher-order-components/authenticated/index.js +++ b/ui/app/helpers/higher-order-components/authenticated/index.js @@ -1 +1 @@ -export { default } from './authenticated.container' +export { default } from './authenticated.container'; diff --git a/ui/app/helpers/higher-order-components/feature-toggled-route.js b/ui/app/helpers/higher-order-components/feature-toggled-route.js index bcfca050bd..6d58b7d049 100644 --- a/ui/app/helpers/higher-order-components/feature-toggled-route.js +++ b/ui/app/helpers/higher-order-components/feature-toggled-route.js @@ -1,15 +1,15 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { Redirect, Route } from 'react-router-dom' +import React from 'react'; +import PropTypes from 'prop-types'; +import { Redirect, Route } from 'react-router-dom'; export default function FeatureToggledRoute({ flag, redirectRoute, ...props }) { if (flag) { - return + return ; } - return + return ; } FeatureToggledRoute.propTypes = { flag: PropTypes.bool.isRequired, redirectRoute: PropTypes.string.isRequired, -} +}; diff --git a/ui/app/helpers/higher-order-components/initialized/index.js b/ui/app/helpers/higher-order-components/initialized/index.js index 5aa9f08092..48ab62577b 100644 --- a/ui/app/helpers/higher-order-components/initialized/index.js +++ b/ui/app/helpers/higher-order-components/initialized/index.js @@ -1 +1 @@ -export { default } from './initialized.container' +export { default } from './initialized.container'; diff --git a/ui/app/helpers/higher-order-components/initialized/initialized.component.js b/ui/app/helpers/higher-order-components/initialized/initialized.component.js index 88a4deb1d6..a953403fdb 100644 --- a/ui/app/helpers/higher-order-components/initialized/initialized.component.js +++ b/ui/app/helpers/higher-order-components/initialized/initialized.component.js @@ -1,16 +1,16 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { Redirect, Route } from 'react-router-dom' -import { INITIALIZE_ROUTE } from '../../constants/routes' +import React from 'react'; +import PropTypes from 'prop-types'; +import { Redirect, Route } from 'react-router-dom'; +import { INITIALIZE_ROUTE } from '../../constants/routes'; export default function Initialized(props) { return props.completedOnboarding ? ( ) : ( - ) + ); } Initialized.propTypes = { completedOnboarding: PropTypes.bool, -} +}; diff --git a/ui/app/helpers/higher-order-components/initialized/initialized.container.js b/ui/app/helpers/higher-order-components/initialized/initialized.container.js index d7b5633a44..c4143cc077 100644 --- a/ui/app/helpers/higher-order-components/initialized/initialized.container.js +++ b/ui/app/helpers/higher-order-components/initialized/initialized.container.js @@ -1,14 +1,14 @@ -import { connect } from 'react-redux' -import Initialized from './initialized.component' +import { connect } from 'react-redux'; +import Initialized from './initialized.component'; const mapStateToProps = (state) => { const { metamask: { completedOnboarding }, - } = state + } = state; return { completedOnboarding, - } -} + }; +}; -export default connect(mapStateToProps)(Initialized) +export default connect(mapStateToProps)(Initialized); diff --git a/ui/app/helpers/higher-order-components/with-modal-props/index.js b/ui/app/helpers/higher-order-components/with-modal-props/index.js index e476b51d27..0bc8f5e2a7 100644 --- a/ui/app/helpers/higher-order-components/with-modal-props/index.js +++ b/ui/app/helpers/higher-order-components/with-modal-props/index.js @@ -1 +1 @@ -export { default } from './with-modal-props' +export { default } from './with-modal-props'; diff --git a/ui/app/helpers/higher-order-components/with-modal-props/tests/with-modal-props.test.js b/ui/app/helpers/higher-order-components/with-modal-props/tests/with-modal-props.test.js index 06f95129af..79339b4ad6 100644 --- a/ui/app/helpers/higher-order-components/with-modal-props/tests/with-modal-props.test.js +++ b/ui/app/helpers/higher-order-components/with-modal-props/tests/with-modal-props.test.js @@ -1,8 +1,8 @@ -import assert from 'assert' -import configureMockStore from 'redux-mock-store' -import { mount } from 'enzyme' -import React from 'react' -import withModalProps from '../with-modal-props' +import assert from 'assert'; +import configureMockStore from 'redux-mock-store'; +import { mount } from 'enzyme'; +import React from 'react'; +import withModalProps from '../with-modal-props'; const mockState = { appState: { @@ -16,23 +16,23 @@ const mockState = { }, }, }, -} +}; describe('withModalProps', function () { it('should return a component wrapped with modal state props', function () { - const TestComponent = () =>
    Testing
    - const WrappedComponent = withModalProps(TestComponent) - const store = configureMockStore()(mockState) - const wrapper = mount() + const TestComponent = () =>
    Testing
    ; + const WrappedComponent = withModalProps(TestComponent); + const store = configureMockStore()(mockState); + const wrapper = mount(); - assert.ok(wrapper) - const testComponent = wrapper.find(TestComponent).at(0) - assert.strictEqual(testComponent.length, 1) - assert.strictEqual(testComponent.find('.test').text(), 'Testing') - const testComponentProps = testComponent.props() - assert.strictEqual(testComponentProps.prop1, 'prop1') - assert.strictEqual(testComponentProps.prop2, 2) - assert.strictEqual(testComponentProps.prop3, true) - assert.strictEqual(typeof testComponentProps.hideModal, 'function') - }) -}) + assert.ok(wrapper); + const testComponent = wrapper.find(TestComponent).at(0); + assert.strictEqual(testComponent.length, 1); + assert.strictEqual(testComponent.find('.test').text(), 'Testing'); + const testComponentProps = testComponent.props(); + assert.strictEqual(testComponentProps.prop1, 'prop1'); + assert.strictEqual(testComponentProps.prop2, 2); + assert.strictEqual(testComponentProps.prop3, true); + assert.strictEqual(typeof testComponentProps.hideModal, 'function'); + }); +}); diff --git a/ui/app/helpers/higher-order-components/with-modal-props/with-modal-props.js b/ui/app/helpers/higher-order-components/with-modal-props/with-modal-props.js index 88dbfa9255..8d19a4958f 100644 --- a/ui/app/helpers/higher-order-components/with-modal-props/with-modal-props.js +++ b/ui/app/helpers/higher-order-components/with-modal-props/with-modal-props.js @@ -1,21 +1,21 @@ -import { connect } from 'react-redux' -import { hideModal } from '../../../store/actions' +import { connect } from 'react-redux'; +import { hideModal } from '../../../store/actions'; const mapStateToProps = (state) => { - const { appState } = state - const { props: modalProps } = appState.modal.modalState + const { appState } = state; + const { props: modalProps } = appState.modal.modalState; return { ...modalProps, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { hideModal: () => dispatch(hideModal()), - } -} + }; +}; export default function withModalProps(Component) { - return connect(mapStateToProps, mapDispatchToProps)(Component) + return connect(mapStateToProps, mapDispatchToProps)(Component); } diff --git a/ui/app/helpers/utils/common.util.js b/ui/app/helpers/utils/common.util.js index 0c0d49c15d..06272009a2 100644 --- a/ui/app/helpers/utils/common.util.js +++ b/ui/app/helpers/utils/common.util.js @@ -1,3 +1,3 @@ export function camelCaseToCapitalize(str = '') { - return str.replace(/([A-Z])/gu, ' $1').replace(/^./u, (s) => s.toUpperCase()) + return str.replace(/([A-Z])/gu, ' $1').replace(/^./u, (s) => s.toUpperCase()); } diff --git a/ui/app/helpers/utils/common.util.test.js b/ui/app/helpers/utils/common.util.test.js index 2e083322da..50a50d47b9 100644 --- a/ui/app/helpers/utils/common.util.test.js +++ b/ui/app/helpers/utils/common.util.test.js @@ -1,5 +1,5 @@ -import assert from 'assert' -import * as utils from './common.util' +import assert from 'assert'; +import * as utils from './common.util'; describe('Common utils', function () { describe('camelCaseToCapitalize', function () { @@ -17,11 +17,11 @@ describe('Common utils', function () { test: 'thisIsATest', expected: 'This Is A Test', }, - ] + ]; tests.forEach(({ test, expected }) => { - assert.strictEqual(utils.camelCaseToCapitalize(test), expected) - }) - }) - }) -}) + assert.strictEqual(utils.camelCaseToCapitalize(test), expected); + }); + }); + }); +}); diff --git a/ui/app/helpers/utils/confirm-tx.util.js b/ui/app/helpers/utils/confirm-tx.util.js index 8ff39e4988..80fe2f3df0 100644 --- a/ui/app/helpers/utils/confirm-tx.util.js +++ b/ui/app/helpers/utils/confirm-tx.util.js @@ -1,15 +1,15 @@ -import currencyFormatter from 'currency-formatter' -import currencies from 'currency-formatter/currencies' -import BigNumber from 'bignumber.js' -import { addHexPrefix } from '../../../../app/scripts/lib/util' +import currencyFormatter from 'currency-formatter'; +import currencies from 'currency-formatter/currencies'; +import BigNumber from 'bignumber.js'; +import { addHexPrefix } from '../../../../app/scripts/lib/util'; -import { unconfirmedTransactionsCountSelector } from '../../selectors' +import { unconfirmedTransactionsCountSelector } from '../../selectors'; import { conversionUtil, addCurrencies, multiplyCurrencies, conversionGreaterThan, -} from './conversion-util' +} from './conversion-util'; export function increaseLastGasPrice(lastGasPrice) { return addHexPrefix( @@ -18,14 +18,14 @@ export function increaseLastGasPrice(lastGasPrice) { multiplierBase: 10, toNumericBase: 'hex', }), - ) + ); } export function hexGreaterThan(a, b) { return conversionGreaterThan( { value: a, fromNumericBase: 'hex' }, { value: b, fromNumericBase: 'hex' }, - ) + ); } export function getHexGasTotal({ gasLimit, gasPrice }) { @@ -35,7 +35,7 @@ export function getHexGasTotal({ gasLimit, gasPrice }) { multiplicandBase: 16, multiplierBase: 16, }), - ) + ); } export function addEth(...args) { @@ -45,8 +45,8 @@ export function addEth(...args) { numberOfDecimals: 6, aBase: 10, bBase: 10, - }) - }) + }); + }); } export function addFiat(...args) { @@ -56,8 +56,8 @@ export function addFiat(...args) { numberOfDecimals: 2, aBase: 10, bBase: 10, - }) - }) + }); + }); } export function getValueFromWeiHex({ @@ -77,7 +77,7 @@ export function getValueFromWeiHex({ fromDenomination: 'WEI', toDenomination, conversionRate, - }) + }); } export function getTransactionFee({ @@ -95,18 +95,18 @@ export function getTransactionFee({ toCurrency, numberOfDecimals, conversionRate, - }) + }); } export function formatCurrency(value, currencyCode) { - const upperCaseCurrencyCode = currencyCode.toUpperCase() + const upperCaseCurrencyCode = currencyCode.toUpperCase(); return currencies.find((currency) => currency.code === upperCaseCurrencyCode) ? currencyFormatter.format(Number(value), { code: upperCaseCurrencyCode, style: 'currency', }) - : value + : value; } export function convertTokenToFiat({ @@ -116,7 +116,7 @@ export function convertTokenToFiat({ conversionRate, contractExchangeRate, }) { - const totalExchangeRate = conversionRate * contractExchangeRate + const totalExchangeRate = conversionRate * contractExchangeRate; return conversionUtil(value, { fromNumericBase: 'dec', @@ -125,11 +125,11 @@ export function convertTokenToFiat({ toCurrency, numberOfDecimals: 2, conversionRate: totalExchangeRate, - }) + }); } export function hasUnconfirmedTransactions(state) { - return unconfirmedTransactionsCountSelector(state) > 0 + return unconfirmedTransactionsCountSelector(state) > 0; } /** @@ -140,11 +140,11 @@ export function hasUnconfirmedTransactions(state) { * rounding was necessary. */ export function roundExponential(decimalString) { - const PRECISION = 4 - const bigNumberValue = new BigNumber(decimalString) + const PRECISION = 4; + const bigNumberValue = new BigNumber(decimalString); // In JS, numbers with exponentials greater than 20 get displayed as an exponential. return bigNumberValue.e > 20 ? bigNumberValue.toPrecision(PRECISION) - : decimalString + : decimalString; } diff --git a/ui/app/helpers/utils/confirm-tx.util.test.js b/ui/app/helpers/utils/confirm-tx.util.test.js index a05090648f..e4e6287dab 100644 --- a/ui/app/helpers/utils/confirm-tx.util.test.js +++ b/ui/app/helpers/utils/confirm-tx.util.test.js @@ -1,57 +1,57 @@ -import assert from 'assert' -import * as utils from './confirm-tx.util' +import assert from 'assert'; +import * as utils from './confirm-tx.util'; describe('Confirm Transaction utils', function () { describe('increaseLastGasPrice', function () { it('should increase the gasPrice by 10%', function () { - const increasedGasPrice = utils.increaseLastGasPrice('0xa') - assert.strictEqual(increasedGasPrice, '0xb') - }) + const increasedGasPrice = utils.increaseLastGasPrice('0xa'); + assert.strictEqual(increasedGasPrice, '0xb'); + }); it('should prefix the result with 0x', function () { - const increasedGasPrice = utils.increaseLastGasPrice('a') - assert.strictEqual(increasedGasPrice, '0xb') - }) - }) + const increasedGasPrice = utils.increaseLastGasPrice('a'); + assert.strictEqual(increasedGasPrice, '0xb'); + }); + }); describe('hexGreaterThan', function () { it('should return true if the first value is greater than the second value', function () { - assert.strictEqual(utils.hexGreaterThan('0xb', '0xa'), true) - }) + assert.strictEqual(utils.hexGreaterThan('0xb', '0xa'), true); + }); it('should return false if the first value is less than the second value', function () { - assert.strictEqual(utils.hexGreaterThan('0xa', '0xb'), false) - }) + assert.strictEqual(utils.hexGreaterThan('0xa', '0xb'), false); + }); it('should return false if the first value is equal to the second value', function () { - assert.strictEqual(utils.hexGreaterThan('0xa', '0xa'), false) - }) + assert.strictEqual(utils.hexGreaterThan('0xa', '0xa'), false); + }); it('should correctly compare prefixed and non-prefixed hex values', function () { - assert.strictEqual(utils.hexGreaterThan('0xb', 'a'), true) - }) - }) + assert.strictEqual(utils.hexGreaterThan('0xb', 'a'), true); + }); + }); describe('getHexGasTotal', function () { it('should multiply the hex gasLimit and hex gasPrice values together', function () { assert.strictEqual( utils.getHexGasTotal({ gasLimit: '0x5208', gasPrice: '0x3b9aca00' }), '0x1319718a5000', - ) - }) + ); + }); it('should prefix the result with 0x', function () { assert.strictEqual( utils.getHexGasTotal({ gasLimit: '5208', gasPrice: '3b9aca00' }), '0x1319718a5000', - ) - }) - }) + ); + }); + }); describe('addEth', function () { it('should add two values together rounding to 6 decimal places', function () { - assert.strictEqual(utils.addEth('0.12345678', '0'), '0.123457') - }) + assert.strictEqual(utils.addEth('0.12345678', '0'), '0.123457'); + }); it('should add any number of values together rounding to 6 decimal places', function () { assert.strictEqual( @@ -65,14 +65,14 @@ describe('Confirm Transaction utils', function () { '0.0000007', ), '0.123457', - ) - }) - }) + ); + }); + }); describe('addFiat', function () { it('should add two values together rounding to 2 decimal places', function () { - assert.strictEqual(utils.addFiat('0.12345678', '0'), '0.12') - }) + assert.strictEqual(utils.addFiat('0.12345678', '0'), '0.12'); + }); it('should add any number of values together rounding to 2 decimal places', function () { assert.strictEqual( @@ -86,9 +86,9 @@ describe('Confirm Transaction utils', function () { '0.0000007', ), '0.12', - ) - }) - }) + ); + }); + }); describe('getValueFromWeiHex', function () { it('should get the transaction amount in ETH', function () { @@ -97,10 +97,10 @@ describe('Confirm Transaction utils', function () { toCurrency: 'ETH', conversionRate: 468.58, numberOfDecimals: 6, - }) + }); - assert.strictEqual(ethTransactionAmount, '1') - }) + assert.strictEqual(ethTransactionAmount, '1'); + }); it('should get the transaction amount in fiat', function () { const fiatTransactionAmount = utils.getValueFromWeiHex({ @@ -108,11 +108,11 @@ describe('Confirm Transaction utils', function () { toCurrency: 'usd', conversionRate: 468.58, numberOfDecimals: 2, - }) + }); - assert.strictEqual(fiatTransactionAmount, '468.58') - }) - }) + assert.strictEqual(fiatTransactionAmount, '468.58'); + }); + }); describe('getTransactionFee', function () { it('should get the transaction fee in ETH', function () { @@ -121,10 +121,10 @@ describe('Confirm Transaction utils', function () { toCurrency: 'ETH', conversionRate: 468.58, numberOfDecimals: 6, - }) + }); - assert.strictEqual(ethTransactionFee, '0.000021') - }) + assert.strictEqual(ethTransactionFee, '0.000021'); + }); it('should get the transaction fee in fiat', function () { const fiatTransactionFee = utils.getTransactionFee({ @@ -132,16 +132,16 @@ describe('Confirm Transaction utils', function () { toCurrency: 'usd', conversionRate: 468.58, numberOfDecimals: 2, - }) + }); - assert.strictEqual(fiatTransactionFee, '0.01') - }) - }) + assert.strictEqual(fiatTransactionFee, '0.01'); + }); + }); describe('formatCurrency', function () { it('should format USD values', function () { - const value = utils.formatCurrency('123.45', 'usd') - assert.strictEqual(value, '$123.45') - }) - }) -}) + const value = utils.formatCurrency('123.45', 'usd'); + assert.strictEqual(value, '$123.45'); + }); + }); +}); diff --git a/ui/app/helpers/utils/conversion-util.js b/ui/app/helpers/utils/conversion-util.js index ca6bad62b4..fac0dd415f 100644 --- a/ui/app/helpers/utils/conversion-util.js +++ b/ui/app/helpers/utils/conversion-util.js @@ -21,43 +21,43 @@ * on the accompanying options. */ -import BigNumber from 'bignumber.js' +import BigNumber from 'bignumber.js'; -import ethUtil, { stripHexPrefix } from 'ethereumjs-util' +import ethUtil, { stripHexPrefix } from 'ethereumjs-util'; -const { BN } = ethUtil +const { BN } = ethUtil; // Big Number Constants -const BIG_NUMBER_WEI_MULTIPLIER = new BigNumber('1000000000000000000') -const BIG_NUMBER_GWEI_MULTIPLIER = new BigNumber('1000000000') -const BIG_NUMBER_ETH_MULTIPLIER = new BigNumber('1') +const BIG_NUMBER_WEI_MULTIPLIER = new BigNumber('1000000000000000000'); +const BIG_NUMBER_GWEI_MULTIPLIER = new BigNumber('1000000000'); +const BIG_NUMBER_ETH_MULTIPLIER = new BigNumber('1'); // Setter Maps const toBigNumber = { hex: (n) => new BigNumber(stripHexPrefix(n), 16), dec: (n) => new BigNumber(String(n), 10), BN: (n) => new BigNumber(n.toString(16), 16), -} +}; const toNormalizedDenomination = { WEI: (bigNumber) => bigNumber.div(BIG_NUMBER_WEI_MULTIPLIER), GWEI: (bigNumber) => bigNumber.div(BIG_NUMBER_GWEI_MULTIPLIER), ETH: (bigNumber) => bigNumber.div(BIG_NUMBER_ETH_MULTIPLIER), -} +}; const toSpecifiedDenomination = { WEI: (bigNumber) => bigNumber.times(BIG_NUMBER_WEI_MULTIPLIER).round(), GWEI: (bigNumber) => bigNumber.times(BIG_NUMBER_GWEI_MULTIPLIER).round(9), ETH: (bigNumber) => bigNumber.times(BIG_NUMBER_ETH_MULTIPLIER).round(9), -} +}; const baseChange = { hex: (n) => n.toString(16), dec: (n) => new BigNumber(n).toString(10), BN: (n) => new BN(n.toString(16)), -} +}; // Utility function for checking base types const isValidBase = (base) => { - return Number.isInteger(base) && base > 1 -} + return Number.isInteger(base) && base > 1; +}; /** * Defines the base type of numeric value @@ -99,45 +99,45 @@ const converter = ({ }) => { let convertedValue = fromNumericBase ? toBigNumber[fromNumericBase](value) - : value + : value; if (fromDenomination) { - convertedValue = toNormalizedDenomination[fromDenomination](convertedValue) + convertedValue = toNormalizedDenomination[fromDenomination](convertedValue); } if (fromCurrency !== toCurrency) { if (conversionRate === null || conversionRate === undefined) { throw new Error( `Converting from ${fromCurrency} to ${toCurrency} requires a conversionRate, but one was not provided`, - ) + ); } - let rate = toBigNumber.dec(conversionRate) + let rate = toBigNumber.dec(conversionRate); if (invertConversionRate) { - rate = new BigNumber(1.0).div(conversionRate) + rate = new BigNumber(1.0).div(conversionRate); } - convertedValue = convertedValue.times(rate) + convertedValue = convertedValue.times(rate); } if (toDenomination) { - convertedValue = toSpecifiedDenomination[toDenomination](convertedValue) + convertedValue = toSpecifiedDenomination[toDenomination](convertedValue); } if (numberOfDecimals) { convertedValue = convertedValue.round( numberOfDecimals, BigNumber.ROUND_HALF_DOWN, - ) + ); } if (roundDown) { - convertedValue = convertedValue.round(roundDown, BigNumber.ROUND_DOWN) + convertedValue = convertedValue.round(roundDown, BigNumber.ROUND_DOWN); } if (toNumericBase) { - convertedValue = baseChange[toNumericBase](convertedValue) + convertedValue = baseChange[toNumericBase](convertedValue); } - return convertedValue -} + return convertedValue; +}; const conversionUtil = ( value, @@ -164,107 +164,107 @@ const conversionUtil = ( conversionRate, invertConversionRate, value: value || '0', - }) + }); const getBigNumber = (value, base) => { if (!isValidBase(base)) { - throw new Error('Must specificy valid base') + throw new Error('Must specificy valid base'); } // We don't include 'number' here, because BigNumber will throw if passed // a number primitive it considers unsafe. if (typeof value === 'string' || value instanceof BigNumber) { - return new BigNumber(value, base) + return new BigNumber(value, base); } - return new BigNumber(String(value), base) -} + return new BigNumber(String(value), base); +}; const addCurrencies = (a, b, options = {}) => { - const { aBase, bBase, ...conversionOptions } = options + const { aBase, bBase, ...conversionOptions } = options; if (!isValidBase(aBase) || !isValidBase(bBase)) { - throw new Error('Must specify valid aBase and bBase') + throw new Error('Must specify valid aBase and bBase'); } - const value = getBigNumber(a, aBase).add(getBigNumber(b, bBase)) + const value = getBigNumber(a, aBase).add(getBigNumber(b, bBase)); return converter({ value, ...conversionOptions, - }) -} + }); +}; const subtractCurrencies = (a, b, options = {}) => { - const { aBase, bBase, ...conversionOptions } = options + const { aBase, bBase, ...conversionOptions } = options; if (!isValidBase(aBase) || !isValidBase(bBase)) { - throw new Error('Must specify valid aBase and bBase') + throw new Error('Must specify valid aBase and bBase'); } - const value = getBigNumber(a, aBase).minus(getBigNumber(b, bBase)) + const value = getBigNumber(a, aBase).minus(getBigNumber(b, bBase)); return converter({ value, ...conversionOptions, - }) -} + }); +}; const multiplyCurrencies = (a, b, options = {}) => { - const { multiplicandBase, multiplierBase, ...conversionOptions } = options + const { multiplicandBase, multiplierBase, ...conversionOptions } = options; if (!isValidBase(multiplicandBase) || !isValidBase(multiplierBase)) { - throw new Error('Must specify valid multiplicandBase and multiplierBase') + throw new Error('Must specify valid multiplicandBase and multiplierBase'); } const value = getBigNumber(a, multiplicandBase).times( getBigNumber(b, multiplierBase), - ) + ); return converter({ value, ...conversionOptions, - }) -} + }); +}; const conversionGreaterThan = ({ ...firstProps }, { ...secondProps }) => { - const firstValue = converter({ ...firstProps }) - const secondValue = converter({ ...secondProps }) + const firstValue = converter({ ...firstProps }); + const secondValue = converter({ ...secondProps }); - return firstValue.gt(secondValue) -} + return firstValue.gt(secondValue); +}; const conversionLessThan = ({ ...firstProps }, { ...secondProps }) => { - const firstValue = converter({ ...firstProps }) - const secondValue = converter({ ...secondProps }) + const firstValue = converter({ ...firstProps }); + const secondValue = converter({ ...secondProps }); - return firstValue.lt(secondValue) -} + return firstValue.lt(secondValue); +}; const conversionMax = ({ ...firstProps }, { ...secondProps }) => { const firstIsGreater = conversionGreaterThan( { ...firstProps }, { ...secondProps }, - ) + ); - return firstIsGreater ? firstProps.value : secondProps.value -} + return firstIsGreater ? firstProps.value : secondProps.value; +}; const conversionGTE = ({ ...firstProps }, { ...secondProps }) => { - const firstValue = converter({ ...firstProps }) - const secondValue = converter({ ...secondProps }) - return firstValue.greaterThanOrEqualTo(secondValue) -} + const firstValue = converter({ ...firstProps }); + const secondValue = converter({ ...secondProps }); + return firstValue.greaterThanOrEqualTo(secondValue); +}; const conversionLTE = ({ ...firstProps }, { ...secondProps }) => { - const firstValue = converter({ ...firstProps }) - const secondValue = converter({ ...secondProps }) - return firstValue.lessThanOrEqualTo(secondValue) -} + const firstValue = converter({ ...firstProps }); + const secondValue = converter({ ...secondProps }); + return firstValue.lessThanOrEqualTo(secondValue); +}; const toNegative = (n, options = {}) => { - return multiplyCurrencies(n, -1, options) -} + return multiplyCurrencies(n, -1, options); +}; export { conversionUtil, @@ -277,4 +277,4 @@ export { conversionMax, toNegative, subtractCurrencies, -} +}; diff --git a/ui/app/helpers/utils/conversion-util.test.js b/ui/app/helpers/utils/conversion-util.test.js index 5e05f67271..bb1f2a690a 100644 --- a/ui/app/helpers/utils/conversion-util.test.js +++ b/ui/app/helpers/utils/conversion-util.test.js @@ -1,6 +1,6 @@ -import assert from 'assert' -import BigNumber from 'bignumber.js' -import { addCurrencies, conversionUtil } from './conversion-util' +import assert from 'assert'; +import BigNumber from 'bignumber.js'; +import { addCurrencies, conversionUtil } from './conversion-util'; describe('conversion utils', function () { describe('addCurrencies()', function () { @@ -8,44 +8,44 @@ describe('conversion utils', function () { const result = addCurrencies(3, 9, { aBase: 10, bBase: 10, - }) - assert.strictEqual(result.toNumber(), 12) - }) + }); + assert.strictEqual(result.toNumber(), 12); + }); it('add decimals', function () { const result = addCurrencies(1.3, 1.9, { aBase: 10, bBase: 10, - }) - assert.strictEqual(result.toNumber(), 3.2) - }) + }); + assert.strictEqual(result.toNumber(), 3.2); + }); it('add repeating decimals', function () { const result = addCurrencies(1 / 3, 1 / 9, { aBase: 10, bBase: 10, - }) - assert.strictEqual(result.toNumber(), 0.4444444444444444) - }) - }) + }); + assert.strictEqual(result.toNumber(), 0.4444444444444444); + }); + }); describe('conversionUtil', function () { it('Returns expected types', function () { const conv1 = conversionUtil(1000000000000000000, { fromNumericBase: 'dec', toNumericBase: 'hex', - }) + }); const conv2 = conversionUtil(1, { fromNumericBase: 'dec', fromDenomination: 'ETH', toDenomination: 'WEI', - }) + }); assert( typeof conv1 === 'string', 'conversion 1 should return type string', - ) - assert(conv2 instanceof BigNumber, 'conversion 2 should be a BigNumber') - }) + ); + assert(conv2 instanceof BigNumber, 'conversion 2 should be a BigNumber'); + }); it('Converts from dec to hex', function () { assert.strictEqual( conversionUtil('1000000000000000000', { @@ -53,15 +53,15 @@ describe('conversion utils', function () { toNumericBase: 'hex', }), 'de0b6b3a7640000', - ) + ); assert.strictEqual( conversionUtil('1500000000000000000', { fromNumericBase: 'dec', toNumericBase: 'hex', }), '14d1120d7b160000', - ) - }) + ); + }); it('Converts hex formatted numbers to dec', function () { assert.strictEqual( conversionUtil('0xde0b6b3a7640000', { @@ -69,15 +69,15 @@ describe('conversion utils', function () { toNumericBase: 'dec', }), '1000000000000000000', - ) + ); assert.strictEqual( conversionUtil('0x14d1120d7b160000', { fromNumericBase: 'hex', toNumericBase: 'dec', }), '1500000000000000000', - ) - }) + ); + }); it('Converts WEI to ETH', function () { assert.strictEqual( conversionUtil('0xde0b6b3a7640000', { @@ -87,7 +87,7 @@ describe('conversion utils', function () { toDenomination: 'ETH', }), '1', - ) + ); assert.strictEqual( conversionUtil('0x14d1120d7b160000', { fromNumericBase: 'hex', @@ -96,8 +96,8 @@ describe('conversion utils', function () { toDenomination: 'ETH', }), '1.5', - ) - }) + ); + }); it('Converts ETH to WEI', function () { assert.strictEqual( conversionUtil('1', { @@ -106,7 +106,7 @@ describe('conversion utils', function () { toDenomination: 'WEI', }).toNumber(), 1000000000000000000, - ) + ); assert.strictEqual( conversionUtil('1.5', { fromNumericBase: 'dec', @@ -114,8 +114,8 @@ describe('conversion utils', function () { toDenomination: 'WEI', }).toNumber(), 1500000000000000000, - ) - }) + ); + }); it('Converts ETH to GWEI', function () { assert.strictEqual( conversionUtil('1', { @@ -124,7 +124,7 @@ describe('conversion utils', function () { toDenomination: 'GWEI', }).toNumber(), 1000000000, - ) + ); assert.strictEqual( conversionUtil('1.5', { fromNumericBase: 'dec', @@ -132,8 +132,8 @@ describe('conversion utils', function () { toDenomination: 'GWEI', }).toNumber(), 1500000000, - ) - }) + ); + }); it('Converts ETH to USD', function () { assert.strictEqual( conversionUtil('1', { @@ -144,7 +144,7 @@ describe('conversion utils', function () { numberOfDecimals: 2, }), '468.58', - ) + ); assert.strictEqual( conversionUtil('1.5', { fromNumericBase: 'dec', @@ -154,8 +154,8 @@ describe('conversion utils', function () { numberOfDecimals: 2, }), '702.87', - ) - }) + ); + }); it('Converts USD to ETH', function () { assert.strictEqual( conversionUtil('468.58', { @@ -167,7 +167,7 @@ describe('conversion utils', function () { invertConversionRate: true, }), '1', - ) + ); assert.strictEqual( conversionUtil('702.87', { fromNumericBase: 'dec', @@ -178,7 +178,7 @@ describe('conversion utils', function () { invertConversionRate: true, }), '1.5', - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/ui/app/helpers/utils/conversions.util.js b/ui/app/helpers/utils/conversions.util.js index 9e0f97681c..ce4fe8c511 100644 --- a/ui/app/helpers/utils/conversions.util.js +++ b/ui/app/helpers/utils/conversions.util.js @@ -1,28 +1,28 @@ -import { ETH, GWEI, WEI } from '../constants/common' -import { addHexPrefix } from '../../../../app/scripts/lib/util' +import { ETH, GWEI, WEI } from '../constants/common'; +import { addHexPrefix } from '../../../../app/scripts/lib/util'; import { conversionUtil, addCurrencies, subtractCurrencies, -} from './conversion-util' -import { formatCurrency } from './confirm-tx.util' +} from './conversion-util'; +import { formatCurrency } from './confirm-tx.util'; export function bnToHex(inputBn) { - return addHexPrefix(inputBn.toString(16)) + return addHexPrefix(inputBn.toString(16)); } export function hexToDecimal(hexValue) { return conversionUtil(hexValue, { fromNumericBase: 'hex', toNumericBase: 'dec', - }) + }); } export function decimalToHex(decimal) { return conversionUtil(decimal, { fromNumericBase: 'dec', toNumericBase: 'hex', - }) + }); } export function getEthConversionFromWeiHex({ @@ -31,9 +31,9 @@ export function getEthConversionFromWeiHex({ conversionRate, numberOfDecimals = 6, }) { - const denominations = [fromCurrency, GWEI, WEI] + const denominations = [fromCurrency, GWEI, WEI]; - let nonZeroDenomination + let nonZeroDenomination; for (let i = 0; i < denominations.length; i++) { const convertedValue = getValueFromWeiHex({ @@ -43,15 +43,15 @@ export function getEthConversionFromWeiHex({ toCurrency: fromCurrency, numberOfDecimals, toDenomination: denominations[i], - }) + }); if (convertedValue !== '0' || i === denominations.length - 1) { - nonZeroDenomination = `${convertedValue} ${denominations[i]}` - break + nonZeroDenomination = `${convertedValue} ${denominations[i]}`; + break; } } - return nonZeroDenomination + return nonZeroDenomination; } export function getValueFromWeiHex({ @@ -71,7 +71,7 @@ export function getValueFromWeiHex({ fromDenomination: WEI, toDenomination, conversionRate, - }) + }); } export function getWeiHexFromDecimalValue({ @@ -90,7 +90,7 @@ export function getWeiHexFromDecimalValue({ invertConversionRate, fromDenomination, toDenomination: WEI, - }) + }); } export function addHexWEIsToDec(aHexWEI, bHexWEI) { @@ -99,7 +99,7 @@ export function addHexWEIsToDec(aHexWEI, bHexWEI) { bBase: 16, fromDenomination: 'WEI', numberOfDecimals: 6, - }) + }); } export function subtractHexWEIsToDec(aHexWEI, bHexWEI) { @@ -108,7 +108,7 @@ export function subtractHexWEIsToDec(aHexWEI, bHexWEI) { bBase: 16, fromDenomination: 'WEI', numberOfDecimals: 6, - }) + }); } export function decEthToConvertedCurrency( @@ -123,7 +123,7 @@ export function decEthToConvertedCurrency( toCurrency: convertedCurrency, numberOfDecimals: 2, conversionRate, - }) + }); } export function decGWEIToHexWEI(decGWEI) { @@ -132,7 +132,7 @@ export function decGWEIToHexWEI(decGWEI) { toNumericBase: 'hex', fromDenomination: 'GWEI', toDenomination: 'WEI', - }) + }); } export function hexWEIToDecGWEI(decGWEI) { @@ -141,7 +141,7 @@ export function hexWEIToDecGWEI(decGWEI) { toNumericBase: 'dec', fromDenomination: 'WEI', toDenomination: 'GWEI', - }) + }); } export function decETHToDecWEI(decEth) { @@ -150,7 +150,7 @@ export function decETHToDecWEI(decEth) { toNumericBase: 'dec', fromDenomination: 'ETH', toDenomination: 'WEI', - }) + }); } export function hexWEIToDecETH(hexWEI) { @@ -159,7 +159,7 @@ export function hexWEIToDecETH(hexWEI) { toNumericBase: 'dec', fromDenomination: 'WEI', toDenomination: 'ETH', - }) + }); } export function addHexes(aHexWEI, bHexWEI) { @@ -168,11 +168,11 @@ export function addHexes(aHexWEI, bHexWEI) { bBase: 16, toNumericBase: 'hex', numberOfDecimals: 6, - }) + }); } export function sumHexWEIs(hexWEIs) { - return hexWEIs.filter(Boolean).reduce(addHexes) + return hexWEIs.filter(Boolean).reduce(addHexes); } export function sumHexWEIsToUnformattedFiat( @@ -180,7 +180,7 @@ export function sumHexWEIsToUnformattedFiat( convertedCurrency, conversionRate, ) { - const hexWEIsSum = sumHexWEIs(hexWEIs) + const hexWEIsSum = sumHexWEIs(hexWEIs); const convertedTotal = decEthToConvertedCurrency( getValueFromWeiHex({ value: hexWEIsSum, @@ -189,8 +189,8 @@ export function sumHexWEIsToUnformattedFiat( }), convertedCurrency, conversionRate, - ) - return convertedTotal + ); + return convertedTotal; } export function sumHexWEIsToRenderableFiat( @@ -202,6 +202,6 @@ export function sumHexWEIsToRenderableFiat( hexWEIs, convertedCurrency, conversionRate, - ) - return formatCurrency(convertedTotal, convertedCurrency) + ); + return formatCurrency(convertedTotal, convertedCurrency); } diff --git a/ui/app/helpers/utils/conversions.util.test.js b/ui/app/helpers/utils/conversions.util.test.js index 6ae58ca835..6fe4159ea4 100644 --- a/ui/app/helpers/utils/conversions.util.test.js +++ b/ui/app/helpers/utils/conversions.util.test.js @@ -1,6 +1,6 @@ -import assert from 'assert' -import { ETH } from '../constants/common' -import * as utils from './conversions.util' +import assert from 'assert'; +import { ETH } from '../constants/common'; +import * as utils from './conversions.util'; describe('conversion utils', function () { describe('getWeiHexFromDecimalValue', function () { @@ -9,35 +9,35 @@ describe('conversion utils', function () { value: '0', fromCurrency: ETH, fromDenomination: ETH, - }) - assert.strictEqual(weiValue, '0') - }) - }) + }); + assert.strictEqual(weiValue, '0'); + }); + }); describe('decETHToDecWEI', function () { it('should correctly convert 1 ETH to WEI', function () { - const weiValue = utils.decETHToDecWEI('1') - assert.strictEqual(weiValue, '1000000000000000000') - }) + const weiValue = utils.decETHToDecWEI('1'); + assert.strictEqual(weiValue, '1000000000000000000'); + }); it('should correctly convert 0.000000000000000001 ETH to WEI', function () { - const weiValue = utils.decETHToDecWEI('0.000000000000000001') - assert.strictEqual(weiValue, '1') - }) + const weiValue = utils.decETHToDecWEI('0.000000000000000001'); + assert.strictEqual(weiValue, '1'); + }); it('should correctly convert 1000000.000000000000000001 ETH to WEI', function () { - const weiValue = utils.decETHToDecWEI('1000000.000000000000000001') - assert.strictEqual(weiValue, '1000000000000000000000001') - }) + const weiValue = utils.decETHToDecWEI('1000000.000000000000000001'); + assert.strictEqual(weiValue, '1000000000000000000000001'); + }); it('should correctly convert 9876.543210 ETH to WEI', function () { - const weiValue = utils.decETHToDecWEI('9876.543210') - assert.strictEqual(weiValue, '9876543210000000000000') - }) + const weiValue = utils.decETHToDecWEI('9876.543210'); + assert.strictEqual(weiValue, '9876543210000000000000'); + }); it('should correctly convert 1.0000000000000000 ETH to WEI', function () { - const weiValue = utils.decETHToDecWEI('1.0000000000000000') - assert.strictEqual(weiValue, '1000000000000000000') - }) - }) -}) + const weiValue = utils.decETHToDecWEI('1.0000000000000000'); + assert.strictEqual(weiValue, '1000000000000000000'); + }); + }); +}); diff --git a/ui/app/helpers/utils/fetch-with-cache.js b/ui/app/helpers/utils/fetch-with-cache.js index a903680c44..6dc3775931 100644 --- a/ui/app/helpers/utils/fetch-with-cache.js +++ b/ui/app/helpers/utils/fetch-with-cache.js @@ -1,5 +1,5 @@ -import { getStorageItem, setStorageItem } from '../../../lib/storage-helpers' -import getFetchWithTimeout from '../../../../shared/modules/fetch-with-timeout' +import { getStorageItem, setStorageItem } from '../../../lib/storage-helpers'; +import getFetchWithTimeout from '../../../../shared/modules/fetch-with-timeout'; const fetchWithCache = async ( url, @@ -10,46 +10,46 @@ const fetchWithCache = async ( fetchOptions.body || (fetchOptions.method && fetchOptions.method !== 'GET') ) { - throw new Error('fetchWithCache only supports GET requests') + throw new Error('fetchWithCache only supports GET requests'); } if (!(fetchOptions.headers instanceof window.Headers)) { - fetchOptions.headers = new window.Headers(fetchOptions.headers) + fetchOptions.headers = new window.Headers(fetchOptions.headers); } if ( fetchOptions.headers.has('Content-Type') && fetchOptions.headers.get('Content-Type') !== 'application/json' ) { - throw new Error('fetchWithCache only supports JSON responses') + throw new Error('fetchWithCache only supports JSON responses'); } - const currentTime = Date.now() - const cacheKey = `cachedFetch:${url}` - const { cachedResponse, cachedTime } = (await getStorageItem(cacheKey)) || {} + const currentTime = Date.now(); + const cacheKey = `cachedFetch:${url}`; + const { cachedResponse, cachedTime } = (await getStorageItem(cacheKey)) || {}; if (cachedResponse && currentTime - cachedTime < cacheRefreshTime) { - return cachedResponse + return cachedResponse; } - fetchOptions.headers.set('Content-Type', 'application/json') - const fetchWithTimeout = getFetchWithTimeout(timeout) + fetchOptions.headers.set('Content-Type', 'application/json'); + const fetchWithTimeout = getFetchWithTimeout(timeout); const response = await fetchWithTimeout(url, { referrerPolicy: 'no-referrer-when-downgrade', body: null, method: 'GET', mode: 'cors', ...fetchOptions, - }) + }); if (!response.ok) { throw new Error( `Fetch failed with status '${response.status}': '${response.statusText}'`, - ) + ); } - const responseJson = await response.json() + const responseJson = await response.json(); const cacheEntry = { cachedResponse: responseJson, cachedTime: currentTime, - } + }; - await setStorageItem(cacheKey, cacheEntry) - return responseJson -} + await setStorageItem(cacheKey, cacheEntry); + return responseJson; +}; -export default fetchWithCache +export default fetchWithCache; diff --git a/ui/app/helpers/utils/fetch-with-cache.test.js b/ui/app/helpers/utils/fetch-with-cache.test.js index 3c98cadba4..0b6dc3da3a 100644 --- a/ui/app/helpers/utils/fetch-with-cache.test.js +++ b/ui/app/helpers/utils/fetch-with-cache.test.js @@ -1,79 +1,79 @@ -import assert from 'assert' -import nock from 'nock' -import sinon from 'sinon' -import proxyquire from 'proxyquire' +import assert from 'assert'; +import nock from 'nock'; +import sinon from 'sinon'; +import proxyquire from 'proxyquire'; -const fakeStorage = {} +const fakeStorage = {}; const fetchWithCache = proxyquire('./fetch-with-cache', { '../../../lib/storage-helpers': fakeStorage, -}).default +}).default; describe('Fetch with cache', function () { beforeEach(function () { - fakeStorage.getStorageItem = sinon.stub() - fakeStorage.setStorageItem = sinon.stub() - }) + fakeStorage.getStorageItem = sinon.stub(); + fakeStorage.setStorageItem = sinon.stub(); + }); afterEach(function () { - sinon.restore() - nock.cleanAll() - }) + sinon.restore(); + nock.cleanAll(); + }); it('fetches a url', async function () { nock('https://fetchwithcache.metamask.io') .get('/price') - .reply(200, '{"average": 1}') + .reply(200, '{"average": 1}'); const response = await fetchWithCache( 'https://fetchwithcache.metamask.io/price', - ) + ); assert.deepStrictEqual(response, { average: 1, - }) - }) + }); + }); it('returns cached response', async function () { nock('https://fetchwithcache.metamask.io') .get('/price') - .reply(200, '{"average": 2}') + .reply(200, '{"average": 2}'); fakeStorage.getStorageItem.returns({ cachedResponse: { average: 1 }, cachedTime: Date.now(), - }) + }); const response = await fetchWithCache( 'https://fetchwithcache.metamask.io/price', - ) + ); assert.deepStrictEqual(response, { average: 1, - }) - }) + }); + }); it('fetches URL again after cache refresh time has passed', async function () { nock('https://fetchwithcache.metamask.io') .get('/price') - .reply(200, '{"average": 3}') + .reply(200, '{"average": 3}'); fakeStorage.getStorageItem.returns({ cachedResponse: { average: 1 }, cachedTime: Date.now() - 1000, - }) + }); const response = await fetchWithCache( 'https://fetchwithcache.metamask.io/price', {}, { cacheRefreshTime: 123 }, - ) + ); assert.deepStrictEqual(response, { average: 3, - }) - }) + }); + }); it('should abort the request when the custom timeout is hit', async function () { nock('https://fetchwithcache.metamask.io') .get('/price') .delay(100) - .reply(200, '{"average": 4}') + .reply(200, '{"average": 4}'); await assert.rejects( () => @@ -83,45 +83,45 @@ describe('Fetch with cache', function () { { timeout: 20 }, ), { name: 'AbortError', message: 'Aborted' }, - ) - }) + ); + }); it('throws when the response is unsuccessful', async function () { nock('https://fetchwithcache.metamask.io') .get('/price') - .reply(500, '{"average": 6}') + .reply(500, '{"average": 6}'); await assert.rejects(() => fetchWithCache('https://fetchwithcache.metamask.io/price'), - ) - }) + ); + }); it('throws when a POST request is attempted', async function () { nock('https://fetchwithcache.metamask.io') .post('/price') - .reply(200, '{"average": 7}') + .reply(200, '{"average": 7}'); await assert.rejects(() => fetchWithCache('https://fetchwithcache.metamask.io/price', { method: 'POST', }), - ) - }) + ); + }); it('throws when the request has a truthy body', async function () { nock('https://fetchwithcache.metamask.io') .get('/price') - .reply(200, '{"average": 8}') + .reply(200, '{"average": 8}'); await assert.rejects(() => fetchWithCache('https://fetchwithcache.metamask.io/price', { body: 1 }), - ) - }) + ); + }); it('throws when the request has an invalid Content-Type header', async function () { nock('https://fetchwithcache.metamask.io') .get('/price') - .reply(200, '{"average": 9}') + .reply(200, '{"average": 9}'); await assert.rejects( () => @@ -129,22 +129,22 @@ describe('Fetch with cache', function () { headers: { 'Content-Type': 'text/plain' }, }), { message: 'fetchWithCache only supports JSON responses' }, - ) - }) + ); + }); it('should correctly cache responses from interwoven requests', async function () { nock('https://fetchwithcache.metamask.io') .get('/foo') - .reply(200, '{"average": 9}') + .reply(200, '{"average": 9}'); nock('https://fetchwithcache.metamask.io') .get('/bar') - .reply(200, '{"average": 9}') + .reply(200, '{"average": 9}'); - const testCache = {} - fakeStorage.getStorageItem.callsFake((key) => testCache[key]) + const testCache = {}; + fakeStorage.getStorageItem.callsFake((key) => testCache[key]); fakeStorage.setStorageItem.callsFake((key, value) => { - testCache[key] = value - }) + testCache[key] = value; + }); await Promise.all([ fetchWithCache( @@ -157,17 +157,17 @@ describe('Fetch with cache', function () { {}, { cacheRefreshTime: 123 }, ), - ]) + ]); assert.deepStrictEqual( testCache['cachedFetch:https://fetchwithcache.metamask.io/foo'] .cachedResponse, { average: 9 }, - ) + ); assert.deepStrictEqual( testCache['cachedFetch:https://fetchwithcache.metamask.io/bar'] .cachedResponse, { average: 9 }, - ) - }) -}) + ); + }); +}); diff --git a/ui/app/helpers/utils/formatters.js b/ui/app/helpers/utils/formatters.js index f4a1200443..c75e30f1cf 100644 --- a/ui/app/helpers/utils/formatters.js +++ b/ui/app/helpers/utils/formatters.js @@ -1,3 +1,3 @@ export function formatETHFee(ethFee) { - return `${ethFee} ETH` + return `${ethFee} ETH`; } diff --git a/ui/app/helpers/utils/i18n-helper.js b/ui/app/helpers/utils/i18n-helper.js index bb89326831..ea2d7049ff 100644 --- a/ui/app/helpers/utils/i18n-helper.js +++ b/ui/app/helpers/utils/i18n-helper.js @@ -1,15 +1,15 @@ // cross-browser connection to extension i18n API -import React from 'react' -import log from 'loglevel' -import * as Sentry from '@sentry/browser' +import React from 'react'; +import log from 'loglevel'; +import * as Sentry from '@sentry/browser'; -import getFetchWithTimeout from '../../../../shared/modules/fetch-with-timeout' +import getFetchWithTimeout from '../../../../shared/modules/fetch-with-timeout'; -const fetchWithTimeout = getFetchWithTimeout(30000) +const fetchWithTimeout = getFetchWithTimeout(30000); -const warned = {} -const missingMessageErrors = {} -const missingSubstitutionErrors = {} +const warned = {}; +const missingMessageErrors = {}; +const missingSubstitutionErrors = {}; /** * Returns a localized message for the given key @@ -21,110 +21,110 @@ const missingSubstitutionErrors = {} */ export const getMessage = (localeCode, localeMessages, key, substitutions) => { if (!localeMessages) { - return null + return null; } if (!localeMessages[key]) { if (localeCode === 'en') { if (!missingMessageErrors[key]) { missingMessageErrors[key] = new Error( `Unable to find value of key "${key}" for locale "${localeCode}"`, - ) - Sentry.captureException(missingMessageErrors[key]) - log.error(missingMessageErrors[key]) + ); + Sentry.captureException(missingMessageErrors[key]); + log.error(missingMessageErrors[key]); if (process.env.IN_TEST === 'true') { - throw missingMessageErrors[key] + throw missingMessageErrors[key]; } } } else if (!warned[localeCode] || !warned[localeCode][key]) { if (!warned[localeCode]) { - warned[localeCode] = {} + warned[localeCode] = {}; } - warned[localeCode][key] = true + warned[localeCode][key] = true; log.warn( `Translator - Unable to find value of key "${key}" for locale "${localeCode}"`, - ) + ); } - return null + return null; } - const entry = localeMessages[key] - let phrase = entry.message + const entry = localeMessages[key]; + let phrase = entry.message; - const hasSubstitutions = Boolean(substitutions && substitutions.length) + const hasSubstitutions = Boolean(substitutions && substitutions.length); const hasReactSubstitutions = hasSubstitutions && substitutions.some( (element) => element !== null && (typeof element === 'function' || typeof element === 'object'), - ) + ); // perform substitutions if (hasSubstitutions) { - const parts = phrase.split(/(\$\d)/gu) + const parts = phrase.split(/(\$\d)/gu); const substitutedParts = parts.map((part) => { - const subMatch = part.match(/\$(\d)/u) + const subMatch = part.match(/\$(\d)/u); if (!subMatch) { - return part + return part; } - const substituteIndex = Number(subMatch[1]) - 1 + const substituteIndex = Number(subMatch[1]) - 1; if ( (substitutions[substituteIndex] === null || substitutions[substituteIndex] === undefined) && !missingSubstitutionErrors[localeCode]?.[key] ) { if (!missingSubstitutionErrors[localeCode]) { - missingSubstitutionErrors[localeCode] = {} + missingSubstitutionErrors[localeCode] = {}; } - missingSubstitutionErrors[localeCode][key] = true + missingSubstitutionErrors[localeCode][key] = true; const error = new Error( `Insufficient number of substitutions for key "${key}" with locale "${localeCode}"`, - ) - log.error(error) - Sentry.captureException(error) + ); + log.error(error); + Sentry.captureException(error); } - return substitutions[substituteIndex] - }) + return substitutions[substituteIndex]; + }); phrase = hasReactSubstitutions ? ( {substitutedParts} ) : ( substitutedParts.join('') - ) + ); } - return phrase -} + return phrase; +}; export async function fetchLocale(localeCode) { try { const response = await fetchWithTimeout( `./_locales/${localeCode}/messages.json`, - ) - return await response.json() + ); + return await response.json(); } catch (error) { - log.error(`failed to fetch ${localeCode} locale because of ${error}`) - return {} + log.error(`failed to fetch ${localeCode} locale because of ${error}`); + return {}; } } -const relativeTimeFormatLocaleData = new Set() +const relativeTimeFormatLocaleData = new Set(); export async function loadRelativeTimeFormatLocaleData(localeCode) { - const languageTag = localeCode.split('_')[0] + const languageTag = localeCode.split('_')[0]; if ( Intl.RelativeTimeFormat && typeof Intl.RelativeTimeFormat.__addLocaleData === 'function' && !relativeTimeFormatLocaleData.has(languageTag) ) { - const localeData = await fetchRelativeTimeFormatData(languageTag) - Intl.RelativeTimeFormat.__addLocaleData(localeData) + const localeData = await fetchRelativeTimeFormatData(languageTag); + Intl.RelativeTimeFormat.__addLocaleData(localeData); } } async function fetchRelativeTimeFormatData(languageTag) { const response = await fetchWithTimeout( `./intl/${languageTag}/relative-time-format-data.json`, - ) - return await response.json() + ); + return await response.json(); } diff --git a/ui/app/helpers/utils/i18n-helper.test.js b/ui/app/helpers/utils/i18n-helper.test.js index 1c908f7f34..d020533154 100644 --- a/ui/app/helpers/utils/i18n-helper.test.js +++ b/ui/app/helpers/utils/i18n-helper.test.js @@ -1,30 +1,30 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import { getMessage } from './i18n-helper' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import { getMessage } from './i18n-helper'; describe('i18n helper', function () { - const TEST_LOCALE_CODE = 'TEST_LOCALE_CODE' + const TEST_LOCALE_CODE = 'TEST_LOCALE_CODE'; - const TEST_KEY_1 = 'TEST_KEY_1' - const TEST_KEY_2 = 'TEST_KEY_2' - const TEST_KEY_3 = 'TEST_KEY_3' - const TEST_KEY_4 = 'TEST_KEY_4' - const TEST_KEY_5 = 'TEST_KEY_5' - const TEST_KEY_6 = 'TEST_KEY_6' - const TEST_KEY_6_HELPER = 'TEST_KEY_6_HELPER' - const TEST_KEY_7 = 'TEST_KEY_7' - const TEST_KEY_7_HELPER_1 = 'TEST_KEY_7_HELPER_1' - const TEST_KEY_7_HELPER_2 = 'TEST_KEY_7_HELPER_2' - const TEST_KEY_8 = 'TEST_KEY_8' - const TEST_KEY_8_HELPER_1 = 'TEST_KEY_8_HELPER_1' - const TEST_KEY_8_HELPER_2 = 'TEST_KEY_8_HELPER_2' + const TEST_KEY_1 = 'TEST_KEY_1'; + const TEST_KEY_2 = 'TEST_KEY_2'; + const TEST_KEY_3 = 'TEST_KEY_3'; + const TEST_KEY_4 = 'TEST_KEY_4'; + const TEST_KEY_5 = 'TEST_KEY_5'; + const TEST_KEY_6 = 'TEST_KEY_6'; + const TEST_KEY_6_HELPER = 'TEST_KEY_6_HELPER'; + const TEST_KEY_7 = 'TEST_KEY_7'; + const TEST_KEY_7_HELPER_1 = 'TEST_KEY_7_HELPER_1'; + const TEST_KEY_7_HELPER_2 = 'TEST_KEY_7_HELPER_2'; + const TEST_KEY_8 = 'TEST_KEY_8'; + const TEST_KEY_8_HELPER_1 = 'TEST_KEY_8_HELPER_1'; + const TEST_KEY_8_HELPER_2 = 'TEST_KEY_8_HELPER_2'; - const TEST_SUBSTITUTION_1 = 'TEST_SUBSTITUTION_1' - const TEST_SUBSTITUTION_2 = 'TEST_SUBSTITUTION_2' - const TEST_SUBSTITUTION_3 = 'TEST_SUBSTITUTION_3' - const TEST_SUBSTITUTION_4 = 'TEST_SUBSTITUTION_4' - const TEST_SUBSTITUTION_5 = 'TEST_SUBSTITUTION_5' + const TEST_SUBSTITUTION_1 = 'TEST_SUBSTITUTION_1'; + const TEST_SUBSTITUTION_2 = 'TEST_SUBSTITUTION_2'; + const TEST_SUBSTITUTION_3 = 'TEST_SUBSTITUTION_3'; + const TEST_SUBSTITUTION_4 = 'TEST_SUBSTITUTION_4'; + const TEST_SUBSTITUTION_5 = 'TEST_SUBSTITUTION_5'; const testLocaleMessages = { [TEST_KEY_1]: { @@ -68,56 +68,56 @@ describe('i18n helper', function () { [TEST_KEY_8_HELPER_2]: { message: TEST_SUBSTITUTION_4, }, - } - const t = getMessage.bind(null, TEST_LOCALE_CODE, testLocaleMessages) + }; + const t = getMessage.bind(null, TEST_LOCALE_CODE, testLocaleMessages); const TEST_SUBSTITUTION_6 = (
    {t(TEST_KEY_6_HELPER)}
    - ) + ); const TEST_SUBSTITUTION_7_1 = (
    {t(TEST_KEY_7_HELPER_1)}
    - ) + ); const TEST_SUBSTITUTION_7_2 = (
    {t(TEST_KEY_7_HELPER_2)}
    - ) + ); const TEST_SUBSTITUTION_8_1 = (
    {t(TEST_KEY_8_HELPER_1)}
    - ) + ); const TEST_SUBSTITUTION_8_2 = (
    {t(TEST_KEY_8_HELPER_2)}
    - ) + ); describe('getMessage', function () { it('should return the exact message paired with key if there are no substitutions', function () { - const result = t(TEST_KEY_1) - assert.strictEqual(result, 'This is a simple message.') - }) + const result = t(TEST_KEY_1); + assert.strictEqual(result, 'This is a simple message.'); + }); it('should return the correct message when a single non-react substitution is made', function () { - const result = t(TEST_KEY_2, [TEST_SUBSTITUTION_1]) + const result = t(TEST_KEY_2, [TEST_SUBSTITUTION_1]); assert.strictEqual( result, `This is a message with a single non-react substitution ${TEST_SUBSTITUTION_1}.`, - ) - }) + ); + }); it('should return the correct message when two non-react substitutions are made', function () { - const result = t(TEST_KEY_3, [TEST_SUBSTITUTION_1, TEST_SUBSTITUTION_2]) + const result = t(TEST_KEY_3, [TEST_SUBSTITUTION_1, TEST_SUBSTITUTION_2]); assert.strictEqual( result, `This is a message with two non-react substitutions ${TEST_SUBSTITUTION_1} and ${TEST_SUBSTITUTION_2}.`, - ) - }) + ); + }); it('should return the correct message when multiple non-react substitutions are made', function () { const result = t(TEST_KEY_4, [ @@ -126,41 +126,41 @@ describe('i18n helper', function () { TEST_SUBSTITUTION_3, TEST_SUBSTITUTION_4, TEST_SUBSTITUTION_5, - ]) + ]); assert.strictEqual( result, `${TEST_SUBSTITUTION_1} - ${TEST_SUBSTITUTION_2} - ${TEST_SUBSTITUTION_3} - ${TEST_SUBSTITUTION_4} - ${TEST_SUBSTITUTION_5}`, - ) - }) + ); + }); it('should correctly render falsey substitutions', function () { - const result = t(TEST_KEY_4, [0, -0, '', false, NaN]) - assert.strictEqual(result, '0 - 0 - - false - NaN') - }) + const result = t(TEST_KEY_4, [0, -0, '', false, NaN]); + assert.strictEqual(result, '0 - 0 - - false - NaN'); + }); it('should render nothing for "null" and "undefined" substitutions', function () { - const result = t(TEST_KEY_5, [null, TEST_SUBSTITUTION_2]) - assert.strictEqual(result, ` - ${TEST_SUBSTITUTION_2} - `) - }) + const result = t(TEST_KEY_5, [null, TEST_SUBSTITUTION_2]); + assert.strictEqual(result, ` - ${TEST_SUBSTITUTION_2} - `); + }); it('should return the correct message when a single react substitution is made', function () { - const result = t(TEST_KEY_6, [TEST_SUBSTITUTION_6]) + const result = t(TEST_KEY_6, [TEST_SUBSTITUTION_6]); assert.strictEqual( shallow(result).html(), ' Testing a react substitution
    TEST_SUBSTITUTION_1
    .
    ', - ) - }) + ); + }); it('should return the correct message when two react substitutions are made', function () { const result = t(TEST_KEY_7, [ TEST_SUBSTITUTION_7_1, TEST_SUBSTITUTION_7_2, - ]) + ]); assert.strictEqual( shallow(result).html(), ' Testing a react substitution
    TEST_SUBSTITUTION_1
    and another
    TEST_SUBSTITUTION_2
    .
    ', - ) - }) + ); + }); it('should return the correct message when substituting a mix of react elements and strings', function () { const result = t(TEST_KEY_8, [ @@ -168,11 +168,11 @@ describe('i18n helper', function () { TEST_SUBSTITUTION_8_1, TEST_SUBSTITUTION_2, TEST_SUBSTITUTION_8_2, - ]) + ]); assert.strictEqual( shallow(result).html(), ' Testing a mix TEST_SUBSTITUTION_1 of react substitutions
    TEST_SUBSTITUTION_3
    and string substitutions TEST_SUBSTITUTION_2 +
    TEST_SUBSTITUTION_4
    .
    ', - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/ui/app/helpers/utils/switch-direction.js b/ui/app/helpers/utils/switch-direction.js index 5d4075896c..606f452f6d 100644 --- a/ui/app/helpers/utils/switch-direction.js +++ b/ui/app/helpers/utils/switch-direction.js @@ -6,30 +6,30 @@ const switchDirection = async (direction) => { if (direction === 'auto') { // eslint-disable-next-line no-param-reassign - direction = 'ltr' + direction = 'ltr'; } - let updatedLink + let updatedLink; Array.from(document.getElementsByTagName('link')) .filter((link) => link.rel === 'stylesheet') .forEach((link) => { if (link.title === direction && link.disabled) { - link.disabled = false - updatedLink = link + link.disabled = false; + updatedLink = link; } else if (link.title !== direction && !link.disabled) { - link.disabled = true + link.disabled = true; } - }) + }); if (updatedLink) { return new Promise((resolve, reject) => { updatedLink.onload = () => { - resolve() - } + resolve(); + }; updatedLink.onerror = () => - reject(new Error(`Failed to load '${direction}' stylesheet`)) - }) + reject(new Error(`Failed to load '${direction}' stylesheet`)); + }); } - return undefined -} + return undefined; +}; -export default switchDirection +export default switchDirection; diff --git a/ui/app/helpers/utils/token-util.js b/ui/app/helpers/utils/token-util.js index e8965edb33..8811bec5d9 100644 --- a/ui/app/helpers/utils/token-util.js +++ b/ui/app/helpers/utils/token-util.js @@ -1,154 +1,154 @@ -import log from 'loglevel' -import BigNumber from 'bignumber.js' -import contractMap from '@metamask/contract-metadata' -import * as util from './util' -import { conversionUtil, multiplyCurrencies } from './conversion-util' -import { formatCurrency } from './confirm-tx.util' +import log from 'loglevel'; +import BigNumber from 'bignumber.js'; +import contractMap from '@metamask/contract-metadata'; +import * as util from './util'; +import { conversionUtil, multiplyCurrencies } from './conversion-util'; +import { formatCurrency } from './confirm-tx.util'; const casedContractMap = Object.keys(contractMap).reduce((acc, base) => { return { ...acc, [base.toLowerCase()]: contractMap[base], - } -}, {}) + }; +}, {}); -const DEFAULT_SYMBOL = '' -const DEFAULT_DECIMALS = '0' +const DEFAULT_SYMBOL = ''; +const DEFAULT_DECIMALS = '0'; async function getSymbolFromContract(tokenAddress) { - const token = util.getContractAtAddress(tokenAddress) + const token = util.getContractAtAddress(tokenAddress); try { - const result = await token.symbol() - return result[0] + const result = await token.symbol(); + return result[0]; } catch (error) { log.warn( `symbol() call for token at address ${tokenAddress} resulted in error:`, error, - ) - return undefined + ); + return undefined; } } async function getDecimalsFromContract(tokenAddress) { - const token = util.getContractAtAddress(tokenAddress) + const token = util.getContractAtAddress(tokenAddress); try { - const result = await token.decimals() - const decimalsBN = result[0] - return decimalsBN?.toString() + const result = await token.decimals(); + const decimalsBN = result[0]; + return decimalsBN?.toString(); } catch (error) { log.warn( `decimals() call for token at address ${tokenAddress} resulted in error:`, error, - ) - return undefined + ); + return undefined; } } function getContractMetadata(tokenAddress) { - return tokenAddress && casedContractMap[tokenAddress.toLowerCase()] + return tokenAddress && casedContractMap[tokenAddress.toLowerCase()]; } async function getSymbol(tokenAddress) { - let symbol = await getSymbolFromContract(tokenAddress) + let symbol = await getSymbolFromContract(tokenAddress); if (!symbol) { - const contractMetadataInfo = getContractMetadata(tokenAddress) + const contractMetadataInfo = getContractMetadata(tokenAddress); if (contractMetadataInfo) { - symbol = contractMetadataInfo.symbol + symbol = contractMetadataInfo.symbol; } } - return symbol + return symbol; } async function getDecimals(tokenAddress) { - let decimals = await getDecimalsFromContract(tokenAddress) + let decimals = await getDecimalsFromContract(tokenAddress); if (!decimals || decimals === '0') { - const contractMetadataInfo = getContractMetadata(tokenAddress) + const contractMetadataInfo = getContractMetadata(tokenAddress); if (contractMetadataInfo) { - decimals = contractMetadataInfo.decimals + decimals = contractMetadataInfo.decimals; } } - return decimals + return decimals; } export async function fetchSymbolAndDecimals(tokenAddress) { - let symbol, decimals + let symbol, decimals; try { - symbol = await getSymbol(tokenAddress) - decimals = await getDecimals(tokenAddress) + symbol = await getSymbol(tokenAddress); + decimals = await getDecimals(tokenAddress); } catch (error) { log.warn( `symbol() and decimal() calls for token at address ${tokenAddress} resulted in error:`, error, - ) + ); } return { symbol: symbol || DEFAULT_SYMBOL, decimals: decimals || DEFAULT_DECIMALS, - } + }; } export async function getSymbolAndDecimals(tokenAddress, existingTokens = []) { const existingToken = existingTokens.find( ({ address }) => tokenAddress === address, - ) + ); if (existingToken) { return { symbol: existingToken.symbol, decimals: existingToken.decimals, - } + }; } - let symbol, decimals + let symbol, decimals; try { - symbol = await getSymbol(tokenAddress) - decimals = await getDecimals(tokenAddress) + symbol = await getSymbol(tokenAddress); + decimals = await getDecimals(tokenAddress); } catch (error) { log.warn( `symbol() and decimal() calls for token at address ${tokenAddress} resulted in error:`, error, - ) + ); } return { symbol: symbol || DEFAULT_SYMBOL, decimals: decimals || DEFAULT_DECIMALS, - } + }; } export function tokenInfoGetter() { - const tokens = {} + const tokens = {}; return async (address) => { if (tokens[address]) { - return tokens[address] + return tokens[address]; } - tokens[address] = await getSymbolAndDecimals(address) + tokens[address] = await getSymbolAndDecimals(address); - return tokens[address] - } + return tokens[address]; + }; } export function calcTokenAmount(value, decimals) { - const multiplier = Math.pow(10, Number(decimals || 0)) - return new BigNumber(String(value)).div(multiplier) + const multiplier = Math.pow(10, Number(decimals || 0)); + return new BigNumber(String(value)).div(multiplier); } export function calcTokenValue(value, decimals) { - const multiplier = Math.pow(10, Number(decimals || 0)) - return new BigNumber(String(value)).times(multiplier) + const multiplier = Math.pow(10, Number(decimals || 0)); + return new BigNumber(String(value)).times(multiplier); } /** @@ -162,8 +162,8 @@ export function calcTokenValue(value, decimals) { * @returns {string | undefined} A lowercase address string. */ export function getTokenAddressParam(tokenData = {}) { - const value = tokenData?.args?._to || tokenData?.args?.[0] - return value?.toString().toLowerCase() + const value = tokenData?.args?._to || tokenData?.args?.[0]; + return value?.toString().toLowerCase(); } /** @@ -174,12 +174,12 @@ export function getTokenAddressParam(tokenData = {}) { * @returns {string | undefined} A decimal string value. */ export function getTokenValueParam(tokenData = {}) { - return tokenData?.args?._value?.toString() + return tokenData?.args?._value?.toString(); } export function getTokenValue(tokenParams = []) { - const valueData = tokenParams.find((param) => param.name === '_value') - return valueData && valueData.value + const valueData = tokenParams.find((param) => param.name === '_value'); + return valueData && valueData.value; } /** @@ -211,7 +211,7 @@ export function getTokenFiatAmount( !contractExchangeRate || tokenAmount === undefined ) { - return undefined + return undefined; } const currentTokenToFiatRate = multiplyCurrencies( @@ -221,24 +221,24 @@ export function getTokenFiatAmount( multiplicandBase: 10, multiplierBase: 10, }, - ) + ); const currentTokenInFiat = conversionUtil(tokenAmount, { fromNumericBase: 'dec', fromCurrency: tokenSymbol, toCurrency: currentCurrency.toUpperCase(), numberOfDecimals: 2, conversionRate: currentTokenToFiatRate, - }) - let result + }); + let result; if (hideCurrencySymbol) { - result = formatCurrency(currentTokenInFiat, currentCurrency) + result = formatCurrency(currentTokenInFiat, currentCurrency); } else if (formatted) { result = `${formatCurrency( currentTokenInFiat, currentCurrency, - )} ${currentCurrency.toUpperCase()}` + )} ${currentCurrency.toUpperCase()}`; } else { - result = currentTokenInFiat + result = currentTokenInFiat; } - return result + return result; } diff --git a/ui/app/helpers/utils/transactions.util.js b/ui/app/helpers/utils/transactions.util.js index bcafae9700..61f2e1f8c0 100644 --- a/ui/app/helpers/utils/transactions.util.js +++ b/ui/app/helpers/utils/transactions.util.js @@ -1,20 +1,20 @@ -import { MethodRegistry } from 'eth-method-registry' -import abi from 'human-standard-token-abi' -import { ethers } from 'ethers' -import log from 'loglevel' -import { addHexPrefix } from '../../../../app/scripts/lib/util' -import { getEtherscanNetworkPrefix } from '../../../lib/etherscan-prefix-for-network' +import { MethodRegistry } from 'eth-method-registry'; +import abi from 'human-standard-token-abi'; +import { ethers } from 'ethers'; +import log from 'loglevel'; +import { addHexPrefix } from '../../../../app/scripts/lib/util'; +import { getEtherscanNetworkPrefix } from '../../../lib/etherscan-prefix-for-network'; import { TRANSACTION_CATEGORIES, TRANSACTION_GROUP_STATUSES, TRANSACTION_STATUSES, TRANSACTION_TYPES, -} from '../../../../shared/constants/transaction' -import fetchWithCache from './fetch-with-cache' +} from '../../../../shared/constants/transaction'; +import fetchWithCache from './fetch-with-cache'; -import { addCurrencies } from './conversion-util' +import { addCurrencies } from './conversion-util'; -const hstInterface = new ethers.utils.Interface(abi) +const hstInterface = new ethers.utils.Interface(abi); /** * @typedef EthersContractCall @@ -34,10 +34,10 @@ const hstInterface = new ethers.utils.Interface(abi) */ export function getTokenData(data) { try { - return hstInterface.parseTransaction({ data }) + return hstInterface.parseTransaction({ data }); } catch (error) { - log.debug('Failed to parse transaction data.', error, data) - return undefined + log.debug('Failed to parse transaction data.', error, data); + return undefined; } } @@ -50,14 +50,14 @@ async function getMethodFrom4Byte(fourBytePrefix) { method: 'GET', mode: 'cors', }, - ) + ); if (fourByteResponse.count === 1) { - return fourByteResponse.results[0].text_signature + return fourByteResponse.results[0].text_signature; } - return null + return null; } -let registry +let registry; /** * Attempts to return the method data from the MethodRegistry library, the message registry library and the token abi, in that order of preference @@ -67,33 +67,33 @@ let registry export async function getMethodDataAsync(fourBytePrefix) { try { const fourByteSig = getMethodFrom4Byte(fourBytePrefix).catch((e) => { - log.error(e) - return null - }) + log.error(e); + return null; + }); if (!registry) { - registry = new MethodRegistry({ provider: global.ethereumProvider }) + registry = new MethodRegistry({ provider: global.ethereumProvider }); } - let sig = await registry.lookup(fourBytePrefix) + let sig = await registry.lookup(fourBytePrefix); if (!sig) { - sig = await fourByteSig + sig = await fourByteSig; } if (!sig) { - return {} + return {}; } - const parsedResult = registry.parse(sig) + const parsedResult = registry.parse(sig); return { name: parsedResult.name, params: parsedResult.args, - } + }; } catch (error) { - log.error(error) - return {} + log.error(error); + return {}; } } @@ -104,9 +104,9 @@ export async function getMethodDataAsync(fourBytePrefix) { * @returns {string} The four-byte method signature */ export function getFourBytePrefix(data = '') { - const prefixedData = addHexPrefix(data) - const fourBytePrefix = prefixedData.slice(0, 10) - return fourBytePrefix + const prefixedData = addHexPrefix(data); + const fourBytePrefix = prefixedData.slice(0, 10); + return fourBytePrefix; } /** @@ -120,7 +120,7 @@ export function isTokenMethodAction(transactionCategory) { TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER, TRANSACTION_CATEGORIES.TOKEN_METHOD_APPROVE, TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER_FROM, - ].includes(transactionCategory) + ].includes(transactionCategory); } export function getLatestSubmittedTxWithNonce( @@ -128,27 +128,27 @@ export function getLatestSubmittedTxWithNonce( nonce = '0x0', ) { if (!transactions.length) { - return {} + return {}; } return transactions.reduce((acc, current) => { - const { submittedTime, txParams: { nonce: currentNonce } = {} } = current + const { submittedTime, txParams: { nonce: currentNonce } = {} } = current; if (currentNonce === nonce) { if (!acc.submittedTime) { - return current + return current; } - return submittedTime > acc.submittedTime ? current : acc + return submittedTime > acc.submittedTime ? current : acc; } - return acc - }, {}) + return acc; + }, {}); } export async function isSmartContractAddress(address) { - const code = await global.eth.getCode(address) + const code = await global.eth.getCode(address); // Geth will return '0x', and ganache-core v2.2.1 will return '0x0' - const codeIsEmpty = !code || code === '0x' || code === '0x0' - return !codeIsEmpty + const codeIsEmpty = !code || code === '0x' || code === '0x0'; + return !codeIsEmpty; } export function sumHexes(...args) { @@ -157,10 +157,10 @@ export function sumHexes(...args) { toNumericBase: 'hex', aBase: 16, bBase: 16, - }) - }) + }); + }); - return addHexPrefix(total) + return addHexPrefix(total); } /** @@ -175,21 +175,21 @@ export function getStatusKey(transaction) { txReceipt: { status: receiptStatus } = {}, type, status, - } = transaction + } = transaction; // There was an on-chain failure if (receiptStatus === '0x0') { - return TRANSACTION_STATUSES.FAILED + return TRANSACTION_STATUSES.FAILED; } if ( status === TRANSACTION_STATUSES.CONFIRMED && type === TRANSACTION_TYPES.CANCEL ) { - return TRANSACTION_GROUP_STATUSES.CANCELLED + return TRANSACTION_GROUP_STATUSES.CANCELLED; } - return transaction.status + return transaction.status; } /** @@ -200,8 +200,8 @@ export function getStatusKey(transaction) { */ export function getBlockExplorerUrlForTx(networkId, hash, rpcPrefs = {}) { if (rpcPrefs.blockExplorerUrl) { - return `${rpcPrefs.blockExplorerUrl.replace(/\/+$/u, '')}/tx/${hash}` + return `${rpcPrefs.blockExplorerUrl.replace(/\/+$/u, '')}/tx/${hash}`; } - const prefix = getEtherscanNetworkPrefix(networkId) - return `https://${prefix}etherscan.io/tx/${hash}` + const prefix = getEtherscanNetworkPrefix(networkId); + return `https://${prefix}etherscan.io/tx/${hash}`; } diff --git a/ui/app/helpers/utils/transactions.util.test.js b/ui/app/helpers/utils/transactions.util.test.js index 9079028dda..a725156bdc 100644 --- a/ui/app/helpers/utils/transactions.util.test.js +++ b/ui/app/helpers/utils/transactions.util.test.js @@ -1,30 +1,30 @@ -import assert from 'assert' +import assert from 'assert'; import { TRANSACTION_CATEGORIES, TRANSACTION_GROUP_STATUSES, TRANSACTION_STATUSES, -} from '../../../../shared/constants/transaction' -import * as utils from './transactions.util' +} from '../../../../shared/constants/transaction'; +import * as utils from './transactions.util'; describe('Transactions utils', function () { describe('getTokenData', function () { it('should return token data', function () { const tokenData = utils.getTokenData( '0xa9059cbb00000000000000000000000050a9d56c2b8ba9a5c7f2c08c3d26e0499f23a7060000000000000000000000000000000000000000000000000000000000004e20', - ) - assert.ok(tokenData) - const { name, args } = tokenData - assert.strictEqual(name, TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER) - const to = args._to - const value = args._value.toString() - assert.strictEqual(to, '0x50A9D56C2B8BA9A5c7f2C08C3d26E0499F23a706') - assert.strictEqual(value, '20000') - }) + ); + assert.ok(tokenData); + const { name, args } = tokenData; + assert.strictEqual(name, TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER); + const to = args._to; + const value = args._value.toString(); + assert.strictEqual(to, '0x50A9D56C2B8BA9A5c7f2C08C3d26E0499F23a706'); + assert.strictEqual(value, '20000'); + }); it('should not throw errors when called without arguments', function () { - assert.doesNotThrow(() => utils.getTokenData()) - }) - }) + assert.doesNotThrow(() => utils.getTokenData()); + }); + }); describe('getStatusKey', function () { it('should return the correct status', function () { @@ -53,13 +53,13 @@ describe('Transactions utils', function () { }, expected: TRANSACTION_GROUP_STATUSES.PENDING, }, - ] + ]; tests.forEach(({ transaction, expected }) => { - assert.strictEqual(utils.getStatusKey(transaction), expected) - }) - }) - }) + assert.strictEqual(utils.getStatusKey(transaction), expected); + }); + }); + }); describe('getBlockExplorerUrlForTx', function () { it('should return the correct block explorer url for a transaction', function () { @@ -93,14 +93,14 @@ describe('Transactions utils', function () { blockExplorerUrl: 'https://another.block.explorer/', }, }, - ] + ]; tests.forEach(({ expected, networkId, hash, rpcPrefs }) => { assert.strictEqual( utils.getBlockExplorerUrlForTx(networkId, hash, rpcPrefs), expected, - ) - }) - }) - }) -}) + ); + }); + }); + }); +}); diff --git a/ui/app/helpers/utils/util.js b/ui/app/helpers/utils/util.js index b88abc876e..bc22d05c15 100644 --- a/ui/app/helpers/utils/util.js +++ b/ui/app/helpers/utils/util.js @@ -1,16 +1,16 @@ -import punycode from 'punycode/punycode' -import abi from 'human-standard-token-abi' -import BigNumber from 'bignumber.js' -import ethUtil from 'ethereumjs-util' -import { DateTime } from 'luxon' -import { addHexPrefix } from '../../../../app/scripts/lib/util' -import getFetchWithTimeout from '../../../../shared/modules/fetch-with-timeout' +import punycode from 'punycode/punycode'; +import abi from 'human-standard-token-abi'; +import BigNumber from 'bignumber.js'; +import ethUtil from 'ethereumjs-util'; +import { DateTime } from 'luxon'; +import { addHexPrefix } from '../../../../app/scripts/lib/util'; +import getFetchWithTimeout from '../../../../shared/modules/fetch-with-timeout'; -const fetchWithTimeout = getFetchWithTimeout(30000) +const fetchWithTimeout = getFetchWithTimeout(30000); // formatData :: ( date: ) -> String export function formatDate(date, format = "M/d/y 'at' T") { - return DateTime.fromMillis(date).toFormat(format) + return DateTime.fromMillis(date).toFormat(format); } export function formatDateWithYearContext( @@ -18,11 +18,11 @@ export function formatDateWithYearContext( formatThisYear = 'MMM d', fallback = 'MMM d, y', ) { - const dateTime = DateTime.fromMillis(date) - const now = DateTime.local() + const dateTime = DateTime.fromMillis(date); + const now = DateTime.local(); return dateTime.toFormat( now.year === dateTime.year ? formatThisYear : fallback, - ) + ); } const valueTable = { @@ -37,11 +37,11 @@ const valueTable = { mether: '0.000001', gether: '0.000000001', tether: '0.000000000001', -} -const bnTable = {} +}; +const bnTable = {}; Object.keys(valueTable).forEach((currency) => { - bnTable[currency] = new ethUtil.BN(valueTable[currency], 10) -}) + bnTable[currency] = new ethUtil.BN(valueTable[currency], 10); +}); export function isEthNetwork(netId) { if ( @@ -52,19 +52,19 @@ export function isEthNetwork(netId) { netId === '42' || netId === '1337' ) { - return true + return true; } - return false + return false; } export function valuesFor(obj) { if (!obj) { - return [] + return []; } return Object.keys(obj).map(function (key) { - return obj[key] - }) + return obj[key]; + }); } export function addressSummary( @@ -74,28 +74,28 @@ export function addressSummary( includeHex = true, ) { if (!address) { - return '' + return ''; } - let checked = checksumAddress(address) + let checked = checksumAddress(address); if (!includeHex) { - checked = ethUtil.stripHexPrefix(checked) + checked = ethUtil.stripHexPrefix(checked); } return checked ? `${checked.slice(0, firstSegLength)}...${checked.slice( checked.length - lastSegLength, )}` - : '...' + : '...'; } export function isValidAddress(address) { if (!address || address === '0x0000000000000000000000000000000000000000') { - return false + return false; } - const prefixed = addHexPrefix(address) + const prefixed = addHexPrefix(address); return ( (isAllOneCase(prefixed.slice(2)) && ethUtil.isValidAddress(prefixed)) || ethUtil.isValidChecksumAddress(prefixed) - ) + ); } export function isValidDomainName(address) { @@ -107,44 +107,44 @@ export function isValidDomainName(address) { // A chunk has minimum length of 1, but minimum tld is set to 2 for now (no 1-character tlds exist yet) .match( /^(?:[a-z0-9](?:[-a-z0-9]*[a-z0-9])?\.)+[a-z0-9][-a-z0-9]*[a-z0-9]$/u, - ) - return match !== null + ); + return match !== null; } export function isAllOneCase(address) { if (!address) { - return true + return true; } - const lower = address.toLowerCase() - const upper = address.toUpperCase() - return address === lower || address === upper + const lower = address.toLowerCase(); + const upper = address.toUpperCase(); + return address === lower || address === upper; } // Takes wei Hex, returns wei BN, even if input is null export function numericBalance(balance) { if (!balance) { - return new ethUtil.BN(0, 16) + return new ethUtil.BN(0, 16); } - const stripped = ethUtil.stripHexPrefix(balance) - return new ethUtil.BN(stripped, 16) + const stripped = ethUtil.stripHexPrefix(balance); + return new ethUtil.BN(stripped, 16); } // Takes hex, returns [beforeDecimal, afterDecimal] export function parseBalance(balance) { - let afterDecimal - const wei = numericBalance(balance) - const weiString = wei.toString() - const trailingZeros = /0+$/u + let afterDecimal; + const wei = numericBalance(balance); + const weiString = wei.toString(); + const trailingZeros = /0+$/u; const beforeDecimal = - weiString.length > 18 ? weiString.slice(0, weiString.length - 18) : '0' + weiString.length > 18 ? weiString.slice(0, weiString.length - 18) : '0'; afterDecimal = `000000000000000000${wei}` .slice(-18) - .replace(trailingZeros, '') + .replace(trailingZeros, ''); if (afterDecimal === '') { - afterDecimal = '0' + afterDecimal = '0'; } - return [beforeDecimal, afterDecimal] + return [beforeDecimal, afterDecimal]; } // Takes wei hex, returns an object with three properties. @@ -155,147 +155,147 @@ export function formatBalance( needsParse = true, ticker = 'ETH', ) { - const parsed = needsParse ? parseBalance(balance) : balance.split('.') - const beforeDecimal = parsed[0] - let afterDecimal = parsed[1] - let formatted = 'None' + const parsed = needsParse ? parseBalance(balance) : balance.split('.'); + const beforeDecimal = parsed[0]; + let afterDecimal = parsed[1]; + let formatted = 'None'; if (decimalsToKeep === undefined) { if (beforeDecimal === '0') { if (afterDecimal !== '0') { - const sigFigs = afterDecimal.match(/^0*(.{2})/u) // default: grabs 2 most significant digits + const sigFigs = afterDecimal.match(/^0*(.{2})/u); // default: grabs 2 most significant digits if (sigFigs) { - afterDecimal = sigFigs[0] + afterDecimal = sigFigs[0]; } - formatted = `0.${afterDecimal} ${ticker}` + formatted = `0.${afterDecimal} ${ticker}`; } } else { - formatted = `${beforeDecimal}.${afterDecimal.slice(0, 3)} ${ticker}` + formatted = `${beforeDecimal}.${afterDecimal.slice(0, 3)} ${ticker}`; } } else { - afterDecimal += Array(decimalsToKeep).join('0') + afterDecimal += Array(decimalsToKeep).join('0'); formatted = `${beforeDecimal}.${afterDecimal.slice( 0, decimalsToKeep, - )} ${ticker}` + )} ${ticker}`; } - return formatted + return formatted; } export function generateBalanceObject(formattedBalance, decimalsToKeep = 1) { - let balance = formattedBalance.split(' ')[0] - const label = formattedBalance.split(' ')[1] - const beforeDecimal = balance.split('.')[0] - const afterDecimal = balance.split('.')[1] - const shortBalance = shortenBalance(balance, decimalsToKeep) + let balance = formattedBalance.split(' ')[0]; + const label = formattedBalance.split(' ')[1]; + const beforeDecimal = balance.split('.')[0]; + const afterDecimal = balance.split('.')[1]; + const shortBalance = shortenBalance(balance, decimalsToKeep); if (beforeDecimal === '0' && afterDecimal.substr(0, 5) === '00000') { // eslint-disable-next-line eqeqeq if (afterDecimal == 0) { - balance = '0' + balance = '0'; } else { - balance = '<1.0e-5' + balance = '<1.0e-5'; } } else if (beforeDecimal !== '0') { - balance = `${beforeDecimal}.${afterDecimal.slice(0, decimalsToKeep)}` + balance = `${beforeDecimal}.${afterDecimal.slice(0, decimalsToKeep)}`; } - return { balance, label, shortBalance } + return { balance, label, shortBalance }; } export function shortenBalance(balance, decimalsToKeep = 1) { - let truncatedValue - const convertedBalance = parseFloat(balance) + let truncatedValue; + const convertedBalance = parseFloat(balance); if (convertedBalance > 1000000) { - truncatedValue = (balance / 1000000).toFixed(decimalsToKeep) - return `${truncatedValue}m` + truncatedValue = (balance / 1000000).toFixed(decimalsToKeep); + return `${truncatedValue}m`; } else if (convertedBalance > 1000) { - truncatedValue = (balance / 1000).toFixed(decimalsToKeep) - return `${truncatedValue}k` + truncatedValue = (balance / 1000).toFixed(decimalsToKeep); + return `${truncatedValue}k`; } else if (convertedBalance === 0) { - return '0' + return '0'; } else if (convertedBalance < 0.001) { - return '<0.001' + return '<0.001'; } else if (convertedBalance < 1) { - const stringBalance = convertedBalance.toString() + const stringBalance = convertedBalance.toString(); if (stringBalance.split('.')[1].length > 3) { - return convertedBalance.toFixed(3) + return convertedBalance.toFixed(3); } - return stringBalance + return stringBalance; } - return convertedBalance.toFixed(decimalsToKeep) + return convertedBalance.toFixed(decimalsToKeep); } // Takes a BN and an ethereum currency name, // returns a BN in wei export function normalizeToWei(amount, currency) { try { - return amount.mul(bnTable.wei).div(bnTable[currency]) + return amount.mul(bnTable.wei).div(bnTable[currency]); } catch (e) { - return amount + return amount; } } export function normalizeEthStringToWei(str) { - const parts = str.split('.') - let eth = new ethUtil.BN(parts[0], 10).mul(bnTable.wei) + const parts = str.split('.'); + let eth = new ethUtil.BN(parts[0], 10).mul(bnTable.wei); if (parts[1]) { - let decimal = parts[1] + let decimal = parts[1]; while (decimal.length < 18) { - decimal += '0' + decimal += '0'; } if (decimal.length > 18) { - decimal = decimal.slice(0, 18) + decimal = decimal.slice(0, 18); } - const decimalBN = new ethUtil.BN(decimal, 10) - eth = eth.add(decimalBN) + const decimalBN = new ethUtil.BN(decimal, 10); + eth = eth.add(decimalBN); } - return eth + return eth; } -const multiple = new ethUtil.BN('10000', 10) +const multiple = new ethUtil.BN('10000', 10); export function normalizeNumberToWei(n, currency) { - const enlarged = n * 10000 - const amount = new ethUtil.BN(String(enlarged), 10) - return normalizeToWei(amount, currency).div(multiple) + const enlarged = n * 10000; + const amount = new ethUtil.BN(String(enlarged), 10); + return normalizeToWei(amount, currency).div(multiple); } export function isHex(str) { - return Boolean(str.match(/^(0x)?[0-9a-fA-F]+$/u)) + return Boolean(str.match(/^(0x)?[0-9a-fA-F]+$/u)); } export function getContractAtAddress(tokenAddress) { - return global.eth.contract(abi).at(tokenAddress) + return global.eth.contract(abi).at(tokenAddress); } export function getRandomFileName() { - let fileName = '' + let fileName = ''; const charBank = [ ...'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', - ] - const fileNameLength = Math.floor(Math.random() * 7 + 6) + ]; + const fileNameLength = Math.floor(Math.random() * 7 + 6); for (let i = 0; i < fileNameLength; i++) { - fileName += charBank[Math.floor(Math.random() * charBank.length)] + fileName += charBank[Math.floor(Math.random() * charBank.length)]; } - return fileName + return fileName; } export function exportAsFile(filename, data, type = 'text/csv') { // eslint-disable-next-line no-param-reassign - filename = filename || getRandomFileName() + filename = filename || getRandomFileName(); // source: https://stackoverflow.com/a/33542499 by Ludovic Feltz - const blob = new window.Blob([data], { type }) + const blob = new window.Blob([data], { type }); if (window.navigator.msSaveOrOpenBlob) { - window.navigator.msSaveBlob(blob, filename) + window.navigator.msSaveBlob(blob, filename); } else { - const elem = window.document.createElement('a') - elem.target = '_blank' - elem.href = window.URL.createObjectURL(blob) - elem.download = filename - document.body.appendChild(elem) - elem.click() - document.body.removeChild(elem) + const elem = window.document.createElement('a'); + elem.target = '_blank'; + elem.href = window.URL.createObjectURL(blob); + elem.download = filename; + document.body.appendChild(elem); + elem.click(); + document.body.removeChild(elem); } } @@ -307,8 +307,8 @@ export function exportAsFile(filename, data, type = 'text/csv') { * */ export function checksumAddress(address) { - const checksummed = address ? ethUtil.toChecksumAddress(address) : '' - return checksummed + const checksummed = address ? ethUtil.toChecksumAddress(address) : ''; + return checksummed; } /** @@ -324,21 +324,21 @@ export function checksumAddress(address) { */ export function shortenAddress(address = '') { if (address.length < 11) { - return address + return address; } - return `${address.slice(0, 6)}...${address.slice(-4)}` + return `${address.slice(0, 6)}...${address.slice(-4)}`; } export function isValidAddressHead(address) { - const addressLengthIsLessThanFull = address.length < 42 - const addressIsHex = isHex(address) + const addressLengthIsLessThanFull = address.length < 42; + const addressIsHex = isHex(address); - return addressLengthIsLessThanFull && addressIsHex + return addressLengthIsLessThanFull && addressIsHex; } export function getAccountByAddress(accounts = [], targetAddress) { - return accounts.find(({ address }) => address === targetAddress) + return accounts.find(({ address }) => address === targetAddress); } /** @@ -350,7 +350,7 @@ export function getAccountByAddress(accounts = [], targetAddress) { * @returns {string} The URL string, without the scheme, if it was stripped. */ export function stripHttpSchemes(urlString) { - return urlString.replace(/^https?:\/\//u, '') + return urlString.replace(/^https?:\/\//u, ''); } /** @@ -360,20 +360,20 @@ export function stripHttpSchemes(urlString) { * @returns {boolean} Whether the URL-like value is an extension URL. */ export function isExtensionUrl(urlLike) { - const EXT_PROTOCOLS = ['chrome-extension:', 'moz-extension:'] + const EXT_PROTOCOLS = ['chrome-extension:', 'moz-extension:']; if (typeof urlLike === 'string') { for (const protocol of EXT_PROTOCOLS) { if (urlLike.startsWith(protocol)) { - return true + return true; } } } if (urlLike?.protocol) { - return EXT_PROTOCOLS.includes(urlLike.protocol) + return EXT_PROTOCOLS.includes(urlLike.protocol); } - return false + return false; } /** @@ -386,14 +386,14 @@ export function isExtensionUrl(urlLike) { */ export function checkExistingAddresses(address, list = []) { if (!address) { - return false + return false; } const matchesAddress = (obj) => { - return obj.address.toLowerCase() === address.toLowerCase() - } + return obj.address.toLowerCase() === address.toLowerCase(); + }; - return list.some(matchesAddress) + return list.some(matchesAddress); } /** @@ -408,7 +408,7 @@ export function checkExistingAddresses(address, list = []) { export function toPrecisionWithoutTrailingZeros(n, precision) { return new BigNumber(n) .toPrecision(precision) - .replace(/(\.[0-9]*[1-9])0*|(\.0*)/u, '$1') + .replace(/(\.[0-9]*[1-9])0*|(\.0*)/u, '$1'); } /** @@ -417,8 +417,8 @@ export function toPrecisionWithoutTrailingZeros(n, precision) { */ export function addHexPrefixToObjectValues(obj) { return Object.keys(obj).reduce((newObj, key) => { - return { ...newObj, [key]: addHexPrefix(obj[key]) } - }, {}) + return { ...newObj, [key]: addHexPrefix(obj[key]) }; + }, {}); } /** @@ -448,13 +448,13 @@ export function constructTxParams({ value: '0', gas, gasPrice, - } + }; if (!sendToken) { - txParams.value = amount - txParams.to = to + txParams.value = amount; + txParams.to = to; } - return addHexPrefixToObjectValues(txParams) + return addHexPrefixToObjectValues(txParams); } /** @@ -467,19 +467,19 @@ export function constructTxParams({ * or throws an error in case of failure. */ export async function jsonRpcRequest(rpcUrl, rpcMethod, rpcParams = []) { - let fetchUrl = rpcUrl + let fetchUrl = rpcUrl; const headers = { 'Content-Type': 'application/json', - } + }; // Convert basic auth URL component to Authorization header - const { origin, pathname, username, password, search } = new URL(rpcUrl) + const { origin, pathname, username, password, search } = new URL(rpcUrl); // URLs containing username and password needs special processing if (username && password) { const encodedAuth = Buffer.from(`${username}:${password}`).toString( 'base64', - ) - headers.Authorization = `Basic ${encodedAuth}` - fetchUrl = `${origin}${pathname}${search}` + ); + headers.Authorization = `Basic ${encodedAuth}`; + fetchUrl = `${origin}${pathname}${search}`; } const jsonRpcResponse = await fetchWithTimeout(fetchUrl, { method: 'POST', @@ -491,19 +491,19 @@ export async function jsonRpcRequest(rpcUrl, rpcMethod, rpcParams = []) { }), headers, cache: 'default', - }).then((httpResponse) => httpResponse.json()) + }).then((httpResponse) => httpResponse.json()); if ( !jsonRpcResponse || Array.isArray(jsonRpcResponse) || typeof jsonRpcResponse !== 'object' ) { - throw new Error(`RPC endpoint ${rpcUrl} returned non-object response.`) + throw new Error(`RPC endpoint ${rpcUrl} returned non-object response.`); } - const { error, result } = jsonRpcResponse + const { error, result } = jsonRpcResponse; if (error) { - throw new Error(error?.message || error) + throw new Error(error?.message || error); } - return result + return result; } diff --git a/ui/app/helpers/utils/util.test.js b/ui/app/helpers/utils/util.test.js index 9f319c3625..9f9c7ba548 100644 --- a/ui/app/helpers/utils/util.test.js +++ b/ui/app/helpers/utils/util.test.js @@ -1,216 +1,216 @@ -import assert from 'assert' -import ethUtil from 'ethereumjs-util' -import * as util from './util' +import assert from 'assert'; +import ethUtil from 'ethereumjs-util'; +import * as util from './util'; describe('util', function () { - let ethInWei = '1' + let ethInWei = '1'; for (let i = 0; i < 18; i++) { - ethInWei += '0' + ethInWei += '0'; } describe('#parseBalance', function () { it('should render 0.01 eth correctly', function () { - const input = '0x2386F26FC10000' - const output = util.parseBalance(input) - assert.deepStrictEqual(output, ['0', '01']) - }) + const input = '0x2386F26FC10000'; + const output = util.parseBalance(input); + assert.deepStrictEqual(output, ['0', '01']); + }); it('should render 12.023 eth correctly', function () { - const input = 'A6DA46CCA6858000' - const output = util.parseBalance(input) - assert.deepStrictEqual(output, ['12', '023']) - }) + const input = 'A6DA46CCA6858000'; + const output = util.parseBalance(input); + assert.deepStrictEqual(output, ['12', '023']); + }); it('should render 0.0000000342422 eth correctly', function () { - const input = '0x7F8FE81C0' - const output = util.parseBalance(input) - assert.deepStrictEqual(output, ['0', '0000000342422']) - }) + const input = '0x7F8FE81C0'; + const output = util.parseBalance(input); + assert.deepStrictEqual(output, ['0', '0000000342422']); + }); it('should render 0 eth correctly', function () { - const input = '0x0' - const output = util.parseBalance(input) - assert.deepStrictEqual(output, ['0', '0']) - }) - }) + const input = '0x0'; + const output = util.parseBalance(input); + assert.deepStrictEqual(output, ['0', '0']); + }); + }); describe('#addressSummary', function () { it('should add case-sensitive checksum', function () { - const address = '0xfdea65c8e26263f6d9a1b5de9555d2931a33b825' - const result = util.addressSummary(address) - assert.strictEqual(result, '0xFDEa65C8...b825') - }) + const address = '0xfdea65c8e26263f6d9a1b5de9555d2931a33b825'; + const result = util.addressSummary(address); + assert.strictEqual(result, '0xFDEa65C8...b825'); + }); it('should accept arguments for firstseg, lastseg, and keepPrefix', function () { - const address = '0xfdea65c8e26263f6d9a1b5de9555d2931a33b825' - const result = util.addressSummary(address, 4, 4, false) - assert.strictEqual(result, 'FDEa...b825') - }) - }) + const address = '0xfdea65c8e26263f6d9a1b5de9555d2931a33b825'; + const result = util.addressSummary(address, 4, 4, false); + assert.strictEqual(result, 'FDEa...b825'); + }); + }); describe('#isValidAddress', function () { it('should allow 40-char non-prefixed hex', function () { - const address = 'fdea65c8e26263f6d9a1b5de9555d2931a33b825' - const result = util.isValidAddress(address) - assert.ok(result) - }) + const address = 'fdea65c8e26263f6d9a1b5de9555d2931a33b825'; + const result = util.isValidAddress(address); + assert.ok(result); + }); it('should allow 42-char non-prefixed hex', function () { - const address = '0xfdea65c8e26263f6d9a1b5de9555d2931a33b825' - const result = util.isValidAddress(address) - assert.ok(result) - }) + const address = '0xfdea65c8e26263f6d9a1b5de9555d2931a33b825'; + const result = util.isValidAddress(address); + assert.ok(result); + }); it('should not allow less non hex-prefixed', function () { - const address = 'fdea65c8e26263f6d9a1b5de9555d2931a33b85' - const result = util.isValidAddress(address) - assert.ok(!result) - }) + const address = 'fdea65c8e26263f6d9a1b5de9555d2931a33b85'; + const result = util.isValidAddress(address); + assert.ok(!result); + }); it('should not allow less hex-prefixed', function () { - const address = '0xfdea65ce26263f6d9a1b5de9555d2931a33b85' - const result = util.isValidAddress(address) - assert.ok(!result) - }) + const address = '0xfdea65ce26263f6d9a1b5de9555d2931a33b85'; + const result = util.isValidAddress(address); + assert.ok(!result); + }); it('should recognize correct capitalized checksum', function () { - const address = '0xFDEa65C8e26263F6d9A1B5de9555D2931A33b825' - const result = util.isValidAddress(address) - assert.ok(result) - }) + const address = '0xFDEa65C8e26263F6d9A1B5de9555D2931A33b825'; + const result = util.isValidAddress(address); + assert.ok(result); + }); it('should recognize incorrect capitalized checksum', function () { - const address = '0xFDea65C8e26263F6d9A1B5de9555D2931A33b825' - const result = util.isValidAddress(address) - assert.ok(!result) - }) + const address = '0xFDea65C8e26263F6d9A1B5de9555D2931A33b825'; + const result = util.isValidAddress(address); + assert.ok(!result); + }); it('should recognize this sample hashed address', function () { - const address = '0x5Fda30Bb72B8Dfe20e48A00dFc108d0915BE9Bb0' - const result = util.isValidAddress(address) - const hashed = ethUtil.toChecksumAddress(address.toLowerCase()) - assert.strictEqual(hashed, address, 'example is hashed correctly') - assert.ok(result, 'is valid by our check') - }) - }) + const address = '0x5Fda30Bb72B8Dfe20e48A00dFc108d0915BE9Bb0'; + const result = util.isValidAddress(address); + const hashed = ethUtil.toChecksumAddress(address.toLowerCase()); + assert.strictEqual(hashed, address, 'example is hashed correctly'); + assert.ok(result, 'is valid by our check'); + }); + }); describe('isValidDomainName', function () { it('should return true when given a valid domain name', function () { - assert.strictEqual(util.isValidDomainName('foo.bar'), true) - }) + assert.strictEqual(util.isValidDomainName('foo.bar'), true); + }); it('should return true when given a valid subdomain', function () { - assert.strictEqual(util.isValidDomainName('foo.foo.bar'), true) - }) + assert.strictEqual(util.isValidDomainName('foo.foo.bar'), true); + }); it('should return true when given a single-character domain', function () { - assert.strictEqual(util.isValidDomainName('f.bar'), true) - }) + assert.strictEqual(util.isValidDomainName('f.bar'), true); + }); it('should return true when given a unicode TLD', function () { - assert.strictEqual(util.isValidDomainName('台灣.中国'), true) - }) + assert.strictEqual(util.isValidDomainName('台灣.中国'), true); + }); it('should return false when given a domain with unacceptable ASCII characters', function () { - assert.strictEqual(util.isValidDomainName('$.bar'), false) - }) + assert.strictEqual(util.isValidDomainName('$.bar'), false); + }); it('should return false when given a TLD that starts with a dash', function () { - assert.strictEqual(util.isValidDomainName('foo.-bar'), false) - }) + assert.strictEqual(util.isValidDomainName('foo.-bar'), false); + }); it('should return false when given a TLD that ends with a dash', function () { - assert.strictEqual(util.isValidDomainName('foo.bar-'), false) - }) + assert.strictEqual(util.isValidDomainName('foo.bar-'), false); + }); it('should return false when given a domain name with a chunk that starts with a dash', function () { - assert.strictEqual(util.isValidDomainName('-foo.bar'), false) - }) + assert.strictEqual(util.isValidDomainName('-foo.bar'), false); + }); it('should return false when given a domain name with a chunk that ends with a dash', function () { - assert.strictEqual(util.isValidDomainName('foo-.bar'), false) - }) + assert.strictEqual(util.isValidDomainName('foo-.bar'), false); + }); it('should return false when given a bare TLD', function () { - assert.strictEqual(util.isValidDomainName('bar'), false) - }) + assert.strictEqual(util.isValidDomainName('bar'), false); + }); it('should return false when given a domain that starts with a period', function () { - assert.strictEqual(util.isValidDomainName('.bar'), false) - }) + assert.strictEqual(util.isValidDomainName('.bar'), false); + }); it('should return false when given a subdomain that starts with a period', function () { - assert.strictEqual(util.isValidDomainName('.foo.bar'), false) - }) + assert.strictEqual(util.isValidDomainName('.foo.bar'), false); + }); it('should return false when given a domain that ends with a period', function () { - assert.strictEqual(util.isValidDomainName('bar.'), false) - }) + assert.strictEqual(util.isValidDomainName('bar.'), false); + }); it('should return false when given a 1-character TLD', function () { - assert.strictEqual(util.isValidDomainName('foo.b'), false) - }) - }) + assert.strictEqual(util.isValidDomainName('foo.b'), false); + }); + }); describe('#numericBalance', function () { it('should return a BN 0 if given nothing', function () { - const result = util.numericBalance() - assert.strictEqual(result.toString(10), '0') - }) + const result = util.numericBalance(); + assert.strictEqual(result.toString(10), '0'); + }); it('should work with hex prefix', function () { - const result = util.numericBalance('0x012') - assert.strictEqual(result.toString(10), '18') - }) + const result = util.numericBalance('0x012'); + assert.strictEqual(result.toString(10), '18'); + }); it('should work with no hex prefix', function () { - const result = util.numericBalance('012') - assert.strictEqual(result.toString(10), '18') - }) - }) + const result = util.numericBalance('012'); + assert.strictEqual(result.toString(10), '18'); + }); + }); describe('#formatBalance', function () { it('should return None when given nothing', function () { - const result = util.formatBalance() - assert.strictEqual(result, 'None', 'should return "None"') - }) + const result = util.formatBalance(); + assert.strictEqual(result, 'None', 'should return "None"'); + }); it('should return 1.0000 ETH', function () { - const input = new ethUtil.BN(ethInWei, 10).toJSON() - const result = util.formatBalance(input, 4) - assert.strictEqual(result, '1.0000 ETH') - }) + const input = new ethUtil.BN(ethInWei, 10).toJSON(); + const result = util.formatBalance(input, 4); + assert.strictEqual(result, '1.0000 ETH'); + }); it('should return 0.500 ETH', function () { const input = new ethUtil.BN(ethInWei, 10) .div(new ethUtil.BN('2', 10)) - .toJSON() - const result = util.formatBalance(input, 3) - assert.strictEqual(result, '0.500 ETH') - }) + .toJSON(); + const result = util.formatBalance(input, 3); + assert.strictEqual(result, '0.500 ETH'); + }); it('should display specified decimal points', function () { - const input = '0x128dfa6a90b28000' - const result = util.formatBalance(input, 2) - assert.strictEqual(result, '1.33 ETH') - }) + const input = '0x128dfa6a90b28000'; + const result = util.formatBalance(input, 2); + assert.strictEqual(result, '1.33 ETH'); + }); it('should default to 3 decimal points', function () { - const input = '0x128dfa6a90b28000' - const result = util.formatBalance(input) - assert.strictEqual(result, '1.337 ETH') - }) + const input = '0x128dfa6a90b28000'; + const result = util.formatBalance(input); + assert.strictEqual(result, '1.337 ETH'); + }); it('should show 2 significant digits for tiny balances', function () { - const input = '0x1230fa6a90b28' - const result = util.formatBalance(input) - assert.strictEqual(result, '0.00032 ETH') - }) + const input = '0x1230fa6a90b28'; + const result = util.formatBalance(input); + assert.strictEqual(result, '0.00032 ETH'); + }); it('should not parse the balance and return value with 2 decimal points with ETH at the end', function () { - const value = '1.2456789' - const needsParse = false - const result = util.formatBalance(value, 2, needsParse) - assert.strictEqual(result, '1.24 ETH') - }) - }) + const value = '1.2456789'; + const needsParse = false; + const result = util.formatBalance(value, 2, needsParse); + assert.strictEqual(result, '1.24 ETH'); + }); + }); describe('normalizing values', function () { describe('#normalizeToWei', function () { @@ -229,116 +229,116 @@ describe('util', function () { // I think they're big enough to ignore for now. // gether:'0.000000001', // tether:'0.000000000001', - } - const oneEthBn = new ethUtil.BN(ethInWei, 10) + }; + const oneEthBn = new ethUtil.BN(ethInWei, 10); Object.keys(valueTable).forEach((currency) => { - const value = new ethUtil.BN(valueTable[currency], 10) - const output = util.normalizeToWei(value, currency) + const value = new ethUtil.BN(valueTable[currency], 10); + const output = util.normalizeToWei(value, currency); assert.strictEqual( output.toString(10), valueTable.wei, `value of ${output.toString( 10, )} ${currency} should convert to ${oneEthBn}`, - ) - }) - }) - }) + ); + }); + }); + }); describe('#normalizeEthStringToWei', function () { it('should convert decimal eth to pure wei BN', function () { - const input = '1.23456789' - const output = util.normalizeEthStringToWei(input) - assert.strictEqual(output.toString(10), '1234567890000000000') - }) + const input = '1.23456789'; + const output = util.normalizeEthStringToWei(input); + assert.strictEqual(output.toString(10), '1234567890000000000'); + }); it('should convert 1 to expected wei', function () { - const input = '1' - const output = util.normalizeEthStringToWei(input) - assert.strictEqual(output.toString(10), ethInWei) - }) + const input = '1'; + const output = util.normalizeEthStringToWei(input); + assert.strictEqual(output.toString(10), ethInWei); + }); it('should account for overflow numbers gracefully by dropping extra precision.', function () { - const input = '1.11111111111111111111' - const output = util.normalizeEthStringToWei(input) - assert.strictEqual(output.toString(10), '1111111111111111111') - }) + const input = '1.11111111111111111111'; + const output = util.normalizeEthStringToWei(input); + assert.strictEqual(output.toString(10), '1111111111111111111'); + }); it('should not truncate very exact wei values that do not have extra precision.', function () { - const input = '1.100000000000000001' - const output = util.normalizeEthStringToWei(input) - assert.strictEqual(output.toString(10), '1100000000000000001') - }) - }) + const input = '1.100000000000000001'; + const output = util.normalizeEthStringToWei(input); + assert.strictEqual(output.toString(10), '1100000000000000001'); + }); + }); describe('#normalizeNumberToWei', function () { it('should handle a simple use case', function () { - const input = 0.0002 - const output = util.normalizeNumberToWei(input, 'ether') - const str = output.toString(10) - assert.strictEqual(str, '200000000000000') - }) + const input = 0.0002; + const output = util.normalizeNumberToWei(input, 'ether'); + const str = output.toString(10); + assert.strictEqual(str, '200000000000000'); + }); it('should convert a kwei number to the appropriate equivalent wei', function () { - const result = util.normalizeNumberToWei(1.111, 'kwei') - assert.strictEqual(result.toString(10), '1111', 'accepts decimals') - }) + const result = util.normalizeNumberToWei(1.111, 'kwei'); + assert.strictEqual(result.toString(10), '1111', 'accepts decimals'); + }); it('should convert a ether number to the appropriate equivalent wei', function () { - const result = util.normalizeNumberToWei(1.111, 'ether') + const result = util.normalizeNumberToWei(1.111, 'ether'); assert.strictEqual( result.toString(10), '1111000000000000000', 'accepts decimals', - ) - }) - }) + ); + }); + }); describe('#isHex', function () { it('should return true when given a hex string', function () { const result = util.isHex( 'c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2', - ) - assert(result) - }) + ); + assert(result); + }); it('should return false when given a non-hex string', function () { const result = util.isHex( 'c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714imnotreal', - ) - assert(!result) - }) + ); + assert(!result); + }); it('should return false when given a string containing a non letter/number character', function () { const result = util.isHex( 'c3ab8ff13720!8ad9047dd39466b3c%8974e592c2fa383d4a396071imnotreal', - ) - assert(!result) - }) + ); + assert(!result); + }); it('should return true when given a hex string with hex-prefix', function () { const result = util.isHex( '0xc3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2', - ) - assert(result) - }) - }) + ); + assert(result); + }); + }); describe('#getRandomFileName', function () { it('should only return a string containing alphanumeric characters', function () { - const result = util.getRandomFileName() - assert(result.match(/^[a-zA-Z0-9]*$/gu)) - }) + const result = util.getRandomFileName(); + assert(result.match(/^[a-zA-Z0-9]*$/gu)); + }); // 50 samples it('should return a string that is between 6 and 12 characters in length', function () { for (let i = 0; i < 50; i++) { - const result = util.getRandomFileName() - assert(result.length >= 6 && result.length <= 12) + const result = util.getRandomFileName(); + assert(result.length >= 6 && result.length <= 12); } - }) - }) - }) + }); + }); + }); describe('checkExistingAddresses', function () { const tokenList = [ @@ -346,28 +346,28 @@ describe('util', function () { { address: 'n' }, { address: 'Q' }, { address: 'z' }, - ] + ]; it('should return true when a lowercase address matches an uppercase address in the passed list', function () { - assert(util.checkExistingAddresses('q', tokenList) === true) - }) + assert(util.checkExistingAddresses('q', tokenList) === true); + }); it('should return true when an uppercase address matches a lowercase address in the passed list', function () { - assert(util.checkExistingAddresses('N', tokenList) === true) - }) + assert(util.checkExistingAddresses('N', tokenList) === true); + }); it('should return true when a lowercase address matches a lowercase address in the passed list', function () { - assert(util.checkExistingAddresses('z', tokenList) === true) - }) + assert(util.checkExistingAddresses('z', tokenList) === true); + }); it('should return true when an uppercase address matches an uppercase address in the passed list', function () { - assert(util.checkExistingAddresses('Q', tokenList) === true) - }) + assert(util.checkExistingAddresses('Q', tokenList) === true); + }); it('should return false when the passed address is not in the passed list', function () { - assert(util.checkExistingAddresses('b', tokenList) === false) - }) - }) + assert(util.checkExistingAddresses('b', tokenList) === false); + }); + }); describe('toPrecisionWithoutTrailingZeros', function () { const testData = [ @@ -404,17 +404,17 @@ describe('util', function () { { args: ['100000000000000000000', 10], result: '1e+20' }, { args: ['100005000000000000000', 10], result: '1.00005e+20' }, { args: ['100005000000000000000.0', 10], result: '1.00005e+20' }, - ] + ]; testData.forEach(({ args, result }) => { it(`should return ${result} when passed number ${args[0]} and precision ${args[1]}`, function () { assert.strictEqual( util.toPrecisionWithoutTrailingZeros(...args), result, - ) - }) - }) - }) + ); + }); + }); + }); describe('addHexPrefixToObjectValues()', function () { it('should return a new object with the same properties with a 0x prefix', function () { @@ -429,7 +429,7 @@ describe('util', function () { prop2: '0x456', prop3: '0xx', }, - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/ui/app/hooks/tests/useCancelTransaction.test.js b/ui/app/hooks/tests/useCancelTransaction.test.js index 0d3d590f39..28957eb9c3 100644 --- a/ui/app/hooks/tests/useCancelTransaction.test.js +++ b/ui/app/hooks/tests/useCancelTransaction.test.js @@ -1,60 +1,60 @@ -import assert from 'assert' -import * as reactRedux from 'react-redux' -import { renderHook } from '@testing-library/react-hooks' -import sinon from 'sinon' -import transactions from '../../../../test/data/transaction-data.json' -import { getConversionRate, getSelectedAccount } from '../../selectors' -import { useCancelTransaction } from '../useCancelTransaction' -import { showModal } from '../../store/actions' -import { increaseLastGasPrice } from '../../helpers/utils/confirm-tx.util' +import assert from 'assert'; +import * as reactRedux from 'react-redux'; +import { renderHook } from '@testing-library/react-hooks'; +import sinon from 'sinon'; +import transactions from '../../../../test/data/transaction-data.json'; +import { getConversionRate, getSelectedAccount } from '../../selectors'; +import { useCancelTransaction } from '../useCancelTransaction'; +import { showModal } from '../../store/actions'; +import { increaseLastGasPrice } from '../../helpers/utils/confirm-tx.util'; describe('useCancelTransaction', function () { - let useSelector - const dispatch = sinon.spy() + let useSelector; + const dispatch = sinon.spy(); before(function () { - sinon.stub(reactRedux, 'useDispatch').returns(dispatch) - }) + sinon.stub(reactRedux, 'useDispatch').returns(dispatch); + }); afterEach(function () { - dispatch.resetHistory() - }) + dispatch.resetHistory(); + }); describe('when account has insufficient balance to cover gas', function () { before(function () { - useSelector = sinon.stub(reactRedux, 'useSelector') + useSelector = sinon.stub(reactRedux, 'useSelector'); useSelector.callsFake((selector) => { if (selector === getConversionRate) { - return 280.46 + return 280.46; } else if (selector === getSelectedAccount) { return { balance: '0x3', - } + }; } - return undefined - }) - }) + return undefined; + }); + }); transactions.forEach((transactionGroup) => { const originalGasPrice = - transactionGroup.primaryTransaction.txParams?.gasPrice + transactionGroup.primaryTransaction.txParams?.gasPrice; const gasPrice = - originalGasPrice && increaseLastGasPrice(originalGasPrice) - const transactionId = transactionGroup.initialTransaction.id + originalGasPrice && increaseLastGasPrice(originalGasPrice); + const transactionId = transactionGroup.initialTransaction.id; it(`should indicate account has insufficient funds to cover ${gasPrice} gas price`, function () { const { result } = renderHook(() => useCancelTransaction(transactionGroup), - ) - assert.strictEqual(result.current[0], false) - }) + ); + assert.strictEqual(result.current[0], false); + }); it(`should return a function that kicks off cancellation for id ${transactionId}`, function () { const { result } = renderHook(() => useCancelTransaction(transactionGroup), - ) - assert.strictEqual(typeof result.current[1], 'function') + ); + assert.strictEqual(typeof result.current[1], 'function'); result.current[1]({ preventDefault: () => undefined, stopPropagation: () => undefined, - }) + }); assert.strictEqual( dispatch.calledWith( showModal({ @@ -64,49 +64,49 @@ describe('useCancelTransaction', function () { }), ), true, - ) - }) - }) + ); + }); + }); after(function () { - useSelector.restore() - }) - }) + useSelector.restore(); + }); + }); describe('when account has sufficient balance to cover gas', function () { before(function () { - useSelector = sinon.stub(reactRedux, 'useSelector') + useSelector = sinon.stub(reactRedux, 'useSelector'); useSelector.callsFake((selector) => { if (selector === getConversionRate) { - return 280.46 + return 280.46; } else if (selector === getSelectedAccount) { return { balance: '0x9C2007651B2500000', - } + }; } - return undefined - }) - }) + return undefined; + }); + }); transactions.forEach((transactionGroup) => { const originalGasPrice = - transactionGroup.primaryTransaction.txParams?.gasPrice + transactionGroup.primaryTransaction.txParams?.gasPrice; const gasPrice = - originalGasPrice && increaseLastGasPrice(originalGasPrice) - const transactionId = transactionGroup.initialTransaction.id + originalGasPrice && increaseLastGasPrice(originalGasPrice); + const transactionId = transactionGroup.initialTransaction.id; it(`should indicate account has funds to cover ${gasPrice} gas price`, function () { const { result } = renderHook(() => useCancelTransaction(transactionGroup), - ) - assert.strictEqual(result.current[0], true) - }) + ); + assert.strictEqual(result.current[0], true); + }); it(`should return a function that kicks off cancellation for id ${transactionId}`, function () { const { result } = renderHook(() => useCancelTransaction(transactionGroup), - ) - assert.strictEqual(typeof result.current[1], 'function') + ); + assert.strictEqual(typeof result.current[1], 'function'); result.current[1]({ preventDefault: () => undefined, stopPropagation: () => undefined, - }) + }); assert.strictEqual( dispatch.calledWith( showModal({ @@ -116,15 +116,15 @@ describe('useCancelTransaction', function () { }), ), true, - ) - }) - }) + ); + }); + }); after(function () { - useSelector.restore() - }) - }) + useSelector.restore(); + }); + }); after(function () { - sinon.restore() - }) -}) + sinon.restore(); + }); +}); diff --git a/ui/app/hooks/tests/useCurrencyDisplay.test.js b/ui/app/hooks/tests/useCurrencyDisplay.test.js index 4b90e9a79a..8b019ab87f 100644 --- a/ui/app/hooks/tests/useCurrencyDisplay.test.js +++ b/ui/app/hooks/tests/useCurrencyDisplay.test.js @@ -1,13 +1,13 @@ -import assert from 'assert' -import { renderHook } from '@testing-library/react-hooks' -import * as reactRedux from 'react-redux' -import sinon from 'sinon' -import { useCurrencyDisplay } from '../useCurrencyDisplay' +import assert from 'assert'; +import { renderHook } from '@testing-library/react-hooks'; +import * as reactRedux from 'react-redux'; +import sinon from 'sinon'; +import { useCurrencyDisplay } from '../useCurrencyDisplay'; import { getCurrentCurrency, getNativeCurrency, getConversionRate, -} from '../../selectors' +} from '../../selectors'; const tests = [ { @@ -97,34 +97,34 @@ const tests = [ displayValue: '0.000000001', }, }, -] +]; describe('useCurrencyDisplay', function () { tests.forEach(({ input: { value, ...restProps }, result }) => { describe(`when input is { value: ${value}, decimals: ${restProps.numberOfDecimals}, denomation: ${restProps.denomination} }`, function () { - const stub = sinon.stub(reactRedux, 'useSelector') + const stub = sinon.stub(reactRedux, 'useSelector'); stub.callsFake((selector) => { if (selector === getCurrentCurrency) { - return 'usd' + return 'usd'; } else if (selector === getNativeCurrency) { - return 'ETH' + return 'ETH'; } else if (selector === getConversionRate) { - return 280.45 + return 280.45; } - return undefined - }) - const hookReturn = renderHook(() => useCurrencyDisplay(value, restProps)) - const [displayValue, parts] = hookReturn.result.current - stub.restore() + return undefined; + }); + const hookReturn = renderHook(() => useCurrencyDisplay(value, restProps)); + const [displayValue, parts] = hookReturn.result.current; + stub.restore(); it(`should return ${result.displayValue} as displayValue`, function () { - assert.strictEqual(displayValue, result.displayValue) - }) + assert.strictEqual(displayValue, result.displayValue); + }); it(`should return ${result.value} as value`, function () { - assert.strictEqual(parts.value, result.value) - }) + assert.strictEqual(parts.value, result.value); + }); it(`should return ${result.suffix} as suffix`, function () { - assert.strictEqual(parts.suffix, result.suffix) - }) - }) - }) -}) + assert.strictEqual(parts.suffix, result.suffix); + }); + }); + }); +}); diff --git a/ui/app/hooks/tests/useRetryTransaction.test.js b/ui/app/hooks/tests/useRetryTransaction.test.js index 91d99026dd..52be98fc13 100644 --- a/ui/app/hooks/tests/useRetryTransaction.test.js +++ b/ui/app/hooks/tests/useRetryTransaction.test.js @@ -1,32 +1,32 @@ -import assert from 'assert' -import * as reactRedux from 'react-redux' -import { renderHook } from '@testing-library/react-hooks' -import sinon from 'sinon' -import transactions from '../../../../test/data/transaction-data.json' -import * as methodDataHook from '../useMethodData' -import * as metricEventHook from '../useMetricEvent' -import { showSidebar } from '../../store/actions' -import { useRetryTransaction } from '../useRetryTransaction' +import assert from 'assert'; +import * as reactRedux from 'react-redux'; +import { renderHook } from '@testing-library/react-hooks'; +import sinon from 'sinon'; +import transactions from '../../../../test/data/transaction-data.json'; +import * as methodDataHook from '../useMethodData'; +import * as metricEventHook from '../useMetricEvent'; +import { showSidebar } from '../../store/actions'; +import { useRetryTransaction } from '../useRetryTransaction'; describe('useRetryTransaction', function () { describe('when transaction meets retry enabled criteria', function () { - const dispatch = sinon.spy(() => Promise.resolve({ blockTime: 0 })) - const trackEvent = sinon.spy() + const dispatch = sinon.spy(() => Promise.resolve({ blockTime: 0 })); + const trackEvent = sinon.spy(); const event = { preventDefault: () => undefined, stopPropagation: () => undefined, - } + }; before(function () { - sinon.stub(reactRedux, 'useDispatch').returns(dispatch) - sinon.stub(methodDataHook, 'useMethodData').returns({}) - sinon.stub(metricEventHook, 'useMetricEvent').returns(trackEvent) - }) + sinon.stub(reactRedux, 'useDispatch').returns(dispatch); + sinon.stub(methodDataHook, 'useMethodData').returns({}); + sinon.stub(metricEventHook, 'useMetricEvent').returns(trackEvent); + }); afterEach(function () { - dispatch.resetHistory() - trackEvent.resetHistory() - }) + dispatch.resetHistory(); + trackEvent.resetHistory(); + }); const retryEnabledTransaction = { ...transactions[0], transactions: [ @@ -35,23 +35,23 @@ describe('useRetryTransaction', function () { }, ], hasRetried: false, - } + }; it('retryTransaction function should track metrics', function () { const { result } = renderHook(() => useRetryTransaction(retryEnabledTransaction, true), - ) - const retry = result.current - retry(event) - assert.strictEqual(trackEvent.calledOnce, true) - }) + ); + const retry = result.current; + retry(event); + assert.strictEqual(trackEvent.calledOnce, true); + }); it('retryTransaction function should show retry sidebar', async function () { const { result } = renderHook(() => useRetryTransaction(retryEnabledTransaction, true), - ) - const retry = result.current - await retry(event) + ); + const retry = result.current; + await retry(event); assert.strictEqual( dispatch.calledWith( showSidebar({ @@ -61,11 +61,11 @@ describe('useRetryTransaction', function () { }), ), true, - ) - }) + ); + }); after(function () { - sinon.restore() - }) - }) -}) + sinon.restore(); + }); + }); +}); diff --git a/ui/app/hooks/tests/useTokenData.test.js b/ui/app/hooks/tests/useTokenData.test.js index ec473300d4..593176105e 100644 --- a/ui/app/hooks/tests/useTokenData.test.js +++ b/ui/app/hooks/tests/useTokenData.test.js @@ -1,8 +1,8 @@ -import assert from 'assert' -import { ethers } from 'ethers' -import { renderHook } from '@testing-library/react-hooks' -import { useTokenData } from '../useTokenData' -import { TRANSACTION_CATEGORIES } from '../../../../shared/constants/transaction' +import assert from 'assert'; +import { ethers } from 'ethers'; +import { renderHook } from '@testing-library/react-hooks'; +import { useTokenData } from '../useTokenData'; +import { TRANSACTION_CATEGORIES } from '../../../../shared/constants/transaction'; const tests = [ { @@ -42,26 +42,26 @@ const tests = [ data: undefined, tokenData: null, }, -] +]; describe('useTokenData', function () { tests.forEach((test) => { const testTitle = test.tokenData === null ? `should return null when no data provided` - : `should return properly decoded data with _value ${test.tokenData.args[1].value}` + : `should return properly decoded data with _value ${test.tokenData.args[1].value}`; it(testTitle, function () { - const { result } = renderHook(() => useTokenData(test.data)) + const { result } = renderHook(() => useTokenData(test.data)); if (test.tokenData) { - assert.strictEqual(result.current.name, test.tokenData.name) + assert.strictEqual(result.current.name, test.tokenData.name); assert.strictEqual( result.current.args[0].toLowerCase(), test.tokenData.args[0], - ) - assert.ok(test.tokenData.args[1].eq(result.current.args[1])) + ); + assert.ok(test.tokenData.args[1].eq(result.current.args[1])); } else { - assert.strictEqual(result.current, test.tokenData) + assert.strictEqual(result.current, test.tokenData); } - }) - }) -}) + }); + }); +}); diff --git a/ui/app/hooks/tests/useTokenDisplayValue.test.js b/ui/app/hooks/tests/useTokenDisplayValue.test.js index bc77bd6c7b..6fc6f61052 100644 --- a/ui/app/hooks/tests/useTokenDisplayValue.test.js +++ b/ui/app/hooks/tests/useTokenDisplayValue.test.js @@ -1,9 +1,9 @@ -import assert from 'assert' -import { renderHook } from '@testing-library/react-hooks' -import sinon from 'sinon' -import * as tokenUtil from '../../helpers/utils/token-util' -import * as txUtil from '../../helpers/utils/transactions.util' -import { useTokenDisplayValue } from '../useTokenDisplayValue' +import assert from 'assert'; +import { renderHook } from '@testing-library/react-hooks'; +import sinon from 'sinon'; +import * as tokenUtil from '../../helpers/utils/token-util'; +import * as txUtil from '../../helpers/utils/transactions.util'; +import { useTokenDisplayValue } from '../useTokenDisplayValue'; const tests = [ { @@ -116,22 +116,22 @@ const tests = [ tokenValue: '25500000', displayValue: '25.5', }, -] +]; describe('useTokenDisplayValue', function () { tests.forEach((test, idx) => { describe(`when input is decimals: ${test.token.decimals} and value: ${test.tokenValue}`, function () { it(`should return ${test.displayValue} as displayValue`, function () { - const getTokenValueStub = sinon.stub(tokenUtil, 'getTokenValueParam') - const getTokenDataStub = sinon.stub(txUtil, 'getTokenData') - getTokenDataStub.callsFake(() => test.tokenData) - getTokenValueStub.callsFake(() => test.tokenValue) + const getTokenValueStub = sinon.stub(tokenUtil, 'getTokenValueParam'); + const getTokenDataStub = sinon.stub(txUtil, 'getTokenData'); + getTokenDataStub.callsFake(() => test.tokenData); + getTokenValueStub.callsFake(() => test.tokenValue); const { result } = renderHook(() => useTokenDisplayValue(`${idx}-fakestring`, test.token), - ) - sinon.restore() - assert.strictEqual(result.current, test.displayValue) - }) - }) - }) -}) + ); + sinon.restore(); + assert.strictEqual(result.current, test.displayValue); + }); + }); + }); +}); diff --git a/ui/app/hooks/tests/useTransactionDisplayData.test.js b/ui/app/hooks/tests/useTransactionDisplayData.test.js index 64c6a03662..96a24c08bf 100644 --- a/ui/app/hooks/tests/useTransactionDisplayData.test.js +++ b/ui/app/hooks/tests/useTransactionDisplayData.test.js @@ -1,28 +1,28 @@ -import assert from 'assert' -import React from 'react' -import * as reactRedux from 'react-redux' -import { renderHook } from '@testing-library/react-hooks' -import sinon from 'sinon' -import { MemoryRouter } from 'react-router-dom' -import transactions from '../../../../test/data/transaction-data.json' -import { useTransactionDisplayData } from '../useTransactionDisplayData' -import * as useTokenFiatAmountHooks from '../useTokenFiatAmount' +import assert from 'assert'; +import React from 'react'; +import * as reactRedux from 'react-redux'; +import { renderHook } from '@testing-library/react-hooks'; +import sinon from 'sinon'; +import { MemoryRouter } from 'react-router-dom'; +import transactions from '../../../../test/data/transaction-data.json'; +import { useTransactionDisplayData } from '../useTransactionDisplayData'; +import * as useTokenFiatAmountHooks from '../useTokenFiatAmount'; import { getPreferences, getShouldShowFiat, getNativeCurrency, getCurrentCurrency, -} from '../../selectors' -import { getTokens } from '../../ducks/metamask/metamask' -import * as i18nhooks from '../useI18nContext' -import { getMessage } from '../../helpers/utils/i18n-helper' -import messages from '../../../../app/_locales/en/messages.json' -import { ASSET_ROUTE, DEFAULT_ROUTE } from '../../helpers/constants/routes' +} from '../../selectors'; +import { getTokens } from '../../ducks/metamask/metamask'; +import * as i18nhooks from '../useI18nContext'; +import { getMessage } from '../../helpers/utils/i18n-helper'; +import messages from '../../../../app/_locales/en/messages.json'; +import { ASSET_ROUTE, DEFAULT_ROUTE } from '../../helpers/constants/routes'; import { TRANSACTION_CATEGORIES, TRANSACTION_GROUP_CATEGORIES, TRANSACTION_STATUSES, -} from '../../../../shared/constants/transaction' +} from '../../../../shared/constants/transaction'; const expectedResults = [ { @@ -117,34 +117,34 @@ const expectedResults = [ isPending: false, displayedStatusKey: TRANSACTION_STATUSES.CONFIRMED, }, -] +]; -let useSelector, useI18nContext, useTokenFiatAmount +let useSelector, useI18nContext, useTokenFiatAmount; const renderHookWithRouter = (cb, tokenAddress) => { const initialEntries = [ tokenAddress ? `${ASSET_ROUTE}/${tokenAddress}` : DEFAULT_ROUTE, - ] + ]; const wrapper = ({ children }) => ( {children} - ) - return renderHook(cb, { wrapper }) -} + ); + return renderHook(cb, { wrapper }); +}; describe('useTransactionDisplayData', function () { before(function () { - useSelector = sinon.stub(reactRedux, 'useSelector') + useSelector = sinon.stub(reactRedux, 'useSelector'); useTokenFiatAmount = sinon.stub( useTokenFiatAmountHooks, 'useTokenFiatAmount', - ) + ); useTokenFiatAmount.returns((tokenAddress) => { - return tokenAddress ? '1 TST' : undefined - }) - useI18nContext = sinon.stub(i18nhooks, 'useI18nContext') + return tokenAddress ? '1 TST' : undefined; + }); + useI18nContext = sinon.stub(i18nhooks, 'useI18nContext'); useI18nContext.returns((key, variables) => getMessage('en', messages, key, variables), - ) + ); useSelector.callsFake((selector) => { if (selector === getTokens) { return [ @@ -153,104 +153,107 @@ describe('useTransactionDisplayData', function () { symbol: 'ABC', decimals: 18, }, - ] + ]; } else if (selector === getPreferences) { return { useNativeCurrencyAsPrimaryCurrency: true, - } + }; } else if (selector === getShouldShowFiat) { - return false + return false; } else if (selector === getNativeCurrency) { - return 'ETH' + return 'ETH'; } else if (selector === getCurrentCurrency) { - return 'ETH' + return 'ETH'; } - return null - }) - }) + return null; + }); + }); transactions.forEach((transactionGroup, idx) => { describe(`when called with group containing primaryTransaction id ${transactionGroup.primaryTransaction.id}`, function () { - const expected = expectedResults[idx] + const expected = expectedResults[idx]; const tokenAddress = - transactionGroup.primaryTransaction?.destinationTokenAddress + transactionGroup.primaryTransaction?.destinationTokenAddress; it(`should return a title of ${expected.title}`, function () { const { result } = renderHookWithRouter( () => useTransactionDisplayData(transactionGroup), tokenAddress, - ) - assert.strictEqual(result.current.title, expected.title) - }) + ); + assert.strictEqual(result.current.title, expected.title); + }); it(`should return a subtitle of ${expected.subtitle}`, function () { const { result } = renderHookWithRouter( () => useTransactionDisplayData(transactionGroup), tokenAddress, - ) - assert.strictEqual(result.current.subtitle, expected.subtitle) - }) + ); + assert.strictEqual(result.current.subtitle, expected.subtitle); + }); it(`should return a category of ${expected.category}`, function () { const { result } = renderHookWithRouter( () => useTransactionDisplayData(transactionGroup), tokenAddress, - ) - assert.strictEqual(result.current.category, expected.category) - }) + ); + assert.strictEqual(result.current.category, expected.category); + }); it(`should return a primaryCurrency of ${expected.primaryCurrency}`, function () { const { result } = renderHookWithRouter( () => useTransactionDisplayData(transactionGroup), tokenAddress, - ) + ); assert.strictEqual( result.current.primaryCurrency, expected.primaryCurrency, - ) - }) + ); + }); it(`should return a secondaryCurrency of ${expected.secondaryCurrency}`, function () { const { result } = renderHookWithRouter( () => useTransactionDisplayData(transactionGroup), tokenAddress, - ) + ); assert.strictEqual( result.current.secondaryCurrency, expected.secondaryCurrency, - ) - }) + ); + }); it(`should return a displayedStatusKey of ${expected.displayedStatusKey}`, function () { const { result } = renderHookWithRouter( () => useTransactionDisplayData(transactionGroup), tokenAddress, - ) + ); assert.strictEqual( result.current.displayedStatusKey, expected.displayedStatusKey, - ) - }) + ); + }); it(`should return a recipientAddress of ${expected.recipientAddress}`, function () { const { result } = renderHookWithRouter( () => useTransactionDisplayData(transactionGroup), tokenAddress, - ) + ); assert.strictEqual( result.current.recipientAddress, expected.recipientAddress, - ) - }) + ); + }); it(`should return a senderAddress of ${expected.senderAddress}`, function () { const { result } = renderHookWithRouter( () => useTransactionDisplayData(transactionGroup), tokenAddress, - ) - assert.strictEqual(result.current.senderAddress, expected.senderAddress) - }) - }) - }) + ); + assert.strictEqual( + result.current.senderAddress, + expected.senderAddress, + ); + }); + }); + }); it('should return an appropriate object', function () { const { result } = renderHookWithRouter(() => useTransactionDisplayData(transactions[0]), - ) - assert.deepStrictEqual(result.current, expectedResults[0]) - }) + ); + assert.deepStrictEqual(result.current, expectedResults[0]); + }); after(function () { - useSelector.restore() - useI18nContext.restore() - }) -}) + useSelector.restore(); + useI18nContext.restore(); + }); +}); diff --git a/ui/app/hooks/tests/useUserPreferencedCurrency.test.js b/ui/app/hooks/tests/useUserPreferencedCurrency.test.js index 0386e6ec4f..75ee4cf663 100644 --- a/ui/app/hooks/tests/useUserPreferencedCurrency.test.js +++ b/ui/app/hooks/tests/useUserPreferencedCurrency.test.js @@ -1,9 +1,9 @@ -import assert from 'assert' -import { renderHook } from '@testing-library/react-hooks' -import * as reactRedux from 'react-redux' -import sinon from 'sinon' -import { useUserPreferencedCurrency } from '../useUserPreferencedCurrency' -import { getPreferences, getShouldShowFiat } from '../../selectors' +import assert from 'assert'; +import { renderHook } from '@testing-library/react-hooks'; +import * as reactRedux from 'react-redux'; +import sinon from 'sinon'; +import { useUserPreferencedCurrency } from '../useUserPreferencedCurrency'; +import { getPreferences, getShouldShowFiat } from '../../selectors'; const tests = [ { @@ -109,42 +109,42 @@ const tests = [ numberOfDecimals: 2, }, }, -] +]; function getFakeUseSelector(state) { return (selector) => { if (selector === getPreferences) { - return state + return state; } else if (selector === getShouldShowFiat) { - return state.showFiat + return state.showFiat; } - return state.nativeCurrency - } + return state.nativeCurrency; + }; } describe('useUserPreferencedCurrency', function () { tests.forEach(({ params: { type, ...otherParams }, state, result }) => { describe(`when showFiat is ${state.showFiat}, useNativeCurrencyAsPrimary is ${state.useNativeCurrencyAsPrimaryCurrency} and type is ${type}`, function () { - const stub = sinon.stub(reactRedux, 'useSelector') - stub.callsFake(getFakeUseSelector(state)) + const stub = sinon.stub(reactRedux, 'useSelector'); + stub.callsFake(getFakeUseSelector(state)); const { result: hookResult } = renderHook(() => useUserPreferencedCurrency(type, otherParams), - ) - stub.restore() + ); + stub.restore(); it(`should return currency as ${ result.currency || 'not modified by user preferences' }`, function () { - assert.strictEqual(hookResult.current.currency, result.currency) - }) + assert.strictEqual(hookResult.current.currency, result.currency); + }); it(`should return decimals as ${ result.numberOfDecimals || 'not modified by user preferences' }`, function () { assert.strictEqual( hookResult.current.numberOfDecimals, result.numberOfDecimals, - ) - }) - }) - }) -}) + ); + }); + }); + }); +}); diff --git a/ui/app/hooks/useCancelTransaction.js b/ui/app/hooks/useCancelTransaction.js index 3d478e410a..1ad4c12f8c 100644 --- a/ui/app/hooks/useCancelTransaction.js +++ b/ui/app/hooks/useCancelTransaction.js @@ -1,12 +1,12 @@ -import { useDispatch, useSelector } from 'react-redux' -import { useCallback } from 'react' -import { showModal } from '../store/actions' -import { isBalanceSufficient } from '../pages/send/send.utils' +import { useDispatch, useSelector } from 'react-redux'; +import { useCallback } from 'react'; +import { showModal } from '../store/actions'; +import { isBalanceSufficient } from '../pages/send/send.utils'; import { getHexGasTotal, increaseLastGasPrice, -} from '../helpers/utils/confirm-tx.util' -import { getConversionRate, getSelectedAccount } from '../selectors' +} from '../helpers/utils/confirm-tx.util'; +import { getConversionRate, getSelectedAccount } from '../selectors'; /** * Determine whether a transaction can be cancelled and provide a method to @@ -19,17 +19,17 @@ import { getConversionRate, getSelectedAccount } from '../selectors' * @return {[boolean, Function]} */ export function useCancelTransaction(transactionGroup) { - const { primaryTransaction, initialTransaction } = transactionGroup + const { primaryTransaction, initialTransaction } = transactionGroup; const gasPrice = primaryTransaction.txParams?.gasPrice?.startsWith('-') ? '0x0' - : primaryTransaction.txParams?.gasPrice - const { id } = initialTransaction - const dispatch = useDispatch() - const selectedAccount = useSelector(getSelectedAccount) - const conversionRate = useSelector(getConversionRate) + : primaryTransaction.txParams?.gasPrice; + const { id } = initialTransaction; + const dispatch = useDispatch(); + const selectedAccount = useSelector(getSelectedAccount); + const conversionRate = useSelector(getConversionRate); const cancelTransaction = useCallback( (event) => { - event.stopPropagation() + event.stopPropagation(); return dispatch( showModal({ @@ -37,10 +37,10 @@ export function useCancelTransaction(transactionGroup) { transactionId: id, originalGasPrice: gasPrice, }), - ) + ); }, [dispatch, id, gasPrice], - ) + ); const hasEnoughCancelGas = primaryTransaction.txParams && @@ -52,7 +52,7 @@ export function useCancelTransaction(transactionGroup) { }), balance: selectedAccount.balance, conversionRate, - }) + }); - return [hasEnoughCancelGas, cancelTransaction] + return [hasEnoughCancelGas, cancelTransaction]; } diff --git a/ui/app/hooks/useCopyToClipboard.js b/ui/app/hooks/useCopyToClipboard.js index 542496e156..33635d7223 100644 --- a/ui/app/hooks/useCopyToClipboard.js +++ b/ui/app/hooks/useCopyToClipboard.js @@ -1,6 +1,6 @@ -import { useState, useCallback } from 'react' -import copyToClipboard from 'copy-to-clipboard' -import { useTimeout } from './useTimeout' +import { useState, useCallback } from 'react'; +import copyToClipboard from 'copy-to-clipboard'; +import { useTimeout } from './useTimeout'; /** * useCopyToClipboard @@ -9,20 +9,20 @@ import { useTimeout } from './useTimeout' * * @return {[boolean, Function]} */ -const DEFAULT_DELAY = 3000 +const DEFAULT_DELAY = 3000; export function useCopyToClipboard(delay = DEFAULT_DELAY) { - const [copied, setCopied] = useState(false) - const startTimeout = useTimeout(() => setCopied(false), delay, false) + const [copied, setCopied] = useState(false); + const startTimeout = useTimeout(() => setCopied(false), delay, false); const handleCopy = useCallback( (text) => { - setCopied(true) - startTimeout() - copyToClipboard(text) + setCopied(true); + startTimeout(); + copyToClipboard(text); }, [startTimeout], - ) + ); - return [copied, handleCopy] + return [copied, handleCopy]; } diff --git a/ui/app/hooks/useCurrencyDisplay.js b/ui/app/hooks/useCurrencyDisplay.js index 14e274d2f3..8b3f8271d9 100644 --- a/ui/app/hooks/useCurrencyDisplay.js +++ b/ui/app/hooks/useCurrencyDisplay.js @@ -1,14 +1,14 @@ -import { useMemo } from 'react' -import { useSelector } from 'react-redux' +import { useMemo } from 'react'; +import { useSelector } from 'react-redux'; import { formatCurrency, getValueFromWeiHex, -} from '../helpers/utils/confirm-tx.util' +} from '../helpers/utils/confirm-tx.util'; import { getCurrentCurrency, getConversionRate, getNativeCurrency, -} from '../selectors' +} from '../selectors'; /** * Defines the shape of the options parameter for useCurrencyDisplay @@ -42,15 +42,15 @@ export function useCurrencyDisplay( inputValue, { displayValue, prefix, numberOfDecimals, denomination, currency, ...opts }, ) { - const currentCurrency = useSelector(getCurrentCurrency) - const nativeCurrency = useSelector(getNativeCurrency) - const conversionRate = useSelector(getConversionRate) + const currentCurrency = useSelector(getCurrentCurrency); + const nativeCurrency = useSelector(getNativeCurrency); + const conversionRate = useSelector(getConversionRate); - const toCurrency = currency || currentCurrency + const toCurrency = currency || currentCurrency; const value = useMemo(() => { if (displayValue) { - return displayValue + return displayValue; } return formatCurrency( getValueFromWeiHex({ @@ -62,7 +62,7 @@ export function useCurrencyDisplay( toDenomination: denomination, }), toCurrency, - ) + ); }, [ inputValue, nativeCurrency, @@ -71,16 +71,16 @@ export function useCurrencyDisplay( numberOfDecimals, denomination, toCurrency, - ]) + ]); - let suffix + let suffix; if (!opts.hideLabel) { - suffix = opts.suffix || toCurrency.toUpperCase() + suffix = opts.suffix || toCurrency.toUpperCase(); } return [ `${prefix || ''}${value}${suffix ? ` ${suffix}` : ''}`, { prefix, value, suffix }, - ] + ]; } diff --git a/ui/app/hooks/useCurrentAsset.js b/ui/app/hooks/useCurrentAsset.js index 80e905a948..d1d144bedb 100644 --- a/ui/app/hooks/useCurrentAsset.js +++ b/ui/app/hooks/useCurrentAsset.js @@ -1,8 +1,8 @@ -import { useSelector } from 'react-redux' -import { useRouteMatch } from 'react-router-dom' -import { getTokens } from '../ducks/metamask/metamask' -import { ASSET_ROUTE } from '../helpers/constants/routes' -import { ETH_SWAPS_TOKEN_OBJECT } from '../helpers/constants/swaps' +import { useSelector } from 'react-redux'; +import { useRouteMatch } from 'react-router-dom'; +import { getTokens } from '../ducks/metamask/metamask'; +import { ASSET_ROUTE } from '../helpers/constants/routes'; +import { ETH_SWAPS_TOKEN_OBJECT } from '../helpers/constants/swaps'; /** * Returns a token object for the asset that is currently being viewed. @@ -17,11 +17,11 @@ export function useCurrentAsset() { path: `${ASSET_ROUTE}/:asset`, exact: true, strict: true, - }) - const tokenAddress = match?.params?.asset - const knownTokens = useSelector(getTokens) + }); + const tokenAddress = match?.params?.asset; + const knownTokens = useSelector(getTokens); const token = - tokenAddress && knownTokens.find(({ address }) => address === tokenAddress) + tokenAddress && knownTokens.find(({ address }) => address === tokenAddress); - return token ?? ETH_SWAPS_TOKEN_OBJECT + return token ?? ETH_SWAPS_TOKEN_OBJECT; } diff --git a/ui/app/hooks/useEqualityCheck.js b/ui/app/hooks/useEqualityCheck.js index 4212beeab3..3cce17750d 100644 --- a/ui/app/hooks/useEqualityCheck.js +++ b/ui/app/hooks/useEqualityCheck.js @@ -1,6 +1,6 @@ -import { useState, useLayoutEffect } from 'react' +import { useState, useLayoutEffect } from 'react'; -import { isEqual } from 'lodash' +import { isEqual } from 'lodash'; /** * Given a value and a function to determine equality, return a @@ -15,13 +15,13 @@ import { isEqual } from 'lodash' * @returns {T} */ export function useEqualityCheck(value, equalityFn = isEqual) { - const [computedValue, setComputedValue] = useState(value) + const [computedValue, setComputedValue] = useState(value); useLayoutEffect(() => { if (!equalityFn(value, computedValue)) { - setComputedValue(value) + setComputedValue(value); } - }, [value, equalityFn, computedValue]) + }, [value, equalityFn, computedValue]); - return computedValue + return computedValue; } diff --git a/ui/app/hooks/useEthFiatAmount.js b/ui/app/hooks/useEthFiatAmount.js index 7e89e3ad31..10ce717890 100644 --- a/ui/app/hooks/useEthFiatAmount.js +++ b/ui/app/hooks/useEthFiatAmount.js @@ -1,12 +1,12 @@ -import { useMemo } from 'react' -import { useSelector } from 'react-redux' +import { useMemo } from 'react'; +import { useSelector } from 'react-redux'; import { getConversionRate, getCurrentCurrency, getShouldShowFiat, -} from '../selectors' -import { decEthToConvertedCurrency } from '../helpers/utils/conversions.util' -import { formatCurrency } from '../helpers/utils/confirm-tx.util' +} from '../selectors'; +import { decEthToConvertedCurrency } from '../helpers/utils/conversions.util'; +import { formatCurrency } from '../helpers/utils/confirm-tx.util'; /** * Get an Eth amount converted to fiat and formatted for display @@ -23,14 +23,14 @@ export function useEthFiatAmount( overrides = {}, hideCurrencySymbol, ) { - const conversionRate = useSelector(getConversionRate) - const currentCurrency = useSelector(getCurrentCurrency) - const userPrefersShownFiat = useSelector(getShouldShowFiat) - const showFiat = overrides.showFiat ?? userPrefersShownFiat + const conversionRate = useSelector(getConversionRate); + const currentCurrency = useSelector(getCurrentCurrency); + const userPrefersShownFiat = useSelector(getShouldShowFiat); + const showFiat = overrides.showFiat ?? userPrefersShownFiat; const formattedFiat = useMemo( () => decEthToConvertedCurrency(ethAmount, currentCurrency, conversionRate), [conversionRate, currentCurrency, ethAmount], - ) + ); if ( !showFiat || @@ -38,7 +38,7 @@ export function useEthFiatAmount( conversionRate <= 0 || ethAmount === undefined ) { - return undefined + return undefined; } return hideCurrencySymbol @@ -46,5 +46,5 @@ export function useEthFiatAmount( : `${formatCurrency( formattedFiat, currentCurrency, - )} ${currentCurrency.toUpperCase()}` + )} ${currentCurrency.toUpperCase()}`; } diff --git a/ui/app/hooks/useI18nContext.js b/ui/app/hooks/useI18nContext.js index d2fb087c3d..3a1dfa652a 100644 --- a/ui/app/hooks/useI18nContext.js +++ b/ui/app/hooks/useI18nContext.js @@ -1,5 +1,5 @@ -import { useContext } from 'react' -import { I18nContext } from '../contexts/i18n' +import { useContext } from 'react'; +import { I18nContext } from '../contexts/i18n'; /** * useI18ncContext @@ -9,5 +9,5 @@ import { I18nContext } from '../contexts/i18n' * @return {Function} I18n function from contexts/I18n.js */ export function useI18nContext() { - return useContext(I18nContext) + return useContext(I18nContext); } diff --git a/ui/app/hooks/useMethodData.js b/ui/app/hooks/useMethodData.js index 124e130b17..f4ce2f6344 100644 --- a/ui/app/hooks/useMethodData.js +++ b/ui/app/hooks/useMethodData.js @@ -1,8 +1,8 @@ -import { useEffect, useCallback } from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { getContractMethodData as getContractMethodDataAction } from '../store/actions' +import { useEffect, useCallback } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { getContractMethodData as getContractMethodDataAction } from '../store/actions'; -import { getKnownMethodData } from '../selectors/selectors' +import { getKnownMethodData } from '../selectors/selectors'; /** * Access known method data and attempt to resolve unknown method data @@ -17,19 +17,19 @@ import { getKnownMethodData } from '../selectors/selectors' * @return {Object} contract method data */ export function useMethodData(data) { - const dispatch = useDispatch() + const dispatch = useDispatch(); const knownMethodData = useSelector((state) => getKnownMethodData(state, data), - ) + ); const getContractMethodData = useCallback( (methodData) => dispatch(getContractMethodDataAction(methodData)), [dispatch], - ) + ); useEffect(() => { if (data) { - getContractMethodData(data) + getContractMethodData(data); } - }, [getContractMethodData, data]) - return knownMethodData + }, [getContractMethodData, data]); + return knownMethodData; } diff --git a/ui/app/hooks/useMetricEvent.js b/ui/app/hooks/useMetricEvent.js index e428fc5d2a..b30b37eb59 100644 --- a/ui/app/hooks/useMetricEvent.js +++ b/ui/app/hooks/useMetricEvent.js @@ -1,7 +1,7 @@ -import { useContext, useCallback } from 'react' -import { MetaMetricsContext } from '../contexts/metametrics' -import { MetaMetricsContext as NewMetaMetricsContext } from '../contexts/metametrics.new' -import { useEqualityCheck } from './useEqualityCheck' +import { useContext, useCallback } from 'react'; +import { MetaMetricsContext } from '../contexts/metametrics'; +import { MetaMetricsContext as NewMetaMetricsContext } from '../contexts/metametrics.new'; +import { useEqualityCheck } from './useEqualityCheck'; // Type imports /** @@ -10,13 +10,13 @@ import { useEqualityCheck } from './useEqualityCheck' */ export function useMetricEvent(config = {}, overrides = {}) { - const metricsEvent = useContext(MetaMetricsContext) + const metricsEvent = useContext(MetaMetricsContext); const trackEvent = useCallback(() => metricsEvent(config, overrides), [ config, metricsEvent, overrides, - ]) - return trackEvent + ]); + return trackEvent; } /** @@ -28,13 +28,13 @@ export function useMetricEvent(config = {}, overrides = {}) { * @return {() => Promise} function to execute the tracking event */ export function useNewMetricEvent(payload, options) { - const memoizedPayload = useEqualityCheck(payload) - const memoizedOptions = useEqualityCheck(options) - const metricsEvent = useContext(NewMetaMetricsContext) + const memoizedPayload = useEqualityCheck(payload); + const memoizedOptions = useEqualityCheck(options); + const metricsEvent = useContext(NewMetaMetricsContext); return useCallback(() => metricsEvent(memoizedPayload, memoizedOptions), [ metricsEvent, memoizedPayload, memoizedOptions, - ]) + ]); } diff --git a/ui/app/hooks/usePrevious.js b/ui/app/hooks/usePrevious.js index 64ff105f14..8e44b94538 100644 --- a/ui/app/hooks/usePrevious.js +++ b/ui/app/hooks/usePrevious.js @@ -1,9 +1,9 @@ -import { useEffect, useRef } from 'react' +import { useEffect, useRef } from 'react'; export function usePrevious(value) { - const ref = useRef() + const ref = useRef(); useEffect(() => { - ref.current = value - }, [value]) - return ref.current + ref.current = value; + }, [value]); + return ref.current; } diff --git a/ui/app/hooks/useRetryTransaction.js b/ui/app/hooks/useRetryTransaction.js index 63bd6f2833..9081ea44d0 100644 --- a/ui/app/hooks/useRetryTransaction.js +++ b/ui/app/hooks/useRetryTransaction.js @@ -1,13 +1,13 @@ -import { useDispatch } from 'react-redux' -import { useCallback } from 'react' -import { showSidebar } from '../store/actions' +import { useDispatch } from 'react-redux'; +import { useCallback } from 'react'; +import { showSidebar } from '../store/actions'; import { fetchBasicGasEstimates, setCustomGasPriceForRetry, setCustomGasLimit, -} from '../ducks/gas/gas.duck' -import { increaseLastGasPrice } from '../helpers/utils/confirm-tx.util' -import { useMetricEvent } from './useMetricEvent' +} from '../ducks/gas/gas.duck'; +import { increaseLastGasPrice } from '../helpers/utils/confirm-tx.util'; +import { useMetricEvent } from './useMetricEvent'; /** * Provides a reusable hook that, given a transactionGroup, will return @@ -16,42 +16,42 @@ import { useMetricEvent } from './useMetricEvent' * @return {Function} */ export function useRetryTransaction(transactionGroup) { - const { primaryTransaction, initialTransaction } = transactionGroup + const { primaryTransaction, initialTransaction } = transactionGroup; // Signature requests do not have a txParams, but this hook is called indiscriminately - const gasPrice = primaryTransaction.txParams?.gasPrice + const gasPrice = primaryTransaction.txParams?.gasPrice; const trackMetricsEvent = useMetricEvent({ eventOpts: { category: 'Navigation', action: 'Activity Log', name: 'Clicked "Speed Up"', }, - }) - const dispatch = useDispatch() + }); + const dispatch = useDispatch(); const retryTransaction = useCallback( async (event) => { - event.stopPropagation() + event.stopPropagation(); - trackMetricsEvent() - await dispatch(fetchBasicGasEstimates) - const transaction = initialTransaction - const increasedGasPrice = increaseLastGasPrice(gasPrice) + trackMetricsEvent(); + await dispatch(fetchBasicGasEstimates); + const transaction = initialTransaction; + const increasedGasPrice = increaseLastGasPrice(gasPrice); await dispatch( setCustomGasPriceForRetry( increasedGasPrice || transaction.txParams.gasPrice, ), - ) - dispatch(setCustomGasLimit(transaction.txParams.gas)) + ); + dispatch(setCustomGasLimit(transaction.txParams.gas)); dispatch( showSidebar({ transitionName: 'sidebar-left', type: 'customize-gas', props: { transaction }, }), - ) + ); }, [dispatch, trackMetricsEvent, initialTransaction, gasPrice], - ) + ); - return retryTransaction + return retryTransaction; } diff --git a/ui/app/hooks/useShouldShowSpeedUp.js b/ui/app/hooks/useShouldShowSpeedUp.js index 97c79044f0..83c96ca3fa 100644 --- a/ui/app/hooks/useShouldShowSpeedUp.js +++ b/ui/app/hooks/useShouldShowSpeedUp.js @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react' +import { useEffect, useState } from 'react'; /** * Evaluates whether the transaction is eligible to be sped up, and registers @@ -8,12 +8,12 @@ import { useEffect, useState } from 'react' * @param {boolean} isEarliestNonce - Whether this group is currently the earliest nonce */ export function useShouldShowSpeedUp(transactionGroup, isEarliestNonce) { - const { transactions, hasRetried } = transactionGroup - const [earliestTransaction = {}] = transactions - const { submittedTime } = earliestTransaction + const { transactions, hasRetried } = transactionGroup; + const [earliestTransaction = {}] = transactions; + const { submittedTime } = earliestTransaction; const [speedUpEnabled, setSpeedUpEnabled] = useState(() => { - return Date.now() - submittedTime > 5000 && isEarliestNonce && !hasRetried - }) + return Date.now() - submittedTime > 5000 && isEarliestNonce && !hasRetried; + }); useEffect(() => { // because this hook is optimized to only run on changes we have to // key into the changing time delta between submittedTime and now() @@ -22,25 +22,25 @@ export function useShouldShowSpeedUp(transactionGroup, isEarliestNonce) { // also immediately set retryEnabled and not create a timeout if the // condition is already met. This effect will run anytime the variables // for determining enabled status change - let timeoutId + let timeoutId; if (!hasRetried && isEarliestNonce && !speedUpEnabled) { if (Date.now() - submittedTime > 5000) { - setSpeedUpEnabled(true) + setSpeedUpEnabled(true); } else { timeoutId = setTimeout(() => { - setSpeedUpEnabled(true) - clearTimeout(timeoutId) - }, 5001 - (Date.now() - submittedTime)) + setSpeedUpEnabled(true); + clearTimeout(timeoutId); + }, 5001 - (Date.now() - submittedTime)); } } // Anytime the effect is re-ran, make sure to remove a previously set timeout // so as to avoid multiple timers potentially overlapping return () => { if (timeoutId) { - clearTimeout(timeoutId) + clearTimeout(timeoutId); } - } - }, [submittedTime, speedUpEnabled, hasRetried, isEarliestNonce]) + }; + }, [submittedTime, speedUpEnabled, hasRetried, isEarliestNonce]); - return speedUpEnabled + return speedUpEnabled; } diff --git a/ui/app/hooks/useSwappedTokenValue.js b/ui/app/hooks/useSwappedTokenValue.js index 952260c9b5..0a5e5bc27c 100644 --- a/ui/app/hooks/useSwappedTokenValue.js +++ b/ui/app/hooks/useSwappedTokenValue.js @@ -1,7 +1,7 @@ -import { TRANSACTION_CATEGORIES } from '../../../shared/constants/transaction' -import { ETH_SWAPS_TOKEN_ADDRESS } from '../helpers/constants/swaps' -import { getSwapsTokensReceivedFromTxMeta } from '../pages/swaps/swaps.util' -import { useTokenFiatAmount } from './useTokenFiatAmount' +import { TRANSACTION_CATEGORIES } from '../../../shared/constants/transaction'; +import { ETH_SWAPS_TOKEN_ADDRESS } from '../helpers/constants/swaps'; +import { getSwapsTokensReceivedFromTxMeta } from '../pages/swaps/swaps.util'; +import { useTokenFiatAmount } from './useTokenFiatAmount'; /** * @typedef {Object} SwappedTokenValue @@ -23,15 +23,15 @@ import { useTokenFiatAmount } from './useTokenFiatAmount' * @returns {SwappedTokenValue} */ export function useSwappedTokenValue(transactionGroup, currentAsset) { - const { symbol, decimals, address } = currentAsset - const { primaryTransaction, initialTransaction } = transactionGroup - const { transactionCategory } = initialTransaction - const { from: senderAddress } = initialTransaction.txParams || {} + const { symbol, decimals, address } = currentAsset; + const { primaryTransaction, initialTransaction } = transactionGroup; + const { transactionCategory } = initialTransaction; + const { from: senderAddress } = initialTransaction.txParams || {}; const isViewingReceivedTokenFromSwap = currentAsset?.symbol === primaryTransaction.destinationTokenSymbol || (currentAsset.address === ETH_SWAPS_TOKEN_ADDRESS && - primaryTransaction.destinationTokenSymbol === 'ETH') + primaryTransaction.destinationTokenSymbol === 'ETH'); const swapTokenValue = transactionCategory === TRANSACTION_CATEGORIES.SWAP && @@ -44,24 +44,24 @@ export function useSwappedTokenValue(transactionGroup, currentAsset) { decimals, ) : transactionCategory === TRANSACTION_CATEGORIES.SWAP && - primaryTransaction.swapTokenValue + primaryTransaction.swapTokenValue; const isNegative = typeof swapTokenValue === 'string' ? Math.sign(swapTokenValue) === -1 - : false + : false; const _swapTokenFiatAmount = useTokenFiatAmount( address, swapTokenValue || '', symbol, - ) + ); const swapTokenFiatAmount = - swapTokenValue && isViewingReceivedTokenFromSwap && _swapTokenFiatAmount + swapTokenValue && isViewingReceivedTokenFromSwap && _swapTokenFiatAmount; return { swapTokenValue, swapTokenFiatAmount, isViewingReceivedTokenFromSwap, isNegative, - } + }; } diff --git a/ui/app/hooks/useSwapsEthToken.js b/ui/app/hooks/useSwapsEthToken.js index cd531f6e3a..d1707ed88a 100644 --- a/ui/app/hooks/useSwapsEthToken.js +++ b/ui/app/hooks/useSwapsEthToken.js @@ -1,10 +1,10 @@ -import { useSelector } from 'react-redux' -import { getSelectedAccount } from '../selectors' -import { ETH_SWAPS_TOKEN_OBJECT } from '../helpers/constants/swaps' +import { useSelector } from 'react-redux'; +import { getSelectedAccount } from '../selectors'; +import { ETH_SWAPS_TOKEN_OBJECT } from '../helpers/constants/swaps'; import { getValueFromWeiHex, hexToDecimal, -} from '../helpers/utils/conversions.util' +} from '../helpers/utils/conversions.util'; /** * @typedef {Object} SwapsEthToken @@ -38,8 +38,8 @@ import { * selected account's ETH balance, as expected by the Swaps API. */ export function useSwapsEthToken() { - const selectedAccount = useSelector(getSelectedAccount) - const { balance } = selectedAccount + const selectedAccount = useSelector(getSelectedAccount); + const { balance } = selectedAccount; return { ...ETH_SWAPS_TOKEN_OBJECT, @@ -49,5 +49,5 @@ export function useSwapsEthToken() { numberOfDecimals: 4, toDenomination: 'ETH', }), - } + }; } diff --git a/ui/app/hooks/useTimeout.js b/ui/app/hooks/useTimeout.js index dc0a714345..d3b208896d 100644 --- a/ui/app/hooks/useTimeout.js +++ b/ui/app/hooks/useTimeout.js @@ -1,4 +1,4 @@ -import { useState, useEffect, useRef, useCallback } from 'react' +import { useState, useEffect, useRef, useCallback } from 'react'; /** * useTimeout @@ -10,37 +10,37 @@ import { useState, useEffect, useRef, useCallback } from 'react' * @return {Function|undefined} */ export function useTimeout(cb, delay, immediate = true) { - const saveCb = useRef() - const [timeoutId, setTimeoutId] = useState(null) + const saveCb = useRef(); + const [timeoutId, setTimeoutId] = useState(null); useEffect(() => { - saveCb.current = cb - }, [cb]) + saveCb.current = cb; + }, [cb]); useEffect(() => { if (timeoutId !== 'start') { - return undefined + return undefined; } const id = setTimeout(() => { - saveCb.current() - }, delay) + saveCb.current(); + }, delay); - setTimeoutId(id) + setTimeoutId(id); return () => { - clearTimeout(timeoutId) - } - }, [delay, timeoutId]) + clearTimeout(timeoutId); + }; + }, [delay, timeoutId]); const startTimeout = useCallback(() => { - clearTimeout(timeoutId) - setTimeoutId('start') - }, [timeoutId]) + clearTimeout(timeoutId); + setTimeoutId('start'); + }, [timeoutId]); if (immediate) { - startTimeout() + startTimeout(); } - return startTimeout + return startTimeout; } diff --git a/ui/app/hooks/useTokenData.js b/ui/app/hooks/useTokenData.js index c9602f084e..6a93f35123 100644 --- a/ui/app/hooks/useTokenData.js +++ b/ui/app/hooks/useTokenData.js @@ -1,5 +1,5 @@ -import { useMemo } from 'react' -import { getTokenData } from '../helpers/utils/transactions.util' +import { useMemo } from 'react'; +import { getTokenData } from '../helpers/utils/transactions.util'; /** * useTokenData @@ -16,8 +16,8 @@ import { getTokenData } from '../helpers/utils/transactions.util' export function useTokenData(transactionData, isTokenTransaction = true) { return useMemo(() => { if (!isTokenTransaction || !transactionData) { - return null + return null; } - return getTokenData(transactionData) - }, [isTokenTransaction, transactionData]) + return getTokenData(transactionData); + }, [isTokenTransaction, transactionData]); } diff --git a/ui/app/hooks/useTokenDisplayValue.js b/ui/app/hooks/useTokenDisplayValue.js index 331b53dfb0..40c3b1de6c 100644 --- a/ui/app/hooks/useTokenDisplayValue.js +++ b/ui/app/hooks/useTokenDisplayValue.js @@ -1,9 +1,9 @@ -import { useMemo } from 'react' +import { useMemo } from 'react'; import { getTokenValueParam, calcTokenAmount, -} from '../helpers/utils/token-util' -import { useTokenData } from './useTokenData' +} from '../helpers/utils/token-util'; +import { useTokenData } from './useTokenData'; /** * Defines the shape for the Token input parameter for useTokenDisplayValue @@ -32,7 +32,7 @@ export function useTokenDisplayValue( token, isTokenTransaction = true, ) { - const tokenData = useTokenData(transactionData, isTokenTransaction) + const tokenData = useTokenData(transactionData, isTokenTransaction); const shouldCalculateTokenValue = Boolean( // If we are currently processing a token transaction isTokenTransaction && @@ -42,15 +42,15 @@ export function useTokenDisplayValue( token && // and we are able to parse the token details from the raw data tokenData?.args?.length, - ) + ); const displayValue = useMemo(() => { if (!shouldCalculateTokenValue) { - return null + return null; } - const tokenValue = getTokenValueParam(tokenData) - return calcTokenAmount(tokenValue, token.decimals).toString(10) - }, [shouldCalculateTokenValue, tokenData, token]) + const tokenValue = getTokenValueParam(tokenData); + return calcTokenAmount(tokenValue, token.decimals).toString(10); + }, [shouldCalculateTokenValue, tokenData, token]); - return displayValue + return displayValue; } diff --git a/ui/app/hooks/useTokenFiatAmount.js b/ui/app/hooks/useTokenFiatAmount.js index 6f393c8615..835b659364 100644 --- a/ui/app/hooks/useTokenFiatAmount.js +++ b/ui/app/hooks/useTokenFiatAmount.js @@ -1,12 +1,12 @@ -import { useMemo } from 'react' -import { useSelector } from 'react-redux' +import { useMemo } from 'react'; +import { useSelector } from 'react-redux'; import { getTokenExchangeRates, getConversionRate, getCurrentCurrency, getShouldShowFiat, -} from '../selectors' -import { getTokenFiatAmount } from '../helpers/utils/token-util' +} from '../selectors'; +import { getTokenFiatAmount } from '../helpers/utils/token-util'; /** * Get the token balance converted to fiat and formatted for display @@ -28,13 +28,13 @@ export function useTokenFiatAmount( overrides = {}, hideCurrencySymbol, ) { - const contractExchangeRates = useSelector(getTokenExchangeRates) - const conversionRate = useSelector(getConversionRate) - const currentCurrency = useSelector(getCurrentCurrency) - const userPrefersShownFiat = useSelector(getShouldShowFiat) - const showFiat = overrides.showFiat ?? userPrefersShownFiat + const contractExchangeRates = useSelector(getTokenExchangeRates); + const conversionRate = useSelector(getConversionRate); + const currentCurrency = useSelector(getCurrentCurrency); + const userPrefersShownFiat = useSelector(getShouldShowFiat); + const showFiat = overrides.showFiat ?? userPrefersShownFiat; const tokenExchangeRate = - overrides.exchangeRate ?? contractExchangeRates[tokenAddress] + overrides.exchangeRate ?? contractExchangeRates[tokenAddress]; const formattedFiat = useMemo( () => getTokenFiatAmount( @@ -54,11 +54,11 @@ export function useTokenFiatAmount( tokenSymbol, hideCurrencySymbol, ], - ) + ); if (!showFiat || currentCurrency.toUpperCase() === tokenSymbol) { - return undefined + return undefined; } - return formattedFiat + return formattedFiat; } diff --git a/ui/app/hooks/useTokenTracker.js b/ui/app/hooks/useTokenTracker.js index f94b0544fc..ea7892b08d 100644 --- a/ui/app/hooks/useTokenTracker.js +++ b/ui/app/hooks/useTokenTracker.js @@ -1,57 +1,57 @@ -import { useState, useEffect, useRef, useCallback } from 'react' -import TokenTracker from '@metamask/eth-token-tracker' -import { useSelector } from 'react-redux' -import { getCurrentNetwork, getSelectedAddress } from '../selectors' -import { useEqualityCheck } from './useEqualityCheck' +import { useState, useEffect, useRef, useCallback } from 'react'; +import TokenTracker from '@metamask/eth-token-tracker'; +import { useSelector } from 'react-redux'; +import { getCurrentNetwork, getSelectedAddress } from '../selectors'; +import { useEqualityCheck } from './useEqualityCheck'; export function useTokenTracker(tokens, includeFailedTokens = false) { - const network = useSelector(getCurrentNetwork) - const userAddress = useSelector(getSelectedAddress) + const network = useSelector(getCurrentNetwork); + const userAddress = useSelector(getSelectedAddress); - const [loading, setLoading] = useState(() => tokens?.length >= 0) - const [tokensWithBalances, setTokensWithBalances] = useState([]) - const [error, setError] = useState(null) - const tokenTracker = useRef(null) - const memoizedTokens = useEqualityCheck(tokens) + const [loading, setLoading] = useState(() => tokens?.length >= 0); + const [tokensWithBalances, setTokensWithBalances] = useState([]); + const [error, setError] = useState(null); + const tokenTracker = useRef(null); + const memoizedTokens = useEqualityCheck(tokens); const updateBalances = useCallback((tokenWithBalances) => { - setTokensWithBalances(tokenWithBalances) - setLoading(false) - setError(null) - }, []) + setTokensWithBalances(tokenWithBalances); + setLoading(false); + setError(null); + }, []); const showError = useCallback((err) => { - setError(err) - setLoading(false) - }, []) + setError(err); + setLoading(false); + }, []); const teardownTracker = useCallback(() => { if (tokenTracker.current) { - tokenTracker.current.stop() - tokenTracker.current.removeAllListeners('update') - tokenTracker.current.removeAllListeners('error') - tokenTracker.current = null + tokenTracker.current.stop(); + tokenTracker.current.removeAllListeners('update'); + tokenTracker.current.removeAllListeners('error'); + tokenTracker.current = null; } - }, []) + }, []); const buildTracker = useCallback( (address, tokenList) => { // clear out previous tracker, if it exists. - teardownTracker() + teardownTracker(); tokenTracker.current = new TokenTracker({ userAddress: address, provider: global.ethereumProvider, tokens: tokenList, includeFailedTokens, pollingInterval: 8000, - }) + }); - tokenTracker.current.on('update', updateBalances) - tokenTracker.current.on('error', showError) - tokenTracker.current.updateBalances() + tokenTracker.current.on('update', updateBalances); + tokenTracker.current.on('error', showError); + tokenTracker.current.updateBalances(); }, [updateBalances, includeFailedTokens, showError, teardownTracker], - ) + ); // Effect to remove the tracker when the component is removed from DOM // Do not overload this effect with additional dependencies. teardownTracker @@ -59,8 +59,8 @@ export function useTokenTracker(tokens, includeFailedTokens = false) { // never update. The lack of dependencies that change is what confirms // that this effect only runs on mount/unmount useEffect(() => { - return teardownTracker - }, [teardownTracker]) + return teardownTracker; + }, [teardownTracker]); // Effect to set loading state and initialize tracker when values change useEffect(() => { @@ -70,22 +70,22 @@ export function useTokenTracker(tokens, includeFailedTokens = false) { // 3. token list is updated and not equal to previous list // in any of these scenarios, we should indicate to the user that their token // values are in the process of updating by setting loading state. - setLoading(true) + setLoading(true); if (!userAddress || network === 'loading' || !global.ethereumProvider) { // If we do not have enough information to build a TokenTracker, we exit early // When the values above change, the effect will be restarted. We also teardown // tracker because inevitably this effect will run again momentarily. - teardownTracker() - return + teardownTracker(); + return; } if (memoizedTokens.length === 0) { // sets loading state to false and token list to empty - updateBalances([]) + updateBalances([]); } - buildTracker(userAddress, memoizedTokens) + buildTracker(userAddress, memoizedTokens); }, [ userAddress, teardownTracker, @@ -93,7 +93,7 @@ export function useTokenTracker(tokens, includeFailedTokens = false) { memoizedTokens, updateBalances, buildTracker, - ]) + ]); - return { loading, tokensWithBalances, error } + return { loading, tokensWithBalances, error }; } diff --git a/ui/app/hooks/useTokensToSearch.js b/ui/app/hooks/useTokensToSearch.js index a4e0e94f49..cbaf4df669 100644 --- a/ui/app/hooks/useTokensToSearch.js +++ b/ui/app/hooks/useTokensToSearch.js @@ -1,18 +1,18 @@ -import { useMemo } from 'react' -import { useSelector } from 'react-redux' -import contractMap from '@metamask/contract-metadata' -import BigNumber from 'bignumber.js' -import { isEqual, shuffle } from 'lodash' -import { checksumAddress } from '../helpers/utils/util' -import { getTokenFiatAmount } from '../helpers/utils/token-util' +import { useMemo } from 'react'; +import { useSelector } from 'react-redux'; +import contractMap from '@metamask/contract-metadata'; +import BigNumber from 'bignumber.js'; +import { isEqual, shuffle } from 'lodash'; +import { checksumAddress } from '../helpers/utils/util'; +import { getTokenFiatAmount } from '../helpers/utils/token-util'; import { getTokenExchangeRates, getConversionRate, getCurrentCurrency, -} from '../selectors' -import { getSwapsTokens } from '../ducks/swaps/swaps' -import { useSwapsEthToken } from './useSwapsEthToken' -import { useEqualityCheck } from './useEqualityCheck' +} from '../selectors'; +import { getSwapsTokens } from '../ducks/swaps/swaps'; +import { useSwapsEthToken } from './useSwapsEthToken'; +import { useEqualityCheck } from './useEqualityCheck'; const tokenList = shuffle( Object.entries(contractMap) @@ -21,7 +21,7 @@ const tokenList = shuffle( address: address.toLowerCase(), })) .filter((tokenData) => Boolean(tokenData.erc20)), -) +); export function getRenderableTokenData( token, @@ -29,7 +29,7 @@ export function getRenderableTokenData( conversionRate, currentCurrency, ) { - const { symbol, name, address, iconUrl, string, balance, decimals } = token + const { symbol, name, address, iconUrl, string, balance, decimals } = token; const formattedFiat = getTokenFiatAmount( @@ -39,7 +39,7 @@ export function getRenderableTokenData( string, symbol, true, - ) || '' + ) || ''; const rawFiat = getTokenFiatAmount( symbol === 'ETH' ? 1 : contractExchangeRates[address], @@ -48,11 +48,11 @@ export function getRenderableTokenData( string, symbol, false, - ) || '' + ) || ''; const usedIconUrl = iconUrl || (contractMap[checksumAddress(address)] && - `images/contract/${contractMap[checksumAddress(address)].logo}`) + `images/contract/${contractMap[checksumAddress(address)].logo}`); return { ...token, primaryLabel: symbol, @@ -66,7 +66,7 @@ export function getRenderableTokenData( decimals, name: name || contractMap[checksumAddress(address)]?.name, rawFiat, - } + }; } export function useTokensToSearch({ @@ -76,47 +76,47 @@ export function useTokensToSearch({ onlyEth, singleToken, }) { - const tokenConversionRates = useSelector(getTokenExchangeRates, isEqual) - const conversionRate = useSelector(getConversionRate) - const currentCurrency = useSelector(getCurrentCurrency) + const tokenConversionRates = useSelector(getTokenExchangeRates, isEqual); + const conversionRate = useSelector(getConversionRate); + const currentCurrency = useSelector(getCurrentCurrency); - const memoizedTopTokens = useEqualityCheck(topTokens) - const memoizedUsersToken = useEqualityCheck(usersTokens) + const memoizedTopTokens = useEqualityCheck(topTokens); + const memoizedUsersToken = useEqualityCheck(usersTokens); - const swapsEthToken = useSwapsEthToken() + const swapsEthToken = useSwapsEthToken(); const ethToken = getRenderableTokenData( swapsEthToken, tokenConversionRates, conversionRate, currentCurrency, - ) - const memoizedEthToken = useEqualityCheck(ethToken) + ); + const memoizedEthToken = useEqualityCheck(ethToken); - const swapsTokens = useSelector(getSwapsTokens) || [] - let tokensToSearch + const swapsTokens = useSelector(getSwapsTokens) || []; + let tokensToSearch; if (onlyEth) { - tokensToSearch = [memoizedEthToken] + tokensToSearch = [memoizedEthToken]; } else if (singleToken) { - tokensToSearch = providedTokens + tokensToSearch = providedTokens; } else if (providedTokens) { - tokensToSearch = [memoizedEthToken, ...providedTokens] + tokensToSearch = [memoizedEthToken, ...providedTokens]; } else if (swapsTokens.length) { - tokensToSearch = [memoizedEthToken, ...swapsTokens] + tokensToSearch = [memoizedEthToken, ...swapsTokens]; } else { - tokensToSearch = [memoizedEthToken, ...tokenList] + tokensToSearch = [memoizedEthToken, ...tokenList]; } - const memoizedTokensToSearch = useEqualityCheck(tokensToSearch) + const memoizedTokensToSearch = useEqualityCheck(tokensToSearch); return useMemo(() => { const usersTokensAddressMap = memoizedUsersToken.reduce( (acc, token) => ({ ...acc, [token.address]: token }), {}, - ) + ); const tokensToSearchBuckets = { owned: singleToken ? [] : [memoizedEthToken], top: [], others: [], - } + }; memoizedTokensToSearch.forEach((token) => { const renderableDataToken = getRenderableTokenData( @@ -124,33 +124,33 @@ export function useTokensToSearch({ tokenConversionRates, conversionRate, currentCurrency, - ) + ); if ( usersTokensAddressMap[token.address] && (renderableDataToken.symbol === 'ETH' || Number(renderableDataToken.balance ?? 0) !== 0) ) { - tokensToSearchBuckets.owned.push(renderableDataToken) + tokensToSearchBuckets.owned.push(renderableDataToken); } else if (memoizedTopTokens[token.address]) { tokensToSearchBuckets.top[ memoizedTopTokens[token.address].index - ] = renderableDataToken + ] = renderableDataToken; } else { - tokensToSearchBuckets.others.push(renderableDataToken) + tokensToSearchBuckets.others.push(renderableDataToken); } - }) + }); tokensToSearchBuckets.owned = tokensToSearchBuckets.owned.sort( ({ rawFiat }, { rawFiat: secondRawFiat }) => { - return new BigNumber(rawFiat || 0).gt(secondRawFiat || 0) ? -1 : 1 + return new BigNumber(rawFiat || 0).gt(secondRawFiat || 0) ? -1 : 1; }, - ) - tokensToSearchBuckets.top = tokensToSearchBuckets.top.filter(Boolean) + ); + tokensToSearchBuckets.top = tokensToSearchBuckets.top.filter(Boolean); return [ ...tokensToSearchBuckets.owned, ...tokensToSearchBuckets.top, ...tokensToSearchBuckets.others, - ] + ]; }, [ memoizedTokensToSearch, memoizedUsersToken, @@ -160,5 +160,5 @@ export function useTokensToSearch({ memoizedTopTokens, memoizedEthToken, singleToken, - ]) + ]); } diff --git a/ui/app/hooks/useTransactionDisplayData.js b/ui/app/hooks/useTransactionDisplayData.js index 2fe8ae691f..ff0b7b6c9f 100644 --- a/ui/app/hooks/useTransactionDisplayData.js +++ b/ui/app/hooks/useTransactionDisplayData.js @@ -1,32 +1,32 @@ -import { useSelector } from 'react-redux' -import { getKnownMethodData } from '../selectors/selectors' -import { getStatusKey } from '../helpers/utils/transactions.util' -import { camelCaseToCapitalize } from '../helpers/utils/common.util' -import { PRIMARY, SECONDARY } from '../helpers/constants/common' -import { getTokenAddressParam } from '../helpers/utils/token-util' +import { useSelector } from 'react-redux'; +import { getKnownMethodData } from '../selectors/selectors'; +import { getStatusKey } from '../helpers/utils/transactions.util'; +import { camelCaseToCapitalize } from '../helpers/utils/common.util'; +import { PRIMARY, SECONDARY } from '../helpers/constants/common'; +import { getTokenAddressParam } from '../helpers/utils/token-util'; import { formatDateWithYearContext, shortenAddress, stripHttpSchemes, -} from '../helpers/utils/util' +} from '../helpers/utils/util'; import { PENDING_STATUS_HASH, TOKEN_CATEGORY_HASH, -} from '../helpers/constants/transactions' -import { getTokens } from '../ducks/metamask/metamask' +} from '../helpers/constants/transactions'; +import { getTokens } from '../ducks/metamask/metamask'; import { TRANSACTION_CATEGORIES, TRANSACTION_GROUP_CATEGORIES, TRANSACTION_STATUSES, -} from '../../../shared/constants/transaction' -import { useI18nContext } from './useI18nContext' -import { useTokenFiatAmount } from './useTokenFiatAmount' -import { useUserPreferencedCurrency } from './useUserPreferencedCurrency' -import { useCurrencyDisplay } from './useCurrencyDisplay' -import { useTokenDisplayValue } from './useTokenDisplayValue' -import { useTokenData } from './useTokenData' -import { useSwappedTokenValue } from './useSwappedTokenValue' -import { useCurrentAsset } from './useCurrentAsset' +} from '../../../shared/constants/transaction'; +import { useI18nContext } from './useI18nContext'; +import { useTokenFiatAmount } from './useTokenFiatAmount'; +import { useUserPreferencedCurrency } from './useUserPreferencedCurrency'; +import { useCurrencyDisplay } from './useCurrencyDisplay'; +import { useTokenDisplayValue } from './useTokenDisplayValue'; +import { useTokenData } from './useTokenData'; +import { useSwappedTokenValue } from './useSwappedTokenValue'; +import { useCurrentAsset } from './useCurrentAsset'; /** * @typedef {Object} TransactionDisplayData @@ -54,35 +54,35 @@ import { useCurrentAsset } from './useCurrentAsset' export function useTransactionDisplayData(transactionGroup) { // To determine which primary currency to display for swaps transactions we need to be aware // of which asset, if any, we are viewing at present - const currentAsset = useCurrentAsset() - const knownTokens = useSelector(getTokens) - const t = useI18nContext() - const { initialTransaction, primaryTransaction } = transactionGroup + const currentAsset = useCurrentAsset(); + const knownTokens = useSelector(getTokens); + const t = useI18nContext(); + const { initialTransaction, primaryTransaction } = transactionGroup; // initialTransaction contains the data we need to derive the primary purpose of this transaction group - const { transactionCategory } = initialTransaction + const { transactionCategory } = initialTransaction; - const { from: senderAddress, to } = initialTransaction.txParams || {} + const { from: senderAddress, to } = initialTransaction.txParams || {}; // for smart contract interactions, methodData can be used to derive the name of the action being taken const methodData = useSelector((state) => getKnownMethodData(state, initialTransaction?.txParams?.data), - ) || {} + ) || {}; - const displayedStatusKey = getStatusKey(primaryTransaction) - const isPending = displayedStatusKey in PENDING_STATUS_HASH - const isSubmitted = displayedStatusKey === TRANSACTION_STATUSES.SUBMITTED + const displayedStatusKey = getStatusKey(primaryTransaction); + const isPending = displayedStatusKey in PENDING_STATUS_HASH; + const isSubmitted = displayedStatusKey === TRANSACTION_STATUSES.SUBMITTED; - const primaryValue = primaryTransaction.txParams?.value - let prefix = '-' - const date = formatDateWithYearContext(initialTransaction.time || 0) - let subtitle - let subtitleContainsOrigin = false - let recipientAddress = to + const primaryValue = primaryTransaction.txParams?.value; + let prefix = '-'; + const date = formatDateWithYearContext(initialTransaction.time || 0); + let subtitle; + let subtitleContainsOrigin = false; + let recipientAddress = to; // This value is used to determine whether we should look inside txParams.data // to pull out and render token related information - const isTokenCategory = TOKEN_CATEGORY_HASH[transactionCategory] + const isTokenCategory = TOKEN_CATEGORY_HASH[transactionCategory]; // these values are always instantiated because they are either // used by or returned from hooks. Hooks must be called at the top level, @@ -92,46 +92,46 @@ export function useTransactionDisplayData(transactionGroup) { // hook to return null const token = isTokenCategory && - knownTokens.find(({ address }) => address === recipientAddress) + knownTokens.find(({ address }) => address === recipientAddress); const tokenData = useTokenData( initialTransaction?.txParams?.data, isTokenCategory, - ) + ); const tokenDisplayValue = useTokenDisplayValue( initialTransaction?.txParams?.data, token, isTokenCategory, - ) + ); const tokenFiatAmount = useTokenFiatAmount( token?.address, tokenDisplayValue, token?.symbol, - ) + ); const origin = stripHttpSchemes( initialTransaction.origin || initialTransaction.msgParams?.origin || '', - ) + ); // used to append to the primary display value. initialized to either token.symbol or undefined // but can later be modified if dealing with a swap - let primarySuffix = isTokenCategory ? token?.symbol : undefined + let primarySuffix = isTokenCategory ? token?.symbol : undefined; // used to display the primary value of tx. initialized to either tokenDisplayValue or undefined // but can later be modified if dealing with a swap - let primaryDisplayValue = isTokenCategory ? tokenDisplayValue : undefined + let primaryDisplayValue = isTokenCategory ? tokenDisplayValue : undefined; // used to display fiat amount of tx. initialized to either tokenFiatAmount or undefined // but can later be modified if dealing with a swap - let secondaryDisplayValue = isTokenCategory ? tokenFiatAmount : undefined + let secondaryDisplayValue = isTokenCategory ? tokenFiatAmount : undefined; // The transaction group category that will be used for rendering the icon in the activity list - let category + let category; // The primary title of the Tx that will be displayed in the activity list - let title + let title; const { swapTokenValue, isNegative, swapTokenFiatAmount, isViewingReceivedTokenFromSwap, - } = useSwappedTokenValue(transactionGroup, currentAsset) + } = useSwappedTokenValue(transactionGroup, currentAsset); // There are seven types of transaction entries that are currently differentiated in the design // 1. Signature request @@ -143,89 +143,89 @@ export function useTransactionDisplayData(transactionGroup) { // 7. Swap Approval if (transactionCategory === null || transactionCategory === undefined) { - category = TRANSACTION_GROUP_CATEGORIES.SIGNATURE_REQUEST - title = t('signatureRequest') - subtitle = origin - subtitleContainsOrigin = true + category = TRANSACTION_GROUP_CATEGORIES.SIGNATURE_REQUEST; + title = t('signatureRequest'); + subtitle = origin; + subtitleContainsOrigin = true; } else if (transactionCategory === TRANSACTION_CATEGORIES.SWAP) { - category = TRANSACTION_GROUP_CATEGORIES.SWAP + category = TRANSACTION_GROUP_CATEGORIES.SWAP; title = t('swapTokenToToken', [ initialTransaction.sourceTokenSymbol, initialTransaction.destinationTokenSymbol, - ]) - subtitle = origin - subtitleContainsOrigin = true + ]); + subtitle = origin; + subtitleContainsOrigin = true; primarySuffix = isViewingReceivedTokenFromSwap ? currentAsset.symbol - : initialTransaction.sourceTokenSymbol - primaryDisplayValue = swapTokenValue - secondaryDisplayValue = swapTokenFiatAmount + : initialTransaction.sourceTokenSymbol; + primaryDisplayValue = swapTokenValue; + secondaryDisplayValue = swapTokenFiatAmount; if (isNegative) { - prefix = '' + prefix = ''; } else if (isViewingReceivedTokenFromSwap) { - prefix = '+' + prefix = '+'; } else { - prefix = '-' + prefix = '-'; } } else if (transactionCategory === TRANSACTION_CATEGORIES.SWAP_APPROVAL) { - category = TRANSACTION_GROUP_CATEGORIES.APPROVAL - title = t('swapApproval', [primaryTransaction.sourceTokenSymbol]) - subtitle = origin - subtitleContainsOrigin = true - primarySuffix = primaryTransaction.sourceTokenSymbol + category = TRANSACTION_GROUP_CATEGORIES.APPROVAL; + title = t('swapApproval', [primaryTransaction.sourceTokenSymbol]); + subtitle = origin; + subtitleContainsOrigin = true; + primarySuffix = primaryTransaction.sourceTokenSymbol; } else if ( transactionCategory === TRANSACTION_CATEGORIES.TOKEN_METHOD_APPROVE ) { - category = TRANSACTION_GROUP_CATEGORIES.APPROVAL - prefix = '' - title = t('approveSpendLimit', [token?.symbol || t('token')]) - subtitle = origin - subtitleContainsOrigin = true + category = TRANSACTION_GROUP_CATEGORIES.APPROVAL; + prefix = ''; + title = t('approveSpendLimit', [token?.symbol || t('token')]); + subtitle = origin; + subtitleContainsOrigin = true; } else if ( transactionCategory === TRANSACTION_CATEGORIES.DEPLOY_CONTRACT || transactionCategory === TRANSACTION_CATEGORIES.CONTRACT_INTERACTION ) { - category = TRANSACTION_GROUP_CATEGORIES.INTERACTION + category = TRANSACTION_GROUP_CATEGORIES.INTERACTION; title = (methodData?.name && camelCaseToCapitalize(methodData.name)) || - t(transactionCategory) - subtitle = origin - subtitleContainsOrigin = true + t(transactionCategory); + subtitle = origin; + subtitleContainsOrigin = true; } else if (transactionCategory === TRANSACTION_CATEGORIES.INCOMING) { - category = TRANSACTION_GROUP_CATEGORIES.RECEIVE - title = t('receive') - prefix = '' - subtitle = t('fromAddress', [shortenAddress(senderAddress)]) + category = TRANSACTION_GROUP_CATEGORIES.RECEIVE; + title = t('receive'); + prefix = ''; + subtitle = t('fromAddress', [shortenAddress(senderAddress)]); } else if ( transactionCategory === TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER_FROM || transactionCategory === TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER ) { - category = TRANSACTION_GROUP_CATEGORIES.SEND - title = t('sendSpecifiedTokens', [token?.symbol || t('token')]) - recipientAddress = getTokenAddressParam(tokenData) - subtitle = t('toAddress', [shortenAddress(recipientAddress)]) + category = TRANSACTION_GROUP_CATEGORIES.SEND; + title = t('sendSpecifiedTokens', [token?.symbol || t('token')]); + recipientAddress = getTokenAddressParam(tokenData); + subtitle = t('toAddress', [shortenAddress(recipientAddress)]); } else if (transactionCategory === TRANSACTION_CATEGORIES.SENT_ETHER) { - category = TRANSACTION_GROUP_CATEGORIES.SEND - title = t('sendETH') - subtitle = t('toAddress', [shortenAddress(recipientAddress)]) + category = TRANSACTION_GROUP_CATEGORIES.SEND; + title = t('sendETH'); + subtitle = t('toAddress', [shortenAddress(recipientAddress)]); } - const primaryCurrencyPreferences = useUserPreferencedCurrency(PRIMARY) - const secondaryCurrencyPreferences = useUserPreferencedCurrency(SECONDARY) + const primaryCurrencyPreferences = useUserPreferencedCurrency(PRIMARY); + const secondaryCurrencyPreferences = useUserPreferencedCurrency(SECONDARY); const [primaryCurrency] = useCurrencyDisplay(primaryValue, { prefix, displayValue: primaryDisplayValue, suffix: primarySuffix, ...primaryCurrencyPreferences, - }) + }); const [secondaryCurrency] = useCurrencyDisplay(primaryValue, { prefix, displayValue: secondaryDisplayValue, hideLabel: isTokenCategory || Boolean(swapTokenValue), ...secondaryCurrencyPreferences, - }) + }); return { title, @@ -248,5 +248,5 @@ export function useTransactionDisplayData(transactionGroup) { displayedStatusKey, isPending, isSubmitted, - } + }; } diff --git a/ui/app/hooks/useUserPreferencedCurrency.js b/ui/app/hooks/useUserPreferencedCurrency.js index 1764fa24e1..d1a0809548 100644 --- a/ui/app/hooks/useUserPreferencedCurrency.js +++ b/ui/app/hooks/useUserPreferencedCurrency.js @@ -1,10 +1,10 @@ -import { useSelector } from 'react-redux' +import { useSelector } from 'react-redux'; import { getPreferences, getShouldShowFiat, getNativeCurrency, -} from '../selectors' -import { PRIMARY, SECONDARY, ETH } from '../helpers/constants/common' +} from '../selectors'; +import { PRIMARY, SECONDARY, ETH } from '../helpers/constants/common'; /** * Defines the shape of the options parameter for useUserPreferencedCurrency @@ -34,26 +34,26 @@ import { PRIMARY, SECONDARY, ETH } from '../helpers/constants/common' * @return {UserPreferredCurrency} */ export function useUserPreferencedCurrency(type, opts = {}) { - const nativeCurrency = useSelector(getNativeCurrency) - const { useNativeCurrencyAsPrimaryCurrency } = useSelector(getPreferences) - const showFiat = useSelector(getShouldShowFiat) + const nativeCurrency = useSelector(getNativeCurrency); + const { useNativeCurrencyAsPrimaryCurrency } = useSelector(getPreferences); + const showFiat = useSelector(getShouldShowFiat); - let currency, numberOfDecimals + let currency, numberOfDecimals; if ( !showFiat || (type === PRIMARY && useNativeCurrencyAsPrimaryCurrency) || (type === SECONDARY && !useNativeCurrencyAsPrimaryCurrency) ) { // Display ETH - currency = nativeCurrency || ETH - numberOfDecimals = opts.numberOfDecimals || opts.ethNumberOfDecimals || 6 + currency = nativeCurrency || ETH; + numberOfDecimals = opts.numberOfDecimals || opts.ethNumberOfDecimals || 6; } else if ( (type === SECONDARY && useNativeCurrencyAsPrimaryCurrency) || (type === PRIMARY && !useNativeCurrencyAsPrimaryCurrency) ) { // Display Fiat - numberOfDecimals = opts.numberOfDecimals || opts.fiatNumberOfDecimals || 2 + numberOfDecimals = opts.numberOfDecimals || opts.fiatNumberOfDecimals || 2; } - return { currency, numberOfDecimals } + return { currency, numberOfDecimals }; } diff --git a/ui/app/pages/add-token/add-token.component.js b/ui/app/pages/add-token/add-token.component.js index 20d673f735..40f4a36759 100644 --- a/ui/app/pages/add-token/add-token.component.js +++ b/ui/app/pages/add-token/add-token.component.js @@ -1,22 +1,22 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import ethUtil from 'ethereumjs-util' -import { checkExistingAddresses } from '../../helpers/utils/util' -import { tokenInfoGetter } from '../../helpers/utils/token-util' -import { CONFIRM_ADD_TOKEN_ROUTE } from '../../helpers/constants/routes' -import TextField from '../../components/ui/text-field' -import PageContainer from '../../components/ui/page-container' -import { Tabs, Tab } from '../../components/ui/tabs' -import { addHexPrefix } from '../../../../app/scripts/lib/util' -import TokenList from './token-list' -import TokenSearch from './token-search' - -const emptyAddr = '0x0000000000000000000000000000000000000000' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import ethUtil from 'ethereumjs-util'; +import { checkExistingAddresses } from '../../helpers/utils/util'; +import { tokenInfoGetter } from '../../helpers/utils/token-util'; +import { CONFIRM_ADD_TOKEN_ROUTE } from '../../helpers/constants/routes'; +import TextField from '../../components/ui/text-field'; +import PageContainer from '../../components/ui/page-container'; +import { Tabs, Tab } from '../../components/ui/tabs'; +import { addHexPrefix } from '../../../../app/scripts/lib/util'; +import TokenList from './token-list'; +import TokenSearch from './token-search'; + +const emptyAddr = '0x0000000000000000000000000000000000000000'; class AddToken extends Component { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { history: PropTypes.object, @@ -26,7 +26,7 @@ class AddToken extends Component { tokens: PropTypes.array, identities: PropTypes.object, mostRecentOverviewPage: PropTypes.string.isRequired, - } + }; state = { customAddress: '', @@ -40,58 +40,58 @@ class AddToken extends Component { customDecimalsError: null, autoFilled: false, forceEditSymbol: false, - } + }; componentDidMount() { - this.tokenInfoGetter = tokenInfoGetter() - const { pendingTokens = {} } = this.props - const pendingTokenKeys = Object.keys(pendingTokens) + this.tokenInfoGetter = tokenInfoGetter(); + const { pendingTokens = {} } = this.props; + const pendingTokenKeys = Object.keys(pendingTokens); if (pendingTokenKeys.length > 0) { - let selectedTokens = {} - let customToken = {} + let selectedTokens = {}; + let customToken = {}; pendingTokenKeys.forEach((tokenAddress) => { - const token = pendingTokens[tokenAddress] - const { isCustom } = token + const token = pendingTokens[tokenAddress]; + const { isCustom } = token; if (isCustom) { - customToken = { ...token } + customToken = { ...token }; } else { - selectedTokens = { ...selectedTokens, [tokenAddress]: { ...token } } + selectedTokens = { ...selectedTokens, [tokenAddress]: { ...token } }; } - }) + }); const { address: customAddress = '', symbol: customSymbol = '', decimals: customDecimals = 0, - } = customToken + } = customToken; this.setState({ selectedTokens, customAddress, customSymbol, customDecimals, - }) + }); } } handleToggleToken(token) { - const { address } = token - const { selectedTokens = {} } = this.state - const selectedTokensCopy = { ...selectedTokens } + const { address } = token; + const { selectedTokens = {} } = this.state; + const selectedTokensCopy = { ...selectedTokens }; if (address in selectedTokensCopy) { - delete selectedTokensCopy[address] + delete selectedTokensCopy[address]; } else { - selectedTokensCopy[address] = token + selectedTokensCopy[address] = token; } this.setState({ selectedTokens: selectedTokensCopy, tokenSelectorError: null, - }) + }); } hasError() { @@ -100,69 +100,69 @@ class AddToken extends Component { customAddressError, customSymbolError, customDecimalsError, - } = this.state + } = this.state; return ( tokenSelectorError || customAddressError || customSymbolError || customDecimalsError - ) + ); } hasSelected() { - const { customAddress = '', selectedTokens = {} } = this.state - return customAddress || Object.keys(selectedTokens).length > 0 + const { customAddress = '', selectedTokens = {} } = this.state; + return customAddress || Object.keys(selectedTokens).length > 0; } handleNext() { if (this.hasError()) { - return + return; } if (!this.hasSelected()) { - this.setState({ tokenSelectorError: this.context.t('mustSelectOne') }) - return + this.setState({ tokenSelectorError: this.context.t('mustSelectOne') }); + return; } - const { setPendingTokens, history } = this.props + const { setPendingTokens, history } = this.props; const { customAddress: address, customSymbol: symbol, customDecimals: decimals, selectedTokens, - } = this.state + } = this.state; const customToken = { address, symbol, decimals, - } + }; - setPendingTokens({ customToken, selectedTokens }) - history.push(CONFIRM_ADD_TOKEN_ROUTE) + setPendingTokens({ customToken, selectedTokens }); + history.push(CONFIRM_ADD_TOKEN_ROUTE); } async attemptToAutoFillTokenParams(address) { - const { symbol = '', decimals = 0 } = await this.tokenInfoGetter(address) + const { symbol = '', decimals = 0 } = await this.tokenInfoGetter(address); - const autoFilled = Boolean(symbol && decimals) - this.setState({ autoFilled }) - this.handleCustomSymbolChange(symbol || '') - this.handleCustomDecimalsChange(decimals) + const autoFilled = Boolean(symbol && decimals); + this.setState({ autoFilled }); + this.handleCustomSymbolChange(symbol || ''); + this.handleCustomDecimalsChange(decimals); } handleCustomAddressChange(value) { - const customAddress = value.trim() + const customAddress = value.trim(); this.setState({ customAddress, customAddressError: null, tokenSelectorError: null, autoFilled: false, - }) + }); - const isValidAddress = ethUtil.isValidAddress(customAddress) - const standardAddress = addHexPrefix(customAddress).toLowerCase() + const isValidAddress = ethUtil.isValidAddress(customAddress); + const standardAddress = addHexPrefix(customAddress).toLowerCase(); switch (true) { case !isValidAddress: @@ -172,54 +172,54 @@ class AddToken extends Component { customDecimals: 0, customSymbolError: null, customDecimalsError: null, - }) + }); - break + break; case Boolean(this.props.identities[standardAddress]): this.setState({ customAddressError: this.context.t('personalAddressDetected'), - }) + }); - break + break; case checkExistingAddresses(customAddress, this.props.tokens): this.setState({ customAddressError: this.context.t('tokenAlreadyAdded'), - }) + }); - break + break; default: if (customAddress !== emptyAddr) { - this.attemptToAutoFillTokenParams(customAddress) + this.attemptToAutoFillTokenParams(customAddress); } } } handleCustomSymbolChange(value) { - const customSymbol = value.trim() - const symbolLength = customSymbol.length - let customSymbolError = null + const customSymbol = value.trim(); + const symbolLength = customSymbol.length; + let customSymbolError = null; if (symbolLength <= 0 || symbolLength >= 12) { - customSymbolError = this.context.t('symbolBetweenZeroTwelve') + customSymbolError = this.context.t('symbolBetweenZeroTwelve'); } - this.setState({ customSymbol, customSymbolError }) + this.setState({ customSymbol, customSymbolError }); } handleCustomDecimalsChange(value) { - const customDecimals = value.trim() + const customDecimals = value.trim(); const validDecimals = customDecimals !== null && customDecimals !== '' && customDecimals >= 0 && - customDecimals <= 36 - let customDecimalsError = null + customDecimals <= 36; + let customDecimalsError = null; if (!validDecimals) { - customDecimalsError = this.context.t('decimalsMustZerotoTen') + customDecimalsError = this.context.t('decimalsMustZerotoTen'); } - this.setState({ customDecimals, customDecimalsError }) + this.setState({ customDecimals, customDecimalsError }); } renderCustomTokenForm() { @@ -232,7 +232,7 @@ class AddToken extends Component { customDecimalsError, autoFilled, forceEditSymbol, - } = this.state + } = this.state; return (
    @@ -284,11 +284,11 @@ class AddToken extends Component { disabled={autoFilled} />
    - ) + ); } renderSearchToken() { - const { tokenSelectorError, selectedTokens, searchResults } = this.state + const { tokenSelectorError, selectedTokens, searchResults } = this.state; return (
    @@ -306,7 +306,7 @@ class AddToken extends Component { />
    - ) + ); } renderTabs() { @@ -317,11 +317,11 @@ class AddToken extends Component { {this.renderCustomTokenForm()} - ) + ); } render() { - const { history, clearPendingTokens, mostRecentOverviewPage } = this.props + const { history, clearPendingTokens, mostRecentOverviewPage } = this.props; return ( this.handleNext()} disabled={Boolean(this.hasError()) || !this.hasSelected()} onCancel={() => { - clearPendingTokens() - history.push(mostRecentOverviewPage) + clearPendingTokens(); + history.push(mostRecentOverviewPage); }} /> - ) + ); } } -export default AddToken +export default AddToken; diff --git a/ui/app/pages/add-token/add-token.container.js b/ui/app/pages/add-token/add-token.container.js index 80059a6898..490b345836 100644 --- a/ui/app/pages/add-token/add-token.container.js +++ b/ui/app/pages/add-token/add-token.container.js @@ -1,26 +1,26 @@ -import { connect } from 'react-redux' +import { connect } from 'react-redux'; -import { setPendingTokens, clearPendingTokens } from '../../store/actions' -import { getMostRecentOverviewPage } from '../../ducks/history/history' -import AddToken from './add-token.component' +import { setPendingTokens, clearPendingTokens } from '../../store/actions'; +import { getMostRecentOverviewPage } from '../../ducks/history/history'; +import AddToken from './add-token.component'; const mapStateToProps = (state) => { const { metamask: { identities, tokens, pendingTokens }, - } = state + } = state; return { identities, mostRecentOverviewPage: getMostRecentOverviewPage(state), tokens, pendingTokens, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { setPendingTokens: (tokens) => dispatch(setPendingTokens(tokens)), clearPendingTokens: () => dispatch(clearPendingTokens()), - } -} + }; +}; -export default connect(mapStateToProps, mapDispatchToProps)(AddToken) +export default connect(mapStateToProps, mapDispatchToProps)(AddToken); diff --git a/ui/app/pages/add-token/index.js b/ui/app/pages/add-token/index.js index ab78bb05d8..e107950f1f 100644 --- a/ui/app/pages/add-token/index.js +++ b/ui/app/pages/add-token/index.js @@ -1,3 +1,3 @@ -import AddToken from './add-token.container' +import AddToken from './add-token.container'; -export default AddToken +export default AddToken; diff --git a/ui/app/pages/add-token/tests/add-token.test.js b/ui/app/pages/add-token/tests/add-token.test.js index 697724dd75..bc130409c8 100644 --- a/ui/app/pages/add-token/tests/add-token.test.js +++ b/ui/app/pages/add-token/tests/add-token.test.js @@ -1,21 +1,21 @@ -import assert from 'assert' -import React from 'react' -import { Provider } from 'react-redux' -import sinon from 'sinon' -import configureMockStore from 'redux-mock-store' -import { mountWithRouter } from '../../../../../test/lib/render-helpers' -import AddToken from '..' +import assert from 'assert'; +import React from 'react'; +import { Provider } from 'react-redux'; +import sinon from 'sinon'; +import configureMockStore from 'redux-mock-store'; +import { mountWithRouter } from '../../../../../test/lib/render-helpers'; +import AddToken from '..'; describe('Add Token', function () { - let wrapper + let wrapper; const state = { metamask: { tokens: [], }, - } + }; - const store = configureMockStore()(state) + const store = configureMockStore()(state); const props = { history: { @@ -26,7 +26,7 @@ describe('Add Token', function () { tokens: [], identities: {}, mostRecentOverviewPage: '/', - } + }; describe('Add Token', function () { before(function () { @@ -35,81 +35,81 @@ describe('Add Token', function () { , store, - ) + ); - wrapper.find({ name: 'customToken' }).simulate('click') - }) + wrapper.find({ name: 'customToken' }).simulate('click'); + }); afterEach(function () { - props.history.push.reset() - }) + props.history.push.reset(); + }); it('next button is disabled when no fields are populated', function () { const nextButton = wrapper.find( '.button.btn-secondary.page-container__footer-button', - ) + ); - assert.strictEqual(nextButton.props().disabled, true) - }) + assert.strictEqual(nextButton.props().disabled, true); + }); it('edits token address', function () { - const tokenAddress = '0x617b3f8050a0BD94b6b1da02B4384eE5B4DF13F4' - const event = { target: { value: tokenAddress } } - const customAddress = wrapper.find('input#custom-address') + const tokenAddress = '0x617b3f8050a0BD94b6b1da02B4384eE5B4DF13F4'; + const event = { target: { value: tokenAddress } }; + const customAddress = wrapper.find('input#custom-address'); - customAddress.simulate('change', event) + customAddress.simulate('change', event); assert.strictEqual( wrapper.find('AddToken').instance().state.customAddress, tokenAddress, - ) - }) + ); + }); it('edits token symbol', function () { - const tokenSymbol = 'META' - const event = { target: { value: tokenSymbol } } - const customAddress = wrapper.find('#custom-symbol') - customAddress.last().simulate('change', event) + const tokenSymbol = 'META'; + const event = { target: { value: tokenSymbol } }; + const customAddress = wrapper.find('#custom-symbol'); + customAddress.last().simulate('change', event); assert.strictEqual( wrapper.find('AddToken').instance().state.customSymbol, tokenSymbol, - ) - }) + ); + }); it('edits token decimal precision', function () { - const tokenPrecision = '2' - const event = { target: { value: tokenPrecision } } - const customAddress = wrapper.find('#custom-decimals') - customAddress.last().simulate('change', event) + const tokenPrecision = '2'; + const event = { target: { value: tokenPrecision } }; + const customAddress = wrapper.find('#custom-decimals'); + customAddress.last().simulate('change', event); assert.strictEqual( wrapper.find('AddToken').instance().state.customDecimals, tokenPrecision, - ) - }) + ); + }); it('next', function () { const nextButton = wrapper.find( '.button.btn-secondary.page-container__footer-button', - ) - nextButton.simulate('click') + ); + nextButton.simulate('click'); - assert(props.setPendingTokens.calledOnce) - assert(props.history.push.calledOnce) + assert(props.setPendingTokens.calledOnce); + assert(props.history.push.calledOnce); assert.strictEqual( props.history.push.getCall(0).args[0], '/confirm-add-token', - ) - }) + ); + }); it('cancels', function () { const cancelButton = wrapper.find( 'button.btn-default.page-container__footer-button', - ) - cancelButton.simulate('click') - - assert(props.clearPendingTokens.calledOnce) - assert.strictEqual(props.history.push.getCall(0).args[0], '/') - }) - }) -}) + ); + cancelButton.simulate('click'); + + assert(props.clearPendingTokens.calledOnce); + assert.strictEqual(props.history.push.getCall(0).args[0], '/'); + }); + }); +}); diff --git a/ui/app/pages/add-token/token-list/index.js b/ui/app/pages/add-token/token-list/index.js index 6174857284..638d76a973 100644 --- a/ui/app/pages/add-token/token-list/index.js +++ b/ui/app/pages/add-token/token-list/index.js @@ -1,3 +1,3 @@ -import TokenList from './token-list.container' +import TokenList from './token-list.container'; -export default TokenList +export default TokenList; diff --git a/ui/app/pages/add-token/token-list/token-list-placeholder/index.js b/ui/app/pages/add-token/token-list/token-list-placeholder/index.js index 395e7b077f..b23d23a295 100644 --- a/ui/app/pages/add-token/token-list/token-list-placeholder/index.js +++ b/ui/app/pages/add-token/token-list/token-list-placeholder/index.js @@ -1,3 +1,3 @@ -import TokenListPlaceholder from './token-list-placeholder.component' +import TokenListPlaceholder from './token-list-placeholder.component'; -export default TokenListPlaceholder +export default TokenListPlaceholder; diff --git a/ui/app/pages/add-token/token-list/token-list-placeholder/token-list-placeholder.component.js b/ui/app/pages/add-token/token-list/token-list-placeholder/token-list-placeholder.component.js index 1cefea294c..75cef89d1f 100644 --- a/ui/app/pages/add-token/token-list/token-list-placeholder/token-list-placeholder.component.js +++ b/ui/app/pages/add-token/token-list/token-list-placeholder/token-list-placeholder.component.js @@ -1,11 +1,11 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import Button from '../../../../components/ui/button' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import Button from '../../../../components/ui/button'; export default class TokenListPlaceholder extends Component { static contextTypes = { t: PropTypes.func, - } + }; render() { return ( @@ -24,6 +24,6 @@ export default class TokenListPlaceholder extends Component { {this.context.t('learnMore')} - ) + ); } } diff --git a/ui/app/pages/add-token/token-list/token-list.component.js b/ui/app/pages/add-token/token-list/token-list.component.js index 54006136e9..819be41734 100644 --- a/ui/app/pages/add-token/token-list/token-list.component.js +++ b/ui/app/pages/add-token/token-list/token-list.component.js @@ -1,20 +1,20 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { checkExistingAddresses } from '../../../helpers/utils/util' -import TokenListPlaceholder from './token-list-placeholder' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import { checkExistingAddresses } from '../../../helpers/utils/util'; +import TokenListPlaceholder from './token-list-placeholder'; export default class TokenList extends Component { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { tokens: PropTypes.array, results: PropTypes.array, selectedTokens: PropTypes.object, onToggleToken: PropTypes.func, - } + }; render() { const { @@ -22,7 +22,7 @@ export default class TokenList extends Component { selectedTokens = {}, onToggleToken, tokens = [], - } = this.props + } = this.props; return results.length === 0 ? ( @@ -35,10 +35,10 @@ export default class TokenList extends Component { {Array(6) .fill(undefined) .map((_, i) => { - const { logo, symbol, name, address } = results[i] || {} - const tokenAlreadyAdded = checkExistingAddresses(address, tokens) + const { logo, symbol, name, address } = results[i] || {}; + const tokenAlreadyAdded = checkExistingAddresses(address, tokens); const onClick = () => - !tokenAlreadyAdded && onToggleToken(results[i]) + !tokenAlreadyAdded && onToggleToken(results[i]); return ( Boolean(logo || symbol || name) && ( @@ -63,10 +63,10 @@ export default class TokenList extends Component { ) - ) + ); })} - ) + ); } } diff --git a/ui/app/pages/add-token/token-list/token-list.container.js b/ui/app/pages/add-token/token-list/token-list.container.js index cd7b07a378..4896067f7b 100644 --- a/ui/app/pages/add-token/token-list/token-list.container.js +++ b/ui/app/pages/add-token/token-list/token-list.container.js @@ -1,11 +1,11 @@ -import { connect } from 'react-redux' -import TokenList from './token-list.component' +import { connect } from 'react-redux'; +import TokenList from './token-list.component'; const mapStateToProps = ({ metamask }) => { - const { tokens } = metamask + const { tokens } = metamask; return { tokens, - } -} + }; +}; -export default connect(mapStateToProps)(TokenList) +export default connect(mapStateToProps)(TokenList); diff --git a/ui/app/pages/add-token/token-search/index.js b/ui/app/pages/add-token/token-search/index.js index bec39b3cf7..59aee97445 100644 --- a/ui/app/pages/add-token/token-search/index.js +++ b/ui/app/pages/add-token/token-search/index.js @@ -1,3 +1,3 @@ -import TokenSearch from './token-search.component' +import TokenSearch from './token-search.component'; -export default TokenSearch +export default TokenSearch; diff --git a/ui/app/pages/add-token/token-search/token-search.component.js b/ui/app/pages/add-token/token-search/token-search.component.js index 8b889b0575..f58ca299f7 100644 --- a/ui/app/pages/add-token/token-search/token-search.component.js +++ b/ui/app/pages/add-token/token-search/token-search.component.js @@ -1,13 +1,13 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import contractMap from '@metamask/contract-metadata' -import Fuse from 'fuse.js' -import InputAdornment from '@material-ui/core/InputAdornment' -import TextField from '../../../components/ui/text-field' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import contractMap from '@metamask/contract-metadata'; +import Fuse from 'fuse.js'; +import InputAdornment from '@material-ui/core/InputAdornment'; +import TextField from '../../../components/ui/text-field'; const contractList = Object.entries(contractMap) .map(([address, tokenData]) => ({ ...tokenData, address })) - .filter((tokenData) => Boolean(tokenData.erc20)) + .filter((tokenData) => Boolean(tokenData.erc20)); const fuse = new Fuse(contractList, { shouldSort: true, @@ -20,34 +20,34 @@ const fuse = new Fuse(contractList, { { name: 'name', weight: 0.5 }, { name: 'symbol', weight: 0.5 }, ], -}) +}); export default class TokenSearch extends Component { static contextTypes = { t: PropTypes.func, - } + }; static defaultProps = { error: null, - } + }; static propTypes = { onSearch: PropTypes.func, error: PropTypes.string, - } + }; state = { searchQuery: '', - } + }; handleSearch(searchQuery) { - this.setState({ searchQuery }) - const fuseSearchResult = fuse.search(searchQuery) + this.setState({ searchQuery }); + const fuseSearchResult = fuse.search(searchQuery); const addressSearchResult = contractList.filter((token) => { - return token.address.toLowerCase() === searchQuery.toLowerCase() - }) - const results = [...addressSearchResult, ...fuseSearchResult] - this.props.onSearch({ searchQuery, results }) + return token.address.toLowerCase() === searchQuery.toLowerCase(); + }); + const results = [...addressSearchResult, ...fuseSearchResult]; + this.props.onSearch({ searchQuery, results }); } renderAdornment() { @@ -55,12 +55,12 @@ export default class TokenSearch extends Component { - ) + ); } render() { - const { error } = this.props - const { searchQuery } = this.state + const { error } = this.props; + const { searchQuery } = this.state; return ( - ) + ); } } diff --git a/ui/app/pages/asset/asset.js b/ui/app/pages/asset/asset.js index 22baaf68a5..cafdb2285c 100644 --- a/ui/app/pages/asset/asset.js +++ b/ui/app/pages/asset/asset.js @@ -1,28 +1,28 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import { Redirect, useParams } from 'react-router-dom' -import { getTokens } from '../../ducks/metamask/metamask' -import { DEFAULT_ROUTE } from '../../helpers/constants/routes' +import React from 'react'; +import { useSelector } from 'react-redux'; +import { Redirect, useParams } from 'react-router-dom'; +import { getTokens } from '../../ducks/metamask/metamask'; +import { DEFAULT_ROUTE } from '../../helpers/constants/routes'; -import NativeAsset from './components/native-asset' -import TokenAsset from './components/token-asset' +import NativeAsset from './components/native-asset'; +import TokenAsset from './components/token-asset'; const Asset = () => { - const nativeCurrency = useSelector((state) => state.metamask.nativeCurrency) - const tokens = useSelector(getTokens) - const { asset } = useParams() + const nativeCurrency = useSelector((state) => state.metamask.nativeCurrency); + const tokens = useSelector(getTokens); + const { asset } = useParams(); - const token = tokens.find(({ address }) => address === asset) + const token = tokens.find(({ address }) => address === asset); - let content + let content; if (token) { - content = + content = ; } else if (asset === nativeCurrency) { - content = + content = ; } else { - content = + content = ; } - return
    {content}
    -} + return
    {content}
    ; +}; -export default Asset +export default Asset; diff --git a/ui/app/pages/asset/components/asset-breadcrumb.js b/ui/app/pages/asset/components/asset-breadcrumb.js index a081e5b369..ac11054c3f 100644 --- a/ui/app/pages/asset/components/asset-breadcrumb.js +++ b/ui/app/pages/asset/components/asset-breadcrumb.js @@ -1,5 +1,5 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; const AssetBreadcrumb = ({ accountName, assetName, onBack }) => { return ( @@ -12,13 +12,13 @@ const AssetBreadcrumb = ({ accountName, assetName, onBack }) => {  /  {assetName} - ) -} + ); +}; AssetBreadcrumb.propTypes = { accountName: PropTypes.string.isRequired, assetName: PropTypes.string.isRequired, onBack: PropTypes.func.isRequired, -} +}; -export default AssetBreadcrumb +export default AssetBreadcrumb; diff --git a/ui/app/pages/asset/components/asset-navigation.js b/ui/app/pages/asset/components/asset-navigation.js index 2af0fac828..75789afbf2 100644 --- a/ui/app/pages/asset/components/asset-navigation.js +++ b/ui/app/pages/asset/components/asset-navigation.js @@ -1,7 +1,7 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; -import AssetBreadcrumb from './asset-breadcrumb' +import AssetBreadcrumb from './asset-breadcrumb'; const AssetNavigation = ({ accountName, assetName, onBack, optionsButton }) => { return ( @@ -13,18 +13,18 @@ const AssetNavigation = ({ accountName, assetName, onBack, optionsButton }) => { /> {optionsButton} - ) -} + ); +}; AssetNavigation.propTypes = { accountName: PropTypes.string.isRequired, assetName: PropTypes.string.isRequired, onBack: PropTypes.func.isRequired, optionsButton: PropTypes.element, -} +}; AssetNavigation.defaultProps = { optionsButton: undefined, -} +}; -export default AssetNavigation +export default AssetNavigation; diff --git a/ui/app/pages/asset/components/native-asset.js b/ui/app/pages/asset/components/native-asset.js index cb7f857503..629609e921 100644 --- a/ui/app/pages/asset/components/native-asset.js +++ b/ui/app/pages/asset/components/native-asset.js @@ -1,20 +1,20 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { useSelector } from 'react-redux' -import { useHistory } from 'react-router-dom' +import React from 'react'; +import PropTypes from 'prop-types'; +import { useSelector } from 'react-redux'; +import { useHistory } from 'react-router-dom'; -import TransactionList from '../../../components/app/transaction-list' -import { EthOverview } from '../../../components/app/wallet-overview' -import { getSelectedIdentity } from '../../../selectors/selectors' -import { DEFAULT_ROUTE } from '../../../helpers/constants/routes' +import TransactionList from '../../../components/app/transaction-list'; +import { EthOverview } from '../../../components/app/wallet-overview'; +import { getSelectedIdentity } from '../../../selectors/selectors'; +import { DEFAULT_ROUTE } from '../../../helpers/constants/routes'; -import AssetNavigation from './asset-navigation' +import AssetNavigation from './asset-navigation'; export default function NativeAsset({ nativeCurrency }) { const selectedAccountName = useSelector( (state) => getSelectedIdentity(state).name, - ) - const history = useHistory() + ); + const history = useHistory(); return ( <> @@ -26,9 +26,9 @@ export default function NativeAsset({ nativeCurrency }) { - ) + ); } NativeAsset.propTypes = { nativeCurrency: PropTypes.string.isRequired, -} +}; diff --git a/ui/app/pages/asset/components/token-asset.js b/ui/app/pages/asset/components/token-asset.js index 00296a59e8..4c6647ec4b 100644 --- a/ui/app/pages/asset/components/token-asset.js +++ b/ui/app/pages/asset/components/token-asset.js @@ -1,28 +1,28 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { useDispatch, useSelector } from 'react-redux' -import { useHistory } from 'react-router-dom' -import { createTokenTrackerLink } from '@metamask/etherscan-link' +import React from 'react'; +import PropTypes from 'prop-types'; +import { useDispatch, useSelector } from 'react-redux'; +import { useHistory } from 'react-router-dom'; +import { createTokenTrackerLink } from '@metamask/etherscan-link'; -import TransactionList from '../../../components/app/transaction-list' -import { TokenOverview } from '../../../components/app/wallet-overview' +import TransactionList from '../../../components/app/transaction-list'; +import { TokenOverview } from '../../../components/app/wallet-overview'; import { getCurrentNetworkId, getSelectedIdentity, -} from '../../../selectors/selectors' -import { DEFAULT_ROUTE } from '../../../helpers/constants/routes' -import { showModal } from '../../../store/actions' +} from '../../../selectors/selectors'; +import { DEFAULT_ROUTE } from '../../../helpers/constants/routes'; +import { showModal } from '../../../store/actions'; -import AssetNavigation from './asset-navigation' -import TokenOptions from './token-options' +import AssetNavigation from './asset-navigation'; +import TokenOptions from './token-options'; export default function TokenAsset({ token }) { - const dispatch = useDispatch() - const network = useSelector(getCurrentNetworkId) - const selectedIdentity = useSelector(getSelectedIdentity) - const selectedAccountName = selectedIdentity.name - const selectedAddress = selectedIdentity.address - const history = useHistory() + const dispatch = useDispatch(); + const network = useSelector(getCurrentNetworkId); + const selectedIdentity = useSelector(getSelectedIdentity); + const selectedAccountName = selectedIdentity.name; + const selectedAddress = selectedIdentity.address; + const history = useHistory(); return ( <> @@ -40,8 +40,8 @@ export default function TokenAsset({ token }) { token.address, network, selectedAddress, - ) - global.platform.openTab({ url }) + ); + global.platform.openTab({ url }); }} tokenSymbol={token.symbol} /> @@ -50,7 +50,7 @@ export default function TokenAsset({ token }) { - ) + ); } TokenAsset.propTypes = { @@ -59,4 +59,4 @@ TokenAsset.propTypes = { decimals: PropTypes.number, symbol: PropTypes.string, }).isRequired, -} +}; diff --git a/ui/app/pages/asset/components/token-options.js b/ui/app/pages/asset/components/token-options.js index 613455f572..51b18079a7 100644 --- a/ui/app/pages/asset/components/token-options.js +++ b/ui/app/pages/asset/components/token-options.js @@ -1,15 +1,15 @@ -import React, { useContext, useState } from 'react' -import PropTypes from 'prop-types' +import React, { useContext, useState } from 'react'; +import PropTypes from 'prop-types'; -import { I18nContext } from '../../../contexts/i18n' -import { Menu, MenuItem } from '../../../components/ui/menu' +import { I18nContext } from '../../../contexts/i18n'; +import { Menu, MenuItem } from '../../../components/ui/menu'; const TokenOptions = ({ onRemove, onViewEtherscan, tokenSymbol }) => { - const t = useContext(I18nContext) + const t = useContext(I18nContext); const [tokenOptionsButtonElement, setTokenOptionsButtonElement] = useState( null, - ) - const [tokenOptionsOpen, setTokenOptionsOpen] = useState(false) + ); + const [tokenOptionsOpen, setTokenOptionsOpen] = useState(false); return ( <> @@ -29,8 +29,8 @@ const TokenOptions = ({ onRemove, onViewEtherscan, tokenSymbol }) => { iconClassName="fas fa-external-link-alt token-options__icon" data-testid="token-options__etherscan" onClick={() => { - setTokenOptionsOpen(false) - onViewEtherscan() + setTokenOptionsOpen(false); + onViewEtherscan(); }} > {t('viewOnEtherscan')} @@ -39,8 +39,8 @@ const TokenOptions = ({ onRemove, onViewEtherscan, tokenSymbol }) => { iconClassName="fas fa-trash-alt token-options__icon" data-testid="token-options__hide" onClick={() => { - setTokenOptionsOpen(false) - onRemove() + setTokenOptionsOpen(false); + onRemove(); }} > {t('hideTokenSymbol', [tokenSymbol])} @@ -48,13 +48,13 @@ const TokenOptions = ({ onRemove, onViewEtherscan, tokenSymbol }) => { ) : null} - ) -} + ); +}; TokenOptions.propTypes = { onRemove: PropTypes.func.isRequired, onViewEtherscan: PropTypes.func.isRequired, tokenSymbol: PropTypes.string.isRequired, -} +}; -export default TokenOptions +export default TokenOptions; diff --git a/ui/app/pages/asset/index.js b/ui/app/pages/asset/index.js index c8aeeec70d..851200aa65 100644 --- a/ui/app/pages/asset/index.js +++ b/ui/app/pages/asset/index.js @@ -1 +1 @@ -export { default } from './asset' +export { default } from './asset'; diff --git a/ui/app/pages/confirm-add-suggested-token/confirm-add-suggested-token.component.js b/ui/app/pages/confirm-add-suggested-token/confirm-add-suggested-token.component.js index b65af863b7..5c8c0e1d6b 100644 --- a/ui/app/pages/confirm-add-suggested-token/confirm-add-suggested-token.component.js +++ b/ui/app/pages/confirm-add-suggested-token/confirm-add-suggested-token.component.js @@ -1,16 +1,16 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import Button from '../../components/ui/button' -import Identicon from '../../components/ui/identicon' -import TokenBalance from '../../components/ui/token-balance' -import { getEnvironmentType } from '../../../../app/scripts/lib/util' -import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../shared/constants/app' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import Button from '../../components/ui/button'; +import Identicon from '../../components/ui/identicon'; +import TokenBalance from '../../components/ui/token-balance'; +import { getEnvironmentType } from '../../../../app/scripts/lib/util'; +import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../shared/constants/app'; export default class ConfirmAddSuggestedToken extends Component { static contextTypes = { t: PropTypes.func, trackEvent: PropTypes.func, - } + }; static propTypes = { history: PropTypes.object, @@ -19,32 +19,32 @@ export default class ConfirmAddSuggestedToken extends Component { pendingTokens: PropTypes.object, removeSuggestedTokens: PropTypes.func, tokens: PropTypes.array, - } + }; componentDidMount() { - this._checkPendingTokens() + this._checkPendingTokens(); } componentDidUpdate() { - this._checkPendingTokens() + this._checkPendingTokens(); } _checkPendingTokens() { - const { mostRecentOverviewPage, pendingTokens = {}, history } = this.props + const { mostRecentOverviewPage, pendingTokens = {}, history } = this.props; if (Object.keys(pendingTokens).length > 0) { - return + return; } if (getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION) { - global.platform.closeCurrentWindow() + global.platform.closeCurrentWindow(); } else { - history.push(mostRecentOverviewPage) + history.push(mostRecentOverviewPage); } } getTokenName(name, symbol) { - return typeof name === 'undefined' ? symbol : `${name} (${symbol})` + return typeof name === 'undefined' ? symbol : `${name} (${symbol})`; } render() { @@ -55,11 +55,11 @@ export default class ConfirmAddSuggestedToken extends Component { removeSuggestedTokens, history, mostRecentOverviewPage, - } = this.props - const pendingTokenKey = Object.keys(pendingTokens)[0] - const pendingToken = pendingTokens[pendingTokenKey] - const hasTokenDuplicates = this.checkTokenDuplicates(pendingTokens, tokens) - const reusesName = this.checkNameReuse(pendingTokens, tokens) + } = this.props; + const pendingTokenKey = Object.keys(pendingTokens)[0]; + const pendingToken = pendingTokens[pendingTokenKey]; + const hasTokenDuplicates = this.checkTokenDuplicates(pendingTokens, tokens); + const reusesName = this.checkNameReuse(pendingTokens, tokens); return (
    @@ -91,7 +91,7 @@ export default class ConfirmAddSuggestedToken extends Component {
    {Object.entries(pendingTokens).map(([address, token]) => { - const { name, symbol, image } = token + const { name, symbol, image } = token; return (
    - ) + ); })} @@ -127,7 +127,7 @@ export default class ConfirmAddSuggestedToken extends Component { onClick={() => { removeSuggestedTokens().then(() => history.push(mostRecentOverviewPage), - ) + ); }} > {this.context.t('cancel')} @@ -151,9 +151,9 @@ export default class ConfirmAddSuggestedToken extends Component { unlisted: pendingToken.unlisted, source: 'dapp', }, - }) + }); }) - .then(() => history.push(mostRecentOverviewPage)) + .then(() => history.push(mostRecentOverviewPage)); }} > {this.context.t('addToken')} @@ -161,17 +161,17 @@ export default class ConfirmAddSuggestedToken extends Component { - ) + ); } checkTokenDuplicates(pendingTokens, tokens) { - const pending = Object.keys(pendingTokens) - const existing = tokens.map((token) => token.address) + const pending = Object.keys(pendingTokens); + const existing = tokens.map((token) => token.address); const dupes = pending.filter((proposed) => { - return existing.includes(proposed) - }) + return existing.includes(proposed); + }); - return dupes.length > 0 + return dupes.length > 0; } /** @@ -186,9 +186,9 @@ export default class ConfirmAddSuggestedToken extends Component { .filter((token) => { const dupes = tokens .filter((old) => old.symbol === token.symbol) - .filter((old) => old.address !== token.address) - return dupes.length > 0 - }) - return duplicates.length > 0 + .filter((old) => old.address !== token.address); + return dupes.length > 0; + }); + return duplicates.length > 0; } } diff --git a/ui/app/pages/confirm-add-suggested-token/confirm-add-suggested-token.container.js b/ui/app/pages/confirm-add-suggested-token/confirm-add-suggested-token.container.js index 51a29a555c..ae7eb131fb 100644 --- a/ui/app/pages/confirm-add-suggested-token/confirm-add-suggested-token.container.js +++ b/ui/app/pages/confirm-add-suggested-token/confirm-add-suggested-token.container.js @@ -1,32 +1,32 @@ -import { connect } from 'react-redux' -import { compose } from 'redux' -import { withRouter } from 'react-router-dom' -import { addToken, removeSuggestedTokens } from '../../store/actions' -import { getMostRecentOverviewPage } from '../../ducks/history/history' -import ConfirmAddSuggestedToken from './confirm-add-suggested-token.component' +import { connect } from 'react-redux'; +import { compose } from 'redux'; +import { withRouter } from 'react-router-dom'; +import { addToken, removeSuggestedTokens } from '../../store/actions'; +import { getMostRecentOverviewPage } from '../../ducks/history/history'; +import ConfirmAddSuggestedToken from './confirm-add-suggested-token.component'; const mapStateToProps = (state) => { const { metamask: { pendingTokens, suggestedTokens, tokens }, - } = state - const params = { ...pendingTokens, ...suggestedTokens } + } = state; + const params = { ...pendingTokens, ...suggestedTokens }; return { mostRecentOverviewPage: getMostRecentOverviewPage(state), pendingTokens: params, tokens, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { addToken: ({ address, symbol, decimals, image }) => dispatch(addToken(address, symbol, Number(decimals), image)), removeSuggestedTokens: () => dispatch(removeSuggestedTokens()), - } -} + }; +}; export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps), -)(ConfirmAddSuggestedToken) +)(ConfirmAddSuggestedToken); diff --git a/ui/app/pages/confirm-add-suggested-token/index.js b/ui/app/pages/confirm-add-suggested-token/index.js index 275e0287ba..e04fe003b0 100644 --- a/ui/app/pages/confirm-add-suggested-token/index.js +++ b/ui/app/pages/confirm-add-suggested-token/index.js @@ -1,3 +1,3 @@ -import ConfirmAddSuggestedToken from './confirm-add-suggested-token.container' +import ConfirmAddSuggestedToken from './confirm-add-suggested-token.container'; -export default ConfirmAddSuggestedToken +export default ConfirmAddSuggestedToken; diff --git a/ui/app/pages/confirm-add-token/confirm-add-token.component.js b/ui/app/pages/confirm-add-token/confirm-add-token.component.js index 4334f377af..fed9a60e49 100644 --- a/ui/app/pages/confirm-add-token/confirm-add-token.component.js +++ b/ui/app/pages/confirm-add-token/confirm-add-token.component.js @@ -1,15 +1,15 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import { ASSET_ROUTE, ADD_TOKEN_ROUTE } from '../../helpers/constants/routes' -import Button from '../../components/ui/button' -import Identicon from '../../components/ui/identicon' -import TokenBalance from '../../components/ui/token-balance' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { ASSET_ROUTE, ADD_TOKEN_ROUTE } from '../../helpers/constants/routes'; +import Button from '../../components/ui/button'; +import Identicon from '../../components/ui/identicon'; +import TokenBalance from '../../components/ui/token-balance'; export default class ConfirmAddToken extends Component { static contextTypes = { t: PropTypes.func, trackEvent: PropTypes.func, - } + }; static propTypes = { history: PropTypes.object, @@ -17,18 +17,18 @@ export default class ConfirmAddToken extends Component { addTokens: PropTypes.func, mostRecentOverviewPage: PropTypes.string.isRequired, pendingTokens: PropTypes.object, - } + }; componentDidMount() { - const { mostRecentOverviewPage, pendingTokens = {}, history } = this.props + const { mostRecentOverviewPage, pendingTokens = {}, history } = this.props; if (Object.keys(pendingTokens).length === 0) { - history.push(mostRecentOverviewPage) + history.push(mostRecentOverviewPage); } } getTokenName(name, symbol) { - return typeof name === 'undefined' ? symbol : `${name} (${symbol})` + return typeof name === 'undefined' ? symbol : `${name} (${symbol})`; } render() { @@ -38,7 +38,7 @@ export default class ConfirmAddToken extends Component { clearPendingTokens, mostRecentOverviewPage, pendingTokens, - } = this.props + } = this.props; return (
    @@ -62,7 +62,7 @@ export default class ConfirmAddToken extends Component {
    {Object.entries(pendingTokens).map(([address, token]) => { - const { name, symbol } = token + const { name, symbol } = token; return (
    - ) + ); })} @@ -104,7 +104,7 @@ export default class ConfirmAddToken extends Component { className="page-container__footer-button" onClick={() => { addTokens(pendingTokens).then(() => { - const pendingTokenValues = Object.values(pendingTokens) + const pendingTokenValues = Object.values(pendingTokens); pendingTokenValues.forEach((pendingToken) => { this.context.trackEvent({ event: 'Token Added', @@ -116,16 +116,16 @@ export default class ConfirmAddToken extends Component { unlisted: pendingToken.unlisted, source: pendingToken.isCustom ? 'custom' : 'list', }, - }) - }) - clearPendingTokens() - const firstTokenAddress = pendingTokenValues?.[0].address?.toLowerCase() + }); + }); + clearPendingTokens(); + const firstTokenAddress = pendingTokenValues?.[0].address?.toLowerCase(); if (firstTokenAddress) { - history.push(`${ASSET_ROUTE}/${firstTokenAddress}`) + history.push(`${ASSET_ROUTE}/${firstTokenAddress}`); } else { - history.push(mostRecentOverviewPage) + history.push(mostRecentOverviewPage); } - }) + }); }} > {this.context.t('addTokens')} @@ -133,6 +133,6 @@ export default class ConfirmAddToken extends Component { - ) + ); } } diff --git a/ui/app/pages/confirm-add-token/confirm-add-token.container.js b/ui/app/pages/confirm-add-token/confirm-add-token.container.js index 08a01163c7..aef46d2619 100644 --- a/ui/app/pages/confirm-add-token/confirm-add-token.container.js +++ b/ui/app/pages/confirm-add-token/confirm-add-token.container.js @@ -1,24 +1,24 @@ -import { connect } from 'react-redux' +import { connect } from 'react-redux'; -import { addTokens, clearPendingTokens } from '../../store/actions' -import { getMostRecentOverviewPage } from '../../ducks/history/history' -import ConfirmAddToken from './confirm-add-token.component' +import { addTokens, clearPendingTokens } from '../../store/actions'; +import { getMostRecentOverviewPage } from '../../ducks/history/history'; +import ConfirmAddToken from './confirm-add-token.component'; const mapStateToProps = (state) => { const { metamask: { pendingTokens }, - } = state + } = state; return { mostRecentOverviewPage: getMostRecentOverviewPage(state), pendingTokens, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { addTokens: (tokens) => dispatch(addTokens(tokens)), clearPendingTokens: () => dispatch(clearPendingTokens()), - } -} + }; +}; -export default connect(mapStateToProps, mapDispatchToProps)(ConfirmAddToken) +export default connect(mapStateToProps, mapDispatchToProps)(ConfirmAddToken); diff --git a/ui/app/pages/confirm-add-token/index.js b/ui/app/pages/confirm-add-token/index.js index f6b9cc47c4..8b399cdcaf 100644 --- a/ui/app/pages/confirm-add-token/index.js +++ b/ui/app/pages/confirm-add-token/index.js @@ -1,3 +1,3 @@ -import ConfirmAddToken from './confirm-add-token.container' +import ConfirmAddToken from './confirm-add-token.container'; -export default ConfirmAddToken +export default ConfirmAddToken; diff --git a/ui/app/pages/confirm-approve/confirm-approve-content/confirm-approve-content.component.js b/ui/app/pages/confirm-approve/confirm-approve-content/confirm-approve-content.component.js index 78fe41fe71..42798fcd61 100644 --- a/ui/app/pages/confirm-approve/confirm-approve-content/confirm-approve-content.component.js +++ b/ui/app/pages/confirm-approve/confirm-approve-content/confirm-approve-content.component.js @@ -1,14 +1,14 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import Identicon from '../../../components/ui/identicon' -import { addressSummary } from '../../../helpers/utils/util' -import { formatCurrency } from '../../../helpers/utils/confirm-tx.util' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import Identicon from '../../../components/ui/identicon'; +import { addressSummary } from '../../../helpers/utils/util'; +import { formatCurrency } from '../../../helpers/utils/confirm-tx.util'; export default class ConfirmApproveContent extends Component { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { decimals: PropTypes.number, @@ -27,11 +27,11 @@ export default class ConfirmApproveContent extends Component { nativeCurrency: PropTypes.string, fiatTransactionTotal: PropTypes.string, ethTransactionTotal: PropTypes.string, - } + }; state = { showFullTxDetails: false, - } + }; renderApproveContentCard({ symbol, @@ -68,18 +68,18 @@ export default class ConfirmApproveContent extends Component {
    {content}
    {footer} - ) + ); } // TODO: Add "Learn Why" with link to the feeAssociatedRequest text renderTransactionDetailsContent() { - const { t } = this.context + const { t } = this.context; const { currentCurrency, nativeCurrency, ethTransactionTotal, fiatTransactionTotal, - } = this.props + } = this.props; return (
    @@ -94,18 +94,18 @@ export default class ConfirmApproveContent extends Component {
    - ) + ); } renderPermissionContent() { - const { t } = this.context + const { t } = this.context; const { customTokenAmount, tokenAmount, tokenSymbol, origin, toAddress, - } = this.props + } = this.props; return (
    @@ -129,12 +129,12 @@ export default class ConfirmApproveContent extends Component {
    - ) + ); } renderDataContent() { - const { t } = this.context - const { data } = this.props + const { t } = this.context; + const { data } = this.props; return (
    @@ -144,11 +144,11 @@ export default class ConfirmApproveContent extends Component { {data}
    - ) + ); } render() { - const { t } = this.context + const { t } = this.context; const { decimals, siteImage, @@ -160,8 +160,8 @@ export default class ConfirmApproveContent extends Component { showEditApprovalPermissionModal, setCustomAmount, tokenBalance, - } = this.props - const { showFullTxDetails } = this.state + } = this.props; + const { showFullTxDetails } = this.state; return (
    ) : null}
    - ) + ); } } diff --git a/ui/app/pages/confirm-approve/confirm-approve-content/index.js b/ui/app/pages/confirm-approve/confirm-approve-content/index.js index 8f225387a2..b9d1c36509 100644 --- a/ui/app/pages/confirm-approve/confirm-approve-content/index.js +++ b/ui/app/pages/confirm-approve/confirm-approve-content/index.js @@ -1 +1 @@ -export { default } from './confirm-approve-content.component' +export { default } from './confirm-approve-content.component'; diff --git a/ui/app/pages/confirm-approve/confirm-approve.js b/ui/app/pages/confirm-approve/confirm-approve.js index 9b8d7abdeb..bb9cb6cccc 100644 --- a/ui/app/pages/confirm-approve/confirm-approve.js +++ b/ui/app/pages/confirm-approve/confirm-approve.js @@ -1,91 +1,91 @@ -import React, { useEffect, useRef, useState } from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { useParams } from 'react-router-dom' -import ConfirmTransactionBase from '../confirm-transaction-base' -import { showModal } from '../../store/actions' -import { getTokenData } from '../../helpers/utils/transactions.util' +import React, { useEffect, useRef, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { useParams } from 'react-router-dom'; +import ConfirmTransactionBase from '../confirm-transaction-base'; +import { showModal } from '../../store/actions'; +import { getTokenData } from '../../helpers/utils/transactions.util'; import { calcTokenAmount, getTokenAddressParam, getTokenValueParam, -} from '../../helpers/utils/token-util' -import { useTokenTracker } from '../../hooks/useTokenTracker' -import { getTokens } from '../../ducks/metamask/metamask' +} from '../../helpers/utils/token-util'; +import { useTokenTracker } from '../../hooks/useTokenTracker'; +import { getTokens } from '../../ducks/metamask/metamask'; import { transactionFeeSelector, txDataSelector, getCurrentCurrency, getDomainMetadata, getNativeCurrency, -} from '../../selectors' -import { currentNetworkTxListSelector } from '../../selectors/transactions' -import { getCustomTxParamsData } from './confirm-approve.util' -import ConfirmApproveContent from './confirm-approve-content' +} from '../../selectors'; +import { currentNetworkTxListSelector } from '../../selectors/transactions'; +import { getCustomTxParamsData } from './confirm-approve.util'; +import ConfirmApproveContent from './confirm-approve-content'; export default function ConfirmApprove() { - const dispatch = useDispatch() - const { id: paramsTransactionId } = useParams() + const dispatch = useDispatch(); + const { id: paramsTransactionId } = useParams(); const { id: transactionId, txParams: { to: tokenAddress, data } = {}, - } = useSelector(txDataSelector) + } = useSelector(txDataSelector); - const currentCurrency = useSelector(getCurrentCurrency) - const nativeCurrency = useSelector(getNativeCurrency) - const currentNetworkTxList = useSelector(currentNetworkTxListSelector) - const domainMetadata = useSelector(getDomainMetadata) - const tokens = useSelector(getTokens) + const currentCurrency = useSelector(getCurrentCurrency); + const nativeCurrency = useSelector(getNativeCurrency); + const currentNetworkTxList = useSelector(currentNetworkTxListSelector); + const domainMetadata = useSelector(getDomainMetadata); + const tokens = useSelector(getTokens); const transaction = currentNetworkTxList.find( ({ id }) => id === (Number(paramsTransactionId) || transactionId), - ) || {} + ) || {}; const { ethTransactionTotal, fiatTransactionTotal } = useSelector((state) => transactionFeeSelector(state, transaction), - ) + ); const currentToken = (tokens && tokens.find(({ address }) => tokenAddress === address)) || { address: tokenAddress, - } + }; - const { tokensWithBalances } = useTokenTracker([currentToken]) - const tokenTrackerBalance = tokensWithBalances[0]?.balance || '' + const { tokensWithBalances } = useTokenTracker([currentToken]); + const tokenTrackerBalance = tokensWithBalances[0]?.balance || ''; - const tokenSymbol = currentToken?.symbol - const decimals = Number(currentToken?.decimals) - const tokenData = getTokenData(data) - const tokenValue = getTokenValueParam(tokenData) - const toAddress = getTokenAddressParam(tokenData) + const tokenSymbol = currentToken?.symbol; + const decimals = Number(currentToken?.decimals); + const tokenData = getTokenData(data); + const tokenValue = getTokenValueParam(tokenData); + const toAddress = getTokenAddressParam(tokenData); const tokenAmount = - tokenData && calcTokenAmount(tokenValue, decimals).toString(10) + tokenData && calcTokenAmount(tokenValue, decimals).toString(10); - const [customPermissionAmount, setCustomPermissionAmount] = useState('') + const [customPermissionAmount, setCustomPermissionAmount] = useState(''); - const previousTokenAmount = useRef(tokenAmount) + const previousTokenAmount = useRef(tokenAmount); useEffect(() => { if (customPermissionAmount && previousTokenAmount.current !== tokenAmount) { - setCustomPermissionAmount(tokenAmount) + setCustomPermissionAmount(tokenAmount); } - previousTokenAmount.current = tokenAmount - }, [customPermissionAmount, tokenAmount]) + previousTokenAmount.current = tokenAmount; + }, [customPermissionAmount, tokenAmount]); - const { origin } = transaction + const { origin } = transaction; const formattedOrigin = origin ? origin[0].toUpperCase() + origin.slice(1) - : '' - const txData = transaction + : ''; + const txData = transaction; - const { icon: siteImage = '' } = domainMetadata[origin] || {} + const { icon: siteImage = '' } = domainMetadata[origin] || {}; - const tokensText = `${Number(tokenAmount)} ${tokenSymbol}` + const tokensText = `${Number(tokenAmount)} ${tokenSymbol}`; const tokenBalance = tokenTrackerBalance ? calcTokenAmount(tokenTrackerBalance, decimals).toString(10) - : '' + : ''; const customData = customPermissionAmount ? getCustomTxParamsData(data, { customPermissionAmount, decimals }) - : null + : null; return ( - ) + ); } diff --git a/ui/app/pages/confirm-approve/confirm-approve.util.js b/ui/app/pages/confirm-approve/confirm-approve.util.js index b652256a11..e724ba58e0 100644 --- a/ui/app/pages/confirm-approve/confirm-approve.util.js +++ b/ui/app/pages/confirm-approve/confirm-approve.util.js @@ -1,46 +1,49 @@ -import { TRANSACTION_CATEGORIES } from '../../../../shared/constants/transaction' -import { decimalToHex } from '../../helpers/utils/conversions.util' +import { TRANSACTION_CATEGORIES } from '../../../../shared/constants/transaction'; +import { decimalToHex } from '../../helpers/utils/conversions.util'; import { calcTokenValue, getTokenAddressParam, -} from '../../helpers/utils/token-util' -import { getTokenData } from '../../helpers/utils/transactions.util' +} from '../../helpers/utils/token-util'; +import { getTokenData } from '../../helpers/utils/transactions.util'; export function getCustomTxParamsData( data, { customPermissionAmount, decimals }, ) { - const tokenData = getTokenData(data) + const tokenData = getTokenData(data); if (!tokenData) { - throw new Error('Invalid data') + throw new Error('Invalid data'); } else if (tokenData.name !== TRANSACTION_CATEGORIES.TOKEN_METHOD_APPROVE) { throw new Error( `Invalid data; should be 'approve' method, but instead is '${tokenData.name}'`, - ) + ); } - let spender = getTokenAddressParam(tokenData) + let spender = getTokenAddressParam(tokenData); if (spender.startsWith('0x')) { - spender = spender.substring(2) + spender = spender.substring(2); } - const [signature, tokenValue] = data.split(spender) + const [signature, tokenValue] = data.split(spender); if (!signature || !tokenValue) { - throw new Error('Invalid data') + throw new Error('Invalid data'); } else if (tokenValue.length !== 64) { throw new Error( 'Invalid token value; should be exactly 64 hex digits long (u256)', - ) + ); } let customPermissionValue = decimalToHex( calcTokenValue(customPermissionAmount, decimals), - ) + ); if (customPermissionValue.length > 64) { - throw new Error('Custom value is larger than u256') + throw new Error('Custom value is larger than u256'); } - customPermissionValue = customPermissionValue.padStart(tokenValue.length, '0') - const customTxParamsData = `${signature}${spender}${customPermissionValue}` - return customTxParamsData + customPermissionValue = customPermissionValue.padStart( + tokenValue.length, + '0', + ); + const customTxParamsData = `${signature}${spender}${customPermissionValue}`; + return customTxParamsData; } diff --git a/ui/app/pages/confirm-approve/index.js b/ui/app/pages/confirm-approve/index.js index 2042093304..36d3ae1356 100644 --- a/ui/app/pages/confirm-approve/index.js +++ b/ui/app/pages/confirm-approve/index.js @@ -1 +1 @@ -export { default } from './confirm-approve' +export { default } from './confirm-approve'; diff --git a/ui/app/pages/confirm-decrypt-message/confirm-decrypt-message.component.js b/ui/app/pages/confirm-decrypt-message/confirm-decrypt-message.component.js index 40e4a42e23..bae3e22eb6 100644 --- a/ui/app/pages/confirm-decrypt-message/confirm-decrypt-message.component.js +++ b/ui/app/pages/confirm-decrypt-message/confirm-decrypt-message.component.js @@ -1,23 +1,23 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import copyToClipboard from 'copy-to-clipboard' -import classnames from 'classnames' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import copyToClipboard from 'copy-to-clipboard'; +import classnames from 'classnames'; -import AccountListItem from '../../components/app/account-list-item' -import Button from '../../components/ui/button' -import Identicon from '../../components/ui/identicon' -import Tooltip from '../../components/ui/tooltip' -import Copy from '../../components/ui/icon/copy-icon.component' +import AccountListItem from '../../components/app/account-list-item'; +import Button from '../../components/ui/button'; +import Identicon from '../../components/ui/identicon'; +import Tooltip from '../../components/ui/tooltip'; +import Copy from '../../components/ui/icon/copy-icon.component'; -import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../shared/constants/app' -import { getEnvironmentType } from '../../../../app/scripts/lib/util' -import { conversionUtil } from '../../helpers/utils/conversion-util' +import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../shared/constants/app'; +import { getEnvironmentType } from '../../../../app/scripts/lib/util'; +import { conversionUtil } from '../../helpers/utils/conversion-util'; export default class ConfirmDecryptMessage extends Component { static contextTypes = { t: PropTypes.func.isRequired, metricsEvent: PropTypes.func.isRequired, - } + }; static propTypes = { fromAccount: PropTypes.shape({ @@ -35,60 +35,64 @@ export default class ConfirmDecryptMessage extends Component { requesterAddress: PropTypes.string, txData: PropTypes.object, domainMetadata: PropTypes.object, - } + }; state = { fromAccount: this.props.fromAccount, copyToClipboardPressed: false, hasCopied: false, - } + }; componentDidMount = () => { if ( getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_NOTIFICATION ) { - window.addEventListener('beforeunload', this._beforeUnload) + window.addEventListener('beforeunload', this._beforeUnload); } - } + }; componentWillUnmount = () => { - this._removeBeforeUnload() - } + this._removeBeforeUnload(); + }; _beforeUnload = async (event) => { - const { clearConfirmTransaction, cancelDecryptMessage, txData } = this.props - const { metricsEvent } = this.context - await cancelDecryptMessage(txData, event) + const { + clearConfirmTransaction, + cancelDecryptMessage, + txData, + } = this.props; + const { metricsEvent } = this.context; + await cancelDecryptMessage(txData, event); metricsEvent({ eventOpts: { category: 'Messages', action: 'Decrypt Message Request', name: 'Cancel Via Notification Close', }, - }) - clearConfirmTransaction() - } + }); + clearConfirmTransaction(); + }; _removeBeforeUnload = () => { if ( getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_NOTIFICATION ) { - window.removeEventListener('beforeunload', this._beforeUnload) + window.removeEventListener('beforeunload', this._beforeUnload); } - } + }; copyMessage = () => { - copyToClipboard(this.state.rawMessage) + copyToClipboard(this.state.rawMessage); this.context.metricsEvent({ eventOpts: { category: 'Messages', action: 'Decrypt Message Copy', name: 'Copy', }, - }) - this.setState({ hasCopied: true }) - setTimeout(() => this.setState({ hasCopied: false }), 3000) - } + }); + this.setState({ hasCopied: true }); + setTimeout(() => this.setState({ hasCopied: false }), 3000); + }; renderHeader = () => { return ( @@ -103,12 +107,12 @@ export default class ConfirmDecryptMessage extends Component {
    - ) - } + ); + }; renderAccount = () => { - const { fromAccount } = this.state - const { t } = this.context + const { fromAccount } = this.state; + const { t } = this.context; return (
    @@ -120,15 +124,15 @@ export default class ConfirmDecryptMessage extends Component {
    - ) - } + ); + }; renderBalance = () => { - const { conversionRate } = this.props + const { conversionRate } = this.props; const { fromAccount: { balance }, - } = this.state - const { t } = this.context + } = this.state; + const { t } = this.context; const balanceInEther = conversionUtil(balance, { fromNumericBase: 'hex', @@ -136,7 +140,7 @@ export default class ConfirmDecryptMessage extends Component { fromDenomination: 'WEI', numberOfDecimals: 6, conversionRate, - }) + }); return (
    @@ -147,18 +151,18 @@ export default class ConfirmDecryptMessage extends Component { {`${balanceInEther} ETH`}
    - ) - } + ); + }; renderRequestIcon = () => { - const { requesterAddress } = this.props + const { requesterAddress } = this.props; return (
    - ) - } + ); + }; renderAccountInfo = () => { return ( @@ -167,16 +171,16 @@ export default class ConfirmDecryptMessage extends Component { {this.renderRequestIcon()} {this.renderBalance()} - ) - } + ); + }; renderBody = () => { - const { decryptMessageInline, domainMetadata, txData } = this.props - const { t } = this.context + const { decryptMessageInline, domainMetadata, txData } = this.props; + const { t } = this.context; - const originMetadata = domainMetadata[txData.msgParams.origin] - const name = originMetadata?.name || txData.msgParams.origin - const notice = t('decryptMessageNotice', [txData.msgParams.origin]) + const originMetadata = domainMetadata[txData.msgParams.origin]; + const name = originMetadata?.name || txData.msgParams.origin; + const notice = t('decryptMessageNotice', [txData.msgParams.origin]); const { hasCopied, @@ -185,7 +189,7 @@ export default class ConfirmDecryptMessage extends Component { rawMessage, errorMessage, copyToClipboardPressed, - } = this.state + } = this.state; return (
    @@ -232,14 +236,14 @@ export default class ConfirmDecryptMessage extends Component { errorMessage: this.context.t('decryptInlineError', [ result.error, ]), - }) + }); } else { this.setState({ hasDecrypted: true, rawMessage: result.rawData, - }) + }); } - }) + }); }} > @@ -274,8 +278,8 @@ export default class ConfirmDecryptMessage extends Component {
    )}
    - ) - } + ); + }; renderFooter = () => { const { @@ -285,8 +289,8 @@ export default class ConfirmDecryptMessage extends Component { history, mostRecentOverviewPage, txData, - } = this.props - const { metricsEvent, t } = this.context + } = this.props; + const { metricsEvent, t } = this.context; return (
    @@ -295,17 +299,17 @@ export default class ConfirmDecryptMessage extends Component { large className="request-decrypt-message__footer__cancel-button" onClick={async (event) => { - this._removeBeforeUnload() - await cancelDecryptMessage(txData, event) + this._removeBeforeUnload(); + await cancelDecryptMessage(txData, event); metricsEvent({ eventOpts: { category: 'Messages', action: 'Decrypt Message Request', name: 'Cancel', }, - }) - clearConfirmTransaction() - history.push(mostRecentOverviewPage) + }); + clearConfirmTransaction(); + history.push(mostRecentOverviewPage); }} > {t('cancel')} @@ -315,24 +319,24 @@ export default class ConfirmDecryptMessage extends Component { large className="request-decrypt-message__footer__sign-button" onClick={async (event) => { - this._removeBeforeUnload() - await decryptMessage(txData, event) + this._removeBeforeUnload(); + await decryptMessage(txData, event); metricsEvent({ eventOpts: { category: 'Messages', action: 'Decrypt Message Request', name: 'Confirm', }, - }) - clearConfirmTransaction() - history.push(mostRecentOverviewPage) + }); + clearConfirmTransaction(); + history.push(mostRecentOverviewPage); }} > {t('decrypt')}
    - ) - } + ); + }; render = () => { return ( @@ -341,6 +345,6 @@ export default class ConfirmDecryptMessage extends Component { {this.renderBody()} {this.renderFooter()} - ) - } + ); + }; } diff --git a/ui/app/pages/confirm-decrypt-message/confirm-decrypt-message.container.js b/ui/app/pages/confirm-decrypt-message/confirm-decrypt-message.container.js index 6be21e2ea0..800ec7abc1 100644 --- a/ui/app/pages/confirm-decrypt-message/confirm-decrypt-message.container.js +++ b/ui/app/pages/confirm-decrypt-message/confirm-decrypt-message.container.js @@ -1,34 +1,34 @@ -import { connect } from 'react-redux' -import { compose } from 'redux' -import { withRouter } from 'react-router-dom' +import { connect } from 'react-redux'; +import { compose } from 'redux'; +import { withRouter } from 'react-router-dom'; import { goHome, decryptMsg, cancelDecryptMsg, decryptMsgInline, -} from '../../store/actions' +} from '../../store/actions'; import { getTargetAccountWithSendEtherInfo, conversionRateSelector, -} from '../../selectors' -import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck' -import { getMostRecentOverviewPage } from '../../ducks/history/history' -import ConfirmDecryptMessage from './confirm-decrypt-message.component' +} from '../../selectors'; +import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck'; +import { getMostRecentOverviewPage } from '../../ducks/history/history'; +import ConfirmDecryptMessage from './confirm-decrypt-message.component'; function mapStateToProps(state) { const { confirmTransaction, metamask: { domainMetadata = {} }, - } = state + } = state; - const { txData = {} } = confirmTransaction + const { txData = {} } = confirmTransaction; const { msgParams: { from }, - } = txData + } = txData; - const fromAccount = getTargetAccountWithSendEtherInfo(state, from) + const fromAccount = getTargetAccountWithSendEtherInfo(state, from); return { txData, @@ -38,7 +38,7 @@ function mapStateToProps(state) { requesterAddress: null, conversionRate: conversionRateSelector(state), mostRecentOverviewPage: getMostRecentOverviewPage(state), - } + }; } function mapDispatchToProps(dispatch) { @@ -46,25 +46,25 @@ function mapDispatchToProps(dispatch) { goHome: () => dispatch(goHome()), clearConfirmTransaction: () => dispatch(clearConfirmTransaction()), decryptMessage: (msgData, event) => { - const params = msgData.msgParams - params.metamaskId = msgData.id - event.stopPropagation(event) - return dispatch(decryptMsg(params)) + const params = msgData.msgParams; + params.metamaskId = msgData.id; + event.stopPropagation(event); + return dispatch(decryptMsg(params)); }, cancelDecryptMessage: (msgData, event) => { - event.stopPropagation(event) - return dispatch(cancelDecryptMsg(msgData)) + event.stopPropagation(event); + return dispatch(cancelDecryptMsg(msgData)); }, decryptMessageInline: (msgData, event) => { - const params = msgData.msgParams - params.metamaskId = msgData.id - event.stopPropagation(event) - return dispatch(decryptMsgInline(params)) + const params = msgData.msgParams; + params.metamaskId = msgData.id; + event.stopPropagation(event); + return dispatch(decryptMsgInline(params)); }, - } + }; } export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps), -)(ConfirmDecryptMessage) +)(ConfirmDecryptMessage); diff --git a/ui/app/pages/confirm-decrypt-message/index.js b/ui/app/pages/confirm-decrypt-message/index.js index 9cc6716819..c375f08a6f 100644 --- a/ui/app/pages/confirm-decrypt-message/index.js +++ b/ui/app/pages/confirm-decrypt-message/index.js @@ -1 +1 @@ -export { default } from './confirm-decrypt-message.container' +export { default } from './confirm-decrypt-message.container'; diff --git a/ui/app/pages/confirm-deploy-contract/confirm-deploy-contract.component.js b/ui/app/pages/confirm-deploy-contract/confirm-deploy-contract.component.js index d799aa28da..49a192071b 100644 --- a/ui/app/pages/confirm-deploy-contract/confirm-deploy-contract.component.js +++ b/ui/app/pages/confirm-deploy-contract/confirm-deploy-contract.component.js @@ -1,20 +1,20 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import ethUtil from 'ethereumjs-util' -import ConfirmTransactionBase from '../confirm-transaction-base' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import ethUtil from 'ethereumjs-util'; +import ConfirmTransactionBase from '../confirm-transaction-base'; export default class ConfirmDeployContract extends Component { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { txData: PropTypes.object, - } + }; renderData() { - const { t } = this.context - const { txData: { origin, txParams: { data } = {} } = {} } = this.props + const { t } = this.context; + const { txData: { origin, txParams: { data } = {} } = {} } = this.props; return (
    @@ -37,7 +37,7 @@ export default class ConfirmDeployContract extends Component {
    {data}
    - ) + ); } render() { @@ -46,6 +46,6 @@ export default class ConfirmDeployContract extends Component { actionKey="contractDeployment" dataComponent={this.renderData()} /> - ) + ); } } diff --git a/ui/app/pages/confirm-deploy-contract/confirm-deploy-contract.container.js b/ui/app/pages/confirm-deploy-contract/confirm-deploy-contract.container.js index e66dd3b609..633454c0f5 100644 --- a/ui/app/pages/confirm-deploy-contract/confirm-deploy-contract.container.js +++ b/ui/app/pages/confirm-deploy-contract/confirm-deploy-contract.container.js @@ -1,12 +1,12 @@ -import { connect } from 'react-redux' -import ConfirmDeployContract from './confirm-deploy-contract.component' +import { connect } from 'react-redux'; +import ConfirmDeployContract from './confirm-deploy-contract.component'; const mapStateToProps = (state) => { - const { confirmTransaction: { txData } = {} } = state + const { confirmTransaction: { txData } = {} } = state; return { txData, - } -} + }; +}; -export default connect(mapStateToProps)(ConfirmDeployContract) +export default connect(mapStateToProps)(ConfirmDeployContract); diff --git a/ui/app/pages/confirm-deploy-contract/index.js b/ui/app/pages/confirm-deploy-contract/index.js index c4fb01b52a..02f222fb21 100644 --- a/ui/app/pages/confirm-deploy-contract/index.js +++ b/ui/app/pages/confirm-deploy-contract/index.js @@ -1 +1 @@ -export { default } from './confirm-deploy-contract.container' +export { default } from './confirm-deploy-contract.container'; diff --git a/ui/app/pages/confirm-encryption-public-key/confirm-encryption-public-key.component.js b/ui/app/pages/confirm-encryption-public-key/confirm-encryption-public-key.component.js index a1c1178f72..45e192da6b 100644 --- a/ui/app/pages/confirm-encryption-public-key/confirm-encryption-public-key.component.js +++ b/ui/app/pages/confirm-encryption-public-key/confirm-encryption-public-key.component.js @@ -1,19 +1,19 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; -import AccountListItem from '../../components/app/account-list-item' -import Button from '../../components/ui/button' -import Identicon from '../../components/ui/identicon' +import AccountListItem from '../../components/app/account-list-item'; +import Button from '../../components/ui/button'; +import Identicon from '../../components/ui/identicon'; -import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../shared/constants/app' -import { getEnvironmentType } from '../../../../app/scripts/lib/util' -import { conversionUtil } from '../../helpers/utils/conversion-util' +import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../shared/constants/app'; +import { getEnvironmentType } from '../../../../app/scripts/lib/util'; +import { conversionUtil } from '../../helpers/utils/conversion-util'; export default class ConfirmEncryptionPublicKey extends Component { static contextTypes = { t: PropTypes.func.isRequired, metricsEvent: PropTypes.func.isRequired, - } + }; static propTypes = { fromAccount: PropTypes.shape({ @@ -30,49 +30,49 @@ export default class ConfirmEncryptionPublicKey extends Component { txData: PropTypes.object, domainMetadata: PropTypes.object, mostRecentOverviewPage: PropTypes.string.isRequired, - } + }; state = { fromAccount: this.props.fromAccount, - } + }; componentDidMount = () => { if ( getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_NOTIFICATION ) { - window.addEventListener('beforeunload', this._beforeUnload) + window.addEventListener('beforeunload', this._beforeUnload); } - } + }; componentWillUnmount = () => { - this._removeBeforeUnload() - } + this._removeBeforeUnload(); + }; _beforeUnload = async (event) => { const { clearConfirmTransaction, cancelEncryptionPublicKey, txData, - } = this.props - const { metricsEvent } = this.context - await cancelEncryptionPublicKey(txData, event) + } = this.props; + const { metricsEvent } = this.context; + await cancelEncryptionPublicKey(txData, event); metricsEvent({ eventOpts: { category: 'Messages', action: 'Encryption public key Request', name: 'Cancel Via Notification Close', }, - }) - clearConfirmTransaction() - } + }); + clearConfirmTransaction(); + }; _removeBeforeUnload = () => { if ( getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_NOTIFICATION ) { - window.removeEventListener('beforeunload', this._beforeUnload) + window.removeEventListener('beforeunload', this._beforeUnload); } - } + }; renderHeader = () => { return ( @@ -87,12 +87,12 @@ export default class ConfirmEncryptionPublicKey extends Component {
    - ) - } + ); + }; renderAccount = () => { - const { fromAccount } = this.state - const { t } = this.context + const { fromAccount } = this.state; + const { t } = this.context; return (
    @@ -104,15 +104,15 @@ export default class ConfirmEncryptionPublicKey extends Component {
    - ) - } + ); + }; renderBalance = () => { - const { conversionRate } = this.props - const { t } = this.context + const { conversionRate } = this.props; + const { t } = this.context; const { fromAccount: { balance }, - } = this.state + } = this.state; const balanceInEther = conversionUtil(balance, { fromNumericBase: 'hex', @@ -120,7 +120,7 @@ export default class ConfirmEncryptionPublicKey extends Component { fromDenomination: 'WEI', numberOfDecimals: 6, conversionRate, - }) + }); return (
    @@ -131,18 +131,18 @@ export default class ConfirmEncryptionPublicKey extends Component { {`${balanceInEther} ETH`}
    - ) - } + ); + }; renderRequestIcon = () => { - const { requesterAddress } = this.props + const { requesterAddress } = this.props; return (
    - ) - } + ); + }; renderAccountInfo = () => { return ( @@ -151,16 +151,16 @@ export default class ConfirmEncryptionPublicKey extends Component { {this.renderRequestIcon()} {this.renderBalance()} - ) - } + ); + }; renderBody = () => { - const { domainMetadata, txData } = this.props - const { t } = this.context + const { domainMetadata, txData } = this.props; + const { t } = this.context; - const originMetadata = domainMetadata[txData.origin] - const notice = t('encryptionPublicKeyNotice', [txData.origin]) - const name = originMetadata?.name || txData.origin + const originMetadata = domainMetadata[txData.origin]; + const notice = t('encryptionPublicKeyNotice', [txData.origin]); + const name = originMetadata?.name || txData.origin; return (
    @@ -184,8 +184,8 @@ export default class ConfirmEncryptionPublicKey extends Component {
    - ) - } + ); + }; renderFooter = () => { const { @@ -195,8 +195,8 @@ export default class ConfirmEncryptionPublicKey extends Component { history, mostRecentOverviewPage, txData, - } = this.props - const { t, metricsEvent } = this.context + } = this.props; + const { t, metricsEvent } = this.context; return (
    @@ -205,17 +205,17 @@ export default class ConfirmEncryptionPublicKey extends Component { large className="request-encryption-public-key__footer__cancel-button" onClick={async (event) => { - this._removeBeforeUnload() - await cancelEncryptionPublicKey(txData, event) + this._removeBeforeUnload(); + await cancelEncryptionPublicKey(txData, event); metricsEvent({ eventOpts: { category: 'Messages', action: 'Encryption public key Request', name: 'Cancel', }, - }) - clearConfirmTransaction() - history.push(mostRecentOverviewPage) + }); + clearConfirmTransaction(); + history.push(mostRecentOverviewPage); }} > {this.context.t('cancel')} @@ -225,24 +225,24 @@ export default class ConfirmEncryptionPublicKey extends Component { large className="request-encryption-public-key__footer__sign-button" onClick={async (event) => { - this._removeBeforeUnload() - await encryptionPublicKey(txData, event) + this._removeBeforeUnload(); + await encryptionPublicKey(txData, event); this.context.metricsEvent({ eventOpts: { category: 'Messages', action: 'Encryption public key Request', name: 'Confirm', }, - }) - clearConfirmTransaction() - history.push(mostRecentOverviewPage) + }); + clearConfirmTransaction(); + history.push(mostRecentOverviewPage); }} > {t('provide')}
    - ) - } + ); + }; render = () => { return ( @@ -251,6 +251,6 @@ export default class ConfirmEncryptionPublicKey extends Component { {this.renderBody()} {this.renderFooter()} - ) - } + ); + }; } diff --git a/ui/app/pages/confirm-encryption-public-key/confirm-encryption-public-key.container.js b/ui/app/pages/confirm-encryption-public-key/confirm-encryption-public-key.container.js index ea4c156e7d..ee8061dcf1 100644 --- a/ui/app/pages/confirm-encryption-public-key/confirm-encryption-public-key.container.js +++ b/ui/app/pages/confirm-encryption-public-key/confirm-encryption-public-key.container.js @@ -1,33 +1,33 @@ -import { connect } from 'react-redux' -import { compose } from 'redux' -import { withRouter } from 'react-router-dom' +import { connect } from 'react-redux'; +import { compose } from 'redux'; +import { withRouter } from 'react-router-dom'; import { goHome, encryptionPublicKeyMsg, cancelEncryptionPublicKeyMsg, -} from '../../store/actions' +} from '../../store/actions'; import { conversionRateSelector, getTargetAccountWithSendEtherInfo, -} from '../../selectors' +} from '../../selectors'; -import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck' -import { getMostRecentOverviewPage } from '../../ducks/history/history' -import ConfirmEncryptionPublicKey from './confirm-encryption-public-key.component' +import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck'; +import { getMostRecentOverviewPage } from '../../ducks/history/history'; +import ConfirmEncryptionPublicKey from './confirm-encryption-public-key.component'; function mapStateToProps(state) { const { confirmTransaction, metamask: { domainMetadata = {} }, - } = state + } = state; - const { txData = {} } = confirmTransaction + const { txData = {} } = confirmTransaction; - const { msgParams: from } = txData + const { msgParams: from } = txData; - const fromAccount = getTargetAccountWithSendEtherInfo(state, from) + const fromAccount = getTargetAccountWithSendEtherInfo(state, from); return { txData, @@ -37,7 +37,7 @@ function mapStateToProps(state) { requesterAddress: null, conversionRate: conversionRateSelector(state), mostRecentOverviewPage: getMostRecentOverviewPage(state), - } + }; } function mapDispatchToProps(dispatch) { @@ -45,18 +45,18 @@ function mapDispatchToProps(dispatch) { goHome: () => dispatch(goHome()), clearConfirmTransaction: () => dispatch(clearConfirmTransaction()), encryptionPublicKey: (msgData, event) => { - const params = { data: msgData.msgParams, metamaskId: msgData.id } - event.stopPropagation() - return dispatch(encryptionPublicKeyMsg(params)) + const params = { data: msgData.msgParams, metamaskId: msgData.id }; + event.stopPropagation(); + return dispatch(encryptionPublicKeyMsg(params)); }, cancelEncryptionPublicKey: (msgData, event) => { - event.stopPropagation() - return dispatch(cancelEncryptionPublicKeyMsg(msgData)) + event.stopPropagation(); + return dispatch(cancelEncryptionPublicKeyMsg(msgData)); }, - } + }; } export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps), -)(ConfirmEncryptionPublicKey) +)(ConfirmEncryptionPublicKey); diff --git a/ui/app/pages/confirm-encryption-public-key/index.js b/ui/app/pages/confirm-encryption-public-key/index.js index 9eb370e52a..49bb4f367c 100644 --- a/ui/app/pages/confirm-encryption-public-key/index.js +++ b/ui/app/pages/confirm-encryption-public-key/index.js @@ -1 +1 @@ -export { default } from './confirm-encryption-public-key.container' +export { default } from './confirm-encryption-public-key.container'; diff --git a/ui/app/pages/confirm-send-ether/confirm-send-ether.component.js b/ui/app/pages/confirm-send-ether/confirm-send-ether.component.js index 6cff215503..cbdbebb910 100644 --- a/ui/app/pages/confirm-send-ether/confirm-send-ether.component.js +++ b/ui/app/pages/confirm-send-ether/confirm-send-ether.component.js @@ -1,32 +1,32 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import ConfirmTransactionBase from '../confirm-transaction-base' -import { SEND_ROUTE } from '../../helpers/constants/routes' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import ConfirmTransactionBase from '../confirm-transaction-base'; +import { SEND_ROUTE } from '../../helpers/constants/routes'; export default class ConfirmSendEther extends Component { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { editTransaction: PropTypes.func, history: PropTypes.object, txParams: PropTypes.object, - } + }; handleEdit({ txData }) { - const { editTransaction, history } = this.props - editTransaction(txData) - history.push(SEND_ROUTE) + const { editTransaction, history } = this.props; + editTransaction(txData); + history.push(SEND_ROUTE); } shouldHideData() { - const { txParams = {} } = this.props - return !txParams.data + const { txParams = {} } = this.props; + return !txParams.data; } render() { - const hideData = this.shouldHideData() + const hideData = this.shouldHideData(); return ( - ) + ); } } diff --git a/ui/app/pages/confirm-send-ether/confirm-send-ether.container.js b/ui/app/pages/confirm-send-ether/confirm-send-ether.container.js index 8eca1803fa..35f1ccd738 100644 --- a/ui/app/pages/confirm-send-ether/confirm-send-ether.container.js +++ b/ui/app/pages/confirm-send-ether/confirm-send-ether.container.js @@ -1,25 +1,25 @@ -import { connect } from 'react-redux' -import { compose } from 'redux' -import { withRouter } from 'react-router-dom' -import { updateSend } from '../../store/actions' -import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck' -import ConfirmSendEther from './confirm-send-ether.component' +import { connect } from 'react-redux'; +import { compose } from 'redux'; +import { withRouter } from 'react-router-dom'; +import { updateSend } from '../../store/actions'; +import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck'; +import ConfirmSendEther from './confirm-send-ether.component'; const mapStateToProps = (state) => { const { confirmTransaction: { txData: { txParams } = {} }, - } = state + } = state; return { txParams, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { editTransaction: (txData) => { - const { id, txParams } = txData - const { from, gas: gasLimit, gasPrice, to, value: amount } = txParams + const { id, txParams } = txData; + const { from, gas: gasLimit, gasPrice, to, value: amount } = txParams; dispatch( updateSend({ @@ -32,14 +32,14 @@ const mapDispatchToProps = (dispatch) => { errors: { to: null, amount: null }, editingTransactionId: id?.toString(), }), - ) + ); - dispatch(clearConfirmTransaction()) + dispatch(clearConfirmTransaction()); }, - } -} + }; +}; export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps), -)(ConfirmSendEther) +)(ConfirmSendEther); diff --git a/ui/app/pages/confirm-send-ether/index.js b/ui/app/pages/confirm-send-ether/index.js index 2d5767c39c..eba4b48b1c 100644 --- a/ui/app/pages/confirm-send-ether/index.js +++ b/ui/app/pages/confirm-send-ether/index.js @@ -1 +1 @@ -export { default } from './confirm-send-ether.container' +export { default } from './confirm-send-ether.container'; diff --git a/ui/app/pages/confirm-send-token/confirm-send-token.component.js b/ui/app/pages/confirm-send-token/confirm-send-token.component.js index 3c68e564bd..6e040fb061 100644 --- a/ui/app/pages/confirm-send-token/confirm-send-token.component.js +++ b/ui/app/pages/confirm-send-token/confirm-send-token.component.js @@ -1,23 +1,23 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import ConfirmTokenTransactionBaseContainer from '../confirm-token-transaction-base' -import { SEND_ROUTE } from '../../helpers/constants/routes' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import ConfirmTokenTransactionBaseContainer from '../confirm-token-transaction-base'; +import { SEND_ROUTE } from '../../helpers/constants/routes'; export default class ConfirmSendToken extends Component { static propTypes = { history: PropTypes.object, editTransaction: PropTypes.func, tokenAmount: PropTypes.string, - } + }; handleEdit(confirmTransactionData) { - const { editTransaction, history } = this.props - editTransaction(confirmTransactionData) - history.push(SEND_ROUTE) + const { editTransaction, history } = this.props; + editTransaction(confirmTransactionData); + history.push(SEND_ROUTE); } render() { - const { tokenAmount } = this.props + const { tokenAmount } = this.props; return ( - ) + ); } } diff --git a/ui/app/pages/confirm-send-token/confirm-send-token.container.js b/ui/app/pages/confirm-send-token/confirm-send-token.container.js index 04bb1f7b29..e7514acf9e 100644 --- a/ui/app/pages/confirm-send-token/confirm-send-token.container.js +++ b/ui/app/pages/confirm-send-token/confirm-send-token.container.js @@ -1,23 +1,23 @@ -import { connect } from 'react-redux' -import { compose } from 'redux' -import { withRouter } from 'react-router-dom' -import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck' -import { updateSend, showSendTokenPage } from '../../store/actions' -import { conversionUtil } from '../../helpers/utils/conversion-util' +import { connect } from 'react-redux'; +import { compose } from 'redux'; +import { withRouter } from 'react-router-dom'; +import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck'; +import { updateSend, showSendTokenPage } from '../../store/actions'; +import { conversionUtil } from '../../helpers/utils/conversion-util'; import { getTokenValueParam, getTokenAddressParam, -} from '../../helpers/utils/token-util' -import { sendTokenTokenAmountAndToAddressSelector } from '../../selectors' -import ConfirmSendToken from './confirm-send-token.component' +} from '../../helpers/utils/token-util'; +import { sendTokenTokenAmountAndToAddressSelector } from '../../selectors'; +import ConfirmSendToken from './confirm-send-token.component'; const mapStateToProps = (state) => { - const { tokenAmount } = sendTokenTokenAmountAndToAddressSelector(state) + const { tokenAmount } = sendTokenTokenAmountAndToAddressSelector(state); return { tokenAmount, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { @@ -25,15 +25,15 @@ const mapDispatchToProps = (dispatch) => { const { id, txParams: { from, to: tokenAddress, gas: gasLimit, gasPrice } = {}, - } = txData + } = txData; - const to = getTokenValueParam(tokenData) - const tokenAmountInDec = getTokenAddressParam(tokenData) + const to = getTokenValueParam(tokenData); + const tokenAmountInDec = getTokenAddressParam(tokenData); const tokenAmountInHex = conversionUtil(tokenAmountInDec, { fromNumericBase: 'dec', toNumericBase: 'hex', - }) + }); dispatch( updateSend({ @@ -50,14 +50,14 @@ const mapDispatchToProps = (dispatch) => { address: tokenAddress, }, }), - ) - dispatch(clearConfirmTransaction()) - dispatch(showSendTokenPage()) + ); + dispatch(clearConfirmTransaction()); + dispatch(showSendTokenPage()); }, - } -} + }; +}; export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps), -)(ConfirmSendToken) +)(ConfirmSendToken); diff --git a/ui/app/pages/confirm-send-token/index.js b/ui/app/pages/confirm-send-token/index.js index 409b6ef3dd..25067ca43f 100644 --- a/ui/app/pages/confirm-send-token/index.js +++ b/ui/app/pages/confirm-send-token/index.js @@ -1 +1 @@ -export { default } from './confirm-send-token.container' +export { default } from './confirm-send-token.container'; diff --git a/ui/app/pages/confirm-token-transaction-base/confirm-token-transaction-base.component.js b/ui/app/pages/confirm-token-transaction-base/confirm-token-transaction-base.component.js index e8bb691521..a03cee3ef8 100644 --- a/ui/app/pages/confirm-token-transaction-base/confirm-token-transaction-base.component.js +++ b/ui/app/pages/confirm-token-transaction-base/confirm-token-transaction-base.component.js @@ -1,17 +1,17 @@ -import React, { useContext, useMemo } from 'react' -import PropTypes from 'prop-types' -import BigNumber from 'bignumber.js' -import { I18nContext } from '../../contexts/i18n' -import ConfirmTransactionBase from '../confirm-transaction-base' -import UserPreferencedCurrencyDisplay from '../../components/app/user-preferenced-currency-display' +import React, { useContext, useMemo } from 'react'; +import PropTypes from 'prop-types'; +import BigNumber from 'bignumber.js'; +import { I18nContext } from '../../contexts/i18n'; +import ConfirmTransactionBase from '../confirm-transaction-base'; +import UserPreferencedCurrencyDisplay from '../../components/app/user-preferenced-currency-display'; import { formatCurrency, convertTokenToFiat, addFiat, roundExponential, -} from '../../helpers/utils/confirm-tx.util' -import { getWeiHexFromDecimalValue } from '../../helpers/utils/conversions.util' -import { ETH, PRIMARY } from '../../helpers/constants/common' +} from '../../helpers/utils/confirm-tx.util'; +import { getWeiHexFromDecimalValue } from '../../helpers/utils/conversions.util'; +import { ETH, PRIMARY } from '../../helpers/constants/common'; export default function ConfirmTokenTransactionBase({ toAddress, @@ -24,27 +24,27 @@ export default function ConfirmTokenTransactionBase({ conversionRate, currentCurrency, }) { - const t = useContext(I18nContext) + const t = useContext(I18nContext); const hexWeiValue = useMemo(() => { if (tokenAmount === '0' || !contractExchangeRate) { - return '0' + return '0'; } const decimalEthValue = new BigNumber(tokenAmount) .times(new BigNumber(contractExchangeRate)) - .toFixed() + .toFixed(); return getWeiHexFromDecimalValue({ value: decimalEthValue, fromCurrency: ETH, fromDenomination: ETH, - }) - }, [tokenAmount, contractExchangeRate]) + }); + }, [tokenAmount, contractExchangeRate]); const secondaryTotalTextOverride = useMemo(() => { if (typeof contractExchangeRate === 'undefined') { - return formatCurrency(fiatTransactionTotal, currentCurrency) + return formatCurrency(fiatTransactionTotal, currentCurrency); } const fiatTransactionAmount = convertTokenToFiat({ @@ -52,19 +52,19 @@ export default function ConfirmTokenTransactionBase({ toCurrency: currentCurrency, conversionRate, contractExchangeRate, - }) - const fiatTotal = addFiat(fiatTransactionAmount, fiatTransactionTotal) - const roundedFiatTotal = roundExponential(fiatTotal) - return formatCurrency(roundedFiatTotal, currentCurrency) + }); + const fiatTotal = addFiat(fiatTransactionAmount, fiatTransactionTotal); + const roundedFiatTotal = roundExponential(fiatTotal); + return formatCurrency(roundedFiatTotal, currentCurrency); }, [ currentCurrency, conversionRate, contractExchangeRate, fiatTransactionTotal, tokenAmount, - ]) + ]); - const tokensText = `${tokenAmount} ${tokenSymbol}` + const tokensText = `${tokenAmount} ${tokenSymbol}`; return ( - ) + ); } ConfirmTokenTransactionBase.propTypes = { @@ -105,4 +105,4 @@ ConfirmTokenTransactionBase.propTypes = { contractExchangeRate: PropTypes.number, conversionRate: PropTypes.number, currentCurrency: PropTypes.string, -} +}; diff --git a/ui/app/pages/confirm-token-transaction-base/confirm-token-transaction-base.container.js b/ui/app/pages/confirm-token-transaction-base/confirm-token-transaction-base.container.js index 5c01aa9bd1..2d7bbde852 100644 --- a/ui/app/pages/confirm-token-transaction-base/confirm-token-transaction-base.container.js +++ b/ui/app/pages/confirm-token-transaction-base/confirm-token-transaction-base.container.js @@ -1,55 +1,55 @@ -import { connect } from 'react-redux' -import { compose } from 'redux' -import { withRouter } from 'react-router-dom' +import { connect } from 'react-redux'; +import { compose } from 'redux'; +import { withRouter } from 'react-router-dom'; import { contractExchangeRateSelector, transactionFeeSelector, -} from '../../selectors' -import { getTokens } from '../../ducks/metamask/metamask' -import { getTokenData } from '../../helpers/utils/transactions.util' +} from '../../selectors'; +import { getTokens } from '../../ducks/metamask/metamask'; +import { getTokenData } from '../../helpers/utils/transactions.util'; import { calcTokenAmount, getTokenAddressParam, getTokenValueParam, -} from '../../helpers/utils/token-util' -import ConfirmTokenTransactionBase from './confirm-token-transaction-base.component' +} from '../../helpers/utils/token-util'; +import ConfirmTokenTransactionBase from './confirm-token-transaction-base.component'; const mapStateToProps = (state, ownProps) => { const { match: { params = {} }, - } = ownProps - const { id: paramsTransactionId } = params + } = ownProps; + const { id: paramsTransactionId } = params; const { confirmTransaction, metamask: { currentCurrency, conversionRate, currentNetworkTxList }, - } = state + } = state; const { txData: { id: transactionId, txParams: { to: tokenAddress, data } = {}, } = {}, - } = confirmTransaction + } = confirmTransaction; const transaction = currentNetworkTxList.find( ({ id }) => id === (Number(paramsTransactionId) || transactionId), - ) || {} + ) || {}; const { ethTransactionTotal, fiatTransactionTotal } = transactionFeeSelector( state, transaction, - ) - const tokens = getTokens(state) - const currentToken = tokens?.find(({ address }) => tokenAddress === address) - const { decimals, symbol: tokenSymbol } = currentToken || {} + ); + const tokens = getTokens(state); + const currentToken = tokens?.find(({ address }) => tokenAddress === address); + const { decimals, symbol: tokenSymbol } = currentToken || {}; - const tokenData = getTokenData(data) - const tokenValue = getTokenValueParam(tokenData) - const toAddress = getTokenAddressParam(tokenData) + const tokenData = getTokenData(data); + const tokenValue = getTokenValueParam(tokenData); + const toAddress = getTokenAddressParam(tokenData); const tokenAmount = - tokenData && calcTokenAmount(tokenValue, decimals).toFixed() - const contractExchangeRate = contractExchangeRateSelector(state) + tokenData && calcTokenAmount(tokenValue, decimals).toFixed(); + const contractExchangeRate = contractExchangeRateSelector(state); return { toAddress, @@ -61,10 +61,10 @@ const mapStateToProps = (state, ownProps) => { contractExchangeRate, fiatTransactionTotal, ethTransactionTotal, - } -} + }; +}; export default compose( withRouter, connect(mapStateToProps), -)(ConfirmTokenTransactionBase) +)(ConfirmTokenTransactionBase); diff --git a/ui/app/pages/confirm-token-transaction-base/index.js b/ui/app/pages/confirm-token-transaction-base/index.js index e15c5d56b8..e5b6df0313 100644 --- a/ui/app/pages/confirm-token-transaction-base/index.js +++ b/ui/app/pages/confirm-token-transaction-base/index.js @@ -1,2 +1,2 @@ -export { default } from './confirm-token-transaction-base.container' -export { default as ConfirmTokenTransactionBase } from './confirm-token-transaction-base.component' +export { default } from './confirm-token-transaction-base.container'; +export { default as ConfirmTokenTransactionBase } from './confirm-token-transaction-base.component'; diff --git a/ui/app/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.component.js index eeec5a5cde..5d09b3198a 100644 --- a/ui/app/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -1,33 +1,33 @@ -import ethUtil from 'ethereumjs-util' -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../shared/constants/app' -import { getEnvironmentType } from '../../../../app/scripts/lib/util' +import ethUtil from 'ethereumjs-util'; +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../shared/constants/app'; +import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import ConfirmPageContainer, { ConfirmDetailRow, -} from '../../components/app/confirm-page-container' -import { isBalanceSufficient } from '../send/send.utils' -import { CONFIRM_TRANSACTION_ROUTE } from '../../helpers/constants/routes' +} from '../../components/app/confirm-page-container'; +import { isBalanceSufficient } from '../send/send.utils'; +import { CONFIRM_TRANSACTION_ROUTE } from '../../helpers/constants/routes'; import { INSUFFICIENT_FUNDS_ERROR_KEY, TRANSACTION_ERROR_KEY, GAS_LIMIT_TOO_LOW_ERROR_KEY, -} from '../../helpers/constants/error-keys' -import UserPreferencedCurrencyDisplay from '../../components/app/user-preferenced-currency-display' -import { PRIMARY, SECONDARY } from '../../helpers/constants/common' -import { hexToDecimal } from '../../helpers/utils/conversions.util' -import AdvancedGasInputs from '../../components/app/gas-customization/advanced-gas-inputs' -import TextField from '../../components/ui/text-field' +} from '../../helpers/constants/error-keys'; +import UserPreferencedCurrencyDisplay from '../../components/app/user-preferenced-currency-display'; +import { PRIMARY, SECONDARY } from '../../helpers/constants/common'; +import { hexToDecimal } from '../../helpers/utils/conversions.util'; +import AdvancedGasInputs from '../../components/app/gas-customization/advanced-gas-inputs'; +import TextField from '../../components/ui/text-field'; import { TRANSACTION_CATEGORIES, TRANSACTION_STATUSES, -} from '../../../../shared/constants/transaction' +} from '../../../../shared/constants/transaction'; export default class ConfirmTransactionBase extends Component { static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; static propTypes = { // react-router props @@ -94,13 +94,13 @@ export default class ConfirmTransactionBase extends Component { showAccountInHeader: PropTypes.bool, mostRecentOverviewPage: PropTypes.string.isRequired, isMainnet: PropTypes.bool, - } + }; state = { submitting: false, submitError: null, submitWarning: '', - } + }; componentDidUpdate(prevProps) { const { @@ -113,17 +113,17 @@ export default class ConfirmTransactionBase extends Component { customNonceValue, toAddress, tryReverseResolveAddress, - } = this.props + } = this.props; const { customNonceValue: prevCustomNonceValue, nextNonce: prevNextNonce, toAddress: prevToAddress, transactionStatus: prevTxStatus, - } = prevProps - const statusUpdated = transactionStatus !== prevTxStatus + } = prevProps; + const statusUpdated = transactionStatus !== prevTxStatus; const txDroppedOrConfirmed = transactionStatus === TRANSACTION_STATUSES.DROPPED || - transactionStatus === TRANSACTION_STATUSES.CONFIRMED + transactionStatus === TRANSACTION_STATUSES.CONFIRMED; if ( nextNonce !== prevNextNonce || @@ -132,23 +132,23 @@ export default class ConfirmTransactionBase extends Component { if (nextNonce !== null && customNonceValue > nextNonce) { this.setState({ submitWarning: this.context.t('nextNonceWarning', [nextNonce]), - }) + }); } else { - this.setState({ submitWarning: '' }) + this.setState({ submitWarning: '' }); } } if (statusUpdated && txDroppedOrConfirmed) { showTransactionConfirmedModal({ onSubmit: () => { - clearConfirmTransaction() - history.push(mostRecentOverviewPage) + clearConfirmTransaction(); + history.push(mostRecentOverviewPage); }, - }) + }); } if (toAddress && toAddress !== prevToAddress) { - tryReverseResolveAddress(toAddress) + tryReverseResolveAddress(toAddress); } } @@ -159,7 +159,7 @@ export default class ConfirmTransactionBase extends Component { hexTransactionFee, txData: { simulationFails, txParams: { value: amount } = {} } = {}, customGas, - } = this.props + } = this.props; const insufficientBalance = balance && @@ -168,20 +168,20 @@ export default class ConfirmTransactionBase extends Component { gasTotal: hexTransactionFee || '0x0', balance, conversionRate, - }) + }); if (insufficientBalance) { return { valid: false, errorKey: INSUFFICIENT_FUNDS_ERROR_KEY, - } + }; } if (hexToDecimal(customGas.gasLimit) < 21000) { return { valid: false, errorKey: GAS_LIMIT_TOO_LOW_ERROR_KEY, - } + }; } if (simulationFails) { @@ -190,12 +190,12 @@ export default class ConfirmTransactionBase extends Component { errorKey: simulationFails.errorKey ? simulationFails.errorKey : TRANSACTION_ERROR_KEY, - } + }; } return { valid: true, - } + }; } handleEditGas() { @@ -204,7 +204,7 @@ export default class ConfirmTransactionBase extends Component { actionKey, txData: { origin }, methodData = {}, - } = this.props + } = this.props; this.context.metricsEvent({ eventOpts: { @@ -220,9 +220,9 @@ export default class ConfirmTransactionBase extends Component { TRANSACTION_CATEGORIES.CONTRACT_INTERACTION, origin, }, - }) + }); - showCustomizeGasModal() + showCustomizeGasModal(); } renderDetails() { @@ -242,9 +242,9 @@ export default class ConfirmTransactionBase extends Component { nextNonce, getNextNonce, isMainnet, - } = this.props + } = this.props; - const notMainnetOrTest = !(isMainnet || process.env.IN_TEST) + const notMainnetOrTest = !(isMainnet || process.env.IN_TEST); return (
    @@ -313,11 +313,11 @@ export default class ConfirmTransactionBase extends Component { } onChange={({ target: { value } }) => { if (!value.length || Number(value) < 0) { - updateCustomNonce('') + updateCustomNonce(''); } else { - updateCustomNonce(String(Math.floor(value))) + updateCustomNonce(String(Math.floor(value))); } - getNextNonce() + getNextNonce(); }} fullWidth margin="dense" @@ -328,20 +328,20 @@ export default class ConfirmTransactionBase extends Component {
    ) : null} - ) + ); } renderData(functionType) { - const { t } = this.context + const { t } = this.context; const { txData: { txParams: { data } = {} } = {}, methodData: { params } = {}, hideData, dataComponent, - } = this.props + } = this.props; if (hideData) { - return null + return null; } return ( @@ -369,7 +369,7 @@ export default class ConfirmTransactionBase extends Component {
    {data}
    ) - ) + ); } handleEdit() { @@ -381,7 +381,7 @@ export default class ConfirmTransactionBase extends Component { actionKey, txData: { origin }, methodData = {}, - } = this.props + } = this.props; this.context.metricsEvent({ eventOpts: { @@ -397,9 +397,9 @@ export default class ConfirmTransactionBase extends Component { TRANSACTION_CATEGORIES.CONTRACT_INTERACTION, origin, }, - }) + }); - onEdit({ txData, tokenData, tokenProps }) + onEdit({ txData, tokenData, tokenProps }); } handleCancelAll() { @@ -410,21 +410,21 @@ export default class ConfirmTransactionBase extends Component { mostRecentOverviewPage, showRejectTransactionsConfirmationModal, unapprovedTxCount, - } = this.props + } = this.props; showRejectTransactionsConfirmationModal({ unapprovedTxCount, onSubmit: async () => { - this._removeBeforeUnload() - await cancelAllTransactions() - clearConfirmTransaction() - history.push(mostRecentOverviewPage) + this._removeBeforeUnload(); + await cancelAllTransactions(); + clearConfirmTransaction(); + history.push(mostRecentOverviewPage); }, - }) + }); } handleCancel() { - const { metricsEvent } = this.context + const { metricsEvent } = this.context; const { txData, cancelTransaction, @@ -435,9 +435,9 @@ export default class ConfirmTransactionBase extends Component { txData: { origin }, methodData = {}, updateCustomNonce, - } = this.props + } = this.props; - this._removeBeforeUnload() + this._removeBeforeUnload(); metricsEvent({ eventOpts: { category: 'Transactions', @@ -452,16 +452,16 @@ export default class ConfirmTransactionBase extends Component { TRANSACTION_CATEGORIES.CONTRACT_INTERACTION, origin, }, - }) - updateCustomNonce('') + }); + updateCustomNonce(''); cancelTransaction(txData).then(() => { - clearConfirmTransaction() - history.push(mostRecentOverviewPage) - }) + clearConfirmTransaction(); + history.push(mostRecentOverviewPage); + }); } handleSubmit() { - const { metricsEvent } = this.context + const { metricsEvent } = this.context; const { txData: { origin }, sendTransaction, @@ -474,11 +474,11 @@ export default class ConfirmTransactionBase extends Component { setMetaMetricsSendCount, methodData = {}, updateCustomNonce, - } = this.props - const { submitting } = this.state + } = this.props; + const { submitting } = this.state; if (submitting) { - return + return; } this.setState( @@ -487,7 +487,7 @@ export default class ConfirmTransactionBase extends Component { submitError: null, }, () => { - this._removeBeforeUnload() + this._removeBeforeUnload(); metricsEvent({ eventOpts: { category: 'Transactions', @@ -502,40 +502,40 @@ export default class ConfirmTransactionBase extends Component { TRANSACTION_CATEGORIES.CONTRACT_INTERACTION, origin, }, - }) + }); setMetaMetricsSendCount(metaMetricsSendCount + 1).then(() => { sendTransaction(txData) .then(() => { - clearConfirmTransaction() + clearConfirmTransaction(); this.setState( { submitting: false, }, () => { - history.push(mostRecentOverviewPage) - updateCustomNonce('') + history.push(mostRecentOverviewPage); + updateCustomNonce(''); }, - ) + ); }) .catch((error) => { this.setState({ submitting: false, submitError: error.message, - }) - updateCustomNonce('') - }) - }) + }); + updateCustomNonce(''); + }); + }); }, - ) + ); } renderTitleComponent() { - const { title, hexTransactionAmount } = this.props + const { title, hexTransactionAmount } = this.props; // Title string passed in by props takes priority if (title) { - return null + return null; } return ( @@ -546,11 +546,11 @@ export default class ConfirmTransactionBase extends Component { ethLogoHeight="26" hideLabel /> - ) + ); } renderSubtitleComponent() { - const { subtitleComponent, hexTransactionAmount } = this.props + const { subtitleComponent, hexTransactionAmount } = this.props; return ( subtitleComponent || ( @@ -561,22 +561,22 @@ export default class ConfirmTransactionBase extends Component { hideLabel /> ) - ) + ); } handleNextTx(txId) { - const { history, clearConfirmTransaction } = this.props + const { history, clearConfirmTransaction } = this.props; if (txId) { - clearConfirmTransaction() - history.push(`${CONFIRM_TRANSACTION_ROUTE}/${txId}`) + clearConfirmTransaction(); + history.push(`${CONFIRM_TRANSACTION_ROUTE}/${txId}`); } } getNavigateTxData() { - const { currentNetworkUnapprovedTxs, txData: { id } = {} } = this.props - const enumUnapprovedTxs = Object.keys(currentNetworkUnapprovedTxs) - const currentPosition = enumUnapprovedTxs.indexOf(id ? id.toString() : '') + const { currentNetworkUnapprovedTxs, txData: { id } = {} } = this.props; + const enumUnapprovedTxs = Object.keys(currentNetworkUnapprovedTxs); + const currentPosition = enumUnapprovedTxs.indexOf(id ? id.toString() : ''); return { totalTx: enumUnapprovedTxs.length, @@ -588,12 +588,12 @@ export default class ConfirmTransactionBase extends Component { lastTx: enumUnapprovedTxs[enumUnapprovedTxs.length - 1], ofText: this.context.t('ofTextNofM'), requestsWaitingText: this.context.t('requestsAwaitingAcknowledgement'), - } + }; } _beforeUnload = () => { - const { txData: { origin, id } = {}, cancelTransaction } = this.props - const { metricsEvent } = this.context + const { txData: { origin, id } = {}, cancelTransaction } = this.props; + const { metricsEvent } = this.context; metricsEvent({ eventOpts: { category: 'Transactions', @@ -603,15 +603,15 @@ export default class ConfirmTransactionBase extends Component { customVariables: { origin, }, - }) - cancelTransaction({ id }) - } + }); + cancelTransaction({ id }); + }; _removeBeforeUnload = () => { if (getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION) { - window.removeEventListener('beforeunload', this._beforeUnload) + window.removeEventListener('beforeunload', this._beforeUnload); } - } + }; componentDidMount() { const { @@ -619,8 +619,8 @@ export default class ConfirmTransactionBase extends Component { txData: { origin } = {}, getNextNonce, tryReverseResolveAddress, - } = this.props - const { metricsEvent } = this.context + } = this.props; + const { metricsEvent } = this.context; metricsEvent({ eventOpts: { category: 'Transactions', @@ -630,24 +630,24 @@ export default class ConfirmTransactionBase extends Component { customVariables: { origin, }, - }) + }); if (getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION) { - window.addEventListener('beforeunload', this._beforeUnload) + window.addEventListener('beforeunload', this._beforeUnload); } - getNextNonce() + getNextNonce(); if (toAddress) { - tryReverseResolveAddress(toAddress) + tryReverseResolveAddress(toAddress); } } componentWillUnmount() { - this._removeBeforeUnload() + this._removeBeforeUnload(); } render() { - const { t } = this.context + const { t } = this.context; const { isTxReprice, fromName, @@ -670,11 +670,11 @@ export default class ConfirmTransactionBase extends Component { hideSenderToRecipient, showAccountInHeader, txData, - } = this.props - const { submitting, submitError, submitWarning } = this.state + } = this.props; + const { submitting, submitError, submitWarning } = this.state; - const { name } = methodData - const { valid, errorKey } = this.getErrorKey() + const { name } = methodData; + const { valid, errorKey } = this.getErrorKey(); const { totalTx, positionOfCurrentTx, @@ -685,14 +685,14 @@ export default class ConfirmTransactionBase extends Component { lastTx, ofText, requestsWaitingText, - } = this.getNavigateTxData() + } = this.getNavigateTxData(); - let functionType = getMethodName(name) + let functionType = getMethodName(name); if (!functionType) { if (transactionCategory) { - functionType = t(transactionCategory) || transactionCategory + functionType = t(transactionCategory) || transactionCategory; } else { - functionType = t('contractInteraction') + functionType = t('contractInteraction'); } } @@ -739,17 +739,17 @@ export default class ConfirmTransactionBase extends Component { hideSenderToRecipient={hideSenderToRecipient} origin={txData.origin} /> - ) + ); } } export function getMethodName(camelCase) { if (!camelCase || typeof camelCase !== 'string') { - return '' + return ''; } return camelCase .replace(/([a-z])([A-Z])/gu, '$1 $2') .replace(/([A-Z])([a-z])/gu, ' $1$2') - .replace(/ +/gu, ' ') + .replace(/ +/gu, ' '); } diff --git a/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js index 09cece00e7..0875f88925 100644 --- a/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js +++ b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js @@ -1,8 +1,8 @@ -import { connect } from 'react-redux' -import { compose } from 'redux' -import { withRouter } from 'react-router-dom' -import contractMap from '@metamask/contract-metadata' -import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck' +import { connect } from 'react-redux'; +import { compose } from 'redux'; +import { withRouter } from 'react-router-dom'; +import contractMap from '@metamask/contract-metadata'; +import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck'; import { updateCustomNonce, @@ -14,20 +14,20 @@ import { updateTransaction, getNextNonce, tryReverseResolveAddress, -} from '../../store/actions' +} from '../../store/actions'; import { INSUFFICIENT_FUNDS_ERROR_KEY, GAS_LIMIT_TOO_LOW_ERROR_KEY, -} from '../../helpers/constants/error-keys' -import { getHexGasTotal } from '../../helpers/utils/confirm-tx.util' -import { isBalanceSufficient, calcGasTotal } from '../send/send.utils' -import { conversionGreaterThan } from '../../helpers/utils/conversion-util' -import { MIN_GAS_LIMIT_DEC } from '../send/send.constants' +} from '../../helpers/constants/error-keys'; +import { getHexGasTotal } from '../../helpers/utils/confirm-tx.util'; +import { isBalanceSufficient, calcGasTotal } from '../send/send.utils'; +import { conversionGreaterThan } from '../../helpers/utils/conversion-util'; +import { MIN_GAS_LIMIT_DEC } from '../send/send.constants'; import { checksumAddress, shortenAddress, valuesFor, -} from '../../helpers/utils/util' +} from '../../helpers/utils/util'; import { getAdvancedInlineGasShown, getCustomNonceValue, @@ -37,36 +37,36 @@ import { getUseNonceField, getPreferences, transactionFeeSelector, -} from '../../selectors' -import { getMostRecentOverviewPage } from '../../ducks/history/history' -import ConfirmTransactionBase from './confirm-transaction-base.component' +} from '../../selectors'; +import { getMostRecentOverviewPage } from '../../ducks/history/history'; +import ConfirmTransactionBase from './confirm-transaction-base.component'; const casedContractMap = Object.keys(contractMap).reduce((acc, base) => { return { ...acc, [base.toLowerCase()]: contractMap[base], - } -}, {}) + }; +}, {}); -let customNonceValue = '' +let customNonceValue = ''; const customNonceMerge = (txData) => customNonceValue ? { ...txData, customNonceValue, } - : txData + : txData; const mapStateToProps = (state, ownProps) => { const { toAddress: propsToAddress, customTxParamsData, match: { params = {} }, - } = ownProps - const { id: paramsTransactionId } = params - const { showFiatInTestnets } = getPreferences(state) - const isMainnet = getIsMainnet(state) - const { confirmTransaction, metamask } = state + } = ownProps; + const { id: paramsTransactionId } = params; + const { showFiatInTestnets } = getPreferences(state); + const isMainnet = getIsMainnet(state); + const { confirmTransaction, metamask } = state; const { ensResolutionsByAddress, conversionRate, @@ -77,18 +77,18 @@ const mapStateToProps = (state, ownProps) => { unapprovedTxs, metaMetricsSendCount, nextNonce, - } = metamask - const { tokenData, txData, tokenProps, nonce } = confirmTransaction + } = metamask; + const { tokenData, txData, tokenProps, nonce } = confirmTransaction; const { txParams = {}, lastGasPrice, id: transactionId, transactionCategory, - } = txData + } = txData; const transaction = Object.values(unapprovedTxs).find( ({ id }) => id === (transactionId || Number(paramsTransactionId)), - ) || {} + ) || {}; const { from: fromAddress, to: txParamsToAddress, @@ -96,51 +96,51 @@ const mapStateToProps = (state, ownProps) => { gas: gasLimit, value: amount, data, - } = (transaction && transaction.txParams) || txParams - const accounts = getMetaMaskAccounts(state) - const assetImage = assetImages[txParamsToAddress] + } = (transaction && transaction.txParams) || txParams; + const accounts = getMetaMaskAccounts(state); + const assetImage = assetImages[txParamsToAddress]; - const { balance } = accounts[fromAddress] - const { name: fromName } = identities[fromAddress] - const toAddress = propsToAddress || txParamsToAddress + const { balance } = accounts[fromAddress]; + const { name: fromName } = identities[fromAddress]; + const toAddress = propsToAddress || txParamsToAddress; const toName = identities[toAddress]?.name || casedContractMap[toAddress]?.name || - shortenAddress(checksumAddress(toAddress)) + shortenAddress(checksumAddress(toAddress)); - const checksummedAddress = checksumAddress(toAddress) - const addressBookObject = addressBook[checksummedAddress] - const toEns = ensResolutionsByAddress[checksummedAddress] || '' - const toNickname = addressBookObject ? addressBookObject.name : '' - const isTxReprice = Boolean(lastGasPrice) - const transactionStatus = transaction ? transaction.status : '' + const checksummedAddress = checksumAddress(toAddress); + const addressBookObject = addressBook[checksummedAddress]; + const toEns = ensResolutionsByAddress[checksummedAddress] || ''; + const toNickname = addressBookObject ? addressBookObject.name : ''; + const isTxReprice = Boolean(lastGasPrice); + const transactionStatus = transaction ? transaction.status : ''; const { hexTransactionAmount, hexTransactionFee, hexTransactionTotal, - } = transactionFeeSelector(state, transaction) + } = transactionFeeSelector(state, transaction); if (transaction && transaction.simulationFails) { - txData.simulationFails = transaction.simulationFails + txData.simulationFails = transaction.simulationFails; } const currentNetworkUnapprovedTxs = Object.keys(unapprovedTxs) .filter((key) => unapprovedTxs[key].metamaskNetworkId === network) - .reduce((acc, key) => ({ ...acc, [key]: unapprovedTxs[key] }), {}) - const unapprovedTxCount = valuesFor(currentNetworkUnapprovedTxs).length + .reduce((acc, key) => ({ ...acc, [key]: unapprovedTxs[key] }), {}); + const unapprovedTxCount = valuesFor(currentNetworkUnapprovedTxs).length; const insufficientBalance = !isBalanceSufficient({ amount, gasTotal: calcGasTotal(gasLimit, gasPrice), balance, conversionRate, - }) + }); - const methodData = getKnownMethodData(state, data) || {} + const methodData = getKnownMethodData(state, data) || {}; - let fullTxData = { ...txData, ...transaction } + let fullTxData = { ...txData, ...transaction }; if (customTxParamsData) { fullTxData = { ...fullTxData, @@ -148,7 +148,7 @@ const mapStateToProps = (state, ownProps) => { ...fullTxData.txParams, data: customTxParamsData, }, - } + }; } return { @@ -189,29 +189,29 @@ const mapStateToProps = (state, ownProps) => { nextNonce, mostRecentOverviewPage: getMostRecentOverviewPage(state), isMainnet, - } -} + }; +}; export const mapDispatchToProps = (dispatch) => { return { tryReverseResolveAddress: (address) => { - return dispatch(tryReverseResolveAddress(address)) + return dispatch(tryReverseResolveAddress(address)); }, updateCustomNonce: (value) => { - customNonceValue = value - dispatch(updateCustomNonce(value)) + customNonceValue = value; + dispatch(updateCustomNonce(value)); }, clearConfirmTransaction: () => dispatch(clearConfirmTransaction()), showTransactionConfirmedModal: ({ onSubmit }) => { - return dispatch(showModal({ name: 'TRANSACTION_CONFIRMED', onSubmit })) + return dispatch(showModal({ name: 'TRANSACTION_CONFIRMED', onSubmit })); }, showCustomizeGasModal: ({ txData, onSubmit, validate }) => { return dispatch( showModal({ name: 'CUSTOMIZE_GAS', txData, onSubmit, validate }), - ) + ); }, updateGasAndCalculate: (updatedTx) => { - return dispatch(updateTransaction(updatedTx)) + return dispatch(updateTransaction(updatedTx)); }, showRejectTransactionsConfirmationModal: ({ onSubmit, @@ -219,7 +219,7 @@ export const mapDispatchToProps = (dispatch) => { }) => { return dispatch( showModal({ name: 'REJECT_TRANSACTIONS', onSubmit, unapprovedTxCount }), - ) + ); }, cancelTransaction: ({ id }) => dispatch(cancelTx({ id })), cancelAllTransactions: (txList) => dispatch(cancelTxs(txList)), @@ -227,26 +227,26 @@ export const mapDispatchToProps = (dispatch) => { dispatch(updateAndApproveTx(customNonceMerge(txData))), setMetaMetricsSendCount: (val) => dispatch(setMetaMetricsSendCount(val)), getNextNonce: () => dispatch(getNextNonce()), - } -} + }; +}; const getValidateEditGas = ({ balance, conversionRate, txData }) => { - const { txParams: { value: amount } = {} } = txData + const { txParams: { value: amount } = {} } = txData; return ({ gasLimit, gasPrice }) => { - const gasTotal = getHexGasTotal({ gasLimit, gasPrice }) + const gasTotal = getHexGasTotal({ gasLimit, gasPrice }); const hasSufficientBalance = isBalanceSufficient({ amount, gasTotal, balance, conversionRate, - }) + }); if (!hasSufficientBalance) { return { valid: false, errorKey: INSUFFICIENT_FUNDS_ERROR_KEY, - } + }; } const gasLimitTooLow = @@ -261,35 +261,35 @@ const getValidateEditGas = ({ balance, conversionRate, txData }) => { value: gasLimit, fromNumericBase: 'hex', }, - ) + ); if (gasLimitTooLow) { return { valid: false, errorKey: GAS_LIMIT_TOO_LOW_ERROR_KEY, - } + }; } return { valid: true, - } - } -} + }; + }; +}; const mergeProps = (stateProps, dispatchProps, ownProps) => { - const { balance, conversionRate, txData, unapprovedTxs } = stateProps + const { balance, conversionRate, txData, unapprovedTxs } = stateProps; const { cancelAllTransactions: dispatchCancelAllTransactions, showCustomizeGasModal: dispatchShowCustomizeGasModal, updateGasAndCalculate: dispatchUpdateGasAndCalculate, ...otherDispatchProps - } = dispatchProps + } = dispatchProps; const validateEditGas = getValidateEditGas({ balance, conversionRate, txData, - }) + }); return { ...stateProps, @@ -311,13 +311,13 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { gas: gasLimit, gasPrice, }, - } - dispatchUpdateGasAndCalculate(updatedTx) + }; + dispatchUpdateGasAndCalculate(updatedTx); }, - } -} + }; +}; export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps, mergeProps), -)(ConfirmTransactionBase) +)(ConfirmTransactionBase); diff --git a/ui/app/pages/confirm-transaction-base/index.js b/ui/app/pages/confirm-transaction-base/index.js index 9996e9aeb3..0ea19b073c 100644 --- a/ui/app/pages/confirm-transaction-base/index.js +++ b/ui/app/pages/confirm-transaction-base/index.js @@ -1 +1 @@ -export { default } from './confirm-transaction-base.container' +export { default } from './confirm-transaction-base.container'; diff --git a/ui/app/pages/confirm-transaction-base/tests/confirm-transaction-base.component.test.js b/ui/app/pages/confirm-transaction-base/tests/confirm-transaction-base.component.test.js index 96ddc2ff48..a46d89f95d 100644 --- a/ui/app/pages/confirm-transaction-base/tests/confirm-transaction-base.component.test.js +++ b/ui/app/pages/confirm-transaction-base/tests/confirm-transaction-base.component.test.js @@ -1,17 +1,17 @@ -import assert from 'assert' -import { getMethodName } from '../confirm-transaction-base.component' +import assert from 'assert'; +import { getMethodName } from '../confirm-transaction-base.component'; describe('ConfirmTransactionBase Component', function () { describe('getMethodName', function () { it('should get correct method names', function () { - assert.strictEqual(getMethodName(undefined), '') - assert.strictEqual(getMethodName({}), '') - assert.strictEqual(getMethodName('confirm'), 'confirm') - assert.strictEqual(getMethodName('balanceOf'), 'balance Of') + assert.strictEqual(getMethodName(undefined), ''); + assert.strictEqual(getMethodName({}), ''); + assert.strictEqual(getMethodName('confirm'), 'confirm'); + assert.strictEqual(getMethodName('balanceOf'), 'balance Of'); assert.strictEqual( getMethodName('ethToTokenSwapInput'), 'eth To Token Swap Input', - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.component.js b/ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.component.js index 0de4f2951a..18969e2335 100644 --- a/ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.component.js +++ b/ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.component.js @@ -1,7 +1,7 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import { Redirect } from 'react-router-dom' -import Loading from '../../components/ui/loading-screen' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { Redirect } from 'react-router-dom'; +import Loading from '../../components/ui/loading-screen'; import { CONFIRM_TRANSACTION_ROUTE, CONFIRM_DEPLOY_CONTRACT_PATH, @@ -13,68 +13,68 @@ import { SIGNATURE_REQUEST_PATH, DECRYPT_MESSAGE_REQUEST_PATH, ENCRYPTION_PUBLIC_KEY_REQUEST_PATH, -} from '../../helpers/constants/routes' -import { MESSAGE_TYPE } from '../../../../shared/constants/app' -import { TRANSACTION_CATEGORIES } from '../../../../shared/constants/transaction' +} from '../../helpers/constants/routes'; +import { MESSAGE_TYPE } from '../../../../shared/constants/app'; +import { TRANSACTION_CATEGORIES } from '../../../../shared/constants/transaction'; export default class ConfirmTransactionSwitch extends Component { static propTypes = { txData: PropTypes.object, - } + }; redirectToTransaction() { - const { txData } = this.props - const { id, txParams: { data } = {}, transactionCategory } = txData + const { txData } = this.props; + const { id, txParams: { data } = {}, transactionCategory } = txData; if (transactionCategory === TRANSACTION_CATEGORIES.DEPLOY_CONTRACT) { - const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_DEPLOY_CONTRACT_PATH}` - return + const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_DEPLOY_CONTRACT_PATH}`; + return ; } if (transactionCategory === TRANSACTION_CATEGORIES.SENT_ETHER) { - const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_SEND_ETHER_PATH}` - return + const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_SEND_ETHER_PATH}`; + return ; } if (data) { switch (transactionCategory) { case TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER: { - const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_SEND_TOKEN_PATH}` - return + const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_SEND_TOKEN_PATH}`; + return ; } case TRANSACTION_CATEGORIES.TOKEN_METHOD_APPROVE: { - const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_APPROVE_PATH}` - return + const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_APPROVE_PATH}`; + return ; } case TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER_FROM: { - const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_TRANSFER_FROM_PATH}` - return + const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_TRANSFER_FROM_PATH}`; + return ; } default: { - const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_TOKEN_METHOD_PATH}` - return + const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_TOKEN_METHOD_PATH}`; + return ; } } } - const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_SEND_ETHER_PATH}` - return + const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_SEND_ETHER_PATH}`; + return ; } render() { - const { txData } = this.props + const { txData } = this.props; if (txData.txParams) { - return this.redirectToTransaction() + return this.redirectToTransaction(); } else if (txData.msgParams) { - let pathname = `${CONFIRM_TRANSACTION_ROUTE}/${txData.id}${SIGNATURE_REQUEST_PATH}` + let pathname = `${CONFIRM_TRANSACTION_ROUTE}/${txData.id}${SIGNATURE_REQUEST_PATH}`; if (txData.type === MESSAGE_TYPE.ETH_DECRYPT) { - pathname = `${CONFIRM_TRANSACTION_ROUTE}/${txData.id}${DECRYPT_MESSAGE_REQUEST_PATH}` + pathname = `${CONFIRM_TRANSACTION_ROUTE}/${txData.id}${DECRYPT_MESSAGE_REQUEST_PATH}`; } else if (txData.type === MESSAGE_TYPE.ETH_GET_ENCRYPTION_PUBLIC_KEY) { - pathname = `${CONFIRM_TRANSACTION_ROUTE}/${txData.id}${ENCRYPTION_PUBLIC_KEY_REQUEST_PATH}` + pathname = `${CONFIRM_TRANSACTION_ROUTE}/${txData.id}${ENCRYPTION_PUBLIC_KEY_REQUEST_PATH}`; } - return + return ; } - return + return ; } } diff --git a/ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.container.js b/ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.container.js index 59d3f9555a..f0d0c5ec0f 100644 --- a/ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.container.js +++ b/ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.container.js @@ -1,27 +1,27 @@ -import { connect } from 'react-redux' -import { unconfirmedTransactionsListSelector } from '../../selectors' -import ConfirmTransactionSwitch from './confirm-transaction-switch.component' +import { connect } from 'react-redux'; +import { unconfirmedTransactionsListSelector } from '../../selectors'; +import ConfirmTransactionSwitch from './confirm-transaction-switch.component'; const mapStateToProps = (state, ownProps) => { const { metamask: { unapprovedTxs }, - } = state + } = state; const { match: { params = {}, url }, - } = ownProps - const urlId = url?.match(/\d+/u) && url?.match(/\d+/u)[0] - const { id: paramsId } = params - const transactionId = paramsId || urlId + } = ownProps; + const urlId = url?.match(/\d+/u) && url?.match(/\d+/u)[0]; + const { id: paramsId } = params; + const transactionId = paramsId || urlId; - const unconfirmedTransactions = unconfirmedTransactionsListSelector(state) - const totalUnconfirmed = unconfirmedTransactions.length + const unconfirmedTransactions = unconfirmedTransactionsListSelector(state); + const totalUnconfirmed = unconfirmedTransactions.length; const transaction = totalUnconfirmed ? unapprovedTxs[transactionId] || unconfirmedTransactions[0] - : {} + : {}; return { txData: transaction, - } -} + }; +}; -export default connect(mapStateToProps)(ConfirmTransactionSwitch) +export default connect(mapStateToProps)(ConfirmTransactionSwitch); diff --git a/ui/app/pages/confirm-transaction-switch/index.js b/ui/app/pages/confirm-transaction-switch/index.js index 86576d388b..6b5e0cbbf3 100644 --- a/ui/app/pages/confirm-transaction-switch/index.js +++ b/ui/app/pages/confirm-transaction-switch/index.js @@ -1,3 +1,3 @@ -import ConfirmTransactionSwitch from './confirm-transaction-switch.container' +import ConfirmTransactionSwitch from './confirm-transaction-switch.container'; -export default ConfirmTransactionSwitch +export default ConfirmTransactionSwitch; diff --git a/ui/app/pages/confirm-transaction/conf-tx.js b/ui/app/pages/confirm-transaction/conf-tx.js index 3298baae61..5acc1c4356 100644 --- a/ui/app/pages/confirm-transaction/conf-tx.js +++ b/ui/app/pages/confirm-transaction/conf-tx.js @@ -1,26 +1,26 @@ -import PropTypes from 'prop-types' -import React, { Component } from 'react' -import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom' -import { compose } from 'redux' -import log from 'loglevel' -import * as actions from '../../store/actions' -import txHelper from '../../../lib/tx-helper' -import SignatureRequest from '../../components/app/signature-request' -import SignatureRequestOriginal from '../../components/app/signature-request-original' -import Loading from '../../components/ui/loading-screen' -import { getMostRecentOverviewPage } from '../../ducks/history/history' -import { MESSAGE_TYPE } from '../../../../shared/constants/app' -import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction' +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import { connect } from 'react-redux'; +import { withRouter } from 'react-router-dom'; +import { compose } from 'redux'; +import log from 'loglevel'; +import * as actions from '../../store/actions'; +import txHelper from '../../../lib/tx-helper'; +import SignatureRequest from '../../components/app/signature-request'; +import SignatureRequestOriginal from '../../components/app/signature-request-original'; +import Loading from '../../components/ui/loading-screen'; +import { getMostRecentOverviewPage } from '../../ducks/history/history'; +import { MESSAGE_TYPE } from '../../../../shared/constants/app'; +import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'; function mapStateToProps(state) { - const { metamask, appState } = state + const { metamask, appState } = state; const { unapprovedMsgCount, unapprovedPersonalMsgCount, unapprovedTypedMessagesCount, - } = metamask - const { txId } = appState + } = metamask; + const { txId } = appState; return { identities: state.metamask.identities, @@ -39,7 +39,7 @@ function mapStateToProps(state) { unapprovedTypedMessagesCount, send: state.metamask.send, currentNetworkTxList: state.metamask.currentNetworkTxList, - } + }; } class ConfirmTxScreen extends Component { @@ -69,20 +69,20 @@ class ConfirmTxScreen extends Component { send: PropTypes.shape({ to: PropTypes.string, }).isRequired, - } + }; getUnapprovedMessagesTotal() { const { unapprovedMsgCount = 0, unapprovedPersonalMsgCount = 0, unapprovedTypedMessagesCount = 0, - } = this.props + } = this.props; return ( unapprovedTypedMessagesCount + unapprovedMsgCount + unapprovedPersonalMsgCount - ) + ); } getTxData() { @@ -94,7 +94,7 @@ class ConfirmTxScreen extends Component { unapprovedPersonalMsgs, unapprovedTypedMessages, match: { params: { id: transactionId } = {} }, - } = this.props + } = this.props; const unconfTxList = txHelper( unapprovedTxs, @@ -102,13 +102,13 @@ class ConfirmTxScreen extends Component { unapprovedPersonalMsgs, unapprovedTypedMessages, network, - ) + ); - log.info(`rendering a combined ${unconfTxList.length} unconf msgs & txs`) + log.info(`rendering a combined ${unconfTxList.length} unconf msgs & txs`); return transactionId ? unconfTxList.find(({ id }) => `${id}` === transactionId) - : unconfTxList[index] + : unconfTxList[index]; } signatureSelect(type, version) { @@ -117,58 +117,58 @@ class ConfirmTxScreen extends Component { type === MESSAGE_TYPE.ETH_SIGN_TYPED_DATA && (version === 'V3' || version === 'V4') ) { - return SignatureRequest + return SignatureRequest; } - return SignatureRequestOriginal + return SignatureRequestOriginal; } signMessage(msgData, event) { - log.info('conf-tx.js: signing message') - const params = msgData.msgParams - params.metamaskId = msgData.id - this.stopPropagation(event) - return this.props.dispatch(actions.signMsg(params)) + log.info('conf-tx.js: signing message'); + const params = msgData.msgParams; + params.metamaskId = msgData.id; + this.stopPropagation(event); + return this.props.dispatch(actions.signMsg(params)); } stopPropagation(event) { if (event.stopPropagation) { - event.stopPropagation() + event.stopPropagation(); } } signPersonalMessage(msgData, event) { - log.info('conf-tx.js: signing personal message') - const params = msgData.msgParams - params.metamaskId = msgData.id - this.stopPropagation(event) - return this.props.dispatch(actions.signPersonalMsg(params)) + log.info('conf-tx.js: signing personal message'); + const params = msgData.msgParams; + params.metamaskId = msgData.id; + this.stopPropagation(event); + return this.props.dispatch(actions.signPersonalMsg(params)); } signTypedMessage(msgData, event) { - log.info('conf-tx.js: signing typed message') - const params = msgData.msgParams - params.metamaskId = msgData.id - this.stopPropagation(event) - return this.props.dispatch(actions.signTypedMsg(params)) + log.info('conf-tx.js: signing typed message'); + const params = msgData.msgParams; + params.metamaskId = msgData.id; + this.stopPropagation(event); + return this.props.dispatch(actions.signTypedMsg(params)); } cancelMessage(msgData, event) { - log.info('canceling message') - this.stopPropagation(event) - return this.props.dispatch(actions.cancelMsg(msgData)) + log.info('canceling message'); + this.stopPropagation(event); + return this.props.dispatch(actions.cancelMsg(msgData)); } cancelPersonalMessage(msgData, event) { - log.info('canceling personal message') - this.stopPropagation(event) - return this.props.dispatch(actions.cancelPersonalMsg(msgData)) + log.info('canceling personal message'); + this.stopPropagation(event); + return this.props.dispatch(actions.cancelPersonalMsg(msgData)); } cancelTypedMessage(msgData, event) { - log.info('canceling typed message') - this.stopPropagation(event) - return this.props.dispatch(actions.cancelTypedMsg(msgData)) + log.info('canceling typed message'); + this.stopPropagation(event); + return this.props.dispatch(actions.cancelTypedMsg(msgData)); } componentDidMount() { @@ -178,15 +178,15 @@ class ConfirmTxScreen extends Component { mostRecentOverviewPage, network, send, - } = this.props - const unconfTxList = txHelper(unapprovedTxs, {}, {}, {}, network) + } = this.props; + const unconfTxList = txHelper(unapprovedTxs, {}, {}, {}, network); if ( unconfTxList.length === 0 && !send.to && this.getUnapprovedMessagesTotal() === 0 ) { - history.push(mostRecentOverviewPage) + history.push(mostRecentOverviewPage); } } @@ -199,20 +199,21 @@ class ConfirmTxScreen extends Component { history, match: { params: { id: transactionId } = {} }, mostRecentOverviewPage, - } = this.props + } = this.props; - let prevTx + let prevTx; if (transactionId) { - prevTx = currentNetworkTxList.find(({ id }) => `${id}` === transactionId) + prevTx = currentNetworkTxList.find(({ id }) => `${id}` === transactionId); } else { - const { index: prevIndex, unapprovedTxs: prevUnapprovedTxs } = prevProps - const prevUnconfTxList = txHelper(prevUnapprovedTxs, {}, {}, {}, network) - const prevTxData = prevUnconfTxList[prevIndex] || {} - prevTx = currentNetworkTxList.find(({ id }) => id === prevTxData.id) || {} + const { index: prevIndex, unapprovedTxs: prevUnapprovedTxs } = prevProps; + const prevUnconfTxList = txHelper(prevUnapprovedTxs, {}, {}, {}, network); + const prevTxData = prevUnconfTxList[prevIndex] || {}; + prevTx = + currentNetworkTxList.find(({ id }) => id === prevTxData.id) || {}; } - const unconfTxList = txHelper(unapprovedTxs, {}, {}, {}, network) + const unconfTxList = txHelper(unapprovedTxs, {}, {}, {}, network); if (prevTx && prevTx.status === TRANSACTION_STATUSES.DROPPED) { this.props.dispatch( @@ -220,9 +221,9 @@ class ConfirmTxScreen extends Component { name: 'TRANSACTION_CONFIRMED', onSubmit: () => history.push(mostRecentOverviewPage), }), - ) + ); - return + return; } if ( @@ -230,26 +231,26 @@ class ConfirmTxScreen extends Component { !send.to && this.getUnapprovedMessagesTotal() === 0 ) { - this.props.history.push(mostRecentOverviewPage) + this.props.history.push(mostRecentOverviewPage); } } render() { - const { currentCurrency, blockGasLimit } = this.props + const { currentCurrency, blockGasLimit } = this.props; - const txData = this.getTxData() || {} + const txData = this.getTxData() || {}; const { msgParams, type, msgParams: { version }, - } = txData - log.debug('msgParams detected, rendering pending msg') + } = txData; + log.debug('msgParams detected, rendering pending msg'); if (!msgParams) { - return + return ; } - const SigComponent = this.signatureSelect(type, version) + const SigComponent = this.signatureSelect(type, version); return ( - ) + ); } } -export default compose(withRouter, connect(mapStateToProps))(ConfirmTxScreen) +export default compose(withRouter, connect(mapStateToProps))(ConfirmTxScreen); diff --git a/ui/app/pages/confirm-transaction/confirm-transaction.component.js b/ui/app/pages/confirm-transaction/confirm-transaction.component.js index d794717ae0..c08b4f387b 100644 --- a/ui/app/pages/confirm-transaction/confirm-transaction.component.js +++ b/ui/app/pages/confirm-transaction/confirm-transaction.component.js @@ -1,16 +1,16 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import { Switch, Route } from 'react-router-dom' -import Loading from '../../components/ui/loading-screen' -import ConfirmTransactionSwitch from '../confirm-transaction-switch' -import ConfirmTransactionBase from '../confirm-transaction-base' -import ConfirmSendEther from '../confirm-send-ether' -import ConfirmSendToken from '../confirm-send-token' -import ConfirmDeployContract from '../confirm-deploy-contract' -import ConfirmApprove from '../confirm-approve' -import ConfirmTokenTransactionBaseContainer from '../confirm-token-transaction-base' -import ConfirmDecryptMessage from '../confirm-decrypt-message' -import ConfirmEncryptionPublicKey from '../confirm-encryption-public-key' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { Switch, Route } from 'react-router-dom'; +import Loading from '../../components/ui/loading-screen'; +import ConfirmTransactionSwitch from '../confirm-transaction-switch'; +import ConfirmTransactionBase from '../confirm-transaction-base'; +import ConfirmSendEther from '../confirm-send-ether'; +import ConfirmSendToken from '../confirm-send-token'; +import ConfirmDeployContract from '../confirm-deploy-contract'; +import ConfirmApprove from '../confirm-approve'; +import ConfirmTokenTransactionBaseContainer from '../confirm-token-transaction-base'; +import ConfirmDecryptMessage from '../confirm-decrypt-message'; +import ConfirmEncryptionPublicKey from '../confirm-encryption-public-key'; import { CONFIRM_TRANSACTION_ROUTE, @@ -23,13 +23,13 @@ import { SIGNATURE_REQUEST_PATH, DECRYPT_MESSAGE_REQUEST_PATH, ENCRYPTION_PUBLIC_KEY_REQUEST_PATH, -} from '../../helpers/constants/routes' -import ConfTx from './conf-tx' +} from '../../helpers/constants/routes'; +import ConfTx from './conf-tx'; export default class ConfirmTransaction extends Component { static contextTypes = { metricsEvent: PropTypes.func, - } + }; static propTypes = { history: PropTypes.object.isRequired, @@ -45,7 +45,7 @@ export default class ConfirmTransaction extends Component { paramsTransactionId: PropTypes.string, getTokenParams: PropTypes.func, isTokenMethodAction: PropTypes.bool, - } + }; componentDidMount() { const { @@ -60,21 +60,21 @@ export default class ConfirmTransaction extends Component { paramsTransactionId, getTokenParams, isTokenMethodAction, - } = this.props + } = this.props; if (!totalUnapprovedCount && !send.to) { - history.replace(mostRecentOverviewPage) - return + history.replace(mostRecentOverviewPage); + return; } - fetchBasicGasEstimates() - getContractMethodData(data) + fetchBasicGasEstimates(); + getContractMethodData(data); if (isTokenMethodAction) { - getTokenParams(to) + getTokenParams(to); } - const txId = transactionId || paramsTransactionId + const txId = transactionId || paramsTransactionId; if (txId) { - this.props.setTransactionToConfirm(txId) + this.props.setTransactionToConfirm(txId); } } @@ -89,33 +89,33 @@ export default class ConfirmTransaction extends Component { history, mostRecentOverviewPage, totalUnapprovedCount, - } = this.props + } = this.props; if ( paramsTransactionId && transactionId && prevProps.paramsTransactionId !== paramsTransactionId ) { - clearConfirmTransaction() - getContractMethodData(data) - setTransactionToConfirm(paramsTransactionId) + clearConfirmTransaction(); + getContractMethodData(data); + setTransactionToConfirm(paramsTransactionId); } else if ( prevProps.transactionId && !transactionId && !totalUnapprovedCount ) { - history.replace(mostRecentOverviewPage) + history.replace(mostRecentOverviewPage); } else if ( prevProps.transactionId && transactionId && prevProps.transactionId !== transactionId ) { - history.replace(mostRecentOverviewPage) + history.replace(mostRecentOverviewPage); } } render() { - const { transactionId, paramsTransactionId } = this.props + const { transactionId, paramsTransactionId } = this.props; // Show routes when state.confirmTransaction has been set and when either the ID in the params // isn't specified or is specified and matches the ID in state.confirmTransaction in order to // support URLs of /confirm-transaction or /confirm-transaction/ @@ -171,6 +171,6 @@ export default class ConfirmTransaction extends Component { ) : ( - ) + ); } } diff --git a/ui/app/pages/confirm-transaction/confirm-transaction.container.js b/ui/app/pages/confirm-transaction/confirm-transaction.container.js index 8dc56236d7..d076652563 100644 --- a/ui/app/pages/confirm-transaction/confirm-transaction.container.js +++ b/ui/app/pages/confirm-transaction/confirm-transaction.container.js @@ -1,33 +1,33 @@ -import { connect } from 'react-redux' -import { compose } from 'redux' -import { withRouter } from 'react-router-dom' +import { connect } from 'react-redux'; +import { compose } from 'redux'; +import { withRouter } from 'react-router-dom'; import { setTransactionToConfirm, clearConfirmTransaction, -} from '../../ducks/confirm-transaction/confirm-transaction.duck' -import { isTokenMethodAction } from '../../helpers/utils/transactions.util' -import { fetchBasicGasEstimates } from '../../ducks/gas/gas.duck' +} from '../../ducks/confirm-transaction/confirm-transaction.duck'; +import { isTokenMethodAction } from '../../helpers/utils/transactions.util'; +import { fetchBasicGasEstimates } from '../../ducks/gas/gas.duck'; -import { getContractMethodData, getTokenParams } from '../../store/actions' -import { unconfirmedTransactionsListSelector } from '../../selectors' -import { getMostRecentOverviewPage } from '../../ducks/history/history' -import ConfirmTransaction from './confirm-transaction.component' +import { getContractMethodData, getTokenParams } from '../../store/actions'; +import { unconfirmedTransactionsListSelector } from '../../selectors'; +import { getMostRecentOverviewPage } from '../../ducks/history/history'; +import ConfirmTransaction from './confirm-transaction.component'; const mapStateToProps = (state, ownProps) => { const { metamask: { send, unapprovedTxs }, - } = state + } = state; const { match: { params = {} }, - } = ownProps - const { id } = params + } = ownProps; + const { id } = params; - const unconfirmedTransactions = unconfirmedTransactionsListSelector(state) - const totalUnconfirmed = unconfirmedTransactions.length + const unconfirmedTransactions = unconfirmedTransactionsListSelector(state); + const totalUnconfirmed = unconfirmedTransactions.length; const transaction = totalUnconfirmed ? unapprovedTxs[id] || unconfirmedTransactions[0] - : {} - const { id: transactionId, transactionCategory } = transaction + : {}; + const { id: transactionId, transactionCategory } = transaction; return { totalUnapprovedCount: totalUnconfirmed, @@ -39,22 +39,22 @@ const mapStateToProps = (state, ownProps) => { transactionId: transactionId && String(transactionId), transaction, isTokenMethodAction: isTokenMethodAction(transactionCategory), - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { setTransactionToConfirm: (transactionId) => { - dispatch(setTransactionToConfirm(transactionId)) + dispatch(setTransactionToConfirm(transactionId)); }, clearConfirmTransaction: () => dispatch(clearConfirmTransaction()), fetchBasicGasEstimates: () => dispatch(fetchBasicGasEstimates()), getContractMethodData: (data) => dispatch(getContractMethodData(data)), getTokenParams: (tokenAddress) => dispatch(getTokenParams(tokenAddress)), - } -} + }; +}; export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps), -)(ConfirmTransaction) +)(ConfirmTransaction); diff --git a/ui/app/pages/confirm-transaction/index.js b/ui/app/pages/confirm-transaction/index.js index a51e7b1629..108e7e8874 100644 --- a/ui/app/pages/confirm-transaction/index.js +++ b/ui/app/pages/confirm-transaction/index.js @@ -1,3 +1,3 @@ -import ConfirmTransaction from './confirm-transaction.container' +import ConfirmTransaction from './confirm-transaction.container'; -export default ConfirmTransaction +export default ConfirmTransaction; diff --git a/ui/app/pages/connected-accounts/connected-accounts.component.js b/ui/app/pages/connected-accounts/connected-accounts.component.js index 5a0a30109f..5b9e5f06f6 100644 --- a/ui/app/pages/connected-accounts/connected-accounts.component.js +++ b/ui/app/pages/connected-accounts/connected-accounts.component.js @@ -1,18 +1,18 @@ -import PropTypes from 'prop-types' -import React, { PureComponent } from 'react' -import Popover from '../../components/ui/popover' -import ConnectedAccountsList from '../../components/app/connected-accounts-list' -import ConnectedAccountsPermissions from '../../components/app/connected-accounts-permissions' +import PropTypes from 'prop-types'; +import React, { PureComponent } from 'react'; +import Popover from '../../components/ui/popover'; +import ConnectedAccountsList from '../../components/app/connected-accounts-list'; +import ConnectedAccountsPermissions from '../../components/app/connected-accounts-permissions'; export default class ConnectedAccounts extends PureComponent { static contextTypes = { t: PropTypes.func.isRequired, - } + }; static defaultProps = { accountToConnect: null, permissions: undefined, - } + }; static propTypes = { accountToConnect: PropTypes.object, @@ -26,7 +26,7 @@ export default class ConnectedAccounts extends PureComponent { removePermittedAccount: PropTypes.func.isRequired, setSelectedAddress: PropTypes.func.isRequired, history: PropTypes.object.isRequired, - } + }; render() { const { @@ -41,13 +41,13 @@ export default class ConnectedAccounts extends PureComponent { selectedAddress, removePermittedAccount, setSelectedAddress, - } = this.props - const { t } = this.context + } = this.props; + const { t } = this.context; const connectedAccountsDescription = connectedAccounts.length > 1 ? t('connectedAccountsDescriptionPlural', [connectedAccounts.length]) - : t('connectedAccountsDescriptionSingular') + : t('connectedAccountsDescriptionSingular'); return ( - ) + ); } } diff --git a/ui/app/pages/connected-accounts/connected-accounts.container.js b/ui/app/pages/connected-accounts/connected-accounts.container.js index b1a1a24337..8a8cffb3b5 100644 --- a/ui/app/pages/connected-accounts/connected-accounts.container.js +++ b/ui/app/pages/connected-accounts/connected-accounts.container.js @@ -1,27 +1,27 @@ -import { connect } from 'react-redux' +import { connect } from 'react-redux'; import { getAccountToConnectToActiveTab, getOrderedConnectedAccountsForActiveTab, getPermissionsForActiveTab, getSelectedAddress, -} from '../../selectors' -import { isExtensionUrl } from '../../helpers/utils/util' +} from '../../selectors'; +import { isExtensionUrl } from '../../helpers/utils/util'; import { addPermittedAccount, removePermittedAccount, setSelectedAddress, -} from '../../store/actions' -import { getMostRecentOverviewPage } from '../../ducks/history/history' -import ConnectedAccounts from './connected-accounts.component' +} from '../../store/actions'; +import { getMostRecentOverviewPage } from '../../ducks/history/history'; +import ConnectedAccounts from './connected-accounts.component'; const mapStateToProps = (state) => { - const { activeTab } = state - const accountToConnect = getAccountToConnectToActiveTab(state) - const connectedAccounts = getOrderedConnectedAccountsForActiveTab(state) - const permissions = getPermissionsForActiveTab(state) - const selectedAddress = getSelectedAddress(state) + const { activeTab } = state; + const accountToConnect = getAccountToConnectToActiveTab(state); + const connectedAccounts = getOrderedConnectedAccountsForActiveTab(state); + const permissions = getPermissionsForActiveTab(state); + const selectedAddress = getSelectedAddress(state); - const isActiveTabExtension = isExtensionUrl(activeTab) + const isActiveTabExtension = isExtensionUrl(activeTab); return { accountToConnect, isActiveTabExtension, @@ -30,8 +30,8 @@ const mapStateToProps = (state) => { mostRecentOverviewPage: getMostRecentOverviewPage(state), permissions, selectedAddress, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { @@ -40,11 +40,11 @@ const mapDispatchToProps = (dispatch) => { removePermittedAccount: (origin, address) => dispatch(removePermittedAccount(origin, address)), setSelectedAddress: (address) => dispatch(setSelectedAddress(address)), - } -} + }; +}; const mergeProps = (stateProps, dispatchProps, ownProps) => { - const { activeTabOrigin } = stateProps + const { activeTabOrigin } = stateProps; return { ...ownProps, @@ -54,11 +54,11 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { dispatchProps.addPermittedAccount(activeTabOrigin, address), removePermittedAccount: (address) => dispatchProps.removePermittedAccount(activeTabOrigin, address), - } -} + }; +}; export default connect( mapStateToProps, mapDispatchToProps, mergeProps, -)(ConnectedAccounts) +)(ConnectedAccounts); diff --git a/ui/app/pages/connected-accounts/index.js b/ui/app/pages/connected-accounts/index.js index 7497bc560e..d97dbc5a84 100644 --- a/ui/app/pages/connected-accounts/index.js +++ b/ui/app/pages/connected-accounts/index.js @@ -1 +1 @@ -export { default } from './connected-accounts.container' +export { default } from './connected-accounts.container'; diff --git a/ui/app/pages/connected-sites/connected-sites.component.js b/ui/app/pages/connected-sites/connected-sites.component.js index 5c8f84e5f2..90d880811e 100644 --- a/ui/app/pages/connected-sites/connected-sites.component.js +++ b/ui/app/pages/connected-sites/connected-sites.component.js @@ -1,17 +1,17 @@ -import PropTypes from 'prop-types' -import React, { Component } from 'react' -import ConnectedSitesList from '../../components/app/connected-sites-list' -import Popover from '../../components/ui/popover/popover.component' -import Button from '../../components/ui/button' +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import ConnectedSitesList from '../../components/app/connected-sites-list'; +import Popover from '../../components/ui/popover/popover.component'; +import Button from '../../components/ui/button'; export default class ConnectedSites extends Component { static contextTypes = { t: PropTypes.func, - } + }; static defaultProps = { tabToConnect: null, - } + }; static propTypes = { accountLabel: PropTypes.string.isRequired, @@ -26,15 +26,15 @@ export default class ConnectedSites extends Component { ).isRequired, tabToConnect: PropTypes.object, requestAccountsPermission: PropTypes.func.isRequired, - } + }; state = { sitePendingDisconnect: null, - } + }; componentDidMount() { - const { getOpenMetamaskTabsIds } = this.props - getOpenMetamaskTabsIds() + const { getOpenMetamaskTabsIds } = this.props; + getOpenMetamaskTabsIds(); } setPendingDisconnect = (domainKey) => { @@ -42,30 +42,30 @@ export default class ConnectedSites extends Component { sitePendingDisconnect: { domainKey, }, - }) - } + }); + }; clearPendingDisconnect = () => { this.setState({ sitePendingDisconnect: null, - }) - } + }); + }; disconnectAccount = () => { - const { disconnectAccount } = this.props - const { sitePendingDisconnect } = this.state + const { disconnectAccount } = this.props; + const { sitePendingDisconnect } = this.state; - disconnectAccount(sitePendingDisconnect.domainKey) - this.clearPendingDisconnect() - } + disconnectAccount(sitePendingDisconnect.domainKey); + this.clearPendingDisconnect(); + }; disconnectAllAccounts = () => { - const { disconnectAllAccounts } = this.props - const { sitePendingDisconnect } = this.state + const { disconnectAllAccounts } = this.props; + const { sitePendingDisconnect } = this.state; - disconnectAllAccounts(sitePendingDisconnect.domainKey) - this.clearPendingDisconnect() - } + disconnectAllAccounts(sitePendingDisconnect.domainKey); + this.clearPendingDisconnect(); + }; renderConnectedSitesList() { return ( @@ -74,7 +74,7 @@ export default class ConnectedSites extends Component { connectedDomains={this.props.connectedDomains} onDisconnect={this.setPendingDisconnect} /> - ) + ); } renderConnectedSitesPopover() { @@ -84,8 +84,8 @@ export default class ConnectedSites extends Component { connectedDomains, tabToConnect, requestAccountsPermission, - } = this.props - const { t } = this.context + } = this.props; + const { t } = this.context; return ( {this.renderConnectedSitesList()} - ) + ); } renderDisconnectPopover() { - const { closePopover, permittedAccountsByOrigin } = this.props - const { t } = this.context + const { closePopover, permittedAccountsByOrigin } = this.props; + const { t } = this.context; const { sitePendingDisconnect: { domainKey }, - } = this.state + } = this.state; - const numPermittedAccounts = permittedAccountsByOrigin[domainKey].length + const numPermittedAccounts = permittedAccountsByOrigin[domainKey].length; return ( - ) + ); } render() { - const { sitePendingDisconnect } = this.state + const { sitePendingDisconnect } = this.state; return sitePendingDisconnect ? this.renderDisconnectPopover() - : this.renderConnectedSitesPopover() + : this.renderConnectedSitesPopover(); } } diff --git a/ui/app/pages/connected-sites/connected-sites.container.js b/ui/app/pages/connected-sites/connected-sites.container.js index ef5edd85b2..39c8150c87 100644 --- a/ui/app/pages/connected-sites/connected-sites.container.js +++ b/ui/app/pages/connected-sites/connected-sites.container.js @@ -1,10 +1,10 @@ -import { connect } from 'react-redux' +import { connect } from 'react-redux'; import { getOpenMetamaskTabsIds, requestAccountsPermissionWithId, removePermissionsFor, removePermittedAccount, -} from '../../store/actions' +} from '../../store/actions'; import { getConnectedDomainsForSelectedAddress, getCurrentAccountWithSendEtherInfo, @@ -13,27 +13,27 @@ import { getPermissionsMetadataHostCounts, getPermittedAccountsByOrigin, getSelectedAddress, -} from '../../selectors' -import { CONNECT_ROUTE } from '../../helpers/constants/routes' -import { getMostRecentOverviewPage } from '../../ducks/history/history' -import ConnectedSites from './connected-sites.component' +} from '../../selectors'; +import { CONNECT_ROUTE } from '../../helpers/constants/routes'; +import { getMostRecentOverviewPage } from '../../ducks/history/history'; +import ConnectedSites from './connected-sites.component'; const mapStateToProps = (state) => { - const { openMetaMaskTabs } = state.appState - const { id } = state.activeTab - const connectedDomains = getConnectedDomainsForSelectedAddress(state) - const originOfCurrentTab = getOriginOfCurrentTab(state) - const permittedAccountsByOrigin = getPermittedAccountsByOrigin(state) - const selectedAddress = getSelectedAddress(state) + const { openMetaMaskTabs } = state.appState; + const { id } = state.activeTab; + const connectedDomains = getConnectedDomainsForSelectedAddress(state); + const originOfCurrentTab = getOriginOfCurrentTab(state); + const permittedAccountsByOrigin = getPermittedAccountsByOrigin(state); + const selectedAddress = getSelectedAddress(state); const currentTabHasNoAccounts = !permittedAccountsByOrigin[originOfCurrentTab] - ?.length + ?.length; - let tabToConnect + let tabToConnect; if (originOfCurrentTab && currentTabHasNoAccounts && !openMetaMaskTabs[id]) { tabToConnect = { origin: originOfCurrentTab, - } + }; } return { @@ -45,29 +45,29 @@ const mapStateToProps = (state) => { permittedAccountsByOrigin, selectedAddress, tabToConnect, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { getOpenMetamaskTabsIds: () => dispatch(getOpenMetamaskTabsIds()), disconnectAccount: (domainKey, address) => { - dispatch(removePermittedAccount(domainKey, address)) + dispatch(removePermittedAccount(domainKey, address)); }, disconnectAllAccounts: (domainKey, domain) => { const permissionMethodNames = domain.permissions.map( ({ parentCapability }) => parentCapability, - ) + ); dispatch( removePermissionsFor({ [domainKey]: permissionMethodNames, }), - ) + ); }, requestAccountsPermissionWithId: (origin) => dispatch(requestAccountsPermissionWithId(origin)), - } -} + }; +}; const mergeProps = (stateProps, dispatchProps, ownProps) => { const { @@ -76,16 +76,16 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { mostRecentOverviewPage, selectedAddress, tabToConnect, - } = stateProps + } = stateProps; const { disconnectAccount, disconnectAllAccounts, // eslint-disable-next-line no-shadow requestAccountsPermissionWithId, - } = dispatchProps - const { history } = ownProps + } = dispatchProps; + const { history } = ownProps; - const closePopover = () => history.push(mostRecentOverviewPage) + const closePopover = () => history.push(mostRecentOverviewPage); return { ...ownProps, @@ -93,26 +93,26 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { ...dispatchProps, closePopover, disconnectAccount: (domainKey) => { - disconnectAccount(domainKey, selectedAddress) + disconnectAccount(domainKey, selectedAddress); if (connectedDomains.length === 1) { - closePopover() + closePopover(); } }, disconnectAllAccounts: (domainKey) => { - disconnectAllAccounts(domainKey, domains[domainKey]) + disconnectAllAccounts(domainKey, domains[domainKey]); if (connectedDomains.length === 1) { - closePopover() + closePopover(); } }, requestAccountsPermission: async () => { - const id = await requestAccountsPermissionWithId(tabToConnect.origin) - history.push(`${CONNECT_ROUTE}/${id}`) + const id = await requestAccountsPermissionWithId(tabToConnect.origin); + history.push(`${CONNECT_ROUTE}/${id}`); }, - } -} + }; +}; export default connect( mapStateToProps, mapDispatchToProps, mergeProps, -)(ConnectedSites) +)(ConnectedSites); diff --git a/ui/app/pages/connected-sites/index.js b/ui/app/pages/connected-sites/index.js index 96cf6e67de..c7daa8393f 100644 --- a/ui/app/pages/connected-sites/index.js +++ b/ui/app/pages/connected-sites/index.js @@ -1 +1 @@ -export { default } from './connected-sites.container' +export { default } from './connected-sites.container'; diff --git a/ui/app/pages/create-account/connect-hardware/account-list.js b/ui/app/pages/create-account/connect-hardware/account-list.js index 2cf315ae77..df1ec8cddd 100644 --- a/ui/app/pages/create-account/connect-hardware/account-list.js +++ b/ui/app/pages/create-account/connect-hardware/account-list.js @@ -1,8 +1,8 @@ -import PropTypes from 'prop-types' -import React, { Component } from 'react' -import Select from 'react-select' -import getAccountLink from '../../../../lib/account-link' -import Button from '../../../components/ui/button' +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import Select from 'react-select'; +import getAccountLink from '../../../../lib/account-link'; +import Button from '../../../components/ui/button'; class AccountList extends Component { getHdPaths() { @@ -15,26 +15,26 @@ class AccountList extends Component { label: `Legacy (MEW / MyCrypto)`, value: `m/44'/60'/0'`, }, - ] + ]; } goToNextPage = () => { // If we have < 5 accounts, it's restricted by BIP-44 if (this.props.accounts.length === 5) { - this.props.getPage(this.props.device, 1, this.props.selectedPath) + this.props.getPage(this.props.device, 1, this.props.selectedPath); } else { - this.props.onAccountRestriction() + this.props.onAccountRestriction(); } - } + }; goToPreviousPage = () => { - this.props.getPage(this.props.device, -1, this.props.selectedPath) - } + this.props.getPage(this.props.device, -1, this.props.selectedPath); + }; renderHdPathSelector() { - const { onPathChange, selectedPath } = this.props + const { onPathChange, selectedPath } = this.props; - const options = this.getHdPaths() + const options = this.getHdPaths(); return (

    @@ -49,20 +49,20 @@ class AccountList extends Component { value={selectedPath} options={options} onChange={(opt) => { - onPathChange(opt.value) + onPathChange(opt.value); }} />

    - ) + ); } capitalizeDevice(device) { - return device.slice(0, 1).toUpperCase() + device.slice(1) + return device.slice(0, 1).toUpperCase() + device.slice(1); } renderHeader() { - const { device } = this.props + const { device } = this.props; return (

    @@ -76,7 +76,7 @@ class AccountList extends Component { {this.context.t('selectAnAccountHelp')}

    - ) + ); } renderAccounts() { @@ -120,7 +120,7 @@ class AccountList extends Component { ))} - ) + ); } renderPagination() { @@ -139,14 +139,14 @@ class AccountList extends Component { {`${this.context.t('next')} >`} - ) + ); } renderButtons() { - const disabled = this.props.selectedAccount === null - const buttonProps = {} + const disabled = this.props.selectedAccount === null; + const buttonProps = {}; if (disabled) { - buttonProps.disabled = true + buttonProps.disabled = true; } return ( @@ -169,7 +169,7 @@ class AccountList extends Component { {this.context.t('unlock')} - ) + ); } renderForgetDevice() { @@ -179,7 +179,7 @@ class AccountList extends Component { {this.context.t('forgetDevice')} - ) + ); } render() { @@ -191,7 +191,7 @@ class AccountList extends Component { {this.renderButtons()} {this.renderForgetDevice()} - ) + ); } } @@ -208,10 +208,10 @@ AccountList.propTypes = { onUnlockAccount: PropTypes.func, onCancel: PropTypes.func, onAccountRestriction: PropTypes.func, -} +}; AccountList.contextTypes = { t: PropTypes.func, -} +}; -export default AccountList +export default AccountList; diff --git a/ui/app/pages/create-account/connect-hardware/index.js b/ui/app/pages/create-account/connect-hardware/index.js index a17806207a..1531950882 100644 --- a/ui/app/pages/create-account/connect-hardware/index.js +++ b/ui/app/pages/create-account/connect-hardware/index.js @@ -1,14 +1,14 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import { connect } from 'react-redux' -import * as actions from '../../../store/actions' -import { getMetaMaskAccounts } from '../../../selectors' -import { formatBalance } from '../../../helpers/utils/util' -import { getMostRecentOverviewPage } from '../../../ducks/history/history' -import SelectHardware from './select-hardware' -import AccountList from './account-list' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; +import * as actions from '../../../store/actions'; +import { getMetaMaskAccounts } from '../../../selectors'; +import { formatBalance } from '../../../helpers/utils/util'; +import { getMostRecentOverviewPage } from '../../../ducks/history/history'; +import SelectHardware from './select-hardware'; +import AccountList from './account-list'; -const U2F_ERROR = 'U2F' +const U2F_ERROR = 'U2F'; class ConnectHardwareForm extends Component { state = { @@ -18,23 +18,23 @@ class ConnectHardwareForm extends Component { browserSupported: true, unlocked: false, device: null, - } + }; UNSAFE_componentWillReceiveProps(nextProps) { - const { accounts } = nextProps + const { accounts } = nextProps; const newAccounts = this.state.accounts.map((a) => { - const normalizedAddress = a.address.toLowerCase() + const normalizedAddress = a.address.toLowerCase(); const balanceValue = (accounts[normalizedAddress] && accounts[normalizedAddress].balance) || - null - a.balance = balanceValue ? formatBalance(balanceValue, 6) : '...' - return a - }) - this.setState({ accounts: newAccounts }) + null; + a.balance = balanceValue ? formatBalance(balanceValue, 6) : '...'; + return a; + }); + this.setState({ accounts: newAccounts }); } componentDidMount() { - this.checkIfUnlocked() + this.checkIfUnlocked(); } async checkIfUnlocked() { @@ -42,46 +42,46 @@ class ConnectHardwareForm extends Component { const unlocked = await this.props.checkHardwareStatus( device, this.props.defaultHdPaths[device], - ) + ); if (unlocked) { - this.setState({ unlocked: true }) - this.getPage(device, 0, this.props.defaultHdPaths[device]) + this.setState({ unlocked: true }); + this.getPage(device, 0, this.props.defaultHdPaths[device]); } } } connectToHardwareWallet = (device) => { - this.setState({ device }) + this.setState({ device }); if (this.state.accounts.length) { - return + return; } // Default values - this.getPage(device, 0, this.props.defaultHdPaths[device]) - } + this.getPage(device, 0, this.props.defaultHdPaths[device]); + }; onPathChange = (path) => { this.props.setHardwareWalletDefaultHdPath({ device: this.state.device, path, - }) - this.getPage(this.state.device, 0, path) - } + }); + this.getPage(this.state.device, 0, path); + }; onAccountChange = (account) => { - this.setState({ selectedAccount: account.toString(), error: null }) - } + this.setState({ selectedAccount: account.toString(), error: null }); + }; onAccountRestriction = () => { - this.setState({ error: this.context.t('ledgerAccountRestriction') }) - } + this.setState({ error: this.context.t('ledgerAccountRestriction') }); + }; showTemporaryAlert() { - this.props.showAlert(this.context.t('hardwareWalletConnected')) + this.props.showAlert(this.context.t('hardwareWalletConnected')); // Autohide the alert after 5 seconds setTimeout((_) => { - this.props.hideAlert() - }, 5000) + this.props.hideAlert(); + }, 5000); } getPage = (device, page, hdPath) => { @@ -92,56 +92,56 @@ class ConnectHardwareForm extends Component { // If we just loaded the accounts for the first time // (device previously locked) show the global alert if (this.state.accounts.length === 0 && !this.state.unlocked) { - this.showTemporaryAlert() + this.showTemporaryAlert(); } - const newState = { unlocked: true, device, error: null } + const newState = { unlocked: true, device, error: null }; // Default to the first account if (this.state.selectedAccount === null) { accounts.forEach((a) => { if (a.address.toLowerCase() === this.props.address) { - newState.selectedAccount = a.index.toString() + newState.selectedAccount = a.index.toString(); } - }) + }); // If the page doesn't contain the selected account, let's deselect it } else if ( !accounts.filter( (a) => a.index.toString() === this.state.selectedAccount, ).length ) { - newState.selectedAccount = null + newState.selectedAccount = null; } // Map accounts with balances newState.accounts = accounts.map((account) => { - const normalizedAddress = account.address.toLowerCase() + const normalizedAddress = account.address.toLowerCase(); const balanceValue = (this.props.accounts[normalizedAddress] && this.props.accounts[normalizedAddress].balance) || - null + null; account.balance = balanceValue ? formatBalance(balanceValue, 6) - : '...' - return account - }) + : '...'; + return account; + }); - this.setState(newState) + this.setState(newState); } }) .catch((e) => { - const errorMessage = typeof e === 'string' ? e : e.message + const errorMessage = typeof e === 'string' ? e : e.message; if (errorMessage === 'Window blocked') { - this.setState({ browserSupported: false, error: null }) + this.setState({ browserSupported: false, error: null }); } else if (errorMessage.includes(U2F_ERROR)) { - this.setState({ error: U2F_ERROR }) + this.setState({ error: U2F_ERROR }); } else if ( errorMessage !== 'Window closed' && errorMessage !== 'Popup closed' ) { - this.setState({ error: errorMessage }) + this.setState({ error: errorMessage }); } - }) - } + }); + }; onForgetDevice = (device) => { this.props @@ -152,22 +152,22 @@ class ConnectHardwareForm extends Component { selectedAccount: null, accounts: [], unlocked: false, - }) + }); }) .catch((e) => { - this.setState({ error: e.message }) - }) - } + this.setState({ error: e.message }); + }); + }; onUnlockAccount = (device) => { const { history, mostRecentOverviewPage, unlockHardwareWalletAccount, - } = this.props + } = this.props; if (this.state.selectedAccount === null) { - this.setState({ error: this.context.t('accountSelectionRequired') }) + this.setState({ error: this.context.t('accountSelectionRequired') }); } unlockHardwareWalletAccount(this.state.selectedAccount, device) @@ -178,8 +178,8 @@ class ConnectHardwareForm extends Component { action: 'Connected Hardware Wallet', name: `Connected Account with: ${device}`, }, - }) - history.push(mostRecentOverviewPage) + }); + history.push(mostRecentOverviewPage); }) .catch((e) => { this.context.metricsEvent({ @@ -191,15 +191,15 @@ class ConnectHardwareForm extends Component { customVariables: { error: e.message, }, - }) - this.setState({ error: e.message }) - }) - } + }); + this.setState({ error: e.message }); + }); + }; onCancel = () => { - const { history, mostRecentOverviewPage } = this.props - history.push(mostRecentOverviewPage) - } + const { history, mostRecentOverviewPage } = this.props; + history.push(mostRecentOverviewPage); + }; renderError() { if (this.state.error === U2F_ERROR) { @@ -220,11 +220,11 @@ class ConnectHardwareForm extends Component { , ])}

    - ) + ); } return this.state.error ? ( {this.state.error} - ) : null + ) : null; } renderContent() { @@ -234,7 +234,7 @@ class ConnectHardwareForm extends Component { connectToHardwareWallet={this.connectToHardwareWallet} browserSupported={this.state.browserSupported} /> - ) + ); } return ( @@ -252,7 +252,7 @@ class ConnectHardwareForm extends Component { onCancel={this.onCancel} onAccountRestriction={this.onAccountRestriction} /> - ) + ); } render() { @@ -261,7 +261,7 @@ class ConnectHardwareForm extends Component { {this.renderError()} {this.renderContent()} - ) + ); } } @@ -279,16 +279,16 @@ ConnectHardwareForm.propTypes = { address: PropTypes.string, defaultHdPaths: PropTypes.object, mostRecentOverviewPage: PropTypes.string.isRequired, -} +}; const mapStateToProps = (state) => { const { metamask: { network, selectedAddress }, - } = state - const accounts = getMetaMaskAccounts(state) + } = state; + const accounts = getMetaMaskAccounts(state); const { appState: { defaultHdPaths }, - } = state + } = state; return { network, @@ -296,36 +296,39 @@ const mapStateToProps = (state) => { address: selectedAddress, defaultHdPaths, mostRecentOverviewPage: getMostRecentOverviewPage(state), - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { setHardwareWalletDefaultHdPath: ({ device, path }) => { - return dispatch(actions.setHardwareWalletDefaultHdPath({ device, path })) + return dispatch(actions.setHardwareWalletDefaultHdPath({ device, path })); }, connectHardware: (deviceName, page, hdPath) => { - return dispatch(actions.connectHardware(deviceName, page, hdPath)) + return dispatch(actions.connectHardware(deviceName, page, hdPath)); }, checkHardwareStatus: (deviceName, hdPath) => { - return dispatch(actions.checkHardwareStatus(deviceName, hdPath)) + return dispatch(actions.checkHardwareStatus(deviceName, hdPath)); }, forgetDevice: (deviceName) => { - return dispatch(actions.forgetDevice(deviceName)) + return dispatch(actions.forgetDevice(deviceName)); }, unlockHardwareWalletAccount: (index, deviceName, hdPath) => { return dispatch( actions.unlockHardwareWalletAccount(index, deviceName, hdPath), - ) + ); }, showAlert: (msg) => dispatch(actions.showAlert(msg)), hideAlert: () => dispatch(actions.hideAlert()), - } -} + }; +}; ConnectHardwareForm.contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, -} +}; -export default connect(mapStateToProps, mapDispatchToProps)(ConnectHardwareForm) +export default connect( + mapStateToProps, + mapDispatchToProps, +)(ConnectHardwareForm); diff --git a/ui/app/pages/create-account/connect-hardware/select-hardware.js b/ui/app/pages/create-account/connect-hardware/select-hardware.js index 5ffb728a53..040245c57f 100644 --- a/ui/app/pages/create-account/connect-hardware/select-hardware.js +++ b/ui/app/pages/create-account/connect-hardware/select-hardware.js @@ -1,28 +1,28 @@ -import classnames from 'classnames' -import PropTypes from 'prop-types' -import React, { Component } from 'react' -import Button from '../../../components/ui/button' +import classnames from 'classnames'; +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import Button from '../../../components/ui/button'; export default class SelectHardware extends Component { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { connectToHardwareWallet: PropTypes.func.isRequired, browserSupported: PropTypes.bool.isRequired, - } + }; state = { selectedDevice: null, - } + }; connect = () => { if (this.state.selectedDevice) { - this.props.connectToHardwareWallet(this.state.selectedDevice) + this.props.connectToHardwareWallet(this.state.selectedDevice); } - return null - } + return null; + }; renderConnectToTrezorButton() { return ( @@ -38,7 +38,7 @@ export default class SelectHardware extends Component { alt="Trezor" /> - ) + ); } renderConnectToLedgerButton() { @@ -55,7 +55,7 @@ export default class SelectHardware extends Component { alt="Ledger" /> - ) + ); } renderButtons() { @@ -75,7 +75,7 @@ export default class SelectHardware extends Component { {this.context.t('connect')} - ) + ); } renderUnsupportedBrowser() { @@ -101,7 +101,7 @@ export default class SelectHardware extends Component { {this.context.t('downloadGoogleChrome')} - ) + ); } renderHeader() { @@ -114,26 +114,26 @@ export default class SelectHardware extends Component { {this.context.t('hardwareWalletsMsg')}

    - ) + ); } getAffiliateLinks() { const links = { trezor: `Trezor`, ledger: `Ledger`, - } + }; - const text = this.context.t('orderOneHere') + const text = this.context.t('orderOneHere'); const response = text .replace('Trezor', links.trezor) - .replace('Ledger', links.ledger) + .replace('Ledger', links.ledger); return (
    - ) + ); } renderTrezorAffiliateLink() { @@ -144,14 +144,14 @@ export default class SelectHardware extends Component {

    {this.getAffiliateLinks()}
    - ) + ); } scrollToTutorial = () => { if (this.referenceNode) { - this.referenceNode.scrollIntoView({ behavior: 'smooth' }) + this.referenceNode.scrollIntoView({ behavior: 'smooth' }); } - } + }; renderLearnMore() { return ( @@ -163,7 +163,7 @@ export default class SelectHardware extends Component { alt="" />

    - ) + ); } renderTutorialSteps() { @@ -186,13 +186,13 @@ export default class SelectHardware extends Component { title: this.context.t('step3HardwareWallet'), message: this.context.t('step3HardwareWalletMsg'), }, - ] + ]; return (
    { - this.referenceNode = node + this.referenceNode = node; }} > {steps.map((step, index) => ( @@ -208,7 +208,7 @@ export default class SelectHardware extends Component {
    ))} - ) + ); } renderFooter() { @@ -230,7 +230,7 @@ export default class SelectHardware extends Component {

    - ) + ); } renderConnectScreen() { @@ -243,13 +243,13 @@ export default class SelectHardware extends Component { {this.renderTutorialSteps()} {this.renderFooter()} - ) + ); } render() { if (this.props.browserSupported) { - return this.renderConnectScreen() + return this.renderConnectScreen(); } - return this.renderUnsupportedBrowser() + return this.renderUnsupportedBrowser(); } } diff --git a/ui/app/pages/create-account/create-account.component.js b/ui/app/pages/create-account/create-account.component.js index 1ec2e52585..4eaefce520 100644 --- a/ui/app/pages/create-account/create-account.component.js +++ b/ui/app/pages/create-account/create-account.component.js @@ -1,29 +1,29 @@ -import React, { Component } from 'react' -import { Switch, Route, matchPath } from 'react-router-dom' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React, { Component } from 'react'; +import { Switch, Route, matchPath } from 'react-router-dom'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; import { NEW_ACCOUNT_ROUTE, IMPORT_ACCOUNT_ROUTE, CONNECT_HARDWARE_ROUTE, -} from '../../helpers/constants/routes' -import NewAccountCreateForm from './new-account.container' -import NewAccountImportForm from './import-account' -import ConnectHardwareForm from './connect-hardware' +} from '../../helpers/constants/routes'; +import NewAccountCreateForm from './new-account.container'; +import NewAccountImportForm from './import-account'; +import ConnectHardwareForm from './connect-hardware'; export default class CreateAccountPage extends Component { renderTabs() { const { history, location: { pathname }, - } = this.props + } = this.props; const getClassNames = (path) => classnames('new-account__tabs__tab', { 'new-account__tabs__selected': matchPath(pathname, { path, exact: true, }), - }) + }); return (
    @@ -46,7 +46,7 @@ export default class CreateAccountPage extends Component { {this.context.t('hardware')}
    - ) + ); } render() { @@ -79,15 +79,15 @@ export default class CreateAccountPage extends Component { - ) + ); } } CreateAccountPage.propTypes = { location: PropTypes.object, history: PropTypes.object, -} +}; CreateAccountPage.contextTypes = { t: PropTypes.func, -} +}; diff --git a/ui/app/pages/create-account/import-account/index.js b/ui/app/pages/create-account/import-account/index.js index 0b7e45cf9b..8068773c36 100644 --- a/ui/app/pages/create-account/import-account/index.js +++ b/ui/app/pages/create-account/import-account/index.js @@ -1,40 +1,40 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import Select from 'react-select' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import Select from 'react-select'; // Subviews -import JsonImportView from './json' -import PrivateKeyImportView from './private-key' +import JsonImportView from './json'; +import PrivateKeyImportView from './private-key'; export default class AccountImportSubview extends Component { static contextTypes = { t: PropTypes.func, - } + }; - state = {} + state = {}; getMenuItemTexts() { - return [this.context.t('privateKey'), this.context.t('jsonFile')] + return [this.context.t('privateKey'), this.context.t('jsonFile')]; } renderImportView() { - const { type } = this.state - const menuItems = this.getMenuItemTexts() - const current = type || menuItems[0] + const { type } = this.state; + const menuItems = this.getMenuItemTexts(); + const current = type || menuItems[0]; switch (current) { case this.context.t('privateKey'): - return + return ; case this.context.t('jsonFile'): - return + return ; default: - return + return ; } } render() { - const menuItems = this.getMenuItemTexts() - const { type } = this.state + const menuItems = this.getMenuItemTexts(); + const { type } = this.state; return (
    @@ -49,7 +49,7 @@ export default class AccountImportSubview extends Component { global.platform.openTab({ url: 'https://metamask.zendesk.com/hc/en-us/articles/360015289932', - }) + }); }} > {this.context.t('here')} @@ -68,15 +68,15 @@ export default class AccountImportSubview extends Component { return { value: text, label: text, - } + }; })} onChange={(opt) => { - this.setState({ type: opt.value }) + this.setState({ type: opt.value }); }} />
    {this.renderImportView()} - ) + ); } } diff --git a/ui/app/pages/create-account/import-account/json.js b/ui/app/pages/create-account/import-account/json.js index 34eadaf844..afaeb77512 100644 --- a/ui/app/pages/create-account/import-account/json.js +++ b/ui/app/pages/create-account/import-account/json.js @@ -1,28 +1,28 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import { withRouter } from 'react-router-dom' -import { compose } from 'redux' -import { connect } from 'react-redux' -import FileInput from 'react-simple-file-input' -import * as actions from '../../../store/actions' -import { getMetaMaskAccounts } from '../../../selectors' -import Button from '../../../components/ui/button' -import { getMostRecentOverviewPage } from '../../../ducks/history/history' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { withRouter } from 'react-router-dom'; +import { compose } from 'redux'; +import { connect } from 'react-redux'; +import FileInput from 'react-simple-file-input'; +import * as actions from '../../../store/actions'; +import { getMetaMaskAccounts } from '../../../selectors'; +import Button from '../../../components/ui/button'; +import { getMostRecentOverviewPage } from '../../../ducks/history/history'; const HELP_LINK = - 'https://metamask.zendesk.com/hc/en-us/articles/360015489331-Importing-an-Account' + 'https://metamask.zendesk.com/hc/en-us/articles/360015489331-Importing-an-Account'; class JsonImportSubview extends Component { state = { fileContents: '', isEmpty: true, - } + }; - inputRef = React.createRef() + inputRef = React.createRef(); render() { - const { error, history, mostRecentOverviewPage } = this.props - const enabled = !this.state.isEmpty && this.state.fileContents !== '' + const { error, history, mostRecentOverviewPage } = this.props; + const enabled = !this.state.isEmpty && this.state.fileContents !== ''; return (
    @@ -76,19 +76,19 @@ class JsonImportSubview extends Component {
    {error ? {error} : null} - ) + ); } onLoad(event) { this.setState({ fileContents: event.target.result, - }) + }); } createKeyringOnEnter(event) { if (event.key === 'Enter') { - event.preventDefault() - this.createNewKeychain() + event.preventDefault(); + this.createNewKeychain(); } } @@ -100,51 +100,51 @@ class JsonImportSubview extends Component { importNewJsonAccount, mostRecentOverviewPage, setSelectedAddress, - } = this.props - const { fileContents } = this.state + } = this.props; + const { fileContents } = this.state; if (!fileContents) { - const message = this.context.t('needImportFile') - displayWarning(message) - return + const message = this.context.t('needImportFile'); + displayWarning(message); + return; } - const password = this.inputRef.current.value + const password = this.inputRef.current.value; importNewJsonAccount([fileContents, password]) .then(({ selectedAddress }) => { if (selectedAddress) { - history.push(mostRecentOverviewPage) + history.push(mostRecentOverviewPage); this.context.metricsEvent({ eventOpts: { category: 'Accounts', action: 'Import Account', name: 'Imported Account with JSON', }, - }) - displayWarning(null) + }); + displayWarning(null); } else { - displayWarning('Error importing account.') + displayWarning('Error importing account.'); this.context.metricsEvent({ eventOpts: { category: 'Accounts', action: 'Import Account', name: 'Error importing JSON', }, - }) - setSelectedAddress(firstAddress) + }); + setSelectedAddress(firstAddress); } }) - .catch((err) => err && displayWarning(err.message || err)) + .catch((err) => err && displayWarning(err.message || err)); } checkInputEmpty() { - const password = this.inputRef.current.value - let isEmpty = true + const password = this.inputRef.current.value; + let isEmpty = true; if (password !== '') { - isEmpty = false + isEmpty = false; } - this.setState({ isEmpty }) + this.setState({ isEmpty }); } } @@ -156,15 +156,15 @@ JsonImportSubview.propTypes = { history: PropTypes.object, setSelectedAddress: PropTypes.func, mostRecentOverviewPage: PropTypes.string.isRequired, -} +}; const mapStateToProps = (state) => { return { error: state.appState.warning, firstAddress: Object.keys(getMetaMaskAccounts(state))[0], mostRecentOverviewPage: getMostRecentOverviewPage(state), - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { @@ -173,15 +173,15 @@ const mapDispatchToProps = (dispatch) => { dispatch(actions.importNewAccount('JSON File', options)), setSelectedAddress: (address) => dispatch(actions.setSelectedAddress(address)), - } -} + }; +}; JsonImportSubview.contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, -} +}; export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps), -)(JsonImportSubview) +)(JsonImportSubview); diff --git a/ui/app/pages/create-account/import-account/private-key.js b/ui/app/pages/create-account/import-account/private-key.js index e2f78ada43..c360424be0 100644 --- a/ui/app/pages/create-account/import-account/private-key.js +++ b/ui/app/pages/create-account/import-account/private-key.js @@ -1,18 +1,18 @@ -import React, { Component } from 'react' -import { withRouter } from 'react-router-dom' -import { compose } from 'redux' -import PropTypes from 'prop-types' -import { connect } from 'react-redux' -import * as actions from '../../../store/actions' -import { getMetaMaskAccounts } from '../../../selectors' -import Button from '../../../components/ui/button' -import { getMostRecentOverviewPage } from '../../../ducks/history/history' +import React, { Component } from 'react'; +import { withRouter } from 'react-router-dom'; +import { compose } from 'redux'; +import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; +import * as actions from '../../../store/actions'; +import { getMetaMaskAccounts } from '../../../selectors'; +import Button from '../../../components/ui/button'; +import { getMostRecentOverviewPage } from '../../../ducks/history/history'; class PrivateKeyImportView extends Component { static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; static propTypes = { importNewAccount: PropTypes.func.isRequired, @@ -22,14 +22,14 @@ class PrivateKeyImportView extends Component { firstAddress: PropTypes.string.isRequired, error: PropTypes.node, mostRecentOverviewPage: PropTypes.string.isRequired, - } + }; - inputRef = React.createRef() + inputRef = React.createRef(); - state = { isEmpty: true } + state = { isEmpty: true }; createNewKeychain() { - const privateKey = this.inputRef.current.value + const privateKey = this.inputRef.current.value; const { importNewAccount, history, @@ -37,7 +37,7 @@ class PrivateKeyImportView extends Component { mostRecentOverviewPage, setSelectedAddress, firstAddress, - } = this.props + } = this.props; importNewAccount('Private Key', [privateKey]) .then(({ selectedAddress }) => { @@ -48,42 +48,42 @@ class PrivateKeyImportView extends Component { action: 'Import Account', name: 'Imported Account with Private Key', }, - }) - history.push(mostRecentOverviewPage) - displayWarning(null) + }); + history.push(mostRecentOverviewPage); + displayWarning(null); } else { - displayWarning('Error importing account.') + displayWarning('Error importing account.'); this.context.metricsEvent({ eventOpts: { category: 'Accounts', action: 'Import Account', name: 'Error importing with Private Key', }, - }) - setSelectedAddress(firstAddress) + }); + setSelectedAddress(firstAddress); } }) - .catch((err) => err && displayWarning(err.message || err)) + .catch((err) => err && displayWarning(err.message || err)); } createKeyringOnEnter = (event) => { if (event.key === 'Enter') { - event.preventDefault() - this.createNewKeychain() + event.preventDefault(); + this.createNewKeychain(); } - } + }; checkInputEmpty() { - const privateKey = this.inputRef.current.value - let isEmpty = true + const privateKey = this.inputRef.current.value; + let isEmpty = true; if (privateKey !== '') { - isEmpty = false + isEmpty = false; } - this.setState({ isEmpty }) + this.setState({ isEmpty }); } render() { - const { error, displayWarning } = this.props + const { error, displayWarning } = this.props; return (
    @@ -107,9 +107,9 @@ class PrivateKeyImportView extends Component { large className="new-account-create-form__button" onClick={() => { - const { history, mostRecentOverviewPage } = this.props - displayWarning(null) - history.push(mostRecentOverviewPage) + const { history, mostRecentOverviewPage } = this.props; + displayWarning(null); + history.push(mostRecentOverviewPage); }} > {this.context.t('cancel')} @@ -126,31 +126,31 @@ class PrivateKeyImportView extends Component {
    {error ? {error} : null} - ) + ); } } export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps), -)(PrivateKeyImportView) +)(PrivateKeyImportView); function mapStateToProps(state) { return { error: state.appState.warning, firstAddress: Object.keys(getMetaMaskAccounts(state))[0], mostRecentOverviewPage: getMostRecentOverviewPage(state), - } + }; } function mapDispatchToProps(dispatch) { return { importNewAccount: (strategy, [privateKey]) => { - return dispatch(actions.importNewAccount(strategy, [privateKey])) + return dispatch(actions.importNewAccount(strategy, [privateKey])); }, displayWarning: (message) => dispatch(actions.displayWarning(message || null)), setSelectedAddress: (address) => dispatch(actions.setSelectedAddress(address)), - } + }; } diff --git a/ui/app/pages/create-account/index.js b/ui/app/pages/create-account/index.js index a736bfff72..ebf30f7c7e 100644 --- a/ui/app/pages/create-account/index.js +++ b/ui/app/pages/create-account/index.js @@ -1 +1 @@ -export { default } from './create-account.component' +export { default } from './create-account.component'; diff --git a/ui/app/pages/create-account/new-account.component.js b/ui/app/pages/create-account/new-account.component.js index 92f832a23a..252eb2821b 100644 --- a/ui/app/pages/create-account/new-account.component.js +++ b/ui/app/pages/create-account/new-account.component.js @@ -1,22 +1,22 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import Button from '../../components/ui/button' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import Button from '../../components/ui/button'; export default class NewAccountCreateForm extends Component { static defaultProps = { newAccountNumber: 0, - } + }; state = { newAccountName: '', defaultAccountName: this.context.t('newAccountNumberName', [ this.props.newAccountNumber, ]), - } + }; render() { - const { newAccountName, defaultAccountName } = this.state - const { history, createAccount, mostRecentOverviewPage } = this.props + const { newAccountName, defaultAccountName } = this.state; + const { history, createAccount, mostRecentOverviewPage } = this.props; const createClick = (_) => { createAccount(newAccountName || defaultAccountName) .then(() => { @@ -26,8 +26,8 @@ export default class NewAccountCreateForm extends Component { action: 'Add New Account', name: 'Added New Account', }, - }) - history.push(mostRecentOverviewPage) + }); + history.push(mostRecentOverviewPage); }) .catch((e) => { this.context.metricsEvent({ @@ -39,9 +39,9 @@ export default class NewAccountCreateForm extends Component { customVariables: { errorMessage: e.message, }, - }) - }) - } + }); + }); + }; return (
    @@ -78,7 +78,7 @@ export default class NewAccountCreateForm extends Component {
    - ) + ); } } @@ -87,9 +87,9 @@ NewAccountCreateForm.propTypes = { newAccountNumber: PropTypes.number, history: PropTypes.object, mostRecentOverviewPage: PropTypes.string.isRequired, -} +}; NewAccountCreateForm.contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, -} +}; diff --git a/ui/app/pages/create-account/new-account.container.js b/ui/app/pages/create-account/new-account.container.js index 833d7143c1..d37c8f30c2 100644 --- a/ui/app/pages/create-account/new-account.container.js +++ b/ui/app/pages/create-account/new-account.container.js @@ -1,34 +1,34 @@ -import { connect } from 'react-redux' -import * as actions from '../../store/actions' -import { getMostRecentOverviewPage } from '../../ducks/history/history' -import NewAccountCreateForm from './new-account.component' +import { connect } from 'react-redux'; +import * as actions from '../../store/actions'; +import { getMostRecentOverviewPage } from '../../ducks/history/history'; +import NewAccountCreateForm from './new-account.component'; const mapStateToProps = (state) => { const { metamask: { identities = {} }, - } = state - const numberOfExistingAccounts = Object.keys(identities).length - const newAccountNumber = numberOfExistingAccounts + 1 + } = state; + const numberOfExistingAccounts = Object.keys(identities).length; + const newAccountNumber = numberOfExistingAccounts + 1; return { newAccountNumber, mostRecentOverviewPage: getMostRecentOverviewPage(state), - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { createAccount: (newAccountName) => { return dispatch(actions.addNewAccount()).then((newAccountAddress) => { if (newAccountName) { - dispatch(actions.setAccountLabel(newAccountAddress, newAccountName)) + dispatch(actions.setAccountLabel(newAccountAddress, newAccountName)); } - }) + }); }, - } -} + }; +}; export default connect( mapStateToProps, mapDispatchToProps, -)(NewAccountCreateForm) +)(NewAccountCreateForm); diff --git a/ui/app/pages/create-account/tests/create-account.test.js b/ui/app/pages/create-account/tests/create-account.test.js index 335d3c5bae..0c564a64be 100644 --- a/ui/app/pages/create-account/tests/create-account.test.js +++ b/ui/app/pages/create-account/tests/create-account.test.js @@ -1,11 +1,11 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import { mountWithRouter } from '../../../../../test/lib/render-helpers' -import CreateAccountPage from '..' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import { mountWithRouter } from '../../../../../test/lib/render-helpers'; +import CreateAccountPage from '..'; describe('Create Account Page', function () { - let wrapper + let wrapper; const props = { history: { @@ -14,37 +14,37 @@ describe('Create Account Page', function () { location: { pathname: '/new-account', }, - } + }; before(function () { - wrapper = mountWithRouter() - }) + wrapper = mountWithRouter(); + }); afterEach(function () { - props.history.push.resetHistory() - }) + props.history.push.resetHistory(); + }); it('clicks create account and routes to new-account path', function () { - const createAccount = wrapper.find('.new-account__tabs__tab').at(0) - createAccount.simulate('click') - assert.strictEqual(props.history.push.getCall(0).args[0], '/new-account') - }) + const createAccount = wrapper.find('.new-account__tabs__tab').at(0); + createAccount.simulate('click'); + assert.strictEqual(props.history.push.getCall(0).args[0], '/new-account'); + }); it('clicks import account and routes to import new account path', function () { - const importAccount = wrapper.find('.new-account__tabs__tab').at(1) - importAccount.simulate('click') + const importAccount = wrapper.find('.new-account__tabs__tab').at(1); + importAccount.simulate('click'); assert.strictEqual( props.history.push.getCall(0).args[0], '/new-account/import', - ) - }) + ); + }); it('clicks connect HD Wallet and routes to connect new account path', function () { - const connectHdWallet = wrapper.find('.new-account__tabs__tab').at(2) - connectHdWallet.simulate('click') + const connectHdWallet = wrapper.find('.new-account__tabs__tab').at(2); + connectHdWallet.simulate('click'); assert.strictEqual( props.history.push.getCall(0).args[0], '/new-account/connect', - ) - }) -}) + ); + }); +}); diff --git a/ui/app/pages/error/error.component.js b/ui/app/pages/error/error.component.js index e7e9ff6ed8..22d7f52298 100644 --- a/ui/app/pages/error/error.component.js +++ b/ui/app/pages/error/error.component.js @@ -1,23 +1,23 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import { getEnvironmentType } from '../../../../app/scripts/lib/util' -import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { getEnvironmentType } from '../../../../app/scripts/lib/util'; +import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app'; class ErrorPage extends PureComponent { static contextTypes = { t: PropTypes.func.isRequired, - } + }; static propTypes = { error: PropTypes.object.isRequired, - } + }; renderErrorDetail(content) { return (
  • {content}

  • - ) + ); } renderErrorStack(title, stack) { @@ -26,14 +26,14 @@ class ErrorPage extends PureComponent { {title}
    {stack}
    - ) + ); } render() { - const { error } = this.props - const { t } = this.context + const { error } = this.props; + const { t } = this.context; - const isPopup = getEnvironmentType() === ENVIRONMENT_TYPE_POPUP + const isPopup = getEnvironmentType() === ENVIRONMENT_TYPE_POPUP; return (
    @@ -61,8 +61,8 @@ class ErrorPage extends PureComponent {
    - ) + ); } } -export default ErrorPage +export default ErrorPage; diff --git a/ui/app/pages/error/index.js b/ui/app/pages/error/index.js index c2a9f62d9a..386b797863 100644 --- a/ui/app/pages/error/index.js +++ b/ui/app/pages/error/index.js @@ -1 +1 @@ -export { default } from './error.component' +export { default } from './error.component'; diff --git a/ui/app/pages/first-time-flow/create-password/create-password.component.js b/ui/app/pages/first-time-flow/create-password/create-password.component.js index b249c3aba4..6913c10faf 100644 --- a/ui/app/pages/first-time-flow/create-password/create-password.component.js +++ b/ui/app/pages/first-time-flow/create-password/create-password.component.js @@ -1,14 +1,14 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import { Switch, Route } from 'react-router-dom' -import MetaFoxLogo from '../../../components/ui/metafox-logo' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { Switch, Route } from 'react-router-dom'; +import MetaFoxLogo from '../../../components/ui/metafox-logo'; import { INITIALIZE_CREATE_PASSWORD_ROUTE, INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE, INITIALIZE_SEED_PHRASE_ROUTE, -} from '../../../helpers/constants/routes' -import NewAccount from './new-account' -import ImportWithSeedPhrase from './import-with-seed-phrase' +} from '../../../helpers/constants/routes'; +import NewAccount from './new-account'; +import ImportWithSeedPhrase from './import-with-seed-phrase'; export default class CreatePassword extends PureComponent { static propTypes = { @@ -16,18 +16,18 @@ export default class CreatePassword extends PureComponent { isInitialized: PropTypes.bool, onCreateNewAccount: PropTypes.func, onCreateNewAccountFromSeed: PropTypes.func, - } + }; componentDidMount() { - const { isInitialized, history } = this.props + const { isInitialized, history } = this.props; if (isInitialized) { - history.push(INITIALIZE_SEED_PHRASE_ROUTE) + history.push(INITIALIZE_SEED_PHRASE_ROUTE); } } render() { - const { onCreateNewAccount, onCreateNewAccountFromSeed } = this.props + const { onCreateNewAccount, onCreateNewAccountFromSeed } = this.props; return (
    @@ -52,6 +52,6 @@ export default class CreatePassword extends PureComponent { />
    - ) + ); } } diff --git a/ui/app/pages/first-time-flow/create-password/create-password.container.js b/ui/app/pages/first-time-flow/create-password/create-password.container.js index 9e8d12870b..ccb35af75b 100644 --- a/ui/app/pages/first-time-flow/create-password/create-password.container.js +++ b/ui/app/pages/first-time-flow/create-password/create-password.container.js @@ -1,14 +1,14 @@ -import { connect } from 'react-redux' -import CreatePassword from './create-password.component' +import { connect } from 'react-redux'; +import CreatePassword from './create-password.component'; const mapStateToProps = (state) => { const { metamask: { isInitialized }, - } = state + } = state; return { isInitialized, - } -} + }; +}; -export default connect(mapStateToProps)(CreatePassword) +export default connect(mapStateToProps)(CreatePassword); diff --git a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.component.js b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.component.js index b9de025758..5bb58fd666 100644 --- a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.component.js +++ b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.component.js @@ -1,27 +1,27 @@ -import { ethers } from 'ethers' -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import TextField from '../../../../components/ui/text-field' -import Button from '../../../../components/ui/button' +import { ethers } from 'ethers'; +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import TextField from '../../../../components/ui/text-field'; +import Button from '../../../../components/ui/button'; import { INITIALIZE_SELECT_ACTION_ROUTE, INITIALIZE_END_OF_FLOW_ROUTE, -} from '../../../../helpers/constants/routes' +} from '../../../../helpers/constants/routes'; -const { isValidMnemonic } = ethers.utils +const { isValidMnemonic } = ethers.utils; export default class ImportWithSeedPhrase extends PureComponent { static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; static propTypes = { history: PropTypes.object, onSubmit: PropTypes.func.isRequired, setSeedPhraseBackedUp: PropTypes.func, initializeThreeBox: PropTypes.func, - } + }; state = { seedPhrase: '', @@ -32,10 +32,10 @@ export default class ImportWithSeedPhrase extends PureComponent { passwordError: '', confirmPasswordError: '', termsChecked: false, - } + }; parseSeedPhrase = (seedPhrase) => - (seedPhrase || '').trim().toLowerCase().match(/\w+/gu)?.join(' ') || '' + (seedPhrase || '').trim().toLowerCase().match(/\w+/gu)?.join(' ') || ''; UNSAFE_componentWillMount() { this._onBeforeUnload = () => @@ -49,105 +49,105 @@ export default class ImportWithSeedPhrase extends PureComponent { errorLabel: 'Seed Phrase Error', errorMessage: this.state.seedPhraseError, }, - }) - window.addEventListener('beforeunload', this._onBeforeUnload) + }); + window.addEventListener('beforeunload', this._onBeforeUnload); } componentWillUnmount() { - window.removeEventListener('beforeunload', this._onBeforeUnload) + window.removeEventListener('beforeunload', this._onBeforeUnload); } handleSeedPhraseChange(seedPhrase) { - let seedPhraseError = '' + let seedPhraseError = ''; if (seedPhrase) { - const parsedSeedPhrase = this.parseSeedPhrase(seedPhrase) - const wordCount = parsedSeedPhrase.split(/\s/u).length + const parsedSeedPhrase = this.parseSeedPhrase(seedPhrase); + const wordCount = parsedSeedPhrase.split(/\s/u).length; if (wordCount % 3 !== 0 || wordCount > 24 || wordCount < 12) { - seedPhraseError = this.context.t('seedPhraseReq') + seedPhraseError = this.context.t('seedPhraseReq'); } else if (!isValidMnemonic(parsedSeedPhrase)) { - seedPhraseError = this.context.t('invalidSeedPhrase') + seedPhraseError = this.context.t('invalidSeedPhrase'); } } - this.setState({ seedPhrase, seedPhraseError }) + this.setState({ seedPhrase, seedPhraseError }); } handlePasswordChange(password) { - const { t } = this.context + const { t } = this.context; this.setState((state) => { - const { confirmPassword } = state - let confirmPasswordError = '' - let passwordError = '' + const { confirmPassword } = state; + let confirmPasswordError = ''; + let passwordError = ''; if (password && password.length < 8) { - passwordError = t('passwordNotLongEnough') + passwordError = t('passwordNotLongEnough'); } if (confirmPassword && password !== confirmPassword) { - confirmPasswordError = t('passwordsDontMatch') + confirmPasswordError = t('passwordsDontMatch'); } return { password, passwordError, confirmPasswordError, - } - }) + }; + }); } handleConfirmPasswordChange(confirmPassword) { - const { t } = this.context + const { t } = this.context; this.setState((state) => { - const { password } = state - let confirmPasswordError = '' + const { password } = state; + let confirmPasswordError = ''; if (password !== confirmPassword) { - confirmPasswordError = t('passwordsDontMatch') + confirmPasswordError = t('passwordsDontMatch'); } return { confirmPassword, confirmPasswordError, - } - }) + }; + }); } handleImport = async (event) => { - event.preventDefault() + event.preventDefault(); if (!this.isValid()) { - return + return; } - const { password, seedPhrase } = this.state + const { password, seedPhrase } = this.state; const { history, onSubmit, setSeedPhraseBackedUp, initializeThreeBox, - } = this.props + } = this.props; try { - await onSubmit(password, this.parseSeedPhrase(seedPhrase)) + await onSubmit(password, this.parseSeedPhrase(seedPhrase)); this.context.metricsEvent({ eventOpts: { category: 'Onboarding', action: 'Import Seed Phrase', name: 'Import Complete', }, - }) + }); setSeedPhraseBackedUp(true).then(async () => { - initializeThreeBox() - history.push(INITIALIZE_END_OF_FLOW_ROUTE) - }) + initializeThreeBox(); + history.push(INITIALIZE_END_OF_FLOW_ROUTE); + }); } catch (error) { - this.setState({ seedPhraseError: error.message }) + this.setState({ seedPhraseError: error.message }); } - } + }; isValid() { const { @@ -157,7 +157,7 @@ export default class ImportWithSeedPhrase extends PureComponent { passwordError, confirmPasswordError, seedPhraseError, - } = this.state + } = this.state; if ( !password || @@ -165,21 +165,21 @@ export default class ImportWithSeedPhrase extends PureComponent { !seedPhrase || password !== confirmPassword ) { - return false + return false; } if (password.length < 8) { - return false + return false; } - return !passwordError && !confirmPasswordError && !seedPhraseError + return !passwordError && !confirmPasswordError && !seedPhraseError; } onTermsKeyPress = ({ key }) => { if (key === ' ' || key === 'Enter') { - this.toggleTermsCheck() + this.toggleTermsCheck(); } - } + }; toggleTermsCheck = () => { this.context.metricsEvent({ @@ -188,34 +188,34 @@ export default class ImportWithSeedPhrase extends PureComponent { action: 'Import Seed Phrase', name: 'Check ToS', }, - }) + }); this.setState((prevState) => ({ termsChecked: !prevState.termsChecked, - })) - } + })); + }; toggleShowSeedPhrase = () => { this.setState(({ showSeedPhrase }) => ({ showSeedPhrase: !showSeedPhrase, - })) - } + })); + }; render() { - const { t } = this.context + const { t } = this.context; const { seedPhraseError, showSeedPhrase, passwordError, confirmPasswordError, termsChecked, - } = this.state + } = this.state; return (
    { - e.preventDefault() + e.preventDefault(); this.context.metricsEvent({ eventOpts: { category: 'Onboarding', @@ -226,8 +226,8 @@ export default class ImportWithSeedPhrase extends PureComponent { errorLabel: 'Seed Phrase Error', errorMessage: seedPhraseError, }, - }) - this.props.history.push(INITIALIZE_SELECT_ACTION_ROUTE) + }); + this.props.history.push(INITIALIZE_SELECT_ACTION_ROUTE); }} href="#" > @@ -342,6 +342,6 @@ export default class ImportWithSeedPhrase extends PureComponent { {t('import')} - ) + ); } } diff --git a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.container.js b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.container.js index 7da5af5a1a..7d2fef50f1 100644 --- a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.container.js +++ b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/import-with-seed-phrase.container.js @@ -1,16 +1,16 @@ -import { connect } from 'react-redux' +import { connect } from 'react-redux'; import { setSeedPhraseBackedUp, initializeThreeBox, -} from '../../../../store/actions' -import ImportWithSeedPhrase from './import-with-seed-phrase.component' +} from '../../../../store/actions'; +import ImportWithSeedPhrase from './import-with-seed-phrase.component'; const mapDispatchToProps = (dispatch) => { return { setSeedPhraseBackedUp: (seedPhraseBackupState) => dispatch(setSeedPhraseBackedUp(seedPhraseBackupState)), initializeThreeBox: () => dispatch(initializeThreeBox()), - } -} + }; +}; -export default connect(null, mapDispatchToProps)(ImportWithSeedPhrase) +export default connect(null, mapDispatchToProps)(ImportWithSeedPhrase); diff --git a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/index.js b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/index.js index 9d4ad7d0fc..3e192d728b 100644 --- a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/index.js +++ b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/index.js @@ -1 +1 @@ -export { default } from './import-with-seed-phrase.container' +export { default } from './import-with-seed-phrase.container'; diff --git a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js index 7aea35494f..57e8ddceee 100644 --- a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js +++ b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js @@ -1,8 +1,8 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import sinon from 'sinon' -import ImportWithSeedPhrase from '../import-with-seed-phrase.component' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import ImportWithSeedPhrase from '../import-with-seed-phrase.component'; function shallowRender(props = {}, context = {}) { return shallow(, { @@ -11,91 +11,91 @@ function shallowRender(props = {}, context = {}) { metricsEvent: sinon.spy(), ...context, }, - }) + }); } describe('ImportWithSeedPhrase Component', function () { it('should render without error', function () { const root = shallowRender({ onSubmit: sinon.spy(), - }) - const textareaCount = root.find('.first-time-flow__textarea').length - assert.strictEqual(textareaCount, 1, 'should render 12 seed phrases') - }) + }); + const textareaCount = root.find('.first-time-flow__textarea').length; + assert.strictEqual(textareaCount, 1, 'should render 12 seed phrases'); + }); describe('parseSeedPhrase', function () { it('should handle a regular seed phrase', function () { const root = shallowRender({ onSubmit: sinon.spy(), - }) + }); - const { parseSeedPhrase } = root.instance() + const { parseSeedPhrase } = root.instance(); - assert.deepStrictEqual(parseSeedPhrase('foo bar baz'), 'foo bar baz') - }) + assert.deepStrictEqual(parseSeedPhrase('foo bar baz'), 'foo bar baz'); + }); it('should handle a mixed-case seed phrase', function () { const root = shallowRender({ onSubmit: sinon.spy(), - }) + }); - const { parseSeedPhrase } = root.instance() + const { parseSeedPhrase } = root.instance(); - assert.deepStrictEqual(parseSeedPhrase('FOO bAr baZ'), 'foo bar baz') - }) + assert.deepStrictEqual(parseSeedPhrase('FOO bAr baZ'), 'foo bar baz'); + }); it('should handle an upper-case seed phrase', function () { const root = shallowRender({ onSubmit: sinon.spy(), - }) + }); - const { parseSeedPhrase } = root.instance() + const { parseSeedPhrase } = root.instance(); - assert.deepStrictEqual(parseSeedPhrase('FOO BAR BAZ'), 'foo bar baz') - }) + assert.deepStrictEqual(parseSeedPhrase('FOO BAR BAZ'), 'foo bar baz'); + }); it('should trim extraneous whitespace from the given seed phrase', function () { const root = shallowRender({ onSubmit: sinon.spy(), - }) + }); - const { parseSeedPhrase } = root.instance() + const { parseSeedPhrase } = root.instance(); assert.deepStrictEqual( parseSeedPhrase(' foo bar baz '), 'foo bar baz', - ) - }) + ); + }); it('should return an empty string when given a whitespace-only string', function () { const root = shallowRender({ onSubmit: sinon.spy(), - }) + }); - const { parseSeedPhrase } = root.instance() + const { parseSeedPhrase } = root.instance(); - assert.deepStrictEqual(parseSeedPhrase(' '), '') - }) + assert.deepStrictEqual(parseSeedPhrase(' '), ''); + }); it('should return an empty string when given a string with only symbols', function () { const root = shallowRender({ onSubmit: sinon.spy(), - }) + }); - const { parseSeedPhrase } = root.instance() + const { parseSeedPhrase } = root.instance(); - assert.deepStrictEqual(parseSeedPhrase('$'), '') - }) + assert.deepStrictEqual(parseSeedPhrase('$'), ''); + }); it('should return an empty string for both null and undefined', function () { const root = shallowRender({ onSubmit: sinon.spy(), - }) + }); - const { parseSeedPhrase } = root.instance() + const { parseSeedPhrase } = root.instance(); - assert.deepStrictEqual(parseSeedPhrase(undefined), '') - assert.deepStrictEqual(parseSeedPhrase(null), '') - }) - }) -}) + assert.deepStrictEqual(parseSeedPhrase(undefined), ''); + assert.deepStrictEqual(parseSeedPhrase(null), ''); + }); + }); +}); diff --git a/ui/app/pages/first-time-flow/create-password/index.js b/ui/app/pages/first-time-flow/create-password/index.js index 42e7436f91..d4baaac71b 100644 --- a/ui/app/pages/first-time-flow/create-password/index.js +++ b/ui/app/pages/first-time-flow/create-password/index.js @@ -1 +1 @@ -export { default } from './create-password.container' +export { default } from './create-password.container'; diff --git a/ui/app/pages/first-time-flow/create-password/new-account/index.js b/ui/app/pages/first-time-flow/create-password/new-account/index.js index 97db39cc3c..f12222878a 100644 --- a/ui/app/pages/first-time-flow/create-password/new-account/index.js +++ b/ui/app/pages/first-time-flow/create-password/new-account/index.js @@ -1 +1 @@ -export { default } from './new-account.component' +export { default } from './new-account.component'; diff --git a/ui/app/pages/first-time-flow/create-password/new-account/new-account.component.js b/ui/app/pages/first-time-flow/create-password/new-account/new-account.component.js index 0f86a5d7b0..b74cce8a96 100644 --- a/ui/app/pages/first-time-flow/create-password/new-account/new-account.component.js +++ b/ui/app/pages/first-time-flow/create-password/new-account/new-account.component.js @@ -1,22 +1,22 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import Button from '../../../../components/ui/button' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import Button from '../../../../components/ui/button'; import { INITIALIZE_SEED_PHRASE_ROUTE, INITIALIZE_SELECT_ACTION_ROUTE, -} from '../../../../helpers/constants/routes' -import TextField from '../../../../components/ui/text-field' +} from '../../../../helpers/constants/routes'; +import TextField from '../../../../components/ui/text-field'; export default class NewAccount extends PureComponent { static contextTypes = { metricsEvent: PropTypes.func, t: PropTypes.func, - } + }; static propTypes = { onSubmit: PropTypes.func.isRequired, history: PropTypes.object.isRequired, - } + }; state = { password: '', @@ -24,7 +24,7 @@ export default class NewAccount extends PureComponent { passwordError: '', confirmPasswordError: '', termsChecked: false, - } + }; isValid() { const { @@ -32,73 +32,73 @@ export default class NewAccount extends PureComponent { confirmPassword, passwordError, confirmPasswordError, - } = this.state + } = this.state; if (!password || !confirmPassword || password !== confirmPassword) { - return false + return false; } if (password.length < 8) { - return false + return false; } - return !passwordError && !confirmPasswordError + return !passwordError && !confirmPasswordError; } handlePasswordChange(password) { - const { t } = this.context + const { t } = this.context; this.setState((state) => { - const { confirmPassword } = state - let passwordError = '' - let confirmPasswordError = '' + const { confirmPassword } = state; + let passwordError = ''; + let confirmPasswordError = ''; if (password && password.length < 8) { - passwordError = t('passwordNotLongEnough') + passwordError = t('passwordNotLongEnough'); } if (confirmPassword && password !== confirmPassword) { - confirmPasswordError = t('passwordsDontMatch') + confirmPasswordError = t('passwordsDontMatch'); } return { password, passwordError, confirmPasswordError, - } - }) + }; + }); } handleConfirmPasswordChange(confirmPassword) { - const { t } = this.context + const { t } = this.context; this.setState((state) => { - const { password } = state - let confirmPasswordError = '' + const { password } = state; + let confirmPasswordError = ''; if (password !== confirmPassword) { - confirmPasswordError = t('passwordsDontMatch') + confirmPasswordError = t('passwordsDontMatch'); } return { confirmPassword, confirmPasswordError, - } - }) + }; + }); } handleCreate = async (event) => { - event.preventDefault() + event.preventDefault(); if (!this.isValid()) { - return + return; } - const { password } = this.state - const { onSubmit, history } = this.props + const { password } = this.state; + const { onSubmit, history } = this.props; try { - await onSubmit(password) + await onSubmit(password); this.context.metricsEvent({ eventOpts: { @@ -106,13 +106,13 @@ export default class NewAccount extends PureComponent { action: 'Create Password', name: 'Submit Password', }, - }) + }); - history.push(INITIALIZE_SEED_PHRASE_ROUTE) + history.push(INITIALIZE_SEED_PHRASE_ROUTE); } catch (error) { - this.setState({ passwordError: error.message }) + this.setState({ passwordError: error.message }); } - } + }; toggleTermsCheck = () => { this.context.metricsEvent({ @@ -121,43 +121,43 @@ export default class NewAccount extends PureComponent { action: 'Create Password', name: 'Check ToS', }, - }) + }); this.setState((prevState) => ({ termsChecked: !prevState.termsChecked, - })) - } + })); + }; onTermsKeyPress = ({ key }) => { if (key === ' ' || key === 'Enter') { - this.toggleTermsCheck() + this.toggleTermsCheck(); } - } + }; render() { - const { t } = this.context + const { t } = this.context; const { password, confirmPassword, passwordError, confirmPasswordError, termsChecked, - } = this.state + } = this.state; return (
    - ) + ); } } diff --git a/ui/app/pages/first-time-flow/create-password/unique-image/index.js b/ui/app/pages/first-time-flow/create-password/unique-image/index.js index 0e97bf7554..8a16dbcce1 100644 --- a/ui/app/pages/first-time-flow/create-password/unique-image/index.js +++ b/ui/app/pages/first-time-flow/create-password/unique-image/index.js @@ -1 +1 @@ -export { default } from './unique-image.container' +export { default } from './unique-image.container'; diff --git a/ui/app/pages/first-time-flow/create-password/unique-image/unique-image.component.js b/ui/app/pages/first-time-flow/create-password/unique-image/unique-image.component.js index ad30c20663..3533b8b2d0 100644 --- a/ui/app/pages/first-time-flow/create-password/unique-image/unique-image.component.js +++ b/ui/app/pages/first-time-flow/create-password/unique-image/unique-image.component.js @@ -1,21 +1,21 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import Button from '../../../../components/ui/button' -import { INITIALIZE_END_OF_FLOW_ROUTE } from '../../../../helpers/constants/routes' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import Button from '../../../../components/ui/button'; +import { INITIALIZE_END_OF_FLOW_ROUTE } from '../../../../helpers/constants/routes'; export default class UniqueImageScreen extends PureComponent { static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; static propTypes = { history: PropTypes.object, - } + }; render() { - const { t } = this.context - const { history } = this.props + const { t } = this.context; + const { history } = this.props; return (
    @@ -37,13 +37,13 @@ export default class UniqueImageScreen extends PureComponent { action: 'Agree to Phishing Warning', name: 'Agree to Phishing Warning', }, - }) - history.push(INITIALIZE_END_OF_FLOW_ROUTE) + }); + history.push(INITIALIZE_END_OF_FLOW_ROUTE); }} > {t('next')}
    - ) + ); } } diff --git a/ui/app/pages/first-time-flow/create-password/unique-image/unique-image.container.js b/ui/app/pages/first-time-flow/create-password/unique-image/unique-image.container.js index 34874aaec5..fd3e5953f6 100644 --- a/ui/app/pages/first-time-flow/create-password/unique-image/unique-image.container.js +++ b/ui/app/pages/first-time-flow/create-password/unique-image/unique-image.container.js @@ -1,12 +1,12 @@ -import { connect } from 'react-redux' -import UniqueImage from './unique-image.component' +import { connect } from 'react-redux'; +import UniqueImage from './unique-image.component'; const mapStateToProps = ({ metamask }) => { - const { selectedAddress } = metamask + const { selectedAddress } = metamask; return { address: selectedAddress, - } -} + }; +}; -export default connect(mapStateToProps)(UniqueImage) +export default connect(mapStateToProps)(UniqueImage); diff --git a/ui/app/pages/first-time-flow/end-of-flow/end-of-flow.component.js b/ui/app/pages/first-time-flow/end-of-flow/end-of-flow.component.js index 34a52a027e..c461fa6376 100644 --- a/ui/app/pages/first-time-flow/end-of-flow/end-of-flow.component.js +++ b/ui/app/pages/first-time-flow/end-of-flow/end-of-flow.component.js @@ -1,16 +1,16 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import Button from '../../../components/ui/button' -import Snackbar from '../../../components/ui/snackbar' -import MetaFoxLogo from '../../../components/ui/metafox-logo' -import { DEFAULT_ROUTE } from '../../../helpers/constants/routes' -import { returnToOnboardingInitiator } from '../onboarding-initiator-util' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import Button from '../../../components/ui/button'; +import Snackbar from '../../../components/ui/snackbar'; +import MetaFoxLogo from '../../../components/ui/metafox-logo'; +import { DEFAULT_ROUTE } from '../../../helpers/constants/routes'; +import { returnToOnboardingInitiator } from '../onboarding-initiator-util'; export default class EndOfFlowScreen extends PureComponent { static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; static propTypes = { history: PropTypes.object, @@ -20,50 +20,50 @@ export default class EndOfFlowScreen extends PureComponent { location: PropTypes.string, tabId: PropTypes.number, }), - } + }; async _beforeUnload() { - await this._onOnboardingComplete() + await this._onOnboardingComplete(); } _removeBeforeUnload() { - window.removeEventListener('beforeunload', this._beforeUnload) + window.removeEventListener('beforeunload', this._beforeUnload); } async _onOnboardingComplete() { - const { setCompletedOnboarding, completionMetaMetricsName } = this.props - await setCompletedOnboarding() + const { setCompletedOnboarding, completionMetaMetricsName } = this.props; + await setCompletedOnboarding(); this.context.metricsEvent({ eventOpts: { category: 'Onboarding', action: 'Onboarding Complete', name: completionMetaMetricsName, }, - }) + }); } onComplete = async () => { - const { history, onboardingInitiator } = this.props + const { history, onboardingInitiator } = this.props; - this._removeBeforeUnload() - await this._onOnboardingComplete() + this._removeBeforeUnload(); + await this._onOnboardingComplete(); if (onboardingInitiator) { - await returnToOnboardingInitiator(onboardingInitiator) + await returnToOnboardingInitiator(onboardingInitiator); } - history.push(DEFAULT_ROUTE) - } + history.push(DEFAULT_ROUTE); + }; componentDidMount() { - window.addEventListener('beforeunload', this._beforeUnload.bind(this)) + window.addEventListener('beforeunload', this._beforeUnload.bind(this)); } componentWillUnmount = () => { - this._removeBeforeUnload() - } + this._removeBeforeUnload(); + }; render() { - const { t } = this.context - const { onboardingInitiator } = this.props + const { t } = this.context; + const { onboardingInitiator } = this.props; return (
    @@ -119,6 +119,6 @@ export default class EndOfFlowScreen extends PureComponent { /> ) : null}
    - ) + ); } } diff --git a/ui/app/pages/first-time-flow/end-of-flow/end-of-flow.container.js b/ui/app/pages/first-time-flow/end-of-flow/end-of-flow.container.js index 5b0d00c17f..fa3bcec2d4 100644 --- a/ui/app/pages/first-time-flow/end-of-flow/end-of-flow.container.js +++ b/ui/app/pages/first-time-flow/end-of-flow/end-of-flow.container.js @@ -1,28 +1,28 @@ -import { connect } from 'react-redux' -import { getOnboardingInitiator } from '../../../selectors' -import { setCompletedOnboarding } from '../../../store/actions' -import EndOfFlow from './end-of-flow.component' +import { connect } from 'react-redux'; +import { getOnboardingInitiator } from '../../../selectors'; +import { setCompletedOnboarding } from '../../../store/actions'; +import EndOfFlow from './end-of-flow.component'; const firstTimeFlowTypeNameMap = { create: 'New Wallet Created', import: 'New Wallet Imported', -} +}; const mapStateToProps = (state) => { const { metamask: { firstTimeFlowType }, - } = state + } = state; return { completionMetaMetricsName: firstTimeFlowTypeNameMap[firstTimeFlowType], onboardingInitiator: getOnboardingInitiator(state), - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { setCompletedOnboarding: () => dispatch(setCompletedOnboarding()), - } -} + }; +}; -export default connect(mapStateToProps, mapDispatchToProps)(EndOfFlow) +export default connect(mapStateToProps, mapDispatchToProps)(EndOfFlow); diff --git a/ui/app/pages/first-time-flow/end-of-flow/index.js b/ui/app/pages/first-time-flow/end-of-flow/index.js index b0643d1552..4b34ccefdf 100644 --- a/ui/app/pages/first-time-flow/end-of-flow/index.js +++ b/ui/app/pages/first-time-flow/end-of-flow/index.js @@ -1 +1 @@ -export { default } from './end-of-flow.container' +export { default } from './end-of-flow.container'; diff --git a/ui/app/pages/first-time-flow/end-of-flow/tests/end-of-flow.test.js b/ui/app/pages/first-time-flow/end-of-flow/tests/end-of-flow.test.js index aef4ef6a14..2e25aa6b94 100644 --- a/ui/app/pages/first-time-flow/end-of-flow/tests/end-of-flow.test.js +++ b/ui/app/pages/first-time-flow/end-of-flow/tests/end-of-flow.test.js @@ -1,35 +1,37 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import { mountWithRouter } from '../../../../../../test/lib/render-helpers' -import { DEFAULT_ROUTE } from '../../../../helpers/constants/routes' -import EndOfFlowScreen from '..' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import { mountWithRouter } from '../../../../../../test/lib/render-helpers'; +import { DEFAULT_ROUTE } from '../../../../helpers/constants/routes'; +import EndOfFlowScreen from '..'; describe('End of Flow Screen', function () { - let wrapper + let wrapper; const props = { history: { push: sinon.spy(), }, setCompletedOnboarding: sinon.spy(), - } + }; beforeEach(function () { - wrapper = mountWithRouter() - }) + wrapper = mountWithRouter(); + }); it('renders', function () { - assert.strictEqual(wrapper.length, 1) - }) + assert.strictEqual(wrapper.length, 1); + }); it('should navigate to the default route on click', function (done) { - const endOfFlowButton = wrapper.find('.btn-primary.first-time-flow__button') - endOfFlowButton.simulate('click') + const endOfFlowButton = wrapper.find( + '.btn-primary.first-time-flow__button', + ); + endOfFlowButton.simulate('click'); setImmediate(() => { - assert(props.history.push.calledOnceWithExactly(DEFAULT_ROUTE)) - done() - }) - }) -}) + assert(props.history.push.calledOnceWithExactly(DEFAULT_ROUTE)); + done(); + }); + }); +}); diff --git a/ui/app/pages/first-time-flow/first-time-flow-switch/first-time-flow-switch.component.js b/ui/app/pages/first-time-flow/first-time-flow-switch/first-time-flow-switch.component.js index 6caad3c003..be27ee7cf8 100644 --- a/ui/app/pages/first-time-flow/first-time-flow-switch/first-time-flow-switch.component.js +++ b/ui/app/pages/first-time-flow/first-time-flow-switch/first-time-flow-switch.component.js @@ -1,13 +1,13 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import { Redirect } from 'react-router-dom' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { Redirect } from 'react-router-dom'; import { DEFAULT_ROUTE, LOCK_ROUTE, INITIALIZE_END_OF_FLOW_ROUTE, INITIALIZE_WELCOME_ROUTE, INITIALIZE_UNLOCK_ROUTE, -} from '../../../helpers/constants/routes' +} from '../../../helpers/constants/routes'; export default class FirstTimeFlowSwitch extends PureComponent { static propTypes = { @@ -15,7 +15,7 @@ export default class FirstTimeFlowSwitch extends PureComponent { isInitialized: PropTypes.bool, isUnlocked: PropTypes.bool, seedPhraseBackedUp: PropTypes.bool, - } + }; render() { const { @@ -23,24 +23,24 @@ export default class FirstTimeFlowSwitch extends PureComponent { isInitialized, isUnlocked, seedPhraseBackedUp, - } = this.props + } = this.props; if (completedOnboarding) { - return + return ; } if (seedPhraseBackedUp !== null) { - return + return ; } if (isUnlocked) { - return + return ; } if (!isInitialized) { - return + return ; } - return + return ; } } diff --git a/ui/app/pages/first-time-flow/first-time-flow-switch/first-time-flow-switch.container.js b/ui/app/pages/first-time-flow/first-time-flow-switch/first-time-flow-switch.container.js index 92423f3dcd..265c51ff01 100644 --- a/ui/app/pages/first-time-flow/first-time-flow-switch/first-time-flow-switch.container.js +++ b/ui/app/pages/first-time-flow/first-time-flow-switch/first-time-flow-switch.container.js @@ -1,5 +1,5 @@ -import { connect } from 'react-redux' -import FirstTimeFlowSwitch from './first-time-flow-switch.component' +import { connect } from 'react-redux'; +import FirstTimeFlowSwitch from './first-time-flow-switch.component'; const mapStateToProps = ({ metamask }) => { const { @@ -7,14 +7,14 @@ const mapStateToProps = ({ metamask }) => { isInitialized, isUnlocked, seedPhraseBackedUp, - } = metamask + } = metamask; return { completedOnboarding, isInitialized, isUnlocked, seedPhraseBackedUp, - } -} + }; +}; -export default connect(mapStateToProps)(FirstTimeFlowSwitch) +export default connect(mapStateToProps)(FirstTimeFlowSwitch); diff --git a/ui/app/pages/first-time-flow/first-time-flow-switch/index.js b/ui/app/pages/first-time-flow/first-time-flow-switch/index.js index 3647756efb..c7280e9b1c 100644 --- a/ui/app/pages/first-time-flow/first-time-flow-switch/index.js +++ b/ui/app/pages/first-time-flow/first-time-flow-switch/index.js @@ -1 +1 @@ -export { default } from './first-time-flow-switch.container' +export { default } from './first-time-flow-switch.container'; diff --git a/ui/app/pages/first-time-flow/first-time-flow-switch/tests/first-time-flow-switch.test.js b/ui/app/pages/first-time-flow/first-time-flow-switch/tests/first-time-flow-switch.test.js index fa3b9788ff..16270b2bd9 100644 --- a/ui/app/pages/first-time-flow/first-time-flow-switch/tests/first-time-flow-switch.test.js +++ b/ui/app/pages/first-time-flow/first-time-flow-switch/tests/first-time-flow-switch.test.js @@ -1,14 +1,14 @@ -import assert from 'assert' -import React from 'react' -import { mountWithRouter } from '../../../../../../test/lib/render-helpers' +import assert from 'assert'; +import React from 'react'; +import { mountWithRouter } from '../../../../../../test/lib/render-helpers'; import { DEFAULT_ROUTE, LOCK_ROUTE, INITIALIZE_WELCOME_ROUTE, INITIALIZE_UNLOCK_ROUTE, INITIALIZE_END_OF_FLOW_ROUTE, -} from '../../../../helpers/constants/routes' -import FirstTimeFlowSwitch from '..' +} from '../../../../helpers/constants/routes'; +import FirstTimeFlowSwitch from '..'; describe('FirstTimeFlowSwitch', function () { it('redirects to /welcome route with null props', function () { @@ -17,83 +17,83 @@ describe('FirstTimeFlowSwitch', function () { isInitialized: null, isUnlocked: null, seedPhraseBackedUp: null, - } + }; const wrapper = mountWithRouter( , - ) + ); assert.strictEqual( wrapper .find('Lifecycle') .find({ to: { pathname: INITIALIZE_WELCOME_ROUTE } }).length, 1, - ) - }) + ); + }); it('redirects to / route when completedOnboarding is true', function () { const props = { completedOnboarding: true, - } + }; const wrapper = mountWithRouter( , - ) + ); assert.strictEqual( wrapper.find('Lifecycle').find({ to: { pathname: DEFAULT_ROUTE } }) .length, 1, - ) - }) + ); + }); it('redirects to end of flow route when seedPhraseBackedUp is true', function () { const props = { completedOnboarding: false, seedPhraseBackedUp: true, - } + }; const wrapper = mountWithRouter( , - ) + ); assert.strictEqual( wrapper .find('Lifecycle') .find({ to: { pathname: INITIALIZE_END_OF_FLOW_ROUTE } }).length, 1, - ) - }) + ); + }); it('redirects to end of flow route when seedPhraseBackedUp is false', function () { const props = { completedOnboarding: false, seedPhraseBackedUp: false, - } + }; const wrapper = mountWithRouter( , - ) + ); assert.strictEqual( wrapper .find('Lifecycle') .find({ to: { pathname: INITIALIZE_END_OF_FLOW_ROUTE } }).length, 1, - ) - }) + ); + }); it('redirects to /lock route when isUnlocked is true ', function () { const props = { completedOnboarding: false, isUnlocked: true, seedPhraseBackedUp: null, - } + }; const wrapper = mountWithRouter( , - ) + ); assert.strictEqual( wrapper.find('Lifecycle').find({ to: { pathname: LOCK_ROUTE } }).length, 1, - ) - }) + ); + }); it('redirects to /welcome route when isInitialized is false', function () { const props = { @@ -101,19 +101,19 @@ describe('FirstTimeFlowSwitch', function () { isUnlocked: false, isInitialized: false, seedPhraseBackedUp: null, - } + }; const wrapper = mountWithRouter( , - ) + ); assert.strictEqual( wrapper .find('Lifecycle') .find({ to: { pathname: INITIALIZE_WELCOME_ROUTE } }).length, 1, - ) - }) + ); + }); it('redirects to /unlock route when isInitialized is true', function () { const props = { @@ -121,17 +121,17 @@ describe('FirstTimeFlowSwitch', function () { isUnlocked: false, isInitialized: true, seedPhraseBackedUp: null, - } + }; const wrapper = mountWithRouter( , - ) + ); assert.strictEqual( wrapper .find('Lifecycle') .find({ to: { pathname: INITIALIZE_UNLOCK_ROUTE } }).length, 1, - ) - }) -}) + ); + }); +}); diff --git a/ui/app/pages/first-time-flow/first-time-flow.component.js b/ui/app/pages/first-time-flow/first-time-flow.component.js index 0a96a8ceb1..5094fb2ba8 100644 --- a/ui/app/pages/first-time-flow/first-time-flow.component.js +++ b/ui/app/pages/first-time-flow/first-time-flow.component.js @@ -1,7 +1,7 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import { Switch, Route } from 'react-router-dom' -import Unlock from '../unlock-page' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { Switch, Route } from 'react-router-dom'; +import Unlock from '../unlock-page'; import { DEFAULT_ROUTE, INITIALIZE_WELCOME_ROUTE, @@ -12,14 +12,14 @@ import { INITIALIZE_END_OF_FLOW_ROUTE, INITIALIZE_METAMETRICS_OPT_IN_ROUTE, INITIALIZE_BACKUP_SEED_PHRASE_ROUTE, -} from '../../helpers/constants/routes' -import FirstTimeFlowSwitch from './first-time-flow-switch' -import Welcome from './welcome' -import SelectAction from './select-action' -import EndOfFlow from './end-of-flow' -import CreatePassword from './create-password' -import SeedPhrase from './seed-phrase' -import MetaMetricsOptInScreen from './metametrics-opt-in' +} from '../../helpers/constants/routes'; +import FirstTimeFlowSwitch from './first-time-flow-switch'; +import Welcome from './welcome'; +import SelectAction from './select-action'; +import EndOfFlow from './end-of-flow'; +import CreatePassword from './create-password'; +import SeedPhrase from './seed-phrase'; +import MetaMetricsOptInScreen from './metametrics-opt-in'; export default class FirstTimeFlow extends PureComponent { static propTypes = { @@ -34,11 +34,11 @@ export default class FirstTimeFlow extends PureComponent { showingSeedPhraseBackupAfterOnboarding: PropTypes.bool, seedPhraseBackedUp: PropTypes.bool, verifySeedPhrase: PropTypes.func, - } + }; state = { seedPhrase: '', - } + }; componentDidMount() { const { @@ -48,59 +48,59 @@ export default class FirstTimeFlow extends PureComponent { isUnlocked, showingSeedPhraseBackupAfterOnboarding, seedPhraseBackedUp, - } = this.props + } = this.props; if ( completedOnboarding && (!showingSeedPhraseBackupAfterOnboarding || seedPhraseBackedUp) ) { - history.push(DEFAULT_ROUTE) - return + history.push(DEFAULT_ROUTE); + return; } if (isInitialized && !isUnlocked) { - history.push(INITIALIZE_UNLOCK_ROUTE) + history.push(INITIALIZE_UNLOCK_ROUTE); } } handleCreateNewAccount = async (password) => { - const { createNewAccount } = this.props + const { createNewAccount } = this.props; try { - const seedPhrase = await createNewAccount(password) - this.setState({ seedPhrase }) + const seedPhrase = await createNewAccount(password); + this.setState({ seedPhrase }); } catch (error) { - throw new Error(error.message) + throw new Error(error.message); } - } + }; handleImportWithSeedPhrase = async (password, seedPhrase) => { - const { createNewAccountFromSeed } = this.props + const { createNewAccountFromSeed } = this.props; try { - const vault = await createNewAccountFromSeed(password, seedPhrase) - return vault + const vault = await createNewAccountFromSeed(password, seedPhrase); + return vault; } catch (error) { - throw new Error(error.message) + throw new Error(error.message); } - } + }; handleUnlock = async (password) => { - const { unlockAccount, history, nextRoute } = this.props + const { unlockAccount, history, nextRoute } = this.props; try { - const seedPhrase = await unlockAccount(password) + const seedPhrase = await unlockAccount(password); this.setState({ seedPhrase }, () => { - history.push(nextRoute) - }) + history.push(nextRoute); + }); } catch (error) { - throw new Error(error.message) + throw new Error(error.message); } - } + }; render() { - const { seedPhrase } = this.state - const { verifySeedPhrase } = this.props + const { seedPhrase } = this.state; + const { verifySeedPhrase } = this.props; return (
    @@ -159,6 +159,6 @@ export default class FirstTimeFlow extends PureComponent {
    - ) + ); } } diff --git a/ui/app/pages/first-time-flow/first-time-flow.container.js b/ui/app/pages/first-time-flow/first-time-flow.container.js index 4e358a6f89..8c0abaf5f0 100644 --- a/ui/app/pages/first-time-flow/first-time-flow.container.js +++ b/ui/app/pages/first-time-flow/first-time-flow.container.js @@ -1,13 +1,13 @@ -import { connect } from 'react-redux' -import { getFirstTimeFlowTypeRoute } from '../../selectors' +import { connect } from 'react-redux'; +import { getFirstTimeFlowTypeRoute } from '../../selectors'; import { createNewVaultAndGetSeedPhrase, createNewVaultAndRestore, unlockAndGetSeedPhrase, verifySeedPhrase, -} from '../../store/actions' -import { INITIALIZE_BACKUP_SEED_PHRASE_ROUTE } from '../../helpers/constants/routes' -import FirstTimeFlow from './first-time-flow.component' +} from '../../store/actions'; +import { INITIALIZE_BACKUP_SEED_PHRASE_ROUTE } from '../../helpers/constants/routes'; +import FirstTimeFlow from './first-time-flow.component'; const mapStateToProps = (state, ownProps) => { const { @@ -17,10 +17,10 @@ const mapStateToProps = (state, ownProps) => { isUnlocked, seedPhraseBackedUp, }, - } = state + } = state; const showingSeedPhraseBackupAfterOnboarding = Boolean( ownProps.location.pathname.match(INITIALIZE_BACKUP_SEED_PHRASE_ROUTE), - ) + ); return { completedOnboarding, @@ -29,19 +29,19 @@ const mapStateToProps = (state, ownProps) => { nextRoute: getFirstTimeFlowTypeRoute(state), showingSeedPhraseBackupAfterOnboarding, seedPhraseBackedUp, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { createNewAccount: (password) => dispatch(createNewVaultAndGetSeedPhrase(password)), createNewAccountFromSeed: (password, seedPhrase) => { - return dispatch(createNewVaultAndRestore(password, seedPhrase)) + return dispatch(createNewVaultAndRestore(password, seedPhrase)); }, unlockAccount: (password) => dispatch(unlockAndGetSeedPhrase(password)), verifySeedPhrase: () => verifySeedPhrase(), - } -} + }; +}; -export default connect(mapStateToProps, mapDispatchToProps)(FirstTimeFlow) +export default connect(mapStateToProps, mapDispatchToProps)(FirstTimeFlow); diff --git a/ui/app/pages/first-time-flow/index.js b/ui/app/pages/first-time-flow/index.js index 5db42437c6..1e045f2ef7 100644 --- a/ui/app/pages/first-time-flow/index.js +++ b/ui/app/pages/first-time-flow/index.js @@ -1 +1 @@ -export { default } from './first-time-flow.container' +export { default } from './first-time-flow.container'; diff --git a/ui/app/pages/first-time-flow/metametrics-opt-in/index.js b/ui/app/pages/first-time-flow/metametrics-opt-in/index.js index 4bc2fc3a7c..285dbd9de1 100644 --- a/ui/app/pages/first-time-flow/metametrics-opt-in/index.js +++ b/ui/app/pages/first-time-flow/metametrics-opt-in/index.js @@ -1 +1 @@ -export { default } from './metametrics-opt-in.container' +export { default } from './metametrics-opt-in.container'; diff --git a/ui/app/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.component.js b/ui/app/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.component.js index 0bafcf01a9..5e3be989b3 100644 --- a/ui/app/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.component.js +++ b/ui/app/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.component.js @@ -1,7 +1,7 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import MetaFoxLogo from '../../../components/ui/metafox-logo' -import PageContainerFooter from '../../../components/ui/page-container/page-container-footer' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import MetaFoxLogo from '../../../components/ui/metafox-logo'; +import PageContainerFooter from '../../../components/ui/page-container/page-container-footer'; export default class MetaMetricsOptIn extends Component { static propTypes = { @@ -10,22 +10,22 @@ export default class MetaMetricsOptIn extends Component { nextRoute: PropTypes.string, firstTimeSelectionMetaMetricsName: PropTypes.string, participateInMetaMetrics: PropTypes.bool, - } + }; static contextTypes = { metricsEvent: PropTypes.func, t: PropTypes.func, - } + }; render() { - const { metricsEvent, t } = this.context + const { metricsEvent, t } = this.context; const { nextRoute, history, setParticipateInMetaMetrics, firstTimeSelectionMetaMetricsName, participateInMetaMetrics, - } = this.props + } = this.props; return (
    @@ -102,7 +102,7 @@ export default class MetaMetricsOptIn extends Component {
    { - await setParticipateInMetaMetrics(false) + await setParticipateInMetaMetrics(false); try { if ( @@ -117,10 +117,10 @@ export default class MetaMetricsOptIn extends Component { }, isOptIn: true, flushImmediately: true, - }) + }); } } finally { - history.push(nextRoute) + history.push(nextRoute); } }} cancelText={t('noThanks')} @@ -128,9 +128,9 @@ export default class MetaMetricsOptIn extends Component { onSubmit={async () => { const [, metaMetricsId] = await setParticipateInMetaMetrics( true, - ) + ); try { - const metrics = [] + const metrics = []; if ( participateInMetaMetrics === null || participateInMetaMetrics === false @@ -145,7 +145,7 @@ export default class MetaMetricsOptIn extends Component { isOptIn: true, flushImmediately: true, }), - ) + ); } metrics.push( metricsEvent({ @@ -158,10 +158,10 @@ export default class MetaMetricsOptIn extends Component { metaMetricsId, flushImmediately: true, }), - ) - await Promise.all(metrics) + ); + await Promise.all(metrics); } finally { - history.push(nextRoute) + history.push(nextRoute); } }} submitText={t('affirmAgree')} @@ -183,6 +183,6 @@ export default class MetaMetricsOptIn extends Component {
    - ) + ); } } diff --git a/ui/app/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.container.js b/ui/app/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.container.js index 4fd76b5f90..e336a9dd2e 100644 --- a/ui/app/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.container.js +++ b/ui/app/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.container.js @@ -1,29 +1,29 @@ -import { connect } from 'react-redux' -import { setParticipateInMetaMetrics } from '../../../store/actions' -import { getFirstTimeFlowTypeRoute } from '../../../selectors' -import MetaMetricsOptIn from './metametrics-opt-in.component' +import { connect } from 'react-redux'; +import { setParticipateInMetaMetrics } from '../../../store/actions'; +import { getFirstTimeFlowTypeRoute } from '../../../selectors'; +import MetaMetricsOptIn from './metametrics-opt-in.component'; const firstTimeFlowTypeNameMap = { create: 'Selected Create New Wallet', import: 'Selected Import Wallet', -} +}; const mapStateToProps = (state) => { - const { firstTimeFlowType, participateInMetaMetrics } = state.metamask + const { firstTimeFlowType, participateInMetaMetrics } = state.metamask; return { nextRoute: getFirstTimeFlowTypeRoute(state), firstTimeSelectionMetaMetricsName: firstTimeFlowTypeNameMap[firstTimeFlowType], participateInMetaMetrics, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { setParticipateInMetaMetrics: (val) => dispatch(setParticipateInMetaMetrics(val)), - } -} + }; +}; -export default connect(mapStateToProps, mapDispatchToProps)(MetaMetricsOptIn) +export default connect(mapStateToProps, mapDispatchToProps)(MetaMetricsOptIn); diff --git a/ui/app/pages/first-time-flow/metametrics-opt-in/tests/metametrics-opt-in.test.js b/ui/app/pages/first-time-flow/metametrics-opt-in/tests/metametrics-opt-in.test.js index 33d9ebb309..7aee309512 100644 --- a/ui/app/pages/first-time-flow/metametrics-opt-in/tests/metametrics-opt-in.test.js +++ b/ui/app/pages/first-time-flow/metametrics-opt-in/tests/metametrics-opt-in.test.js @@ -1,9 +1,9 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import configureMockStore from 'redux-mock-store' -import { mountWithRouter } from '../../../../../../test/lib/render-helpers' -import MetaMetricsOptIn from '..' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import configureMockStore from 'redux-mock-store'; +import { mountWithRouter } from '../../../../../../test/lib/render-helpers'; +import MetaMetricsOptIn from '..'; describe('MetaMetricsOptIn', function () { it('opt out of MetaMetrics', function () { @@ -13,20 +13,20 @@ describe('MetaMetricsOptIn', function () { }, setParticipateInMetaMetrics: sinon.stub().resolves(), participateInMetaMetrics: false, - } + }; const store = configureMockStore()({ metamask: {}, - }) + }); const wrapper = mountWithRouter( , store, - ) + ); const noThanksButton = wrapper.find( '.btn-default.page-container__footer-button', - ) - noThanksButton.simulate('click') + ); + noThanksButton.simulate('click'); - assert.ok(props.setParticipateInMetaMetrics.calledOnceWithExactly(false)) - props.setParticipateInMetaMetrics.resetHistory() - }) -}) + assert.ok(props.setParticipateInMetaMetrics.calledOnceWithExactly(false)); + props.setParticipateInMetaMetrics.resetHistory(); + }); +}); diff --git a/ui/app/pages/first-time-flow/onboarding-initiator-util.js b/ui/app/pages/first-time-flow/onboarding-initiator-util.js index 87427903a1..abfa424d72 100644 --- a/ui/app/pages/first-time-flow/onboarding-initiator-util.js +++ b/ui/app/pages/first-time-flow/onboarding-initiator-util.js @@ -1,5 +1,5 @@ -import extension from 'extensionizer' -import log from 'loglevel' +import extension from 'extensionizer'; +import log from 'loglevel'; const returnToOnboardingInitiatorTab = async (onboardingInitiator) => { const tab = await new Promise((resolve) => { @@ -9,48 +9,48 @@ const returnToOnboardingInitiatorTab = async (onboardingInitiator) => { // eslint-disable-next-line no-shadow (tab) => { if (tab) { - resolve(tab) + resolve(tab); } else { // silence console message about unchecked error if (extension.runtime.lastError) { - log.debug(extension.runtime.lastError) + log.debug(extension.runtime.lastError); } - resolve() + resolve(); } }, - ) - }) + ); + }); if (tab) { - window.close() + window.close(); } else { // this case can happen if the tab was closed since being checked with `extension.tabs.get` log.warn( `Setting current tab to onboarding initiator has failed; falling back to redirect`, - ) - window.location.assign(onboardingInitiator.location) + ); + window.location.assign(onboardingInitiator.location); } -} +}; export const returnToOnboardingInitiator = async (onboardingInitiator) => { const tab = await new Promise((resolve) => { // eslint-disable-next-line no-shadow extension.tabs.get(onboardingInitiator.tabId, (tab) => { if (tab) { - resolve(tab) + resolve(tab); } else { // silence console message about unchecked error if (extension.runtime.lastError) { - log.debug(extension.runtime.lastError) + log.debug(extension.runtime.lastError); } - resolve() + resolve(); } - }) - }) + }); + }); if (tab) { - await returnToOnboardingInitiatorTab(onboardingInitiator) + await returnToOnboardingInitiatorTab(onboardingInitiator); } else { - window.location.assign(onboardingInitiator.location) + window.location.assign(onboardingInitiator.location); } -} +}; diff --git a/ui/app/pages/first-time-flow/seed-phrase/confirm-seed-phrase/confirm-seed-phrase.component.js b/ui/app/pages/first-time-flow/seed-phrase/confirm-seed-phrase/confirm-seed-phrase.component.js index 3494e5f0a7..6c7420ef28 100644 --- a/ui/app/pages/first-time-flow/seed-phrase/confirm-seed-phrase/confirm-seed-phrase.component.js +++ b/ui/app/pages/first-time-flow/seed-phrase/confirm-seed-phrase/confirm-seed-phrase.component.js @@ -1,32 +1,32 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import Button from '../../../../components/ui/button' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import Button from '../../../../components/ui/button'; import { INITIALIZE_END_OF_FLOW_ROUTE, INITIALIZE_SEED_PHRASE_ROUTE, -} from '../../../../helpers/constants/routes' -import { exportAsFile } from '../../../../helpers/utils/util' -import DraggableSeed from './draggable-seed.component' +} from '../../../../helpers/constants/routes'; +import { exportAsFile } from '../../../../helpers/utils/util'; +import DraggableSeed from './draggable-seed.component'; -const EMPTY_SEEDS = Array(12).fill(null) +const EMPTY_SEEDS = Array(12).fill(null); export default class ConfirmSeedPhrase extends PureComponent { static contextTypes = { metricsEvent: PropTypes.func, t: PropTypes.func, - } + }; static defaultProps = { seedPhrase: '', - } + }; static propTypes = { history: PropTypes.object, seedPhrase: PropTypes.string, initializeThreeBox: PropTypes.func, setSeedPhraseBackedUp: PropTypes.func, - } + }; state = { selectedSeedIndices: [], @@ -34,46 +34,46 @@ export default class ConfirmSeedPhrase extends PureComponent { pendingSeedIndices: [], draggingSeedIndex: -1, hoveringIndex: -1, - } + }; componentDidMount() { - const { seedPhrase = '' } = this.props - const sortedSeedWords = (seedPhrase.split(' ') || []).sort() - this.setState({ sortedSeedWords }) + const { seedPhrase = '' } = this.props; + const sortedSeedWords = (seedPhrase.split(' ') || []).sort(); + this.setState({ sortedSeedWords }); } setDraggingSeedIndex = (draggingSeedIndex) => - this.setState({ draggingSeedIndex }) + this.setState({ draggingSeedIndex }); - setHoveringIndex = (hoveringIndex) => this.setState({ hoveringIndex }) + setHoveringIndex = (hoveringIndex) => this.setState({ hoveringIndex }); onDrop = (targetIndex) => { - const { selectedSeedIndices, draggingSeedIndex } = this.state + const { selectedSeedIndices, draggingSeedIndex } = this.state; const indices = insert( selectedSeedIndices, draggingSeedIndex, targetIndex, true, - ) + ); this.setState({ selectedSeedIndices: indices, pendingSeedIndices: indices, draggingSeedIndex: -1, hoveringIndex: -1, - }) - } + }); + }; handleExport = () => { - exportAsFile('', this.props.seedPhrase, 'text/plain') - } + exportAsFile('', this.props.seedPhrase, 'text/plain'); + }; handleSubmit = async () => { - const { history, setSeedPhraseBackedUp, initializeThreeBox } = this.props + const { history, setSeedPhraseBackedUp, initializeThreeBox } = this.props; if (!this.isValid()) { - return + return; } try { @@ -83,23 +83,23 @@ export default class ConfirmSeedPhrase extends PureComponent { action: 'Seed Phrase Setup', name: 'Verify Complete', }, - }) + }); setSeedPhraseBackedUp(true).then(async () => { - initializeThreeBox() - history.push(INITIALIZE_END_OF_FLOW_ROUTE) - }) + initializeThreeBox(); + history.push(INITIALIZE_END_OF_FLOW_ROUTE); + }); } catch (error) { - console.error(error.message) + console.error(error.message); } - } + }; handleSelectSeedWord = (index) => { this.setState({ selectedSeedIndices: [...this.state.selectedSeedIndices, index], pendingSeedIndices: [...this.state.pendingSeedIndices, index], - }) - } + }); + }; handleDeselectSeedWord = (index) => { this.setState({ @@ -109,32 +109,34 @@ export default class ConfirmSeedPhrase extends PureComponent { pendingSeedIndices: this.state.pendingSeedIndices.filter( (i) => index !== i, ), - }) - } + }); + }; isValid() { - const { seedPhrase } = this.props - const { selectedSeedIndices, sortedSeedWords } = this.state - const selectedSeedWords = selectedSeedIndices.map((i) => sortedSeedWords[i]) - return seedPhrase === selectedSeedWords.join(' ') + const { seedPhrase } = this.props; + const { selectedSeedIndices, sortedSeedWords } = this.state; + const selectedSeedWords = selectedSeedIndices.map( + (i) => sortedSeedWords[i], + ); + return seedPhrase === selectedSeedWords.join(' '); } render() { - const { t } = this.context - const { history } = this.props + const { t } = this.context; + const { history } = this.props; const { selectedSeedIndices, sortedSeedWords, draggingSeedIndex, - } = this.state + } = this.state; return ( - ) + ); } renderSelectedSeeds() { @@ -201,10 +203,10 @@ export default class ConfirmSeedPhrase extends PureComponent { sortedSeedWords, selectedSeedIndices, draggingSeedIndex, - } = this.state + } = this.state; return EMPTY_SEEDS.map((_, index) => { - const seedIndex = selectedSeedIndices[index] - const word = sortedSeedWords[seedIndex] + const seedIndex = selectedSeedIndices[index]; + const word = sortedSeedWords[seedIndex]; return ( - ) - }) + ); + }); } renderPendingSeeds() { @@ -229,13 +231,17 @@ export default class ConfirmSeedPhrase extends PureComponent { sortedSeedWords, draggingSeedIndex, hoveringIndex, - } = this.state + } = this.state; - const indices = insert(pendingSeedIndices, draggingSeedIndex, hoveringIndex) + const indices = insert( + pendingSeedIndices, + draggingSeedIndex, + hoveringIndex, + ); return EMPTY_SEEDS.map((_, index) => { - const seedIndex = indices[index] - const word = sortedSeedWords[seedIndex] + const seedIndex = indices[index]; + const word = sortedSeedWords[seedIndex]; return ( - ) - }) + ); + }); } } function insert(list, value, target, removeOld) { - let nextList = [...list] + let nextList = [...list]; if (typeof list[target] === 'number') { - nextList = [...list.slice(0, target), value, ...list.slice(target)] + nextList = [...list.slice(0, target), value, ...list.slice(target)]; } if (removeOld) { nextList = nextList.filter((seed, i) => { - return seed !== value || i === target - }) + return seed !== value || i === target; + }); } - return nextList + return nextList; } diff --git a/ui/app/pages/first-time-flow/seed-phrase/confirm-seed-phrase/confirm-seed-phrase.container.js b/ui/app/pages/first-time-flow/seed-phrase/confirm-seed-phrase/confirm-seed-phrase.container.js index 646314ecd9..339bb35136 100644 --- a/ui/app/pages/first-time-flow/seed-phrase/confirm-seed-phrase/confirm-seed-phrase.container.js +++ b/ui/app/pages/first-time-flow/seed-phrase/confirm-seed-phrase/confirm-seed-phrase.container.js @@ -1,16 +1,16 @@ -import { connect } from 'react-redux' +import { connect } from 'react-redux'; import { setSeedPhraseBackedUp, initializeThreeBox, -} from '../../../../store/actions' -import ConfirmSeedPhrase from './confirm-seed-phrase.component' +} from '../../../../store/actions'; +import ConfirmSeedPhrase from './confirm-seed-phrase.component'; const mapDispatchToProps = (dispatch) => { return { setSeedPhraseBackedUp: (seedPhraseBackupState) => dispatch(setSeedPhraseBackedUp(seedPhraseBackupState)), initializeThreeBox: () => dispatch(initializeThreeBox()), - } -} + }; +}; -export default connect(null, mapDispatchToProps)(ConfirmSeedPhrase) +export default connect(null, mapDispatchToProps)(ConfirmSeedPhrase); diff --git a/ui/app/pages/first-time-flow/seed-phrase/confirm-seed-phrase/draggable-seed.component.js b/ui/app/pages/first-time-flow/seed-phrase/confirm-seed-phrase/draggable-seed.component.js index 291cc80160..eab193293c 100644 --- a/ui/app/pages/first-time-flow/seed-phrase/confirm-seed-phrase/draggable-seed.component.js +++ b/ui/app/pages/first-time-flow/seed-phrase/confirm-seed-phrase/draggable-seed.component.js @@ -1,7 +1,7 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { DragSource, DropTarget } from 'react-dnd' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import { DragSource, DropTarget } from 'react-dnd'; class DraggableSeed extends Component { static propTypes = { @@ -18,17 +18,17 @@ class DraggableSeed extends Component { word: PropTypes.string, className: PropTypes.string, selected: PropTypes.bool, - } + }; static defaultProps = { className: '', onClick: undefined, - } + }; UNSAFE_componentWillReceiveProps(nextProps) { - const { isOver, setHoveringIndex } = this.props + const { isOver, setHoveringIndex } = this.props; if (isOver && !nextProps.isOver) { - setHoveringIndex(-1) + setHoveringIndex(-1); } } @@ -44,7 +44,7 @@ class DraggableSeed extends Component { onClick, isOver, canDrop, - } = this.props + } = this.props; return connectDropTarget( connectDragSource( @@ -67,66 +67,66 @@ class DraggableSeed extends Component { {word}
    , ), - ) + ); } } -const SEEDWORD = 'SEEDWORD' +const SEEDWORD = 'SEEDWORD'; const seedSource = { beginDrag(props) { - setTimeout(() => props.setDraggingSeedIndex(props.seedIndex), 0) + setTimeout(() => props.setDraggingSeedIndex(props.seedIndex), 0); return { seedIndex: props.seedIndex, word: props.word, - } + }; }, canDrag(props) { - return props.draggable + return props.draggable; }, endDrag(props, monitor) { - const dropTarget = monitor.getDropResult() + const dropTarget = monitor.getDropResult(); if (!dropTarget) { - setTimeout(() => props.setDraggingSeedIndex(-1), 0) - return + setTimeout(() => props.setDraggingSeedIndex(-1), 0); + return; } - props.onDrop(dropTarget.targetIndex) + props.onDrop(dropTarget.targetIndex); }, -} +}; const seedTarget = { drop(props) { return { targetIndex: props.index, - } + }; }, canDrop(props) { - return props.droppable + return props.droppable; }, hover(props) { - props.setHoveringIndex(props.index) + props.setHoveringIndex(props.index); }, -} +}; const collectDrag = (connect, monitor) => { return { connectDragSource: connect.dragSource(), isDragging: monitor.isDragging(), - } -} + }; +}; const collectDrop = (connect, monitor) => { return { connectDropTarget: connect.dropTarget(), isOver: monitor.isOver(), canDrop: monitor.canDrop(), - } -} + }; +}; export default DropTarget( SEEDWORD, seedTarget, collectDrop, -)(DragSource(SEEDWORD, seedSource, collectDrag)(DraggableSeed)) +)(DragSource(SEEDWORD, seedSource, collectDrag)(DraggableSeed)); diff --git a/ui/app/pages/first-time-flow/seed-phrase/confirm-seed-phrase/index.js b/ui/app/pages/first-time-flow/seed-phrase/confirm-seed-phrase/index.js index beb53b3836..724a0a3ba7 100644 --- a/ui/app/pages/first-time-flow/seed-phrase/confirm-seed-phrase/index.js +++ b/ui/app/pages/first-time-flow/seed-phrase/confirm-seed-phrase/index.js @@ -1 +1 @@ -export { default } from './confirm-seed-phrase.container' +export { default } from './confirm-seed-phrase.container'; diff --git a/ui/app/pages/first-time-flow/seed-phrase/index.js b/ui/app/pages/first-time-flow/seed-phrase/index.js index 185b3f0893..01bd7431bb 100644 --- a/ui/app/pages/first-time-flow/seed-phrase/index.js +++ b/ui/app/pages/first-time-flow/seed-phrase/index.js @@ -1 +1 @@ -export { default } from './seed-phrase.component' +export { default } from './seed-phrase.component'; diff --git a/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/index.js b/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/index.js index a528f95a27..e1fd81f910 100644 --- a/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/index.js +++ b/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/index.js @@ -1 +1 @@ -export { default } from './reveal-seed-phrase.container' +export { default } from './reveal-seed-phrase.container'; diff --git a/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/reveal-seed-phrase.component.js b/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/reveal-seed-phrase.component.js index bbc438c931..1236817a7d 100644 --- a/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/reveal-seed-phrase.component.js +++ b/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/reveal-seed-phrase.component.js @@ -1,21 +1,21 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import LockIcon from '../../../../components/ui/lock-icon' -import Button from '../../../../components/ui/button' -import Snackbar from '../../../../components/ui/snackbar' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import LockIcon from '../../../../components/ui/lock-icon'; +import Button from '../../../../components/ui/button'; +import Snackbar from '../../../../components/ui/snackbar'; import { INITIALIZE_CONFIRM_SEED_PHRASE_ROUTE, DEFAULT_ROUTE, -} from '../../../../helpers/constants/routes' -import { exportAsFile } from '../../../../helpers/utils/util' -import { returnToOnboardingInitiator } from '../../onboarding-initiator-util' +} from '../../../../helpers/constants/routes'; +import { exportAsFile } from '../../../../helpers/utils/util'; +import { returnToOnboardingInitiator } from '../../onboarding-initiator-util'; export default class RevealSeedPhrase extends PureComponent { static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; static propTypes = { history: PropTypes.object, @@ -26,19 +26,19 @@ export default class RevealSeedPhrase extends PureComponent { location: PropTypes.string, tabId: PropTypes.number, }), - } + }; state = { isShowingSeedPhrase: false, - } + }; handleExport = () => { - exportAsFile('', this.props.seedPhrase, 'text/plain') - } + exportAsFile('', this.props.seedPhrase, 'text/plain'); + }; handleNext = () => { - const { isShowingSeedPhrase } = this.state - const { history } = this.props + const { isShowingSeedPhrase } = this.state; + const { history } = this.props; this.context.metricsEvent({ eventOpts: { @@ -46,14 +46,14 @@ export default class RevealSeedPhrase extends PureComponent { action: 'Seed Phrase Setup', name: 'Advance to Verify', }, - }) + }); if (!isShowingSeedPhrase) { - return + return; } - history.push(INITIALIZE_CONFIRM_SEED_PHRASE_ROUTE) - } + history.push(INITIALIZE_CONFIRM_SEED_PHRASE_ROUTE); + }; handleSkip = async () => { const { @@ -61,7 +61,7 @@ export default class RevealSeedPhrase extends PureComponent { setSeedPhraseBackedUp, setCompletedOnboarding, onboardingInitiator, - } = this.props + } = this.props; this.context.metricsEvent({ eventOpts: { @@ -69,20 +69,20 @@ export default class RevealSeedPhrase extends PureComponent { action: 'Seed Phrase Setup', name: 'Remind me later', }, - }) + }); - await Promise.all([setCompletedOnboarding(), setSeedPhraseBackedUp(false)]) + await Promise.all([setCompletedOnboarding(), setSeedPhraseBackedUp(false)]); if (onboardingInitiator) { - await returnToOnboardingInitiator(onboardingInitiator) + await returnToOnboardingInitiator(onboardingInitiator); } - history.push(DEFAULT_ROUTE) - } + history.push(DEFAULT_ROUTE); + }; renderSecretWordsContainer() { - const { t } = this.context - const { seedPhrase } = this.props - const { isShowingSeedPhrase } = this.state + const { t } = this.context; + const { seedPhrase } = this.props; + const { isShowingSeedPhrase } = this.state; return (
    @@ -106,8 +106,8 @@ export default class RevealSeedPhrase extends PureComponent { action: 'Seed Phrase Setup', name: 'Revealed Words', }, - }) - this.setState({ isShowingSeedPhrase: true }) + }); + this.setState({ isShowingSeedPhrase: true }); }} > @@ -117,13 +117,13 @@ export default class RevealSeedPhrase extends PureComponent {
    )} - ) + ); } render() { - const { t } = this.context - const { isShowingSeedPhrase } = this.state - const { onboardingInitiator } = this.props + const { t } = this.context; + const { isShowingSeedPhrase } = this.state; + const { onboardingInitiator } = this.props; return (
    @@ -187,6 +187,6 @@ export default class RevealSeedPhrase extends PureComponent { /> ) : null}
    - ) + ); } } diff --git a/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/reveal-seed-phrase.container.js b/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/reveal-seed-phrase.container.js index 30b4f9a23f..a9a3cb2ef5 100644 --- a/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/reveal-seed-phrase.container.js +++ b/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/reveal-seed-phrase.container.js @@ -1,23 +1,23 @@ -import { connect } from 'react-redux' +import { connect } from 'react-redux'; import { setCompletedOnboarding, setSeedPhraseBackedUp, -} from '../../../../store/actions' -import { getOnboardingInitiator } from '../../../../selectors' -import RevealSeedPhrase from './reveal-seed-phrase.component' +} from '../../../../store/actions'; +import { getOnboardingInitiator } from '../../../../selectors'; +import RevealSeedPhrase from './reveal-seed-phrase.component'; const mapStateToProps = (state) => { return { onboardingInitiator: getOnboardingInitiator(state), - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { setSeedPhraseBackedUp: (seedPhraseBackupState) => dispatch(setSeedPhraseBackedUp(seedPhraseBackupState)), setCompletedOnboarding: () => dispatch(setCompletedOnboarding()), - } -} + }; +}; -export default connect(mapStateToProps, mapDispatchToProps)(RevealSeedPhrase) +export default connect(mapStateToProps, mapDispatchToProps)(RevealSeedPhrase); diff --git a/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/tests/reveal-seed-phrase.test.js b/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/tests/reveal-seed-phrase.test.js index f0e561a4bf..29f1d6968b 100644 --- a/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/tests/reveal-seed-phrase.test.js +++ b/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/tests/reveal-seed-phrase.test.js @@ -1,14 +1,14 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import { mount } from 'enzyme' -import RevealSeedPhrase from '..' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import { mount } from 'enzyme'; +import RevealSeedPhrase from '..'; describe('Reveal Seed Phrase', function () { - let wrapper + let wrapper; const TEST_SEED = - 'debris dizzy just program just float decrease vacant alarm reduce speak stadium' + 'debris dizzy just program just float decrease vacant alarm reduce speak stadium'; const props = { history: { @@ -17,7 +17,7 @@ describe('Reveal Seed Phrase', function () { seedPhrase: TEST_SEED, setSeedPhraseBackedUp: sinon.spy(), setCompletedOnboarding: sinon.spy(), - } + }; beforeEach(function () { wrapper = mount(, { @@ -25,23 +25,25 @@ describe('Reveal Seed Phrase', function () { t: (str) => str, metricsEvent: () => undefined, }, - }) - }) + }); + }); it('seed phrase', function () { - const seedPhrase = wrapper.find('.reveal-seed-phrase__secret-words--hidden') - assert.strictEqual(seedPhrase.length, 1) - assert.strictEqual(seedPhrase.text(), TEST_SEED) - }) + const seedPhrase = wrapper.find( + '.reveal-seed-phrase__secret-words--hidden', + ); + assert.strictEqual(seedPhrase.length, 1); + assert.strictEqual(seedPhrase.text(), TEST_SEED); + }); it('clicks to reveal', function () { - const reveal = wrapper.find('.reveal-seed-phrase__secret-blocker') + const reveal = wrapper.find('.reveal-seed-phrase__secret-blocker'); - assert.strictEqual(wrapper.state().isShowingSeedPhrase, false) - reveal.simulate('click') - assert.strictEqual(wrapper.state().isShowingSeedPhrase, true) + assert.strictEqual(wrapper.state().isShowingSeedPhrase, false); + reveal.simulate('click'); + assert.strictEqual(wrapper.state().isShowingSeedPhrase, true); - const showSeed = wrapper.find('.reveal-seed-phrase__secret-words') - assert.strictEqual(showSeed.length, 1) - }) -}) + const showSeed = wrapper.find('.reveal-seed-phrase__secret-words'); + assert.strictEqual(showSeed.length, 1); + }); +}); diff --git a/ui/app/pages/first-time-flow/seed-phrase/seed-phrase.component.js b/ui/app/pages/first-time-flow/seed-phrase/seed-phrase.component.js index a953df36d7..97d27998a5 100644 --- a/ui/app/pages/first-time-flow/seed-phrase/seed-phrase.component.js +++ b/ui/app/pages/first-time-flow/seed-phrase/seed-phrase.component.js @@ -1,46 +1,46 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import { Switch, Route } from 'react-router-dom' -import HTML5Backend from 'react-dnd-html5-backend' -import { DragDropContextProvider } from 'react-dnd' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { Switch, Route } from 'react-router-dom'; +import HTML5Backend from 'react-dnd-html5-backend'; +import { DragDropContextProvider } from 'react-dnd'; import { INITIALIZE_SEED_PHRASE_ROUTE, INITIALIZE_CONFIRM_SEED_PHRASE_ROUTE, INITIALIZE_BACKUP_SEED_PHRASE_ROUTE, DEFAULT_ROUTE, -} from '../../../helpers/constants/routes' -import MetaFoxLogo from '../../../components/ui/metafox-logo' -import ConfirmSeedPhrase from './confirm-seed-phrase' -import RevealSeedPhrase from './reveal-seed-phrase' +} from '../../../helpers/constants/routes'; +import MetaFoxLogo from '../../../components/ui/metafox-logo'; +import ConfirmSeedPhrase from './confirm-seed-phrase'; +import RevealSeedPhrase from './reveal-seed-phrase'; export default class SeedPhrase extends PureComponent { static propTypes = { history: PropTypes.object, seedPhrase: PropTypes.string, verifySeedPhrase: PropTypes.func, - } + }; state = { verifiedSeedPhrase: '', - } + }; componentDidMount() { - const { seedPhrase, history, verifySeedPhrase } = this.props + const { seedPhrase, history, verifySeedPhrase } = this.props; if (!seedPhrase) { verifySeedPhrase().then((verifiedSeedPhrase) => { if (verifiedSeedPhrase) { - this.setState({ verifiedSeedPhrase }) + this.setState({ verifiedSeedPhrase }); } else { - history.push(DEFAULT_ROUTE) + history.push(DEFAULT_ROUTE); } - }) + }); } } render() { - const { seedPhrase } = this.props - const { verifiedSeedPhrase } = this.state + const { seedPhrase } = this.props; + const { verifiedSeedPhrase } = this.state; return ( @@ -80,6 +80,6 @@ export default class SeedPhrase extends PureComponent { - ) + ); } } diff --git a/ui/app/pages/first-time-flow/seed-phrase/tests/confirm-seed-phrase-component.test.js b/ui/app/pages/first-time-flow/seed-phrase/tests/confirm-seed-phrase-component.test.js index 1be3b70d78..5add90bd9c 100644 --- a/ui/app/pages/first-time-flow/seed-phrase/tests/confirm-seed-phrase-component.test.js +++ b/ui/app/pages/first-time-flow/seed-phrase/tests/confirm-seed-phrase-component.test.js @@ -1,8 +1,8 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import sinon from 'sinon' -import ConfirmSeedPhrase from '../confirm-seed-phrase/confirm-seed-phrase.component' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import ConfirmSeedPhrase from '../confirm-seed-phrase/confirm-seed-phrase.component'; function shallowRender(props = {}, context = {}) { return shallow(, { @@ -10,25 +10,25 @@ function shallowRender(props = {}, context = {}) { t: (str) => `${str}_t`, ...context, }, - }) + }); } describe('ConfirmSeedPhrase Component', function () { it('should render correctly', function () { const root = shallowRender({ seedPhrase: '鼠 牛 虎 兔 龍 蛇 馬 羊 猴 雞 狗 豬', - }) + }); assert.strictEqual( root.find('.confirm-seed-phrase__seed-word--sorted').length, 12, 'should render 12 seed phrases', - ) - }) + ); + }); it('should add/remove selected on click', function () { - const metricsEventSpy = sinon.spy() - const pushSpy = sinon.spy() + const metricsEventSpy = sinon.spy(); + const pushSpy = sinon.spy(); const root = shallowRender( { seedPhrase: '鼠 牛 虎 兔 龍 蛇 馬 羊 猴 雞 狗 豬', @@ -37,36 +37,39 @@ describe('ConfirmSeedPhrase Component', function () { { metricsEvent: metricsEventSpy, }, - ) + ); - const seeds = root.find('.confirm-seed-phrase__seed-word--sorted') + const seeds = root.find('.confirm-seed-phrase__seed-word--sorted'); // Click on 3 seeds to add to selected - seeds.at(0).simulate('click') - seeds.at(1).simulate('click') - seeds.at(2).simulate('click') + seeds.at(0).simulate('click'); + seeds.at(1).simulate('click'); + seeds.at(2).simulate('click'); assert.deepStrictEqual( root.state().selectedSeedIndices, [0, 1, 2], 'should add seed phrase to selected on click', - ) + ); // Click on a selected seed to remove - root.state() - root.update() - root.state() - root.find('.confirm-seed-phrase__seed-word--sorted').at(1).simulate('click') + root.state(); + root.update(); + root.state(); + root + .find('.confirm-seed-phrase__seed-word--sorted') + .at(1) + .simulate('click'); assert.deepStrictEqual( root.state().selectedSeedIndices, [0, 2], 'should remove seed phrase from selected when click again', - ) - }) + ); + }); it('should render correctly on hover', function () { - const metricsEventSpy = sinon.spy() - const pushSpy = sinon.spy() + const metricsEventSpy = sinon.spy(); + const pushSpy = sinon.spy(); const root = shallowRender( { seedPhrase: '鼠 牛 虎 兔 龍 蛇 馬 羊 猴 雞 狗 豬', @@ -75,33 +78,33 @@ describe('ConfirmSeedPhrase Component', function () { { metricsEvent: metricsEventSpy, }, - ) + ); - const seeds = root.find('.confirm-seed-phrase__seed-word--sorted') + const seeds = root.find('.confirm-seed-phrase__seed-word--sorted'); // Click on 3 seeds to add to selected - seeds.at(0).simulate('click') - seeds.at(1).simulate('click') - seeds.at(2).simulate('click') + seeds.at(0).simulate('click'); + seeds.at(1).simulate('click'); + seeds.at(2).simulate('click'); // Dragging Seed # 2 to 0 placeth - root.instance().setDraggingSeedIndex(2) - root.instance().setHoveringIndex(0) + root.instance().setDraggingSeedIndex(2); + root.instance().setHoveringIndex(0); - root.update() + root.update(); const pendingSeeds = root.find( '.confirm-seed-phrase__selected-seed-words__pending-seed', - ) + ); - assert.strictEqual(pendingSeeds.at(0).props().seedIndex, 2) - assert.strictEqual(pendingSeeds.at(1).props().seedIndex, 0) - assert.strictEqual(pendingSeeds.at(2).props().seedIndex, 1) - }) + assert.strictEqual(pendingSeeds.at(0).props().seedIndex, 2); + assert.strictEqual(pendingSeeds.at(1).props().seedIndex, 0); + assert.strictEqual(pendingSeeds.at(2).props().seedIndex, 1); + }); it('should insert seed in place on drop', function () { - const metricsEventSpy = sinon.spy() - const pushSpy = sinon.spy() + const metricsEventSpy = sinon.spy(); + const pushSpy = sinon.spy(); const root = shallowRender( { seedPhrase: '鼠 牛 虎 兔 龍 蛇 馬 羊 猴 雞 狗 豬', @@ -110,25 +113,25 @@ describe('ConfirmSeedPhrase Component', function () { { metricsEvent: metricsEventSpy, }, - ) + ); - const seeds = root.find('.confirm-seed-phrase__seed-word--sorted') + const seeds = root.find('.confirm-seed-phrase__seed-word--sorted'); // Click on 3 seeds to add to selected - seeds.at(0).simulate('click') - seeds.at(1).simulate('click') - seeds.at(2).simulate('click') + seeds.at(0).simulate('click'); + seeds.at(1).simulate('click'); + seeds.at(2).simulate('click'); // Drop Seed # 2 to 0 placeth - root.instance().setDraggingSeedIndex(2) - root.instance().setHoveringIndex(0) - root.instance().onDrop(0) + root.instance().setDraggingSeedIndex(2); + root.instance().setHoveringIndex(0); + root.instance().onDrop(0); - root.update() + root.update(); - assert.deepStrictEqual(root.state().selectedSeedIndices, [2, 0, 1]) - assert.deepStrictEqual(root.state().pendingSeedIndices, [2, 0, 1]) - }) + assert.deepStrictEqual(root.state().selectedSeedIndices, [2, 0, 1]); + assert.deepStrictEqual(root.state().pendingSeedIndices, [2, 0, 1]); + }); it('should submit correctly', async function () { const originalSeed = [ @@ -144,10 +147,10 @@ describe('ConfirmSeedPhrase Component', function () { '雞', '狗', '豬', - ] - const metricsEventSpy = sinon.spy() - const pushSpy = sinon.spy() - const initialize3BoxSpy = sinon.spy() + ]; + const metricsEventSpy = sinon.spy(); + const pushSpy = sinon.spy(); + const initialize3BoxSpy = sinon.spy(); const root = shallowRender( { seedPhrase: '鼠 牛 虎 兔 龍 蛇 馬 羊 猴 雞 狗 豬', @@ -158,21 +161,21 @@ describe('ConfirmSeedPhrase Component', function () { { metricsEvent: metricsEventSpy, }, - ) + ); - const sorted = root.state().sortedSeedWords - const seeds = root.find('.confirm-seed-phrase__seed-word--sorted') + const sorted = root.state().sortedSeedWords; + const seeds = root.find('.confirm-seed-phrase__seed-word--sorted'); originalSeed.forEach((seed) => { - const seedIndex = sorted.findIndex((s) => s === seed) - seeds.at(seedIndex).simulate('click') - }) + const seedIndex = sorted.findIndex((s) => s === seed); + seeds.at(seedIndex).simulate('click'); + }); - root.update() + root.update(); - root.find('.first-time-flow__button').simulate('click') + root.find('.first-time-flow__button').simulate('click'); - await new Promise((resolve) => setTimeout(resolve, 100)) + await new Promise((resolve) => setTimeout(resolve, 100)); assert.deepStrictEqual(metricsEventSpy.args[0][0], { eventOpts: { @@ -180,8 +183,8 @@ describe('ConfirmSeedPhrase Component', function () { action: 'Seed Phrase Setup', name: 'Verify Complete', }, - }) - assert(initialize3BoxSpy.calledOnce) - assert.strictEqual(pushSpy.args[0][0], '/initialize/end-of-flow') - }) -}) + }); + assert(initialize3BoxSpy.calledOnce); + assert.strictEqual(pushSpy.args[0][0], '/initialize/end-of-flow'); + }); +}); diff --git a/ui/app/pages/first-time-flow/select-action/index.js b/ui/app/pages/first-time-flow/select-action/index.js index 4fbe1823ba..ca98b401d1 100644 --- a/ui/app/pages/first-time-flow/select-action/index.js +++ b/ui/app/pages/first-time-flow/select-action/index.js @@ -1 +1 @@ -export { default } from './select-action.container' +export { default } from './select-action.container'; diff --git a/ui/app/pages/first-time-flow/select-action/select-action.component.js b/ui/app/pages/first-time-flow/select-action/select-action.component.js index 993c0b16e7..2f02df189a 100644 --- a/ui/app/pages/first-time-flow/select-action/select-action.component.js +++ b/ui/app/pages/first-time-flow/select-action/select-action.component.js @@ -1,8 +1,8 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import Button from '../../../components/ui/button' -import MetaFoxLogo from '../../../components/ui/metafox-logo' -import { INITIALIZE_METAMETRICS_OPT_IN_ROUTE } from '../../../helpers/constants/routes' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import Button from '../../../components/ui/button'; +import MetaFoxLogo from '../../../components/ui/metafox-logo'; +import { INITIALIZE_METAMETRICS_OPT_IN_ROUTE } from '../../../helpers/constants/routes'; export default class SelectAction extends PureComponent { static propTypes = { @@ -10,32 +10,32 @@ export default class SelectAction extends PureComponent { isInitialized: PropTypes.bool, setFirstTimeFlowType: PropTypes.func, nextRoute: PropTypes.string, - } + }; static contextTypes = { t: PropTypes.func, - } + }; componentDidMount() { - const { history, isInitialized, nextRoute } = this.props + const { history, isInitialized, nextRoute } = this.props; if (isInitialized) { - history.push(nextRoute) + history.push(nextRoute); } } handleCreate = () => { - this.props.setFirstTimeFlowType('create') - this.props.history.push(INITIALIZE_METAMETRICS_OPT_IN_ROUTE) - } + this.props.setFirstTimeFlowType('create'); + this.props.history.push(INITIALIZE_METAMETRICS_OPT_IN_ROUTE); + }; handleImport = () => { - this.props.setFirstTimeFlowType('import') - this.props.history.push(INITIALIZE_METAMETRICS_OPT_IN_ROUTE) - } + this.props.setFirstTimeFlowType('import'); + this.props.history.push(INITIALIZE_METAMETRICS_OPT_IN_ROUTE); + }; render() { - const { t } = this.context + const { t } = this.context; return (
    @@ -91,6 +91,6 @@ export default class SelectAction extends PureComponent {
    - ) + ); } } diff --git a/ui/app/pages/first-time-flow/select-action/select-action.container.js b/ui/app/pages/first-time-flow/select-action/select-action.container.js index 7b13c1269a..77030f0703 100644 --- a/ui/app/pages/first-time-flow/select-action/select-action.container.js +++ b/ui/app/pages/first-time-flow/select-action/select-action.container.js @@ -1,23 +1,23 @@ -import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom' -import { compose } from 'redux' -import { setFirstTimeFlowType } from '../../../store/actions' -import { getFirstTimeFlowTypeRoute } from '../../../selectors' -import Welcome from './select-action.component' +import { connect } from 'react-redux'; +import { withRouter } from 'react-router-dom'; +import { compose } from 'redux'; +import { setFirstTimeFlowType } from '../../../store/actions'; +import { getFirstTimeFlowTypeRoute } from '../../../selectors'; +import Welcome from './select-action.component'; const mapStateToProps = (state) => { return { nextRoute: getFirstTimeFlowTypeRoute(state), - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { setFirstTimeFlowType: (type) => dispatch(setFirstTimeFlowType(type)), - } -} + }; +}; export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps), -)(Welcome) +)(Welcome); diff --git a/ui/app/pages/first-time-flow/select-action/tests/select-action.test.js b/ui/app/pages/first-time-flow/select-action/tests/select-action.test.js index 447c206026..9f5b66fc6d 100644 --- a/ui/app/pages/first-time-flow/select-action/tests/select-action.test.js +++ b/ui/app/pages/first-time-flow/select-action/tests/select-action.test.js @@ -1,11 +1,11 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import { mountWithRouter } from '../../../../../../test/lib/render-helpers' -import SelectAction from '..' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import { mountWithRouter } from '../../../../../../test/lib/render-helpers'; +import SelectAction from '..'; describe('Selection Action', function () { - let wrapper + let wrapper; const props = { isInitialized: false, @@ -13,36 +13,36 @@ describe('Selection Action', function () { history: { push: sinon.spy(), }, - } + }; beforeEach(function () { - wrapper = mountWithRouter() - }) + wrapper = mountWithRouter(); + }); afterEach(function () { - props.setFirstTimeFlowType.resetHistory() - props.history.push.resetHistory() - }) + props.setFirstTimeFlowType.resetHistory(); + props.history.push.resetHistory(); + }); it('clicks import wallet to route to import FTF', function () { const importWalletButton = wrapper .find('.btn-primary.first-time-flow__button') - .at(0) - importWalletButton.simulate('click') + .at(0); + importWalletButton.simulate('click'); - assert(props.setFirstTimeFlowType.calledOnce) - assert.strictEqual(props.setFirstTimeFlowType.getCall(0).args[0], 'import') - assert(props.history.push.calledOnce) - }) + assert(props.setFirstTimeFlowType.calledOnce); + assert.strictEqual(props.setFirstTimeFlowType.getCall(0).args[0], 'import'); + assert(props.history.push.calledOnce); + }); it('clicks create wallet to route to create FTF ', function () { const createWalletButton = wrapper .find('.btn-primary.first-time-flow__button') - .at(1) - createWalletButton.simulate('click') - - assert(props.setFirstTimeFlowType.calledOnce) - assert.strictEqual(props.setFirstTimeFlowType.getCall(0).args[0], 'create') - assert(props.history.push.calledOnce) - }) -}) + .at(1); + createWalletButton.simulate('click'); + + assert(props.setFirstTimeFlowType.calledOnce); + assert.strictEqual(props.setFirstTimeFlowType.getCall(0).args[0], 'create'); + assert(props.history.push.calledOnce); + }); +}); diff --git a/ui/app/pages/first-time-flow/welcome/index.js b/ui/app/pages/first-time-flow/welcome/index.js index 8abeddaa1e..85e9f94a4e 100644 --- a/ui/app/pages/first-time-flow/welcome/index.js +++ b/ui/app/pages/first-time-flow/welcome/index.js @@ -1 +1 @@ -export { default } from './welcome.container' +export { default } from './welcome.container'; diff --git a/ui/app/pages/first-time-flow/welcome/tests/welcome.test.js b/ui/app/pages/first-time-flow/welcome/tests/welcome.test.js index 4c35d8c0da..cc8dbab082 100644 --- a/ui/app/pages/first-time-flow/welcome/tests/welcome.test.js +++ b/ui/app/pages/first-time-flow/welcome/tests/welcome.test.js @@ -1,42 +1,42 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import configureMockStore from 'redux-mock-store' -import { mountWithRouter } from '../../../../../../test/lib/render-helpers' -import Welcome from '..' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import configureMockStore from 'redux-mock-store'; +import { mountWithRouter } from '../../../../../../test/lib/render-helpers'; +import Welcome from '..'; describe('Welcome', function () { const mockStore = { metamask: {}, - } + }; - const store = configureMockStore()(mockStore) + const store = configureMockStore()(mockStore); after(function () { - sinon.restore() - }) + sinon.restore(); + }); it('routes to select action when participateInMetaMetrics is not initialized', function () { const props = { history: { push: sinon.spy(), }, - } + }; const wrapper = mountWithRouter( , store, - ) + ); const getStartedButton = wrapper.find( '.btn-primary.first-time-flow__button', - ) - getStartedButton.simulate('click') + ); + getStartedButton.simulate('click'); assert.strictEqual( props.history.push.getCall(0).args[0], '/initialize/select-action', - ) - }) + ); + }); it('routes to correct password when participateInMetaMetrics is initialized', function () { const props = { @@ -45,20 +45,20 @@ describe('Welcome', function () { history: { push: sinon.spy(), }, - } + }; const wrapper = mountWithRouter( , store, - ) + ); const getStartedButton = wrapper.find( '.btn-primary.first-time-flow__button', - ) - getStartedButton.simulate('click') + ); + getStartedButton.simulate('click'); assert.strictEqual( props.history.push.getCall(0).args[0], '/initialize/create-password', - ) - }) -}) + ); + }); +}); diff --git a/ui/app/pages/first-time-flow/welcome/welcome.component.js b/ui/app/pages/first-time-flow/welcome/welcome.component.js index 9b62419c95..43d81b4fa5 100644 --- a/ui/app/pages/first-time-flow/welcome/welcome.component.js +++ b/ui/app/pages/first-time-flow/welcome/welcome.component.js @@ -1,46 +1,46 @@ -import EventEmitter from 'events' -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import Mascot from '../../../components/ui/mascot' -import Button from '../../../components/ui/button' +import EventEmitter from 'events'; +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import Mascot from '../../../components/ui/mascot'; +import Button from '../../../components/ui/button'; import { INITIALIZE_CREATE_PASSWORD_ROUTE, INITIALIZE_SELECT_ACTION_ROUTE, -} from '../../../helpers/constants/routes' +} from '../../../helpers/constants/routes'; export default class Welcome extends PureComponent { static propTypes = { history: PropTypes.object, participateInMetaMetrics: PropTypes.bool, welcomeScreenSeen: PropTypes.bool, - } + }; static contextTypes = { t: PropTypes.func, - } + }; constructor(props) { - super(props) + super(props); - this.animationEventEmitter = new EventEmitter() + this.animationEventEmitter = new EventEmitter(); } componentDidMount() { - const { history, participateInMetaMetrics, welcomeScreenSeen } = this.props + const { history, participateInMetaMetrics, welcomeScreenSeen } = this.props; if (welcomeScreenSeen && participateInMetaMetrics !== null) { - history.push(INITIALIZE_CREATE_PASSWORD_ROUTE) + history.push(INITIALIZE_CREATE_PASSWORD_ROUTE); } else if (welcomeScreenSeen) { - history.push(INITIALIZE_SELECT_ACTION_ROUTE) + history.push(INITIALIZE_SELECT_ACTION_ROUTE); } } handleContinue = () => { - this.props.history.push(INITIALIZE_SELECT_ACTION_ROUTE) - } + this.props.history.push(INITIALIZE_SELECT_ACTION_ROUTE); + }; render() { - const { t } = this.context + const { t } = this.context; return (
    @@ -64,6 +64,6 @@ export default class Welcome extends PureComponent {
    - ) + ); } } diff --git a/ui/app/pages/first-time-flow/welcome/welcome.container.js b/ui/app/pages/first-time-flow/welcome/welcome.container.js index 9e8aff339a..77909d25b0 100644 --- a/ui/app/pages/first-time-flow/welcome/welcome.container.js +++ b/ui/app/pages/first-time-flow/welcome/welcome.container.js @@ -1,25 +1,25 @@ -import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom' -import { compose } from 'redux' -import { closeWelcomeScreen } from '../../../store/actions' -import Welcome from './welcome.component' +import { connect } from 'react-redux'; +import { withRouter } from 'react-router-dom'; +import { compose } from 'redux'; +import { closeWelcomeScreen } from '../../../store/actions'; +import Welcome from './welcome.component'; const mapStateToProps = ({ metamask }) => { - const { welcomeScreenSeen, participateInMetaMetrics } = metamask + const { welcomeScreenSeen, participateInMetaMetrics } = metamask; return { welcomeScreenSeen, participateInMetaMetrics, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { closeWelcomeScreen: () => dispatch(closeWelcomeScreen()), - } -} + }; +}; export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps), -)(Welcome) +)(Welcome); diff --git a/ui/app/pages/home/home.component.js b/ui/app/pages/home/home.component.js index 92c8d685dc..d5b5f75d7a 100644 --- a/ui/app/pages/home/home.component.js +++ b/ui/app/pages/home/home.component.js @@ -1,19 +1,19 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import { Redirect, Route } from 'react-router-dom' -import { formatDate } from '../../helpers/utils/util' -import AssetList from '../../components/app/asset-list' -import HomeNotification from '../../components/app/home-notification' -import MultipleNotifications from '../../components/app/multiple-notifications' -import TransactionList from '../../components/app/transaction-list' -import MenuBar from '../../components/app/menu-bar' -import Popover from '../../components/ui/popover' -import Button from '../../components/ui/button' -import ConnectedSites from '../connected-sites' -import ConnectedAccounts from '../connected-accounts' -import { Tabs, Tab } from '../../components/ui/tabs' -import { EthOverview } from '../../components/app/wallet-overview' -import SwapsIntroPopup from '../swaps/intro-popup' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { Redirect, Route } from 'react-router-dom'; +import { formatDate } from '../../helpers/utils/util'; +import AssetList from '../../components/app/asset-list'; +import HomeNotification from '../../components/app/home-notification'; +import MultipleNotifications from '../../components/app/multiple-notifications'; +import TransactionList from '../../components/app/transaction-list'; +import MenuBar from '../../components/app/menu-bar'; +import Popover from '../../components/ui/popover'; +import Button from '../../components/ui/button'; +import ConnectedSites from '../connected-sites'; +import ConnectedAccounts from '../connected-accounts'; +import { Tabs, Tab } from '../../components/ui/tabs'; +import { EthOverview } from '../../components/app/wallet-overview'; +import SwapsIntroPopup from '../swaps/intro-popup'; import { ASSET_ROUTE, @@ -27,17 +27,17 @@ import { AWAITING_SWAP_ROUTE, BUILD_QUOTE_ROUTE, VIEW_QUOTE_ROUTE, -} from '../../helpers/constants/routes' +} from '../../helpers/constants/routes'; const LEARN_MORE_URL = - 'https://metamask.zendesk.com/hc/en-us/articles/360045129011-Intro-to-MetaMask-v8-extension' + 'https://metamask.zendesk.com/hc/en-us/articles/360045129011-Intro-to-MetaMask-v8-extension'; const LEGACY_WEB3_URL = - 'https://metamask.zendesk.com/hc/en-us/articles/360053147012' + 'https://metamask.zendesk.com/hc/en-us/articles/360053147012'; export default class Home extends PureComponent { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { history: PropTypes.object, @@ -72,11 +72,11 @@ export default class Home extends PureComponent { setWeb3ShimUsageAlertDismissed: PropTypes.func.isRequired, originOfCurrentTab: PropTypes.string, disableWeb3ShimUsageAlert: PropTypes.func.isRequired, - } + }; state = { mounted: false, - } + }; componentDidMount() { const { @@ -89,23 +89,23 @@ export default class Home extends PureComponent { haveSwapsQuotes, showAwaitingSwapScreen, swapsFetchParams, - } = this.props + } = this.props; - this.setState({ mounted: true }) + this.setState({ mounted: true }); if (isNotification && totalUnapprovedCount === 0) { - global.platform.closeCurrentWindow() + global.platform.closeCurrentWindow(); } else if (!isNotification && showAwaitingSwapScreen) { - history.push(AWAITING_SWAP_ROUTE) + history.push(AWAITING_SWAP_ROUTE); } else if (!isNotification && haveSwapsQuotes) { - history.push(VIEW_QUOTE_ROUTE) + history.push(VIEW_QUOTE_ROUTE); } else if (!isNotification && swapsFetchParams) { - history.push(BUILD_QUOTE_ROUTE) + history.push(BUILD_QUOTE_ROUTE); } else if (firstPermissionsRequestId) { - history.push(`${CONNECT_ROUTE}/${firstPermissionsRequestId}`) + history.push(`${CONNECT_ROUTE}/${firstPermissionsRequestId}`); } else if (unconfirmedTransactionsCount > 0) { - history.push(CONFIRM_TRANSACTION_ROUTE) + history.push(CONFIRM_TRANSACTION_ROUTE); } else if (Object.keys(suggestedTokens).length > 0) { - history.push(CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE) + history.push(CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE); } } @@ -124,7 +124,7 @@ export default class Home extends PureComponent { ) { if (!mounted) { if (isNotification && totalUnapprovedCount === 0) { - return { closing: true } + return { closing: true }; } else if ( firstPermissionsRequestId || unconfirmedTransactionsCount > 0 || @@ -132,10 +132,10 @@ export default class Home extends PureComponent { (!isNotification && (showAwaitingSwapScreen || haveSwapsQuotes || swapsFetchParams)) ) { - return { redirecting: true } + return { redirecting: true }; } } - return null + return null; } componentDidUpdate(_, prevState) { @@ -144,19 +144,19 @@ export default class Home extends PureComponent { showRestorePrompt, threeBoxLastUpdated, threeBoxSynced, - } = this.props + } = this.props; if (!prevState.closing && this.state.closing) { - global.platform.closeCurrentWindow() + global.platform.closeCurrentWindow(); } if (threeBoxSynced && showRestorePrompt && threeBoxLastUpdated === null) { - setupThreeBox() + setupThreeBox(); } } renderNotifications() { - const { t } = this.context + const { t } = this.context; const { history, shouldShowSeedPhraseReminder, @@ -171,7 +171,7 @@ export default class Home extends PureComponent { setWeb3ShimUsageAlertDismissed, originOfCurrentTab, disableWeb3ShimUsageAlert, - } = this.props + } = this.props; return ( @@ -190,9 +190,9 @@ export default class Home extends PureComponent { ])} ignoreText={t('dismiss')} onIgnore={(disable) => { - setWeb3ShimUsageAlertDismissed(originOfCurrentTab) + setWeb3ShimUsageAlertDismissed(originOfCurrentTab); if (disable) { - disableWeb3ShimUsageAlert() + disableWeb3ShimUsageAlert(); } }} checkboxText={t('dontShowThisAgain')} @@ -208,9 +208,9 @@ export default class Home extends PureComponent { if (isPopup) { global.platform.openExtensionInBrowser( INITIALIZE_BACKUP_SEED_PHRASE_ROUTE, - ) + ); } else { - history.push(INITIALIZE_BACKUP_SEED_PHRASE_ROUTE) + history.push(INITIALIZE_BACKUP_SEED_PHRASE_ROUTE); } }} infoText={t('backupApprovalInfo')} @@ -227,22 +227,22 @@ export default class Home extends PureComponent { infoText={t('dataBackupFoundInfo')} onAccept={() => { restoreFromThreeBox(selectedAddress).then(() => { - turnThreeBoxSyncingOn() - }) + turnThreeBoxSyncingOn(); + }); }} onIgnore={() => { - setShowRestorePromptToFalse() + setShowRestorePromptToFalse(); }} key="home-privacyModeDefault" /> ) : null} - ) + ); } renderPopover = () => { - const { setConnectedStatusPopoverHasBeenShown } = this.props - const { t } = this.context + const { setConnectedStatusPopoverHasBeenShown } = this.props; + const { t } = this.context; return (
    - ) + ); }} footer={ <> @@ -279,11 +279,11 @@ export default class Home extends PureComponent {
    {t('metaMaskConnectStatusParagraphThree')}
    - ) - } + ); + }; render() { - const { t } = this.context + const { t } = this.context; const { defaultHomeActiveTabName, onTabClick, @@ -295,12 +295,12 @@ export default class Home extends PureComponent { setSwapsWelcomeMessageHasBeenShown, swapsEnabled, isMainnet, - } = this.props + } = this.props; if (forgottenPassword) { - return + return ; } else if (this.state.closing || this.state.redirecting) { - return null + return null; } return ( @@ -353,6 +353,6 @@ export default class Home extends PureComponent { {this.renderNotifications()} - ) + ); } } diff --git a/ui/app/pages/home/home.container.js b/ui/app/pages/home/home.container.js index ba4b9e6d43..b53a5a96d4 100644 --- a/ui/app/pages/home/home.container.js +++ b/ui/app/pages/home/home.container.js @@ -1,6 +1,6 @@ -import { compose } from 'redux' -import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom' +import { compose } from 'redux'; +import { connect } from 'react-redux'; +import { withRouter } from 'react-router-dom'; import { activeTabHasPermissions, getCurrentEthBalance, @@ -10,7 +10,7 @@ import { getTotalUnapprovedCount, getWeb3ShimUsageStateForOrigin, unconfirmedTransactionsCountSelector, -} from '../../selectors' +} from '../../selectors'; import { restoreFromThreeBox, @@ -22,26 +22,26 @@ import { setSwapsWelcomeMessageHasBeenShown, setWeb3ShimUsageAlertDismissed, setAlertEnabledness, -} from '../../store/actions' -import { setThreeBoxLastUpdated } from '../../ducks/app/app' -import { getWeb3ShimUsageAlertEnabledness } from '../../ducks/metamask/metamask' +} from '../../store/actions'; +import { setThreeBoxLastUpdated } from '../../ducks/app/app'; +import { getWeb3ShimUsageAlertEnabledness } from '../../ducks/metamask/metamask'; import { getSwapsWelcomeMessageSeenStatus, getSwapsFeatureLiveness, -} from '../../ducks/swaps/swaps' -import { getEnvironmentType } from '../../../../app/scripts/lib/util' +} from '../../ducks/swaps/swaps'; +import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import { ENVIRONMENT_TYPE_NOTIFICATION, ENVIRONMENT_TYPE_POPUP, -} from '../../../../shared/constants/app' +} from '../../../../shared/constants/app'; import { ALERT_TYPES, WEB3_SHIM_USAGE_ALERT_STATES, -} from '../../../../shared/constants/alerts' -import Home from './home.component' +} from '../../../../shared/constants/alerts'; +import Home from './home.component'; const mapStateToProps = (state) => { - const { metamask, appState } = state + const { metamask, appState } = state; const { suggestedTokens, seedPhraseBackedUp, @@ -52,29 +52,29 @@ const mapStateToProps = (state) => { connectedStatusPopoverHasBeenShown, defaultHomeActiveTabName, swapsState, - } = metamask - const accountBalance = getCurrentEthBalance(state) - const { forgottenPassword, threeBoxLastUpdated } = appState - const totalUnapprovedCount = getTotalUnapprovedCount(state) - const swapsEnabled = getSwapsFeatureLiveness(state) + } = metamask; + const accountBalance = getCurrentEthBalance(state); + const { forgottenPassword, threeBoxLastUpdated } = appState; + const totalUnapprovedCount = getTotalUnapprovedCount(state); + const swapsEnabled = getSwapsFeatureLiveness(state); - const envType = getEnvironmentType() - const isPopup = envType === ENVIRONMENT_TYPE_POPUP - const isNotification = envType === ENVIRONMENT_TYPE_NOTIFICATION + const envType = getEnvironmentType(); + const isPopup = envType === ENVIRONMENT_TYPE_POPUP; + const isNotification = envType === ENVIRONMENT_TYPE_NOTIFICATION; - const firstPermissionsRequest = getFirstPermissionRequest(state) + const firstPermissionsRequest = getFirstPermissionRequest(state); const firstPermissionsRequestId = firstPermissionsRequest && firstPermissionsRequest.metadata ? firstPermissionsRequest.metadata.id - : null + : null; - const originOfCurrentTab = getOriginOfCurrentTab(state) + const originOfCurrentTab = getOriginOfCurrentTab(state); const shouldShowWeb3ShimUsageNotification = isPopup && getWeb3ShimUsageAlertEnabledness(state) && activeTabHasPermissions(state) && getWeb3ShimUsageStateForOrigin(state, originOfCurrentTab) === - WEB3_SHIM_USAGE_ALERT_STATES.RECORDED + WEB3_SHIM_USAGE_ALERT_STATES.RECORDED; return { forgottenPassword, @@ -101,20 +101,20 @@ const mapStateToProps = (state) => { isMainnet: getIsMainnet(state), originOfCurrentTab, shouldShowWeb3ShimUsageNotification, - } -} + }; +}; const mapDispatchToProps = (dispatch) => ({ turnThreeBoxSyncingOn: () => dispatch(turnThreeBoxSyncingOn()), setupThreeBox: () => { dispatch(getThreeBoxLastUpdated()).then((lastUpdated) => { if (lastUpdated) { - dispatch(setThreeBoxLastUpdated(lastUpdated)) + dispatch(setThreeBoxLastUpdated(lastUpdated)); } else { - dispatch(setShowRestorePromptToFalse()) - dispatch(turnThreeBoxSyncingOn()) + dispatch(setShowRestorePromptToFalse()); + dispatch(turnThreeBoxSyncingOn()); } - }) + }); }, restoreFromThreeBox: (address) => dispatch(restoreFromThreeBox(address)), setShowRestorePromptToFalse: () => dispatch(setShowRestorePromptToFalse()), @@ -127,9 +127,9 @@ const mapDispatchToProps = (dispatch) => ({ setWeb3ShimUsageAlertDismissed(origin), disableWeb3ShimUsageAlert: () => setAlertEnabledness(ALERT_TYPES.web3ShimUsage, false), -}) +}); export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps), -)(Home) +)(Home); diff --git a/ui/app/pages/home/index.js b/ui/app/pages/home/index.js index 4474ba5b80..b306d20902 100644 --- a/ui/app/pages/home/index.js +++ b/ui/app/pages/home/index.js @@ -1 +1 @@ -export { default } from './home.container' +export { default } from './home.container'; diff --git a/ui/app/pages/index.js b/ui/app/pages/index.js index e64ea3f227..3033e2946e 100644 --- a/ui/app/pages/index.js +++ b/ui/app/pages/index.js @@ -1,34 +1,34 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import { Provider } from 'react-redux' -import { HashRouter } from 'react-router-dom' -import * as Sentry from '@sentry/browser' -import { I18nProvider, LegacyI18nProvider } from '../contexts/i18n' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { Provider } from 'react-redux'; +import { HashRouter } from 'react-router-dom'; +import * as Sentry from '@sentry/browser'; +import { I18nProvider, LegacyI18nProvider } from '../contexts/i18n'; import { MetaMetricsProvider, LegacyMetaMetricsProvider, -} from '../contexts/metametrics' +} from '../contexts/metametrics'; import { MetaMetricsProvider as NewMetaMetricsProvider, LegacyMetaMetricsProvider as NewLegacyMetaMetricsProvider, -} from '../contexts/metametrics.new' -import ErrorPage from './error' -import Routes from './routes' +} from '../contexts/metametrics.new'; +import ErrorPage from './error'; +import Routes from './routes'; class Index extends PureComponent { - state = {} + state = {}; static getDerivedStateFromError(error) { - return { error } + return { error }; } componentDidCatch(error) { - Sentry.captureException(error) + Sentry.captureException(error); } render() { - const { error, errorId } = this.state - const { store } = this.props + const { error, errorId } = this.state; + const { store } = this.props; if (error) { return ( @@ -39,7 +39,7 @@ class Index extends PureComponent { - ) + ); } return ( @@ -60,12 +60,12 @@ class Index extends PureComponent { - ) + ); } } Index.propTypes = { store: PropTypes.object, -} +}; -export default Index +export default Index; diff --git a/ui/app/pages/keychains/restore-vault.js b/ui/app/pages/keychains/restore-vault.js index b8dab7ba59..fc1121c7b0 100644 --- a/ui/app/pages/keychains/restore-vault.js +++ b/ui/app/pages/keychains/restore-vault.js @@ -1,20 +1,20 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import { connect } from 'react-redux' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; import { createNewVaultAndRestore, unMarkPasswordForgotten, initializeThreeBox, -} from '../../store/actions' -import { DEFAULT_ROUTE } from '../../helpers/constants/routes' -import TextField from '../../components/ui/text-field' -import Button from '../../components/ui/button' +} from '../../store/actions'; +import { DEFAULT_ROUTE } from '../../helpers/constants/routes'; +import TextField from '../../components/ui/text-field'; +import Button from '../../components/ui/button'; class RestoreVaultPage extends Component { static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; static propTypes = { createNewVaultAndRestore: PropTypes.func.isRequired, @@ -22,7 +22,7 @@ class RestoreVaultPage extends Component { history: PropTypes.object, isLoading: PropTypes.bool, initializeThreeBox: PropTypes.func, - } + }; state = { seedPhrase: '', @@ -32,54 +32,54 @@ class RestoreVaultPage extends Component { seedPhraseError: null, passwordError: null, confirmPasswordError: null, - } + }; parseSeedPhrase = (seedPhrase) => - (seedPhrase || '').trim().toLowerCase().match(/\w+/gu)?.join(' ') || '' + (seedPhrase || '').trim().toLowerCase().match(/\w+/gu)?.join(' ') || ''; handleSeedPhraseChange(seedPhrase) { - let seedPhraseError = null + let seedPhraseError = null; - const wordCount = this.parseSeedPhrase(seedPhrase).split(/\s/u).length + const wordCount = this.parseSeedPhrase(seedPhrase).split(/\s/u).length; if ( seedPhrase && (wordCount % 3 !== 0 || wordCount < 12 || wordCount > 24) ) { - seedPhraseError = this.context.t('seedPhraseReq') + seedPhraseError = this.context.t('seedPhraseReq'); } - this.setState({ seedPhrase, seedPhraseError }) + this.setState({ seedPhrase, seedPhraseError }); } handlePasswordChange(password) { - const { confirmPassword } = this.state - let confirmPasswordError = null - let passwordError = null + const { confirmPassword } = this.state; + let confirmPasswordError = null; + let passwordError = null; if (password && password.length < 8) { - passwordError = this.context.t('passwordNotLongEnough') + passwordError = this.context.t('passwordNotLongEnough'); } if (confirmPassword && password !== confirmPassword) { - confirmPasswordError = this.context.t('passwordsDontMatch') + confirmPasswordError = this.context.t('passwordsDontMatch'); } - this.setState({ password, passwordError, confirmPasswordError }) + this.setState({ password, passwordError, confirmPasswordError }); } handleConfirmPasswordChange(confirmPassword) { - const { password } = this.state - let confirmPasswordError = null + const { password } = this.state; + let confirmPasswordError = null; if (password !== confirmPassword) { - confirmPasswordError = this.context.t('passwordsDontMatch') + confirmPasswordError = this.context.t('passwordsDontMatch'); } - this.setState({ confirmPassword, confirmPasswordError }) + this.setState({ confirmPassword, confirmPasswordError }); } onClick = () => { - const { password, seedPhrase } = this.state + const { password, seedPhrase } = this.state; const { // eslint-disable-next-line no-shadow createNewVaultAndRestore, @@ -87,9 +87,9 @@ class RestoreVaultPage extends Component { history, // eslint-disable-next-line no-shadow initializeThreeBox, - } = this.props + } = this.props; - leaveImportSeedScreenState() + leaveImportSeedScreenState(); createNewVaultAndRestore(password, this.parseSeedPhrase(seedPhrase)).then( () => { this.context.metricsEvent({ @@ -98,23 +98,23 @@ class RestoreVaultPage extends Component { action: 'userEntersSeedPhrase', name: 'onboardingRestoredVault', }, - }) - initializeThreeBox() - history.push(DEFAULT_ROUTE) + }); + initializeThreeBox(); + history.push(DEFAULT_ROUTE); }, - ) - } + ); + }; hasError() { - const { passwordError, confirmPasswordError, seedPhraseError } = this.state - return passwordError || confirmPasswordError || seedPhraseError + const { passwordError, confirmPasswordError, seedPhraseError } = this.state; + return passwordError || confirmPasswordError || seedPhraseError; } toggleShowSeedPhrase = () => { this.setState(({ showSeedPhrase }) => ({ showSeedPhrase: !showSeedPhrase, - })) - } + })); + }; render() { const { @@ -125,15 +125,15 @@ class RestoreVaultPage extends Component { seedPhraseError, passwordError, confirmPasswordError, - } = this.state - const { t } = this.context - const { isLoading } = this.props + } = this.state; + const { t } = this.context; + const { isLoading } = this.props; const disabled = !seedPhrase || !password || !confirmPassword || isLoading || - this.hasError() + this.hasError(); return (
    - ) + ); } } @@ -248,10 +248,10 @@ export default connect( ({ appState: { isLoading } }) => ({ isLoading }), (dispatch) => ({ leaveImportSeedScreenState: () => { - dispatch(unMarkPasswordForgotten()) + dispatch(unMarkPasswordForgotten()); }, createNewVaultAndRestore: (pw, seed) => dispatch(createNewVaultAndRestore(pw, seed)), initializeThreeBox: () => dispatch(initializeThreeBox()), }), -)(RestoreVaultPage) +)(RestoreVaultPage); diff --git a/ui/app/pages/keychains/reveal-seed.js b/ui/app/pages/keychains/reveal-seed.js index 94f940617b..f9ac0c1052 100644 --- a/ui/app/pages/keychains/reveal-seed.js +++ b/ui/app/pages/keychains/reveal-seed.js @@ -1,15 +1,15 @@ -import React, { Component } from 'react' -import { connect } from 'react-redux' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { requestRevealSeedWords } from '../../store/actions' -import ExportTextContainer from '../../components/ui/export-text-container' -import { getMostRecentOverviewPage } from '../../ducks/history/history' +import React, { Component } from 'react'; +import { connect } from 'react-redux'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import { requestRevealSeedWords } from '../../store/actions'; +import ExportTextContainer from '../../components/ui/export-text-container'; +import { getMostRecentOverviewPage } from '../../ducks/history/history'; -import Button from '../../components/ui/button' +import Button from '../../components/ui/button'; -const PASSWORD_PROMPT_SCREEN = 'PASSWORD_PROMPT_SCREEN' -const REVEAL_SEED_SCREEN = 'REVEAL_SEED_SCREEN' +const PASSWORD_PROMPT_SCREEN = 'PASSWORD_PROMPT_SCREEN'; +const REVEAL_SEED_SCREEN = 'REVEAL_SEED_SCREEN'; class RevealSeedPage extends Component { state = { @@ -17,24 +17,24 @@ class RevealSeedPage extends Component { password: '', seedWords: null, error: null, - } + }; componentDidMount() { - const passwordBox = document.getElementById('password-box') + const passwordBox = document.getElementById('password-box'); if (passwordBox) { - passwordBox.focus() + passwordBox.focus(); } } handleSubmit(event) { - event.preventDefault() - this.setState({ seedWords: null, error: null }) + event.preventDefault(); + this.setState({ seedWords: null, error: null }); this.props .requestRevealSeedWords(this.state.password) .then((seedWords) => this.setState({ seedWords, screen: REVEAL_SEED_SCREEN }), ) - .catch((error) => this.setState({ error: error.message })) + .catch((error) => this.setState({ error: error.message })); } renderWarning() { @@ -52,17 +52,17 @@ class RevealSeedPage extends Component {
    {this.context.t('revealSeedWordsWarning')}
    - ) + ); } renderContent() { return this.state.screen === PASSWORD_PROMPT_SCREEN ? this.renderPasswordPromptContent() - : this.renderRevealSeedContent() + : this.renderRevealSeedContent(); } renderPasswordPromptContent() { - const { t } = this.context + const { t } = this.context; return (
    this.handleSubmit(event)}> @@ -87,11 +87,11 @@ class RevealSeedPage extends Component {
    {this.state.error}
    )}
    - ) + ); } renderRevealSeedContent() { - const { t } = this.context + const { t } = this.context; return (
    @@ -100,13 +100,13 @@ class RevealSeedPage extends Component {
    - ) + ); } renderFooter() { return this.state.screen === PASSWORD_PROMPT_SCREEN ? this.renderPasswordPromptFooter() - : this.renderRevealSeedFooter() + : this.renderRevealSeedFooter(); } renderPasswordPromptFooter() { @@ -134,7 +134,7 @@ class RevealSeedPage extends Component { - ) + ); } renderRevealSeedFooter() { @@ -151,7 +151,7 @@ class RevealSeedPage extends Component { {this.context.t('close')} - ) + ); } render() { @@ -171,7 +171,7 @@ class RevealSeedPage extends Component { {this.renderFooter()} - ) + ); } } @@ -179,23 +179,23 @@ RevealSeedPage.propTypes = { requestRevealSeedWords: PropTypes.func, history: PropTypes.object, mostRecentOverviewPage: PropTypes.string.isRequired, -} +}; RevealSeedPage.contextTypes = { t: PropTypes.func, -} +}; const mapStateToProps = (state) => { return { mostRecentOverviewPage: getMostRecentOverviewPage(state), - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { requestRevealSeedWords: (password) => dispatch(requestRevealSeedWords(password)), - } -} + }; +}; -export default connect(mapStateToProps, mapDispatchToProps)(RevealSeedPage) +export default connect(mapStateToProps, mapDispatchToProps)(RevealSeedPage); diff --git a/ui/app/pages/keychains/tests/reveal-seed.test.js b/ui/app/pages/keychains/tests/reveal-seed.test.js index 7cb8675882..8eeda0ae08 100644 --- a/ui/app/pages/keychains/tests/reveal-seed.test.js +++ b/ui/app/pages/keychains/tests/reveal-seed.test.js @@ -1,8 +1,8 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import { mount } from 'enzyme' -import RevealSeedPage from '../reveal-seed' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import { mount } from 'enzyme'; +import RevealSeedPage from '../reveal-seed'; describe('Reveal Seed Page', function () { it('form submit', function () { @@ -11,14 +11,14 @@ describe('Reveal Seed Page', function () { push: sinon.spy(), }, requestRevealSeedWords: sinon.stub().resolves(), - } + }; const wrapper = mount(, { context: { t: (str) => str, }, - }) + }); - wrapper.find('form').simulate('submit') - assert(props.requestRevealSeedWords.calledOnce) - }) -}) + wrapper.find('form').simulate('submit'); + assert(props.requestRevealSeedWords.calledOnce); + }); +}); diff --git a/ui/app/pages/lock/index.js b/ui/app/pages/lock/index.js index 7bfe2a61fb..793e47c23b 100644 --- a/ui/app/pages/lock/index.js +++ b/ui/app/pages/lock/index.js @@ -1 +1 @@ -export { default } from './lock.container' +export { default } from './lock.container'; diff --git a/ui/app/pages/lock/lock.component.js b/ui/app/pages/lock/lock.component.js index a415f5b559..4b801f5404 100644 --- a/ui/app/pages/lock/lock.component.js +++ b/ui/app/pages/lock/lock.component.js @@ -1,26 +1,26 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import Loading from '../../components/ui/loading-screen' -import { DEFAULT_ROUTE } from '../../helpers/constants/routes' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import Loading from '../../components/ui/loading-screen'; +import { DEFAULT_ROUTE } from '../../helpers/constants/routes'; export default class Lock extends PureComponent { static propTypes = { history: PropTypes.object, isUnlocked: PropTypes.bool, lockMetamask: PropTypes.func, - } + }; componentDidMount() { - const { lockMetamask, isUnlocked, history } = this.props + const { lockMetamask, isUnlocked, history } = this.props; if (isUnlocked) { - lockMetamask().then(() => history.push(DEFAULT_ROUTE)) + lockMetamask().then(() => history.push(DEFAULT_ROUTE)); } else { - history.replace(DEFAULT_ROUTE) + history.replace(DEFAULT_ROUTE); } } render() { - return + return ; } } diff --git a/ui/app/pages/lock/lock.container.js b/ui/app/pages/lock/lock.container.js index b1da86f674..c029d8ddce 100644 --- a/ui/app/pages/lock/lock.container.js +++ b/ui/app/pages/lock/lock.container.js @@ -1,26 +1,26 @@ -import { compose } from 'redux' -import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom' -import { lockMetamask } from '../../store/actions' -import Lock from './lock.component' +import { compose } from 'redux'; +import { connect } from 'react-redux'; +import { withRouter } from 'react-router-dom'; +import { lockMetamask } from '../../store/actions'; +import Lock from './lock.component'; const mapStateToProps = (state) => { const { metamask: { isUnlocked }, - } = state + } = state; return { isUnlocked, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { lockMetamask: () => dispatch(lockMetamask()), - } -} + }; +}; export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps), -)(Lock) +)(Lock); diff --git a/ui/app/pages/lock/tests/lock.test.js b/ui/app/pages/lock/tests/lock.test.js index 688fe062a5..529fe01768 100644 --- a/ui/app/pages/lock/tests/lock.test.js +++ b/ui/app/pages/lock/tests/lock.test.js @@ -1,8 +1,8 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import { mountWithRouter } from '../../../../../test/lib/render-helpers' -import Lock from '..' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import { mountWithRouter } from '../../../../../test/lib/render-helpers'; +import Lock from '..'; describe('Lock', function () { it('replaces history with default route when isUnlocked false', function () { @@ -11,12 +11,12 @@ describe('Lock', function () { history: { replace: sinon.spy(), }, - } + }; - mountWithRouter() + mountWithRouter(); - assert.strictEqual(props.history.replace.getCall(0).args[0], '/') - }) + assert.strictEqual(props.history.replace.getCall(0).args[0], '/'); + }); it('locks and pushes history with default route when isUnlocked true', function (done) { const props = { @@ -25,16 +25,16 @@ describe('Lock', function () { history: { push: sinon.spy(), }, - } + }; - props.lockMetamask.resolves() + props.lockMetamask.resolves(); - mountWithRouter() + mountWithRouter(); - assert(props.lockMetamask.calledOnce) + assert(props.lockMetamask.calledOnce); setImmediate(() => { - assert.strictEqual(props.history.push.getCall(0).args[0], '/') - done() - }) - }) -}) + assert.strictEqual(props.history.push.getCall(0).args[0], '/'); + done(); + }); + }); +}); diff --git a/ui/app/pages/mobile-sync/index.js b/ui/app/pages/mobile-sync/index.js index c7df5ede55..be41d814c9 100644 --- a/ui/app/pages/mobile-sync/index.js +++ b/ui/app/pages/mobile-sync/index.js @@ -1 +1 @@ -export { default } from './mobile-sync.container' +export { default } from './mobile-sync.container'; diff --git a/ui/app/pages/mobile-sync/mobile-sync.component.js b/ui/app/pages/mobile-sync/mobile-sync.component.js index e7efc2364f..339bfa130c 100644 --- a/ui/app/pages/mobile-sync/mobile-sync.component.js +++ b/ui/app/pages/mobile-sync/mobile-sync.component.js @@ -1,22 +1,22 @@ -import React, { Component } from 'react' +import React, { Component } from 'react'; -import PropTypes from 'prop-types' -import classnames from 'classnames' -import PubNub from 'pubnub' -import qrCode from 'qrcode-generator' +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import PubNub from 'pubnub'; +import qrCode from 'qrcode-generator'; -import Button from '../../components/ui/button' -import LoadingScreen from '../../components/ui/loading-screen' +import Button from '../../components/ui/button'; +import LoadingScreen from '../../components/ui/loading-screen'; -const PASSWORD_PROMPT_SCREEN = 'PASSWORD_PROMPT_SCREEN' -const REVEAL_SEED_SCREEN = 'REVEAL_SEED_SCREEN' -const KEYS_GENERATION_TIME = 30000 -const IDLE_TIME = KEYS_GENERATION_TIME * 4 +const PASSWORD_PROMPT_SCREEN = 'PASSWORD_PROMPT_SCREEN'; +const REVEAL_SEED_SCREEN = 'REVEAL_SEED_SCREEN'; +const KEYS_GENERATION_TIME = 30000; +const IDLE_TIME = KEYS_GENERATION_TIME * 4; export default class MobileSyncPage extends Component { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { history: PropTypes.object.isRequired, @@ -27,7 +27,7 @@ export default class MobileSyncPage extends Component { requestRevealSeedWords: PropTypes.func.isRequired, exportAccounts: PropTypes.func.isRequired, keyrings: PropTypes.array, - } + }; state = { screen: PASSWORD_PROMPT_SCREEN, @@ -39,151 +39,152 @@ export default class MobileSyncPage extends Component { completed: false, channelName: undefined, cipherKey: undefined, - } + }; - syncing = false + syncing = false; componentDidMount() { - const passwordBox = document.getElementById('password-box') + const passwordBox = document.getElementById('password-box'); if (passwordBox) { - passwordBox.focus() + passwordBox.focus(); } } startIdleTimeout() { this.idleTimeout = setTimeout(() => { - this.clearTimeouts() - this.goBack() - }, IDLE_TIME) + this.clearTimeouts(); + this.goBack(); + }, IDLE_TIME); } handleSubmit(event) { - event.preventDefault() - this.setState({ seedWords: null, error: null }) + event.preventDefault(); + this.setState({ seedWords: null, error: null }); this.props .requestRevealSeedWords(this.state.password) .then((seedWords) => { - this.startKeysGeneration() - this.startIdleTimeout() + this.startKeysGeneration(); + this.startIdleTimeout(); this.exportAccounts().then((importedAccounts) => { this.setState({ seedWords, importedAccounts, screen: REVEAL_SEED_SCREEN, - }) - }) + }); + }); }) - .catch((error) => this.setState({ error: error.message })) + .catch((error) => this.setState({ error: error.message })); } async exportAccounts() { - const addresses = [] + const addresses = []; this.props.keyrings.forEach((keyring) => { if (keyring.type === 'Simple Key Pair') { - addresses.push(keyring.accounts[0]) + addresses.push(keyring.accounts[0]); } - }) + }); const importedAccounts = await this.props.exportAccounts( this.state.password, addresses, - ) - return importedAccounts + ); + return importedAccounts; } startKeysGeneration() { - this.keysGenerationTimeout && clearTimeout(this.keysGenerationTimeout) - this.disconnectWebsockets() - this.generateCipherKeyAndChannelName() - this.initWebsockets() + this.keysGenerationTimeout && clearTimeout(this.keysGenerationTimeout); + this.disconnectWebsockets(); + this.generateCipherKeyAndChannelName(); + this.initWebsockets(); this.keysGenerationTimeout = setTimeout(() => { - this.startKeysGeneration() - }, KEYS_GENERATION_TIME) + this.startKeysGeneration(); + }, KEYS_GENERATION_TIME); } goBack() { - const { history, mostRecentOverviewPage } = this.props - history.push(mostRecentOverviewPage) + const { history, mostRecentOverviewPage } = this.props; + history.push(mostRecentOverviewPage); } clearTimeouts() { - this.keysGenerationTimeout && clearTimeout(this.keysGenerationTimeout) - this.idleTimeout && clearTimeout(this.idleTimeout) + this.keysGenerationTimeout && clearTimeout(this.keysGenerationTimeout); + this.idleTimeout && clearTimeout(this.idleTimeout); } generateCipherKeyAndChannelName() { this.cipherKey = `${this.props.selectedAddress.substr( -4, - )}-${PubNub.generateUUID()}` - this.channelName = `mm-${PubNub.generateUUID()}` - this.setState({ cipherKey: this.cipherKey, channelName: this.channelName }) + )}-${PubNub.generateUUID()}`; + this.channelName = `mm-${PubNub.generateUUID()}`; + this.setState({ cipherKey: this.cipherKey, channelName: this.channelName }); } initWithCipherKeyAndChannelName(cipherKey, channelName) { - this.cipherKey = cipherKey - this.channelName = channelName + this.cipherKey = cipherKey; + this.channelName = channelName; } initWebsockets() { // Make sure there are no existing listeners - this.disconnectWebsockets() + this.disconnectWebsockets(); this.pubnub = new PubNub({ subscribeKey: process.env.PUBNUB_SUB_KEY, publishKey: process.env.PUBNUB_PUB_KEY, cipherKey: this.cipherKey, ssl: true, - }) + }); this.pubnubListener = { message: (data) => { - const { channel, message } = data + const { channel, message } = data; // handle message if (channel !== this.channelName || !message) { - return + return; } if (message.event === 'start-sync') { - this.startSyncing() + this.startSyncing(); } else if (message.event === 'connection-info') { - this.keysGenerationTimeout && clearTimeout(this.keysGenerationTimeout) - this.disconnectWebsockets() - this.initWithCipherKeyAndChannelName(message.cipher, message.channel) - this.initWebsockets() + this.keysGenerationTimeout && + clearTimeout(this.keysGenerationTimeout); + this.disconnectWebsockets(); + this.initWithCipherKeyAndChannelName(message.cipher, message.channel); + this.initWebsockets(); } else if (message.event === 'end-sync') { - this.disconnectWebsockets() - this.setState({ syncing: false, completed: true }) + this.disconnectWebsockets(); + this.setState({ syncing: false, completed: true }); } }, - } + }; - this.pubnub.addListener(this.pubnubListener) + this.pubnub.addListener(this.pubnubListener); this.pubnub.subscribe({ channels: [this.channelName], withPresence: false, - }) + }); } disconnectWebsockets() { if (this.pubnub && this.pubnubListener) { - this.pubnub.removeListener(this.pubnubListener) + this.pubnub.removeListener(this.pubnubListener); } } // Calculating a PubNub Message Payload Size. calculatePayloadSize(channel, message) { - return encodeURIComponent(channel + JSON.stringify(message)).length + 100 + return encodeURIComponent(channel + JSON.stringify(message)).length + 100; } chunkString(str, size) { - const numChunks = Math.ceil(str.length / size) - const chunks = new Array(numChunks) - let o = 0 + const numChunks = Math.ceil(str.length / size); + const chunks = new Array(numChunks); + let o = 0; for (let i = 0; i < numChunks; i += 1) { - chunks[i] = str.substr(o, size) - o += size + chunks[i] = str.substr(o, size); + o += size; } - return chunks + return chunks; } notifyError(errorMsg) { @@ -200,28 +201,28 @@ export default class MobileSyncPage extends Component { }, (status, response) => { if (status.error) { - reject(response) + reject(response); } else { - resolve() + resolve(); } }, - ) - }) + ); + }); } async startSyncing() { if (this.syncing) { - return + return; } - this.syncing = true - this.setState({ syncing: true }) + this.syncing = true; + this.setState({ syncing: true }); const { accounts, network, preferences, transactions, - } = await this.props.fetchInfoToSync() + } = await this.props.fetchInfoToSync(); const allDataStr = JSON.stringify({ accounts, @@ -233,19 +234,19 @@ export default class MobileSyncPage extends Component { seed: this.state.seedWords, importedAccounts: this.state.importedAccounts, }, - }) + }); - const chunks = this.chunkString(allDataStr, 17000) - const totalChunks = chunks.length + const chunks = this.chunkString(allDataStr, 17000); + const totalChunks = chunks.length; try { for (let i = 0; i < totalChunks; i++) { - await this.sendMessage(chunks[i], i + 1, totalChunks) + await this.sendMessage(chunks[i], i + 1, totalChunks); } } catch (e) { - this.props.displayWarning('Sync failed :(') - this.setState({ syncing: false }) - this.syncing = false - this.notifyError(e.toString()) + this.props.displayWarning('Sync failed :('); + this.setState({ syncing: false }); + this.syncing = false; + this.notifyError(e.toString()); } } @@ -265,18 +266,18 @@ export default class MobileSyncPage extends Component { }, (status, response) => { if (status.error) { - reject(response) + reject(response); } else { - resolve() + resolve(); } }, - ) - }) + ); + }); } componentWillUnmount() { - this.clearTimeouts() - this.disconnectWebsockets() + this.clearTimeouts(); + this.disconnectWebsockets(); } renderWarning(text) { @@ -286,15 +287,15 @@ export default class MobileSyncPage extends Component {
    {text}
    - ) + ); } renderContent() { - const { syncing, completed, screen } = this.state - const { t } = this.context + const { syncing, completed, screen } = this.state; + const { t } = this.context; if (syncing) { - return + return ; } if (completed) { @@ -310,7 +311,7 @@ export default class MobileSyncPage extends Component { {t('syncWithMobileComplete')} - ) + ); } return screen === PASSWORD_PROMPT_SCREEN ? ( @@ -327,11 +328,11 @@ export default class MobileSyncPage extends Component { {this.renderRevealSeedContent()} - ) + ); } renderPasswordPromptContent() { - const { t } = this.context + const { t } = this.context; return (
    this.handleSubmit(event)}> @@ -356,17 +357,17 @@ export default class MobileSyncPage extends Component {
    {this.state.error}
    )}
    - ) + ); } renderRevealSeedContent() { - const qrImage = qrCode(0, 'M') + const qrImage = qrCode(0, 'M'); qrImage.addData( `metamask-sync:${this.state.channelName}|@|${this.state.cipherKey}`, - ) - qrImage.make() + ); + qrImage.make(); - const { t } = this.context + const { t } = this.context; return (
    - ) + ); } renderFooter() { return this.state.screen === PASSWORD_PROMPT_SCREEN ? this.renderPasswordPromptFooter() - : this.renderRevealSeedFooter() + : this.renderRevealSeedFooter(); } renderPasswordPromptFooter() { - const { t } = this.context - const { password } = this.state + const { t } = this.context; + const { password } = this.state; return (
    @@ -421,11 +422,11 @@ export default class MobileSyncPage extends Component { {t('next')}
    - ) + ); } renderRevealSeedFooter() { - const { t } = this.context + const { t } = this.context; return (
    @@ -438,12 +439,12 @@ export default class MobileSyncPage extends Component { {t('close')}
    - ) + ); } render() { - const { t } = this.context - const { screen } = this.state + const { t } = this.context; + const { screen } = this.state; return (
    @@ -465,6 +466,6 @@ export default class MobileSyncPage extends Component {
    {this.renderContent()}
    {this.renderFooter()}
    - ) + ); } } diff --git a/ui/app/pages/mobile-sync/mobile-sync.container.js b/ui/app/pages/mobile-sync/mobile-sync.container.js index 440b16e899..1172a97dc2 100644 --- a/ui/app/pages/mobile-sync/mobile-sync.container.js +++ b/ui/app/pages/mobile-sync/mobile-sync.container.js @@ -1,13 +1,13 @@ -import { connect } from 'react-redux' +import { connect } from 'react-redux'; import { displayWarning, requestRevealSeedWords, fetchInfoToSync, exportAccounts, -} from '../../store/actions' -import { getMostRecentOverviewPage } from '../../ducks/history/history' -import { getMetaMaskKeyrings } from '../../selectors' -import MobileSyncPage from './mobile-sync.component' +} from '../../store/actions'; +import { getMostRecentOverviewPage } from '../../ducks/history/history'; +import { getMetaMaskKeyrings } from '../../selectors'; +import MobileSyncPage from './mobile-sync.component'; const mapDispatchToProps = (dispatch) => { return { @@ -17,19 +17,19 @@ const mapDispatchToProps = (dispatch) => { displayWarning: (message) => dispatch(displayWarning(message || null)), exportAccounts: (password, addresses) => dispatch(exportAccounts(password, addresses)), - } -} + }; +}; const mapStateToProps = (state) => { const { metamask: { selectedAddress }, - } = state + } = state; return { mostRecentOverviewPage: getMostRecentOverviewPage(state), selectedAddress, keyrings: getMetaMaskKeyrings(state), - } -} + }; +}; -export default connect(mapStateToProps, mapDispatchToProps)(MobileSyncPage) +export default connect(mapStateToProps, mapDispatchToProps)(MobileSyncPage); diff --git a/ui/app/pages/permissions-connect/choose-account/choose-account.component.js b/ui/app/pages/permissions-connect/choose-account/choose-account.component.js index fe1d67d7f7..8e245e62e3 100644 --- a/ui/app/pages/permissions-connect/choose-account/choose-account.component.js +++ b/ui/app/pages/permissions-connect/choose-account/choose-account.component.js @@ -1,18 +1,18 @@ -import PropTypes from 'prop-types' -import React, { Component } from 'react' -import classnames from 'classnames' -import Identicon from '../../../components/ui/identicon' -import Button from '../../../components/ui/button' +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import classnames from 'classnames'; +import Identicon from '../../../components/ui/identicon'; +import Button from '../../../components/ui/button'; import CheckBox, { CHECKED, INDETERMINATE, UNCHECKED, -} from '../../../components/ui/check-box' -import Tooltip from '../../../components/ui/tooltip' -import { PRIMARY } from '../../../helpers/constants/common' -import UserPreferencedCurrencyDisplay from '../../../components/app/user-preferenced-currency-display' -import PermissionsConnectHeader from '../../../components/app/permissions-connect-header' -import PermissionsConnectFooter from '../../../components/app/permissions-connect-footer' +} from '../../../components/ui/check-box'; +import Tooltip from '../../../components/ui/tooltip'; +import { PRIMARY } from '../../../helpers/constants/common'; +import UserPreferencedCurrencyDisplay from '../../../components/app/user-preferenced-currency-display'; +import PermissionsConnectHeader from '../../../components/app/permissions-connect-header'; +import PermissionsConnectFooter from '../../../components/app/permissions-connect-footer'; export default class ChooseAccount extends Component { static propTypes = { @@ -38,62 +38,62 @@ export default class ChooseAccount extends Component { name: PropTypes.string.isRequired, origin: PropTypes.string.isRequired, }), - } + }; state = { selectedAccounts: this.props.selectedAccountAddresses, - } + }; static defaultProps = { addressLastConnectedMap: {}, - } + }; static contextTypes = { t: PropTypes.func, - } + }; handleAccountClick(address) { - const { selectedAccounts } = this.state + const { selectedAccounts } = this.state; - const newSelectedAccounts = new Set(selectedAccounts) + const newSelectedAccounts = new Set(selectedAccounts); if (newSelectedAccounts.has(address)) { - newSelectedAccounts.delete(address) + newSelectedAccounts.delete(address); } else { - newSelectedAccounts.add(address) + newSelectedAccounts.add(address); } - this.setState({ selectedAccounts: newSelectedAccounts }) + this.setState({ selectedAccounts: newSelectedAccounts }); } selectAll() { - const { accounts } = this.props + const { accounts } = this.props; const newSelectedAccounts = new Set( accounts.map((account) => account.address), - ) + ); - this.setState({ selectedAccounts: newSelectedAccounts }) + this.setState({ selectedAccounts: newSelectedAccounts }); } deselectAll() { - this.setState({ selectedAccounts: new Set() }) + this.setState({ selectedAccounts: new Set() }); } allAreSelected() { - const { accounts } = this.props - const { selectedAccounts } = this.state + const { accounts } = this.props; + const { selectedAccounts } = this.state; - return accounts.every(({ address }) => selectedAccounts.has(address)) + return accounts.every(({ address }) => selectedAccounts.has(address)); } renderAccountsList = () => { - const { accounts, nativeCurrency, addressLastConnectedMap } = this.props - const { selectedAccounts } = this.state + const { accounts, nativeCurrency, addressLastConnectedMap } = this.props; + const { selectedAccounts } = this.state; return (
    {accounts.map((account, index) => { - const { address, addressLabel, balance } = account + const { address, addressLabel, balance } = account; return (
    ) : null}
    - ) + ); })}
    - ) - } + ); + }; renderAccountsListHeader() { - const { t } = this.context - const { selectNewAccountViaModal, accounts } = this.props - const { selectedAccounts } = this.state + const { t } = this.context; + const { selectNewAccountViaModal, accounts } = this.props; + const { selectedAccounts } = this.state; - let checked + let checked; if (this.allAreSelected()) { - checked = CHECKED + checked = CHECKED; } else if (selectedAccounts.size === 0) { - checked = UNCHECKED + checked = UNCHECKED; } else { - checked = INDETERMINATE + checked = INDETERMINATE; } return ( @@ -191,7 +191,7 @@ export default class ChooseAccount extends Component { {this.context.t('newAccount')} - ) + ); } render() { @@ -201,9 +201,9 @@ export default class ChooseAccount extends Component { cancelPermissionsRequest, targetDomainMetadata, accounts, - } = this.props - const { selectedAccounts } = this.state - const { t } = this.context + } = this.props; + const { selectedAccounts } = this.state; + const { t } = this.context; return (
    - ) + ); } } diff --git a/ui/app/pages/permissions-connect/choose-account/index.js b/ui/app/pages/permissions-connect/choose-account/index.js index 10b4cd2249..3b25d36c7d 100644 --- a/ui/app/pages/permissions-connect/choose-account/index.js +++ b/ui/app/pages/permissions-connect/choose-account/index.js @@ -1 +1 @@ -export { default } from './choose-account.component' +export { default } from './choose-account.component'; diff --git a/ui/app/pages/permissions-connect/index.js b/ui/app/pages/permissions-connect/index.js index 06798a2f61..263242e1a8 100644 --- a/ui/app/pages/permissions-connect/index.js +++ b/ui/app/pages/permissions-connect/index.js @@ -1 +1 @@ -export { default } from './permissions-connect.container' +export { default } from './permissions-connect.container'; diff --git a/ui/app/pages/permissions-connect/permissions-connect.component.js b/ui/app/pages/permissions-connect/permissions-connect.component.js index 06a4f136ce..1927af9ae2 100644 --- a/ui/app/pages/permissions-connect/permissions-connect.component.js +++ b/ui/app/pages/permissions-connect/permissions-connect.component.js @@ -1,14 +1,14 @@ -import PropTypes from 'prop-types' -import React, { Component } from 'react' -import { Switch, Route } from 'react-router-dom' -import { getEnvironmentType } from '../../../../app/scripts/lib/util' -import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../shared/constants/app' -import { DEFAULT_ROUTE } from '../../helpers/constants/routes' -import PermissionPageContainer from '../../components/app/permission-page-container' -import ChooseAccount from './choose-account' -import PermissionsRedirect from './redirect' +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import { Switch, Route } from 'react-router-dom'; +import { getEnvironmentType } from '../../../../app/scripts/lib/util'; +import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../shared/constants/app'; +import { DEFAULT_ROUTE } from '../../helpers/constants/routes'; +import PermissionPageContainer from '../../components/app/permission-page-container'; +import ChooseAccount from './choose-account'; +import PermissionsRedirect from './redirect'; -const APPROVE_TIMEOUT = 1200 +const APPROVE_TIMEOUT = 1200; export default class PermissionConnect extends Component { static propTypes = { @@ -37,18 +37,18 @@ export default class PermissionConnect extends Component { name: PropTypes.string.isRequired, origin: PropTypes.string.isRequired, }), - } + }; static defaultProps = { origin: '', nativeCurrency: '', permissionsRequest: undefined, permissionsRequestId: '', - } + }; static contextTypes = { t: PropTypes.func, - } + }; state = { redirecting: false, @@ -56,23 +56,23 @@ export default class PermissionConnect extends Component { permissionsApproved: null, origin: this.props.origin, targetDomainMetadata: this.props.targetDomainMetadata || {}, - } + }; beforeUnload = () => { - const { permissionsRequestId, rejectPermissionsRequest } = this.props - const { permissionsApproved } = this.state + const { permissionsRequestId, rejectPermissionsRequest } = this.props; + const { permissionsApproved } = this.state; if (permissionsApproved === null && permissionsRequestId) { - rejectPermissionsRequest(permissionsRequestId) + rejectPermissionsRequest(permissionsRequestId); } - } + }; removeBeforeUnload = () => { - const environmentType = getEnvironmentType() + const environmentType = getEnvironmentType(); if (environmentType === ENVIRONMENT_TYPE_NOTIFICATION) { - window.removeEventListener('beforeunload', this.beforeUnload) + window.removeEventListener('beforeunload', this.beforeUnload); } - } + }; componentDidMount() { const { @@ -80,47 +80,47 @@ export default class PermissionConnect extends Component { getRequestAccountTabIds, permissionsRequest, history, - } = this.props - getCurrentWindowTab() - getRequestAccountTabIds() + } = this.props; + getCurrentWindowTab(); + getRequestAccountTabIds(); if (!permissionsRequest) { - history.push(DEFAULT_ROUTE) - return + history.push(DEFAULT_ROUTE); + return; } - const environmentType = getEnvironmentType() + const environmentType = getEnvironmentType(); if (environmentType === ENVIRONMENT_TYPE_NOTIFICATION) { - window.addEventListener('beforeunload', this.beforeUnload) + window.addEventListener('beforeunload', this.beforeUnload); } } static getDerivedStateFromProps(props, state) { - const { permissionsRequest, targetDomainMetadata } = props - const { targetDomainMetadata: savedMetadata } = state + const { permissionsRequest, targetDomainMetadata } = props; + const { targetDomainMetadata: savedMetadata } = state; if ( permissionsRequest && savedMetadata.origin !== targetDomainMetadata?.origin ) { - return { targetDomainMetadata } + return { targetDomainMetadata }; } - return null + return null; } componentDidUpdate(prevProps) { - const { permissionsRequest, lastConnectedInfo } = this.props - const { redirecting, origin } = this.state + const { permissionsRequest, lastConnectedInfo } = this.props; + const { redirecting, origin } = this.state; if (!permissionsRequest && prevProps.permissionsRequest && !redirecting) { const accountsLastApprovedTime = - lastConnectedInfo[origin]?.lastApproved || 0 + lastConnectedInfo[origin]?.lastApproved || 0; const initialAccountsLastApprovedTime = - prevProps.lastConnectedInfo[origin]?.lastApproved || 0 + prevProps.lastConnectedInfo[origin]?.lastApproved || 0; const approved = - accountsLastApprovedTime > initialAccountsLastApprovedTime - this.redirect(approved) + accountsLastApprovedTime > initialAccountsLastApprovedTime; + this.redirect(approved); } } @@ -130,42 +130,42 @@ export default class PermissionConnect extends Component { selectedAccountAddresses: addresses, }, () => this.props.history.push(this.props.confirmPermissionPath), - ) - } + ); + }; redirect(approved) { - const { history } = this.props + const { history } = this.props; this.setState({ redirecting: true, permissionsApproved: approved, - }) - this.removeBeforeUnload() + }); + this.removeBeforeUnload(); if (approved) { - setTimeout(() => history.push(DEFAULT_ROUTE), APPROVE_TIMEOUT) + setTimeout(() => history.push(DEFAULT_ROUTE), APPROVE_TIMEOUT); } else { - history.push(DEFAULT_ROUTE) + history.push(DEFAULT_ROUTE); } } cancelPermissionsRequest = async (requestId) => { - const { rejectPermissionsRequest } = this.props + const { rejectPermissionsRequest } = this.props; if (requestId) { - await rejectPermissionsRequest(requestId) - this.redirect(false) + await rejectPermissionsRequest(requestId); + this.redirect(false); } - } + }; goBack() { - const { history, connectPath } = this.props - history.push(connectPath) + const { history, connectPath } = this.props; + history.push(connectPath); } renderTopBar() { - const { redirecting } = this.state - const { page } = this.props - const { t } = this.context + const { redirecting } = this.state; + const { page } = this.props; + const { t } = this.context; return redirecting ? null : (
    {page === '2' ? ( @@ -181,7 +181,7 @@ export default class PermissionConnect extends Component { {t('xOfY', [page, '2'])}
    - ) + ); } render() { @@ -196,13 +196,13 @@ export default class PermissionConnect extends Component { permissionsRequestId, connectPath, confirmPermissionPath, - } = this.props + } = this.props; const { selectedAccountAddresses, permissionsApproved, redirecting, targetDomainMetadata, - } = this.state + } = this.state; return (
    @@ -224,7 +224,7 @@ export default class PermissionConnect extends Component { onCreateNewAccount: (address) => handleAccountClick(address), newAccountNumber, - }) + }); }} addressLastConnectedMap={addressLastConnectedMap} cancelPermissionsRequest={(requestId) => @@ -243,8 +243,8 @@ export default class PermissionConnect extends Component { { - approvePermissionsRequest(...args) - this.redirect(true) + approvePermissionsRequest(...args); + this.redirect(true); }} rejectPermissionsRequest={(requestId) => this.cancelPermissionsRequest(requestId) @@ -259,6 +259,6 @@ export default class PermissionConnect extends Component { )}
    - ) + ); } } diff --git a/ui/app/pages/permissions-connect/permissions-connect.container.js b/ui/app/pages/permissions-connect/permissions-connect.container.js index 28e71c359a..abf349208a 100644 --- a/ui/app/pages/permissions-connect/permissions-connect.container.js +++ b/ui/app/pages/permissions-connect/permissions-connect.container.js @@ -1,5 +1,5 @@ -import { connect } from 'react-redux' -import PropTypes from 'prop-types' +import { connect } from 'react-redux'; +import PropTypes from 'prop-types'; import { getPermissionsRequests, getNativeCurrency, @@ -7,21 +7,21 @@ import { getLastConnectedInfo, getDomainMetadata, getSelectedAddress, -} from '../../selectors' +} from '../../selectors'; -import { formatDate } from '../../helpers/utils/util' +import { formatDate } from '../../helpers/utils/util'; import { approvePermissionsRequest, rejectPermissionsRequest, showModal, getCurrentWindowTab, getRequestAccountTabIds, -} from '../../store/actions' +} from '../../store/actions'; import { CONNECT_ROUTE, CONNECT_CONFIRM_PERMISSIONS_ROUTE, -} from '../../helpers/constants/routes' -import PermissionApproval from './permissions-connect.component' +} from '../../helpers/constants/routes'; +import PermissionApproval from './permissions-connect.component'; const mapStateToProps = (state, ownProps) => { const { @@ -29,56 +29,56 @@ const mapStateToProps = (state, ownProps) => { params: { id: permissionsRequestId }, }, location: { pathname }, - } = ownProps - const permissionsRequests = getPermissionsRequests(state) - const currentAddress = getSelectedAddress(state) + } = ownProps; + const permissionsRequests = getPermissionsRequests(state); + const currentAddress = getSelectedAddress(state); const permissionsRequest = permissionsRequests.find( (req) => req.metadata.id === permissionsRequestId, - ) + ); - const { metadata = {} } = permissionsRequest || {} - const { origin } = metadata - const nativeCurrency = getNativeCurrency(state) + const { metadata = {} } = permissionsRequest || {}; + const { origin } = metadata; + const nativeCurrency = getNativeCurrency(state); - const domainMetadata = getDomainMetadata(state) + const domainMetadata = getDomainMetadata(state); - let targetDomainMetadata = null + let targetDomainMetadata = null; if (origin) { if (domainMetadata[origin]) { - targetDomainMetadata = { ...domainMetadata[origin], origin } + targetDomainMetadata = { ...domainMetadata[origin], origin }; } else { - const targetUrl = new URL(origin) + const targetUrl = new URL(origin); targetDomainMetadata = { host: targetUrl.host, name: targetUrl.hostname, origin, - } + }; } } - const accountsWithLabels = getAccountsWithLabels(state) + const accountsWithLabels = getAccountsWithLabels(state); - const lastConnectedInfo = getLastConnectedInfo(state) || {} - const addressLastConnectedMap = lastConnectedInfo[origin]?.accounts || {} + const lastConnectedInfo = getLastConnectedInfo(state) || {}; + const addressLastConnectedMap = lastConnectedInfo[origin]?.accounts || {}; Object.keys(addressLastConnectedMap).forEach((key) => { addressLastConnectedMap[key] = formatDate( addressLastConnectedMap[key], 'yyyy-MM-dd', - ) - }) + ); + }); - const connectPath = `${CONNECT_ROUTE}/${permissionsRequestId}` - const confirmPermissionPath = `${CONNECT_ROUTE}/${permissionsRequestId}${CONNECT_CONFIRM_PERMISSIONS_ROUTE}` + const connectPath = `${CONNECT_ROUTE}/${permissionsRequestId}`; + const confirmPermissionPath = `${CONNECT_ROUTE}/${permissionsRequestId}${CONNECT_CONFIRM_PERMISSIONS_ROUTE}`; - let page = '' + let page = ''; if (pathname === connectPath) { - page = '1' + page = '1'; } else if (pathname === confirmPermissionPath) { - page = '2' + page = '2'; } else { - throw new Error('Incorrect path for permissions-connect component') + throw new Error('Incorrect path for permissions-connect component'); } return { @@ -95,8 +95,8 @@ const mapStateToProps = (state, ownProps) => { confirmPermissionPath, page, targetDomainMetadata, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { @@ -111,17 +111,17 @@ const mapDispatchToProps = (dispatch) => { onCreateNewAccount, newAccountNumber, }), - ) + ); }, getRequestAccountTabIds: () => dispatch(getRequestAccountTabIds()), getCurrentWindowTab: () => dispatch(getCurrentWindowTab()), - } -} + }; +}; const PermissionApprovalContainer = connect( mapStateToProps, mapDispatchToProps, -)(PermissionApproval) +)(PermissionApproval); PermissionApprovalContainer.propTypes = { history: PropTypes.object.isRequired, @@ -130,6 +130,6 @@ PermissionApprovalContainer.propTypes = { id: PropTypes.string, }).isRequired, }).isRequired, -} +}; -export default PermissionApprovalContainer +export default PermissionApprovalContainer; diff --git a/ui/app/pages/permissions-connect/redirect/index.js b/ui/app/pages/permissions-connect/redirect/index.js index eebe755509..d389265e2d 100644 --- a/ui/app/pages/permissions-connect/redirect/index.js +++ b/ui/app/pages/permissions-connect/redirect/index.js @@ -1 +1 @@ -export { default } from './permissions-redirect.component' +export { default } from './permissions-redirect.component'; diff --git a/ui/app/pages/permissions-connect/redirect/permissions-redirect.component.js b/ui/app/pages/permissions-connect/redirect/permissions-redirect.component.js index 6f02b550a8..701a9dc4a4 100644 --- a/ui/app/pages/permissions-connect/redirect/permissions-redirect.component.js +++ b/ui/app/pages/permissions-connect/redirect/permissions-redirect.component.js @@ -1,10 +1,10 @@ -import React, { useContext } from 'react' -import PropTypes from 'prop-types' -import SiteIcon from '../../../components/ui/site-icon' -import { I18nContext } from '../../../contexts/i18n' +import React, { useContext } from 'react'; +import PropTypes from 'prop-types'; +import SiteIcon from '../../../components/ui/site-icon'; +import { I18nContext } from '../../../contexts/i18n'; export default function PermissionsRedirect({ domainMetadata }) { - const t = useContext(I18nContext) + const t = useContext(I18nContext); return (
    @@ -24,7 +24,7 @@ export default function PermissionsRedirect({ domainMetadata }) {
    - ) + ); function renderBrokenLine() { return ( @@ -42,7 +42,7 @@ export default function PermissionsRedirect({ domainMetadata }) { strokeDasharray="8 7" /> - ) + ); } } @@ -54,4 +54,4 @@ PermissionsRedirect.propTypes = { name: PropTypes.string.isRequired, origin: PropTypes.string.isRequired, }), -} +}; diff --git a/ui/app/pages/routes/index.js b/ui/app/pages/routes/index.js index a05c9df1af..f92c2a9c79 100644 --- a/ui/app/pages/routes/index.js +++ b/ui/app/pages/routes/index.js @@ -1 +1 @@ -export { default } from './routes.container' +export { default } from './routes.container'; diff --git a/ui/app/pages/routes/routes.component.js b/ui/app/pages/routes/routes.component.js index 5aaf801240..c563d2b03e 100644 --- a/ui/app/pages/routes/routes.component.js +++ b/ui/app/pages/routes/routes.component.js @@ -1,37 +1,37 @@ -import classnames from 'classnames' -import PropTypes from 'prop-types' -import React, { Component } from 'react' -import { matchPath, Route, Switch } from 'react-router-dom' -import IdleTimer from 'react-idle-timer' - -import FirstTimeFlow from '../first-time-flow' -import SendTransactionScreen from '../send' -import Swaps from '../swaps' -import ConfirmTransaction from '../confirm-transaction' -import Sidebar from '../../components/app/sidebars' -import Home from '../home' -import Settings from '../settings' -import Authenticated from '../../helpers/higher-order-components/authenticated' -import Initialized from '../../helpers/higher-order-components/initialized' -import Lock from '../lock' -import PermissionsConnect from '../permissions-connect' -import RestoreVaultPage from '../keychains/restore-vault' -import RevealSeedConfirmation from '../keychains/reveal-seed' -import MobileSyncPage from '../mobile-sync' -import AddTokenPage from '../add-token' -import ConfirmAddTokenPage from '../confirm-add-token' -import ConfirmAddSuggestedTokenPage from '../confirm-add-suggested-token' -import CreateAccountPage from '../create-account' -import Loading from '../../components/ui/loading-screen' -import LoadingNetwork from '../../components/app/loading-network-screen' -import NetworkDropdown from '../../components/app/dropdowns/network-dropdown' -import AccountMenu from '../../components/app/account-menu' -import { Modal } from '../../components/app/modals' -import Alert from '../../components/ui/alert' -import AppHeader from '../../components/app/app-header' -import UnlockPage from '../unlock-page' -import Alerts from '../../components/app/alerts' -import Asset from '../asset' +import classnames from 'classnames'; +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import { matchPath, Route, Switch } from 'react-router-dom'; +import IdleTimer from 'react-idle-timer'; + +import FirstTimeFlow from '../first-time-flow'; +import SendTransactionScreen from '../send'; +import Swaps from '../swaps'; +import ConfirmTransaction from '../confirm-transaction'; +import Sidebar from '../../components/app/sidebars'; +import Home from '../home'; +import Settings from '../settings'; +import Authenticated from '../../helpers/higher-order-components/authenticated'; +import Initialized from '../../helpers/higher-order-components/initialized'; +import Lock from '../lock'; +import PermissionsConnect from '../permissions-connect'; +import RestoreVaultPage from '../keychains/restore-vault'; +import RevealSeedConfirmation from '../keychains/reveal-seed'; +import MobileSyncPage from '../mobile-sync'; +import AddTokenPage from '../add-token'; +import ConfirmAddTokenPage from '../confirm-add-token'; +import ConfirmAddSuggestedTokenPage from '../confirm-add-suggested-token'; +import CreateAccountPage from '../create-account'; +import Loading from '../../components/ui/loading-screen'; +import LoadingNetwork from '../../components/app/loading-network-screen'; +import NetworkDropdown from '../../components/app/dropdowns/network-dropdown'; +import AccountMenu from '../../components/app/account-menu'; +import { Modal } from '../../components/app/modals'; +import Alert from '../../components/ui/alert'; +import AppHeader from '../../components/app/app-header'; +import UnlockPage from '../unlock-page'; +import Alerts from '../../components/app/alerts'; +import Asset from '../asset'; import { ADD_TOKEN_ROUTE, @@ -53,14 +53,14 @@ import { SETTINGS_ROUTE, UNLOCK_ROUTE, BUILD_QUOTE_ROUTE, -} from '../../helpers/constants/routes' +} from '../../helpers/constants/routes'; import { ENVIRONMENT_TYPE_NOTIFICATION, ENVIRONMENT_TYPE_POPUP, -} from '../../../../shared/constants/app' -import { getEnvironmentType } from '../../../../app/scripts/lib/util' -import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction' +} from '../../../../shared/constants/app'; +import { getEnvironmentType } from '../../../../app/scripts/lib/util'; +import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'; export default class Routes extends Component { static propTypes = { @@ -88,29 +88,33 @@ export default class Routes extends Component { autoLockTimeLimit: PropTypes.number, pageChanged: PropTypes.func.isRequired, prepareToLeaveSwaps: PropTypes.func, - } + }; static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; UNSAFE_componentWillMount() { - const { currentCurrency, pageChanged, setCurrentCurrencyToUSD } = this.props + const { + currentCurrency, + pageChanged, + setCurrentCurrencyToUSD, + } = this.props; if (!currentCurrency) { - setCurrentCurrencyToUSD() + setCurrentCurrencyToUSD(); } this.props.history.listen((locationObj, action) => { if (action === 'PUSH') { - pageChanged(locationObj.pathname) + pageChanged(locationObj.pathname); } - }) + }); } renderRoutes() { - const { autoLockTimeLimit, setLastActiveTime } = this.props + const { autoLockTimeLimit, setLastActiveTime } = this.props; const routes = ( @@ -162,75 +166,75 @@ export default class Routes extends Component { - ) + ); if (autoLockTimeLimit > 0) { return ( {routes} - ) + ); } - return routes + return routes; } onInitializationUnlockPage() { - const { location } = this.props + const { location } = this.props; return Boolean( matchPath(location.pathname, { path: INITIALIZE_UNLOCK_ROUTE, exact: true, }), - ) + ); } onConfirmPage() { - const { location } = this.props + const { location } = this.props; return Boolean( matchPath(location.pathname, { path: CONFIRM_TRANSACTION_ROUTE, exact: false, }), - ) + ); } onSwapsPage() { - const { location } = this.props + const { location } = this.props; return Boolean( matchPath(location.pathname, { path: SWAPS_ROUTE, exact: false }), - ) + ); } onSwapsBuildQuotePage() { - const { location } = this.props + const { location } = this.props; return Boolean( matchPath(location.pathname, { path: BUILD_QUOTE_ROUTE, exact: false }), - ) + ); } hideAppHeader() { - const { location } = this.props + const { location } = this.props; const isInitializing = Boolean( matchPath(location.pathname, { path: INITIALIZE_ROUTE, exact: false, }), - ) + ); if (isInitializing && !this.onInitializationUnlockPage()) { - return true + return true; } - const windowType = getEnvironmentType() + const windowType = getEnvironmentType(); if (windowType === ENVIRONMENT_TYPE_NOTIFICATION) { - return true + return true; } if (windowType === ENVIRONMENT_TYPE_POPUP && this.onConfirmPage()) { - return true + return true; } const isHandlingPermissionsRequest = Boolean( @@ -238,9 +242,9 @@ export default class Routes extends Component { path: CONNECT_ROUTE, exact: false, }), - ) + ); - return isHandlingPermissionsRequest + return isHandlingPermissionsRequest; } render() { @@ -258,27 +262,27 @@ export default class Routes extends Component { submittedPendingTransactions, isMouseUser, prepareToLeaveSwaps, - } = this.props - const isLoadingNetwork = network === 'loading' + } = this.props; + const isLoadingNetwork = network === 'loading'; const loadMessage = loadingMessage || isLoadingNetwork ? this.getConnectingLabel(loadingMessage) - : null + : null; const { isOpen: sidebarIsOpen, transitionName: sidebarTransitionName, type: sidebarType, props, - } = sidebar - const { transaction: sidebarTransaction } = props || {} + } = sidebar; + const { transaction: sidebarTransaction } = props || {}; const sidebarShouldClose = sidebarTransaction && !sidebarTransaction.status === TRANSACTION_STATUSES.FAILED && !submittedPendingTransactions.find( ({ id }) => id === sidebarTransaction.id, - ) + ); return (
    setMouseUserState(true)} onKeyDown={(e) => { if (e.keyCode === 9) { - setMouseUserState(false) + setMouseUserState(false); } }} > @@ -299,7 +303,7 @@ export default class Routes extends Component { disableNetworkIndicator={this.onSwapsPage()} onClick={async () => { if (this.onSwapsPage()) { - await prepareToLeaveSwaps() + await prepareToLeaveSwaps(); } }} disabled={ @@ -328,59 +332,59 @@ export default class Routes extends Component {
    {isUnlocked ? : null} - ) + ); } toggleMetamaskActive() { if (this.props.isUnlocked) { // currently active: deactivate - this.props.lockMetaMask() + this.props.lockMetaMask(); } else { // currently inactive: redirect to password box - const passwordBox = document.querySelector('input[type=password]') + const passwordBox = document.querySelector('input[type=password]'); if (!passwordBox) { - return + return; } - passwordBox.focus() + passwordBox.focus(); } } getConnectingLabel(loadingMessage) { if (loadingMessage) { - return loadingMessage + return loadingMessage; } - const { provider, providerId } = this.props + const { provider, providerId } = this.props; switch (provider.type) { case 'mainnet': - return this.context.t('connectingToMainnet') + return this.context.t('connectingToMainnet'); case 'ropsten': - return this.context.t('connectingToRopsten') + return this.context.t('connectingToRopsten'); case 'kovan': - return this.context.t('connectingToKovan') + return this.context.t('connectingToKovan'); case 'rinkeby': - return this.context.t('connectingToRinkeby') + return this.context.t('connectingToRinkeby'); case 'goerli': - return this.context.t('connectingToGoerli') + return this.context.t('connectingToGoerli'); default: - return this.context.t('connectingTo', [providerId]) + return this.context.t('connectingTo', [providerId]); } } getNetworkName() { switch (this.props.provider.type) { case 'mainnet': - return this.context.t('mainnet') + return this.context.t('mainnet'); case 'ropsten': - return this.context.t('ropsten') + return this.context.t('ropsten'); case 'kovan': - return this.context.t('kovan') + return this.context.t('kovan'); case 'rinkeby': - return this.context.t('rinkeby') + return this.context.t('rinkeby'); case 'goerli': - return this.context.t('goerli') + return this.context.t('goerli'); default: - return this.context.t('unknownNetwork') + return this.context.t('unknownNetwork'); } } } diff --git a/ui/app/pages/routes/routes.container.js b/ui/app/pages/routes/routes.container.js index 5fc62e8150..0145b48039 100644 --- a/ui/app/pages/routes/routes.container.js +++ b/ui/app/pages/routes/routes.container.js @@ -1,32 +1,32 @@ -import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom' -import { compose } from 'redux' +import { connect } from 'react-redux'; +import { withRouter } from 'react-router-dom'; +import { compose } from 'redux'; import { getNetworkIdentifier, getPreferences, submittedPendingTransactionsSelector, -} from '../../selectors' +} from '../../selectors'; import { hideSidebar, lockMetamask, setCurrentCurrency, setLastActiveTime, setMouseUserState, -} from '../../store/actions' -import { pageChanged } from '../../ducks/history/history' -import { prepareToLeaveSwaps } from '../../ducks/swaps/swaps' -import Routes from './routes.component' +} from '../../store/actions'; +import { pageChanged } from '../../ducks/history/history'; +import { prepareToLeaveSwaps } from '../../ducks/swaps/swaps'; +import Routes from './routes.component'; function mapStateToProps(state) { - const { appState } = state + const { appState } = state; const { sidebar, alertOpen, alertMessage, isLoading, loadingMessage, - } = appState - const { autoLockTimeLimit = 0 } = getPreferences(state) + } = appState; + const { autoLockTimeLimit = 0 } = getPreferences(state); return { sidebar, @@ -44,7 +44,7 @@ function mapStateToProps(state) { isMouseUser: state.appState.isMouseUser, providerId: getNetworkIdentifier(state), autoLockTimeLimit, - } + }; } function mapDispatchToProps(dispatch) { @@ -57,10 +57,10 @@ function mapDispatchToProps(dispatch) { setLastActiveTime: () => dispatch(setLastActiveTime()), pageChanged: (path) => dispatch(pageChanged(path)), prepareToLeaveSwaps: () => dispatch(prepareToLeaveSwaps()), - } + }; } export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps), -)(Routes) +)(Routes); diff --git a/ui/app/pages/send/index.js b/ui/app/pages/send/index.js index b5114babc1..36fa285d44 100644 --- a/ui/app/pages/send/index.js +++ b/ui/app/pages/send/index.js @@ -1 +1 @@ -export { default } from './send.container' +export { default } from './send.container'; diff --git a/ui/app/pages/send/send-content/add-recipient/add-recipient.component.js b/ui/app/pages/send/send-content/add-recipient/add-recipient.component.js index 1c43d89279..a2126b552a 100644 --- a/ui/app/pages/send/send-content/add-recipient/add-recipient.component.js +++ b/ui/app/pages/send/send-content/add-recipient/add-recipient.component.js @@ -1,13 +1,13 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import Fuse from 'fuse.js' -import Identicon from '../../../../components/ui/identicon' -import { isValidAddress } from '../../../../helpers/utils/util' -import Dialog from '../../../../components/ui/dialog' -import ContactList from '../../../../components/app/contact-list' -import RecipientGroup from '../../../../components/app/contact-list/recipient-group/recipient-group.component' -import { ellipsify } from '../../send.utils' -import Button from '../../../../components/ui/button' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import Fuse from 'fuse.js'; +import Identicon from '../../../../components/ui/identicon'; +import { isValidAddress } from '../../../../helpers/utils/util'; +import Dialog from '../../../../components/ui/dialog'; +import ContactList from '../../../../components/app/contact-list'; +import RecipientGroup from '../../../../components/app/contact-list/recipient-group/recipient-group.component'; +import { ellipsify } from '../../send.utils'; +import Button from '../../../../components/ui/button'; export default class AddRecipient extends Component { static propTypes = { @@ -23,10 +23,10 @@ export default class AddRecipient extends Component { contacts: PropTypes.array, nonContacts: PropTypes.array, setInternalSearch: PropTypes.func, - } + }; constructor(props) { - super(props) + super(props); this.recentFuse = new Fuse(props.nonContacts, { shouldSort: true, threshold: 0.45, @@ -35,7 +35,7 @@ export default class AddRecipient extends Component { maxPatternLength: 32, minMatchCharLength: 1, keys: [{ name: 'address', weight: 0.5 }], - }) + }); this.contactFuse = new Fuse(props.contacts, { shouldSort: true, @@ -48,66 +48,66 @@ export default class AddRecipient extends Component { { name: 'name', weight: 0.5 }, { name: 'address', weight: 0.5 }, ], - }) + }); } static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; state = { isShowingTransfer: false, - } + }; selectRecipient = (to, nickname = '') => { - const { updateSendTo, updateGas } = this.props + const { updateSendTo, updateGas } = this.props; - updateSendTo(to, nickname) - updateGas({ to }) - } + updateSendTo(to, nickname); + updateGas({ to }); + }; searchForContacts = () => { - const { query, contacts } = this.props + const { query, contacts } = this.props; - let _contacts = contacts + let _contacts = contacts; if (query) { - this.contactFuse.setCollection(contacts) - _contacts = this.contactFuse.search(query) + this.contactFuse.setCollection(contacts); + _contacts = this.contactFuse.search(query); } - return _contacts - } + return _contacts; + }; searchForRecents = () => { - const { query, nonContacts } = this.props + const { query, nonContacts } = this.props; - let _nonContacts = nonContacts + let _nonContacts = nonContacts; if (query) { - this.recentFuse.setCollection(nonContacts) - _nonContacts = this.recentFuse.search(query) + this.recentFuse.setCollection(nonContacts); + _nonContacts = this.recentFuse.search(query); } - return _nonContacts - } + return _nonContacts; + }; render() { - const { ensResolution, query, addressBookEntryName } = this.props - const { isShowingTransfer } = this.state + const { ensResolution, query, addressBookEntryName } = this.props; + const { isShowingTransfer } = this.state; - let content + let content; if (isValidAddress(query)) { - content = this.renderExplicitAddress(query) + content = this.renderExplicitAddress(query); } else if (ensResolution) { content = this.renderExplicitAddress( ensResolution, addressBookEntryName || query, - ) + ); } else if (isShowingTransfer) { - content = this.renderTransfer() + content = this.renderTransfer(); } return ( @@ -115,7 +115,7 @@ export default class AddRecipient extends Component { {this.renderDialogs()} {content || this.renderMain()} - ) + ); } renderExplicitAddress(address, name) { @@ -137,21 +137,21 @@ export default class AddRecipient extends Component { )} - ) + ); } renderTransfer() { - let { ownedAccounts } = this.props - const { query, setInternalSearch } = this.props - const { t } = this.context - const { isShowingTransfer } = this.state + let { ownedAccounts } = this.props; + const { query, setInternalSearch } = this.props; + const { t } = this.context; + const { isShowingTransfer } = this.state; if (isShowingTransfer && query) { ownedAccounts = ownedAccounts.filter( (item) => item.name.toLowerCase().indexOf(query.toLowerCase()) > -1 || item.address.toLowerCase().indexOf(query.toLowerCase()) > -1, - ) + ); } return ( @@ -160,8 +160,8 @@ export default class AddRecipient extends Component { type="link" className="send__select-recipient-wrapper__list__link" onClick={() => { - setInternalSearch(false) - this.setState({ isShowingTransfer: false }) + setInternalSearch(false); + this.setState({ isShowingTransfer: false }); }} >
    @@ -173,17 +173,17 @@ export default class AddRecipient extends Component { onSelect={this.selectRecipient} />
    - ) + ); } renderMain() { - const { t } = this.context + const { t } = this.context; const { query, ownedAccounts = [], addressBook, setInternalSearch, - } = this.props + } = this.props; return (
    @@ -198,8 +198,8 @@ export default class AddRecipient extends Component { type="link" className="send__select-recipient-wrapper__list__link" onClick={() => { - setInternalSearch(true) - this.setState({ isShowingTransfer: true }) + setInternalSearch(true); + this.setState({ isShowingTransfer: true }); }} > {t('transferBetweenAccounts')} @@ -207,17 +207,17 @@ export default class AddRecipient extends Component { )}
    - ) + ); } renderDialogs() { - const { toError, ensResolutionError, ensResolution } = this.props - const { t } = this.context - const contacts = this.searchForContacts() - const recents = this.searchForRecents() + const { toError, ensResolutionError, ensResolution } = this.props; + const { t } = this.context; + const contacts = this.searchForContacts(); + const recents = this.searchForRecents(); if (contacts.length || recents.length) { - return null + return null; } if (ensResolutionError) { @@ -225,7 +225,7 @@ export default class AddRecipient extends Component { {ensResolutionError} - ) + ); } if (toError && toError !== 'required' && !ensResolution) { @@ -233,9 +233,9 @@ export default class AddRecipient extends Component { {t(toError)} - ) + ); } - return null + return null; } } diff --git a/ui/app/pages/send/send-content/add-recipient/add-recipient.container.js b/ui/app/pages/send/send-content/add-recipient/add-recipient.container.js index c3f1411830..2e3ea94fc0 100644 --- a/ui/app/pages/send/send-content/add-recipient/add-recipient.container.js +++ b/ui/app/pages/send/send-content/add-recipient/add-recipient.container.js @@ -1,31 +1,31 @@ -import { connect } from 'react-redux' +import { connect } from 'react-redux'; import { getSendEnsResolution, getSendEnsResolutionError, accountsWithSendEtherInfoSelector, getAddressBook, getAddressBookEntry, -} from '../../../../selectors' +} from '../../../../selectors'; -import { updateSendTo } from '../../../../store/actions' -import AddRecipient from './add-recipient.component' +import { updateSendTo } from '../../../../store/actions'; +import AddRecipient from './add-recipient.component'; -export default connect(mapStateToProps, mapDispatchToProps)(AddRecipient) +export default connect(mapStateToProps, mapDispatchToProps)(AddRecipient); function mapStateToProps(state) { - const ensResolution = getSendEnsResolution(state) + const ensResolution = getSendEnsResolution(state); - let addressBookEntryName = '' + let addressBookEntryName = ''; if (ensResolution) { - const addressBookEntry = getAddressBookEntry(state, ensResolution) || {} - addressBookEntryName = addressBookEntry.name + const addressBookEntry = getAddressBookEntry(state, ensResolution) || {}; + addressBookEntryName = addressBookEntry.name; } - const addressBook = getAddressBook(state) + const addressBook = getAddressBook(state); const ownedAccounts = accountsWithSendEtherInfoSelector(state).sort((a, b) => a.name.localeCompare(b.name), - ) + ); return { addressBook, @@ -35,11 +35,11 @@ function mapStateToProps(state) { ensResolutionError: getSendEnsResolutionError(state), nonContacts: addressBook.filter(({ name }) => !name), ownedAccounts, - } + }; } function mapDispatchToProps(dispatch) { return { updateSendTo: (to, nickname) => dispatch(updateSendTo(to, nickname)), - } + }; } diff --git a/ui/app/pages/send/send-content/add-recipient/add-recipient.js b/ui/app/pages/send/send-content/add-recipient/add-recipient.js index 47b64f7749..9a423e9749 100644 --- a/ui/app/pages/send/send-content/add-recipient/add-recipient.js +++ b/ui/app/pages/send/send-content/add-recipient/add-recipient.js @@ -1,41 +1,41 @@ -import ethUtil from 'ethereumjs-util' -import contractMap from '@metamask/contract-metadata' +import ethUtil from 'ethereumjs-util'; +import contractMap from '@metamask/contract-metadata'; import { REQUIRED_ERROR, INVALID_RECIPIENT_ADDRESS_ERROR, KNOWN_RECIPIENT_ADDRESS_ERROR, INVALID_RECIPIENT_ADDRESS_NOT_ETH_NETWORK_ERROR, -} from '../../send.constants' +} from '../../send.constants'; import { isValidAddress, isEthNetwork, checkExistingAddresses, -} from '../../../../helpers/utils/util' +} from '../../../../helpers/utils/util'; export function getToErrorObject(to, hasHexData = false, network) { - let toError = null + let toError = null; if (!to) { if (!hasHexData) { - toError = REQUIRED_ERROR + toError = REQUIRED_ERROR; } } else if (!isValidAddress(to) && !toError) { toError = isEthNetwork(network) ? INVALID_RECIPIENT_ADDRESS_ERROR - : INVALID_RECIPIENT_ADDRESS_NOT_ETH_NETWORK_ERROR + : INVALID_RECIPIENT_ADDRESS_NOT_ETH_NETWORK_ERROR; } - return { to: toError } + return { to: toError }; } export function getToWarningObject(to, tokens = [], sendToken = null) { - let toWarning = null + let toWarning = null; if ( sendToken && (ethUtil.toChecksumAddress(to) in contractMap || checkExistingAddresses(to, tokens)) ) { - toWarning = KNOWN_RECIPIENT_ADDRESS_ERROR + toWarning = KNOWN_RECIPIENT_ADDRESS_ERROR; } - return { to: toWarning } + return { to: toWarning }; } diff --git a/ui/app/pages/send/send-content/add-recipient/ens-input.component.js b/ui/app/pages/send/send-content/add-recipient/ens-input.component.js index a1d884e799..a0977406e8 100644 --- a/ui/app/pages/send/send-content/add-recipient/ens-input.component.js +++ b/ui/app/pages/send/send-content/add-recipient/ens-input.component.js @@ -1,28 +1,28 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' - -import { debounce } from 'lodash' -import copyToClipboard from 'copy-to-clipboard/index' -import ENS from 'ethjs-ens' -import networkMap from 'ethereum-ens-network-map' -import log from 'loglevel' -import { ellipsify } from '../../send.utils' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; + +import { debounce } from 'lodash'; +import copyToClipboard from 'copy-to-clipboard/index'; +import ENS from 'ethjs-ens'; +import networkMap from 'ethereum-ens-network-map'; +import log from 'loglevel'; +import { ellipsify } from '../../send.utils'; import { isValidDomainName, isValidAddress, isValidAddressHead, -} from '../../../../helpers/utils/util' -import { MAINNET_NETWORK_ID } from '../../../../../../shared/constants/network' +} from '../../../../helpers/utils/util'; +import { MAINNET_NETWORK_ID } from '../../../../../../shared/constants/network'; // Local Constants -const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' -const ZERO_X_ERROR_ADDRESS = '0x' +const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; +const ZERO_X_ERROR_ADDRESS = '0x'; export default class EnsInput extends Component { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { className: PropTypes.string, @@ -39,51 +39,51 @@ export default class EnsInput extends Component { contact: PropTypes.object, value: PropTypes.string, internalSearch: PropTypes.bool, - } + }; state = { input: '', toError: null, ensResolution: undefined, - } + }; componentDidMount() { - const { network, internalSearch } = this.props - const networkHasEnsSupport = getNetworkEnsSupport(network) - this.setState({ ensResolution: ZERO_ADDRESS }) + const { network, internalSearch } = this.props; + const networkHasEnsSupport = getNetworkEnsSupport(network); + this.setState({ ensResolution: ZERO_ADDRESS }); if (networkHasEnsSupport && !internalSearch) { - const provider = global.ethereumProvider - this.ens = new ENS({ provider, network }) - this.checkName = debounce(this.lookupEnsName, 200) + const provider = global.ethereumProvider; + this.ens = new ENS({ provider, network }); + this.checkName = debounce(this.lookupEnsName, 200); } } componentDidUpdate(prevProps) { - const { input } = this.state - const { network, value, internalSearch } = this.props + const { input } = this.state; + const { network, value, internalSearch } = this.props; - let newValue + let newValue; // Set the value of our input based on QR code provided by parent - const newProvidedValue = input !== value && prevProps.value !== value + const newProvidedValue = input !== value && prevProps.value !== value; if (newProvidedValue) { - newValue = value + newValue = value; } if (prevProps.network !== network) { - const provider = global.ethereumProvider - this.ens = new ENS({ provider, network }) + const provider = global.ethereumProvider; + this.ens = new ENS({ provider, network }); if (!newProvidedValue) { - newValue = input + newValue = input; } } if (newValue !== undefined) { - this.onChange({ target: { value: newValue } }) + this.onChange({ target: { value: newValue } }); } if (!internalSearch && prevProps.internalSearch) { - this.resetInput() + this.resetInput(); } } @@ -92,28 +92,28 @@ export default class EnsInput extends Component { updateEnsResolution, updateEnsResolutionError, onReset, - } = this.props - this.onChange({ target: { value: '' } }) - onReset() - updateEnsResolution('') - updateEnsResolutionError('') - } + } = this.props; + this.onChange({ target: { value: '' } }); + onReset(); + updateEnsResolution(''); + updateEnsResolutionError(''); + }; lookupEnsName = (ensName) => { - const { network } = this.props - const recipient = ensName.trim() + const { network } = this.props; + const recipient = ensName.trim(); - log.info(`ENS attempting to resolve name: ${recipient}`) + log.info(`ENS attempting to resolve name: ${recipient}`); this.ens .lookup(recipient) .then((address) => { if (address === ZERO_ADDRESS) { - throw new Error(this.context.t('noAddressForName')) + throw new Error(this.context.t('noAddressForName')); } if (address === ZERO_X_ERROR_ADDRESS) { - throw new Error(this.context.t('ensRegistrationError')) + throw new Error(this.context.t('ensRegistrationError')); } - this.props.updateEnsResolution(address) + this.props.updateEnsResolution(address); }) .catch((reason) => { if ( @@ -124,21 +124,21 @@ export default class EnsInput extends Component { network === MAINNET_NETWORK_ID ? this.context.t('noAddressForName') : this.context.t('ensNotFoundOnCurrentNetwork'), - ) + ); } else { - log.error(reason) - this.props.updateEnsResolutionError(reason.message) + log.error(reason); + this.props.updateEnsResolutionError(reason.message); } - }) - } + }); + }; onPaste = (event) => { event.clipboardData.items[0].getAsString((text) => { if (isValidAddress(text)) { - this.props.onPaste(text) + this.props.onPaste(text); } - }) - } + }); + }; onChange = (e) => { const { @@ -148,13 +148,13 @@ export default class EnsInput extends Component { updateEnsResolutionError, onValidAddressTyped, internalSearch, - } = this.props - const input = e.target.value - const networkHasEnsSupport = getNetworkEnsSupport(network) + } = this.props; + const input = e.target.value; + const networkHasEnsSupport = getNetworkEnsSupport(network); - this.setState({ input }, () => onChange(input)) + this.setState({ input }, () => onChange(input)); if (internalSearch) { - return null + return null; } // Empty ENS state if input is empty // maybe scan ENS @@ -164,31 +164,31 @@ export default class EnsInput extends Component { !isValidAddress(input) && !isValidAddressHead(input) ) { - updateEnsResolution('') + updateEnsResolution(''); updateEnsResolutionError( networkHasEnsSupport ? '' : 'Network does not support ENS', - ) - return null + ); + return null; } if (isValidDomainName(input)) { - this.lookupEnsName(input) + this.lookupEnsName(input); } else if (onValidAddressTyped && isValidAddress(input)) { - onValidAddressTyped(input) + onValidAddressTyped(input); } else { - updateEnsResolution('') - updateEnsResolutionError('') + updateEnsResolution(''); + updateEnsResolutionError(''); } - return null - } + return null; + }; render() { - const { t } = this.context - const { className, selectedAddress } = this.props - const { input } = this.state + const { t } = this.context; + const { className, selectedAddress } = this.props; + const { input } = this.state; if (selectedAddress) { - return this.renderSelected() + return this.renderSelected(); } return ( @@ -218,26 +218,26 @@ export default class EnsInput extends Component { })} onClick={() => { if (input) { - this.resetInput() + this.resetInput(); } else { - this.props.scanQrCode() + this.props.scanQrCode(); } }} /> - ) + ); } renderSelected() { - const { t } = this.context + const { t } = this.context; const { className, selectedAddress, selectedName, contact = {}, - } = this.props - const name = contact.name || selectedName + } = this.props; + const name = contact.name || selectedName; return (
    @@ -263,11 +263,11 @@ export default class EnsInput extends Component { />
    - ) + ); } ensIcon(recipient) { - const { hoverText } = this.state + const { hoverText } = this.state; return ( {this.ensIconContents(recipient)} - ) + ); } ensIconContents() { - const { loadingEns, ensFailure, ensResolution, toError } = this.state + const { loadingEns, ensFailure, ensResolution, toError } = this.state; if (toError) { - return null + return null; } if (loadingEns) { @@ -301,11 +301,11 @@ export default class EnsInput extends Component { transform: 'translateY(-6px)', }} /> - ) + ); } if (ensFailure) { - return + return ; } if (ensResolution && ensResolution !== ZERO_ADDRESS) { @@ -314,18 +314,18 @@ export default class EnsInput extends Component { className="fa fa-check-circle fa-lg cursor-pointer" style={{ color: 'green' }} onClick={(event) => { - event.preventDefault() - event.stopPropagation() - copyToClipboard(ensResolution) + event.preventDefault(); + event.stopPropagation(); + copyToClipboard(ensResolution); }} /> - ) + ); } - return null + return null; } } function getNetworkEnsSupport(network) { - return Boolean(networkMap[network]) + return Boolean(networkMap[network]); } diff --git a/ui/app/pages/send/send-content/add-recipient/ens-input.container.js b/ui/app/pages/send/send-content/add-recipient/ens-input.container.js index 712d54ecbf..f8ad890bc8 100644 --- a/ui/app/pages/send/send-content/add-recipient/ens-input.container.js +++ b/ui/app/pages/send/send-content/add-recipient/ens-input.container.js @@ -1,18 +1,18 @@ -import { connect } from 'react-redux' +import { connect } from 'react-redux'; import { getCurrentNetwork, getSendTo, getSendToNickname, getAddressBookEntry, -} from '../../../../selectors' -import EnsInput from './ens-input.component' +} from '../../../../selectors'; +import EnsInput from './ens-input.component'; export default connect((state) => { - const selectedAddress = getSendTo(state) + const selectedAddress = getSendTo(state); return { network: getCurrentNetwork(state), selectedAddress, selectedName: getSendToNickname(state), contact: getAddressBookEntry(state, selectedAddress), - } -})(EnsInput) + }; +})(EnsInput); diff --git a/ui/app/pages/send/send-content/add-recipient/ens-input.js b/ui/app/pages/send/send-content/add-recipient/ens-input.js index 6833ccd033..16c5c26ab8 100644 --- a/ui/app/pages/send/send-content/add-recipient/ens-input.js +++ b/ui/app/pages/send/send-content/add-recipient/ens-input.js @@ -1 +1 @@ -export { default } from './ens-input.container' +export { default } from './ens-input.container'; diff --git a/ui/app/pages/send/send-content/add-recipient/index.js b/ui/app/pages/send/send-content/add-recipient/index.js index d661bd74bd..81697dcc5b 100644 --- a/ui/app/pages/send/send-content/add-recipient/index.js +++ b/ui/app/pages/send/send-content/add-recipient/index.js @@ -1 +1 @@ -export { default } from './add-recipient.container' +export { default } from './add-recipient.container'; diff --git a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-component.test.js b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-component.test.js index fddaf3da73..7736969e93 100644 --- a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-component.test.js +++ b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-component.test.js @@ -1,9 +1,9 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import sinon from 'sinon' -import AddRecipient from '../add-recipient.component' -import Dialog from '../../../../../components/ui/dialog' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import AddRecipient from '../add-recipient.component'; +import Dialog from '../../../../../components/ui/dialog'; const propsMethodSpies = { closeToDropdown: sinon.spy(), @@ -12,11 +12,11 @@ const propsMethodSpies = { updateSendTo: sinon.spy(), updateSendToError: sinon.spy(), updateSendToWarning: sinon.spy(), -} +}; describe('AddRecipient Component', function () { - let wrapper - let instance + let wrapper; + let instance; beforeEach(function () { wrapper = shallow( @@ -53,60 +53,60 @@ describe('AddRecipient Component', function () { ]} />, { context: { t: (str) => `${str}_t` } }, - ) - instance = wrapper.instance() - }) + ); + instance = wrapper.instance(); + }); afterEach(function () { - propsMethodSpies.closeToDropdown.resetHistory() - propsMethodSpies.openToDropdown.resetHistory() - propsMethodSpies.updateSendTo.resetHistory() - propsMethodSpies.updateSendToError.resetHistory() - propsMethodSpies.updateSendToWarning.resetHistory() - propsMethodSpies.updateGas.resetHistory() - }) + propsMethodSpies.closeToDropdown.resetHistory(); + propsMethodSpies.openToDropdown.resetHistory(); + propsMethodSpies.updateSendTo.resetHistory(); + propsMethodSpies.updateSendToError.resetHistory(); + propsMethodSpies.updateSendToWarning.resetHistory(); + propsMethodSpies.updateGas.resetHistory(); + }); describe('selectRecipient', function () { it('should call updateSendTo', function () { - assert.strictEqual(propsMethodSpies.updateSendTo.callCount, 0) - instance.selectRecipient('mockTo2', 'mockNickname') - assert.strictEqual(propsMethodSpies.updateSendTo.callCount, 1) + assert.strictEqual(propsMethodSpies.updateSendTo.callCount, 0); + instance.selectRecipient('mockTo2', 'mockNickname'); + assert.strictEqual(propsMethodSpies.updateSendTo.callCount, 1); assert.deepStrictEqual(propsMethodSpies.updateSendTo.getCall(0).args, [ 'mockTo2', 'mockNickname', - ]) - }) + ]); + }); it('should call updateGas if there is no to error', function () { - assert.strictEqual(propsMethodSpies.updateGas.callCount, 0) - instance.selectRecipient(false) - assert.strictEqual(propsMethodSpies.updateGas.callCount, 1) - }) - }) + assert.strictEqual(propsMethodSpies.updateGas.callCount, 0); + instance.selectRecipient(false); + assert.strictEqual(propsMethodSpies.updateGas.callCount, 1); + }); + }); describe('render', function () { it('should render a component', function () { assert.strictEqual( wrapper.find('.send__select-recipient-wrapper').length, 1, - ) - }) + ); + }); it('should render no content if there are no recents, transfers, and contacts', function () { wrapper.setProps({ ownedAccounts: [], addressBook: [], - }) + }); assert.strictEqual( wrapper.find('.send__select-recipient-wrapper__list__link').length, 0, - ) + ); assert.strictEqual( wrapper.find('.send__select-recipient-wrapper__group').length, 0, - ) - }) + ); + }); it('should render transfer', function () { wrapper.setProps({ @@ -115,20 +115,20 @@ describe('AddRecipient Component', function () { { address: '0x124', name: '124' }, ], addressBook: [{ address: '0x456', name: 'test-name' }], - }) - wrapper.setState({ isShowingTransfer: true }) + }); + wrapper.setState({ isShowingTransfer: true }); const xferLink = wrapper.find( '.send__select-recipient-wrapper__list__link', - ) - assert.strictEqual(xferLink.length, 1) + ); + assert.strictEqual(xferLink.length, 1); - const groups = wrapper.find('RecipientGroup') + const groups = wrapper.find('RecipientGroup'); assert.strictEqual( groups.shallow().find('.send__select-recipient-wrapper__group').length, 1, - ) - }) + ); + }); it('should render ContactList', function () { wrapper.setProps({ @@ -137,12 +137,12 @@ describe('AddRecipient Component', function () { { address: '0x124', name: '124' }, ], addressBook: [{ address: '0x125' }], - }) + }); - const contactList = wrapper.find('ContactList') + const contactList = wrapper.find('ContactList'); - assert.strictEqual(contactList.length, 1) - }) + assert.strictEqual(contactList.length, 1); + }); it('should render contacts', function () { wrapper.setProps({ @@ -151,22 +151,22 @@ describe('AddRecipient Component', function () { { address: '0x126', name: 'alex' }, { address: '0x127', name: 'catherine' }, ], - }) - wrapper.setState({ isShowingTransfer: false }) + }); + wrapper.setState({ isShowingTransfer: false }); const xferLink = wrapper.find( '.send__select-recipient-wrapper__list__link', - ) - assert.strictEqual(xferLink.length, 0) + ); + assert.strictEqual(xferLink.length, 0); - const groups = wrapper.find('ContactList') - assert.strictEqual(groups.length, 1) + const groups = wrapper.find('ContactList'); + assert.strictEqual(groups.length, 1); assert.strictEqual( groups.find('.send__select-recipient-wrapper__group-item').length, 0, - ) - }) + ); + }); it('should render error when query has no results', function () { wrapper.setProps({ @@ -174,14 +174,14 @@ describe('AddRecipient Component', function () { toError: 'bad', contacts: [], nonContacts: [], - }) + }); - const dialog = wrapper.find(Dialog) + const dialog = wrapper.find(Dialog); - assert.strictEqual(dialog.props().type, 'error') - assert.strictEqual(dialog.props().children, 'bad_t') - assert.strictEqual(dialog.length, 1) - }) + assert.strictEqual(dialog.props().type, 'error'); + assert.strictEqual(dialog.props().children, 'bad_t'); + assert.strictEqual(dialog.length, 1); + }); it('should render error when query has ens does not resolve', function () { wrapper.setProps({ @@ -190,26 +190,26 @@ describe('AddRecipient Component', function () { ensResolutionError: 'very bad', contacts: [], nonContacts: [], - }) + }); - const dialog = wrapper.find(Dialog) + const dialog = wrapper.find(Dialog); - assert.strictEqual(dialog.props().type, 'error') - assert.strictEqual(dialog.props().children, 'very bad') - assert.strictEqual(dialog.length, 1) - }) + assert.strictEqual(dialog.props().type, 'error'); + assert.strictEqual(dialog.props().children, 'very bad'); + assert.strictEqual(dialog.length, 1); + }); it('should not render error when ens resolved', function () { wrapper.setProps({ addressBook: [], toError: 'bad', ensResolution: '0x128', - }) + }); - const dialog = wrapper.find(Dialog) + const dialog = wrapper.find(Dialog); - assert.strictEqual(dialog.length, 0) - }) + assert.strictEqual(dialog.length, 0); + }); it('should not render error when query has results', function () { wrapper.setProps({ @@ -219,11 +219,11 @@ describe('AddRecipient Component', function () { { address: '0x127', name: 'catherine' }, ], toError: 'bad', - }) + }); - const dialog = wrapper.find(Dialog) + const dialog = wrapper.find(Dialog); - assert.strictEqual(dialog.length, 0) - }) - }) -}) + assert.strictEqual(dialog.length, 0); + }); + }); +}); diff --git a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-container.test.js b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-container.test.js index f488b2f4ef..a7b4abeb8b 100644 --- a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-container.test.js +++ b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-container.test.js @@ -1,20 +1,20 @@ -import assert from 'assert' -import proxyquire from 'proxyquire' -import sinon from 'sinon' +import assert from 'assert'; +import proxyquire from 'proxyquire'; +import sinon from 'sinon'; -let mapStateToProps -let mapDispatchToProps +let mapStateToProps; +let mapDispatchToProps; const actionSpies = { updateSendTo: sinon.spy(), -} +}; proxyquire('../add-recipient.container.js', { 'react-redux': { connect: (ms, md) => { - mapStateToProps = ms - mapDispatchToProps = md - return () => ({}) + mapStateToProps = ms; + mapDispatchToProps = md; + return () => ({}); }, }, '../../../../selectors': { @@ -28,7 +28,7 @@ proxyquire('../add-recipient.container.js', { ], }, '../../../../store/actions': actionSpies, -}) +}); describe('add-recipient container', function () { describe('mapStateToProps()', function () { @@ -44,24 +44,24 @@ describe('add-recipient container', function () { ], addressBookEntryName: undefined, nonContacts: [], - }) - }) - }) + }); + }); + }); describe('mapDispatchToProps()', function () { describe('updateSendTo()', function () { - const dispatchSpy = sinon.spy() - const mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy) + const dispatchSpy = sinon.spy(); + const mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy); it('should dispatch an action', function () { - mapDispatchToPropsObject.updateSendTo('mockTo', 'mockNickname') - assert(dispatchSpy.calledOnce) - assert(actionSpies.updateSendTo.calledOnce) + mapDispatchToPropsObject.updateSendTo('mockTo', 'mockNickname'); + assert(dispatchSpy.calledOnce); + assert(actionSpies.updateSendTo.calledOnce); assert.deepStrictEqual(actionSpies.updateSendTo.getCall(0).args, [ 'mockTo', 'mockNickname', - ]) - }) - }) - }) -}) + ]); + }); + }); + }); +}); diff --git a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-utils.test.js b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-utils.test.js index bfd83cbd74..9d4947107b 100644 --- a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-utils.test.js +++ b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-utils.test.js @@ -1,52 +1,52 @@ -import assert from 'assert' -import proxyquire from 'proxyquire' -import sinon from 'sinon' +import assert from 'assert'; +import proxyquire from 'proxyquire'; +import sinon from 'sinon'; import { REQUIRED_ERROR, INVALID_RECIPIENT_ADDRESS_ERROR, KNOWN_RECIPIENT_ADDRESS_ERROR, -} from '../../../send.constants' +} from '../../../send.constants'; const stubs = { isValidAddress: sinon .stub() .callsFake((to) => Boolean(to.match(/^[0xabcdef123456798]+$/u))), -} +}; const toRowUtils = proxyquire('../add-recipient.js', { '../../../../helpers/utils/util': { isValidAddress: stubs.isValidAddress, }, -}) -const { getToErrorObject, getToWarningObject } = toRowUtils +}); +const { getToErrorObject, getToWarningObject } = toRowUtils; describe('add-recipient utils', function () { describe('getToErrorObject()', function () { it('should return a required error if "to" is falsy', function () { assert.deepStrictEqual(getToErrorObject(null), { to: REQUIRED_ERROR, - }) - }) + }); + }); it('should return null if "to" is falsy and hexData is truthy', function () { assert.deepStrictEqual(getToErrorObject(null, true), { to: null, - }) - }) + }); + }); it('should return an invalid recipient error if "to" is truthy but invalid', function () { assert.deepStrictEqual(getToErrorObject('mockInvalidTo'), { to: INVALID_RECIPIENT_ADDRESS_ERROR, - }) - }) + }); + }); it('should return null if "to" is truthy and valid', function () { assert.deepStrictEqual(getToErrorObject('0xabc123'), { to: null, - }) - }) - }) + }); + }); + }); describe('getToWarningObject()', function () { it('should return a known address recipient error if "to" is a token address', function () { @@ -57,8 +57,8 @@ describe('add-recipient utils', function () { { to: KNOWN_RECIPIENT_ADDRESS_ERROR, }, - ) - }) + ); + }); it('should null if "to" is a token address but sendToken is falsy', function () { assert.deepStrictEqual( @@ -66,8 +66,8 @@ describe('add-recipient utils', function () { { to: null, }, - ) - }) + ); + }); it('should return a known address recipient error if "to" is part of contract metadata', function () { assert.deepStrictEqual( @@ -79,8 +79,8 @@ describe('add-recipient utils', function () { { to: KNOWN_RECIPIENT_ADDRESS_ERROR, }, - ) - }) + ); + }); it('should null if "to" is part of contract metadata but sendToken is falsy', function () { assert.deepStrictEqual( getToWarningObject( @@ -91,7 +91,7 @@ describe('add-recipient utils', function () { { to: KNOWN_RECIPIENT_ADDRESS_ERROR, }, - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/ui/app/pages/send/send-content/index.js b/ui/app/pages/send/send-content/index.js index 542da4674f..c7c4479bb2 100644 --- a/ui/app/pages/send/send-content/index.js +++ b/ui/app/pages/send/send-content/index.js @@ -1 +1 @@ -export { default } from './send-content.container' +export { default } from './send-content.container'; diff --git a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.component.js b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.component.js index 7fbeb09a13..db520fcdce 100644 --- a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.component.js +++ b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.component.js @@ -1,6 +1,6 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; export default class AmountMaxButton extends Component { static propTypes = { @@ -14,12 +14,12 @@ export default class AmountMaxButton extends Component { setAmountToMax: PropTypes.func, setMaxModeTo: PropTypes.func, tokenBalance: PropTypes.string, - } + }; static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; setMaxAmount() { const { @@ -28,19 +28,19 @@ export default class AmountMaxButton extends Component { sendToken, setAmountToMax, tokenBalance, - } = this.props + } = this.props; setAmountToMax({ balance, gasTotal, sendToken, tokenBalance, - }) + }); } onMaxClick = () => { - const { setMaxModeTo, clearMaxAmount, maxModeOn } = this.props - const { metricsEvent } = this.context + const { setMaxModeTo, clearMaxAmount, maxModeOn } = this.props; + const { metricsEvent } = this.context; metricsEvent({ eventOpts: { @@ -48,18 +48,18 @@ export default class AmountMaxButton extends Component { action: 'Edit Screen', name: 'Clicked "Amount Max"', }, - }) + }); if (maxModeOn) { - setMaxModeTo(false) - clearMaxAmount() + setMaxModeTo(false); + clearMaxAmount(); } else { - setMaxModeTo(true) - this.setMaxAmount() + setMaxModeTo(true); + this.setMaxAmount(); } - } + }; render() { - const { maxModeOn, buttonDataLoading, inError } = this.props + const { maxModeOn, buttonDataLoading, inError } = this.props; return (
    - ) + ); } } diff --git a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.container.js b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.container.js index 3274734e45..593d3e57a0 100644 --- a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.container.js +++ b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.container.js @@ -1,4 +1,4 @@ -import { connect } from 'react-redux' +import { connect } from 'react-redux'; import { getGasTotal, getSendToken, @@ -6,13 +6,13 @@ import { getTokenBalance, getSendMaxModeState, getBasicGasEstimateLoadingStatus, -} from '../../../../../selectors' -import { updateSendAmount, setMaxModeTo } from '../../../../../store/actions' -import { updateSendErrors } from '../../../../../ducks/send/send.duck' -import { calcMaxAmount } from './amount-max-button.utils' -import AmountMaxButton from './amount-max-button.component' +} from '../../../../../selectors'; +import { updateSendAmount, setMaxModeTo } from '../../../../../store/actions'; +import { updateSendErrors } from '../../../../../ducks/send/send.duck'; +import { calcMaxAmount } from './amount-max-button.utils'; +import AmountMaxButton from './amount-max-button.component'; -export default connect(mapStateToProps, mapDispatchToProps)(AmountMaxButton) +export default connect(mapStateToProps, mapDispatchToProps)(AmountMaxButton); function mapStateToProps(state) { return { @@ -22,18 +22,18 @@ function mapStateToProps(state) { maxModeOn: getSendMaxModeState(state), sendToken: getSendToken(state), tokenBalance: getTokenBalance(state), - } + }; } function mapDispatchToProps(dispatch) { return { setAmountToMax: (maxAmountDataObject) => { - dispatch(updateSendErrors({ amount: null })) - dispatch(updateSendAmount(calcMaxAmount(maxAmountDataObject))) + dispatch(updateSendErrors({ amount: null })); + dispatch(updateSendAmount(calcMaxAmount(maxAmountDataObject))); }, clearMaxAmount: () => { - dispatch(updateSendAmount('0')) + dispatch(updateSendAmount('0')); }, setMaxModeTo: (bool) => dispatch(setMaxModeTo(bool)), - } + }; } diff --git a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.utils.js b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.utils.js index 39045a78e1..934e2fd0a2 100644 --- a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.utils.js +++ b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.utils.js @@ -1,12 +1,12 @@ import { multiplyCurrencies, subtractCurrencies, -} from '../../../../../helpers/utils/conversion-util' -import { addHexPrefix } from '../../../../../../../app/scripts/lib/util' +} from '../../../../../helpers/utils/conversion-util'; +import { addHexPrefix } from '../../../../../../../app/scripts/lib/util'; export function calcMaxAmount({ balance, gasTotal, sendToken, tokenBalance }) { - const { decimals } = sendToken || {} - const multiplier = Math.pow(10, Number(decimals || 0)) + const { decimals } = sendToken || {}; + const multiplier = Math.pow(10, Number(decimals || 0)); return sendToken ? multiplyCurrencies(tokenBalance, multiplier, { @@ -18,5 +18,5 @@ export function calcMaxAmount({ balance, gasTotal, sendToken, tokenBalance }) { toNumericBase: 'hex', aBase: 16, bBase: 16, - }) + }); } diff --git a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/index.js b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/index.js index ee8271494d..26d87ffb5c 100644 --- a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/index.js +++ b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/index.js @@ -1 +1 @@ -export { default } from './amount-max-button.container' +export { default } from './amount-max-button.container'; diff --git a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-component.test.js b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-component.test.js index fb040de644..42d7646a9f 100644 --- a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-component.test.js +++ b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-component.test.js @@ -1,23 +1,23 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import sinon from 'sinon' -import AmountMaxButton from '../amount-max-button.component' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import AmountMaxButton from '../amount-max-button.component'; describe('AmountMaxButton Component', function () { - let wrapper - let instance + let wrapper; + let instance; const propsMethodSpies = { setAmountToMax: sinon.spy(), setMaxModeTo: sinon.spy(), - } + }; - const MOCK_EVENT = { preventDefault: () => undefined } + const MOCK_EVENT = { preventDefault: () => undefined }; before(function () { - sinon.spy(AmountMaxButton.prototype, 'setMaxAmount') - }) + sinon.spy(AmountMaxButton.prototype, 'setMaxAmount'); + }); beforeEach(function () { wrapper = shallow( @@ -36,25 +36,25 @@ describe('AmountMaxButton Component', function () { metricsEvent: () => undefined, }, }, - ) - instance = wrapper.instance() - }) + ); + instance = wrapper.instance(); + }); afterEach(function () { - propsMethodSpies.setAmountToMax.resetHistory() - propsMethodSpies.setMaxModeTo.resetHistory() - AmountMaxButton.prototype.setMaxAmount.resetHistory() - }) + propsMethodSpies.setAmountToMax.resetHistory(); + propsMethodSpies.setMaxModeTo.resetHistory(); + AmountMaxButton.prototype.setMaxAmount.resetHistory(); + }); after(function () { - sinon.restore() - }) + sinon.restore(); + }); describe('setMaxAmount', function () { it('should call setAmountToMax with the correct params', function () { - assert.strictEqual(propsMethodSpies.setAmountToMax.callCount, 0) - instance.setMaxAmount() - assert.strictEqual(propsMethodSpies.setAmountToMax.callCount, 1) + assert.strictEqual(propsMethodSpies.setAmountToMax.callCount, 0); + instance.setMaxAmount(); + assert.strictEqual(propsMethodSpies.setAmountToMax.callCount, 1); assert.deepStrictEqual(propsMethodSpies.setAmountToMax.getCall(0).args, [ { balance: 'mockBalance', @@ -62,31 +62,31 @@ describe('AmountMaxButton Component', function () { sendToken: { address: 'mockTokenAddress' }, tokenBalance: 'mockTokenBalance', }, - ]) - }) - }) + ]); + }); + }); describe('render', function () { it('should render an element with a send-v2__amount-max class', function () { - assert(wrapper.exists('.send-v2__amount-max')) - }) + assert(wrapper.exists('.send-v2__amount-max')); + }); it('should call setMaxModeTo and setMaxAmount when the checkbox is checked', function () { - const { onClick } = wrapper.find('.send-v2__amount-max').props() + const { onClick } = wrapper.find('.send-v2__amount-max').props(); - assert.strictEqual(AmountMaxButton.prototype.setMaxAmount.callCount, 0) - assert.strictEqual(propsMethodSpies.setMaxModeTo.callCount, 0) - onClick(MOCK_EVENT) - assert.strictEqual(AmountMaxButton.prototype.setMaxAmount.callCount, 1) - assert.strictEqual(propsMethodSpies.setMaxModeTo.callCount, 1) + assert.strictEqual(AmountMaxButton.prototype.setMaxAmount.callCount, 0); + assert.strictEqual(propsMethodSpies.setMaxModeTo.callCount, 0); + onClick(MOCK_EVENT); + assert.strictEqual(AmountMaxButton.prototype.setMaxAmount.callCount, 1); + assert.strictEqual(propsMethodSpies.setMaxModeTo.callCount, 1); assert.deepStrictEqual(propsMethodSpies.setMaxModeTo.getCall(0).args, [ true, - ]) - }) + ]); + }); it('should render the expected text when maxModeOn is false', function () { - wrapper.setProps({ maxModeOn: false }) - assert.strictEqual(wrapper.find('.send-v2__amount-max').text(), 'max_t') - }) - }) -}) + wrapper.setProps({ maxModeOn: false }); + assert.strictEqual(wrapper.find('.send-v2__amount-max').text(), 'max_t'); + }); + }); +}); diff --git a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-container.test.js b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-container.test.js index ba5325a436..c09e329854 100644 --- a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-container.test.js +++ b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-container.test.js @@ -1,24 +1,24 @@ -import assert from 'assert' -import proxyquire from 'proxyquire' -import sinon from 'sinon' +import assert from 'assert'; +import proxyquire from 'proxyquire'; +import sinon from 'sinon'; -let mapStateToProps -let mapDispatchToProps +let mapStateToProps; +let mapDispatchToProps; const actionSpies = { setMaxModeTo: sinon.spy(), updateSendAmount: sinon.spy(), -} +}; const duckActionSpies = { updateSendErrors: sinon.spy(), -} +}; proxyquire('../amount-max-button.container.js', { 'react-redux': { connect: (ms, md) => { - mapStateToProps = ms - mapDispatchToProps = md - return () => ({}) + mapStateToProps = ms; + mapDispatchToProps = md; + return () => ({}); }, }, '../../../../../selectors': { @@ -34,7 +34,7 @@ proxyquire('../amount-max-button.container.js', { }, '../../../../../store/actions': actionSpies, '../../../../../ducks/send/send.duck': duckActionSpies, -}) +}); describe('amount-max-button container', function () { describe('mapStateToProps()', function () { @@ -46,44 +46,44 @@ describe('amount-max-button container', function () { maxModeOn: 'mockMaxModeOn:mockState', sendToken: 'mockSendToken:mockState', tokenBalance: 'mockTokenBalance:mockState', - }) - }) - }) + }); + }); + }); describe('mapDispatchToProps()', function () { - let dispatchSpy - let mapDispatchToPropsObject + let dispatchSpy; + let mapDispatchToPropsObject; beforeEach(function () { - dispatchSpy = sinon.spy() - mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy) - }) + dispatchSpy = sinon.spy(); + mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy); + }); describe('setAmountToMax()', function () { it('should dispatch an action', function () { - mapDispatchToPropsObject.setAmountToMax({ val: 11, foo: 'bar' }) - assert(dispatchSpy.calledTwice) - assert(duckActionSpies.updateSendErrors.calledOnce) + mapDispatchToPropsObject.setAmountToMax({ val: 11, foo: 'bar' }); + assert(dispatchSpy.calledTwice); + assert(duckActionSpies.updateSendErrors.calledOnce); assert.deepStrictEqual( duckActionSpies.updateSendErrors.getCall(0).args[0], { amount: null, }, - ) - assert(actionSpies.updateSendAmount.calledOnce) - assert.strictEqual(actionSpies.updateSendAmount.getCall(0).args[0], 12) - }) - }) + ); + assert(actionSpies.updateSendAmount.calledOnce); + assert.strictEqual(actionSpies.updateSendAmount.getCall(0).args[0], 12); + }); + }); describe('setMaxModeTo()', function () { it('should dispatch an action', function () { - mapDispatchToPropsObject.setMaxModeTo('mockVal') - assert(dispatchSpy.calledOnce) + mapDispatchToPropsObject.setMaxModeTo('mockVal'); + assert(dispatchSpy.calledOnce); assert.strictEqual( actionSpies.setMaxModeTo.getCall(0).args[0], 'mockVal', - ) - }) - }) - }) -}) + ); + }); + }); + }); +}); diff --git a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-utils.test.js b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-utils.test.js index c99f0449c3..e663951888 100644 --- a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-utils.test.js +++ b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-utils.test.js @@ -1,5 +1,5 @@ -import assert from 'assert' -import { calcMaxAmount } from '../amount-max-button.utils' +import assert from 'assert'; +import { calcMaxAmount } from '../amount-max-button.utils'; describe('amount-max-button utils', function () { describe('calcMaxAmount()', function () { @@ -11,8 +11,8 @@ describe('amount-max-button utils', function () { sendToken: false, }), 'ffff00', - ) - }) + ); + }); it('should calculate the correct amount when a sendToken is defined', function () { assert.deepStrictEqual( @@ -23,7 +23,7 @@ describe('amount-max-button utils', function () { tokenBalance: '64', }), 'e8d4a51000', - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/ui/app/pages/send/send-content/send-amount-row/index.js b/ui/app/pages/send/send-content/send-amount-row/index.js index abc6852fe9..8f8a60ad26 100644 --- a/ui/app/pages/send/send-content/send-amount-row/index.js +++ b/ui/app/pages/send/send-content/send-amount-row/index.js @@ -1 +1 @@ -export { default } from './send-amount-row.container' +export { default } from './send-amount-row.container'; diff --git a/ui/app/pages/send/send-content/send-amount-row/send-amount-row.component.js b/ui/app/pages/send/send-content/send-amount-row/send-amount-row.component.js index 0e03ac2c02..3f3d64e45b 100644 --- a/ui/app/pages/send/send-content/send-amount-row/send-amount-row.component.js +++ b/ui/app/pages/send/send-content/send-amount-row/send-amount-row.component.js @@ -1,10 +1,10 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import { debounce } from 'lodash' -import SendRowWrapper from '../send-row-wrapper' -import UserPreferencedCurrencyInput from '../../../../components/app/user-preferenced-currency-input' -import UserPreferencedTokenInput from '../../../../components/app/user-preferenced-token-input' -import AmountMaxButton from './amount-max-button' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { debounce } from 'lodash'; +import SendRowWrapper from '../send-row-wrapper'; +import UserPreferencedCurrencyInput from '../../../../components/app/user-preferenced-currency-input'; +import UserPreferencedTokenInput from '../../../../components/app/user-preferenced-token-input'; +import AmountMaxButton from './amount-max-button'; export default class SendAmountRow extends Component { static propTypes = { @@ -22,26 +22,26 @@ export default class SendAmountRow extends Component { updateSendAmountError: PropTypes.func, updateGas: PropTypes.func, maxModeOn: PropTypes.bool, - } + }; static contextTypes = { t: PropTypes.func, - } + }; componentDidUpdate(prevProps) { - const { maxModeOn: prevMaxModeOn, gasTotal: prevGasTotal } = prevProps - const { maxModeOn, amount, gasTotal, sendToken } = this.props + const { maxModeOn: prevMaxModeOn, gasTotal: prevGasTotal } = prevProps; + const { maxModeOn, amount, gasTotal, sendToken } = this.props; if (maxModeOn && sendToken && !prevMaxModeOn) { - this.updateGas(amount) + this.updateGas(amount); } if (prevGasTotal !== gasTotal) { - this.validateAmount(amount) + this.validateAmount(amount); } } - updateGas = debounce(this.updateGas.bind(this), 500) + updateGas = debounce(this.updateGas.bind(this), 500); validateAmount(amount) { const { @@ -53,7 +53,7 @@ export default class SendAmountRow extends Component { tokenBalance, updateGasFeeError, updateSendAmountError, - } = this.props + } = this.props; updateSendAmountError({ amount, @@ -63,7 +63,7 @@ export default class SendAmountRow extends Component { primaryCurrency, sendToken, tokenBalance, - }) + }); if (sendToken) { updateGasFeeError({ @@ -73,33 +73,33 @@ export default class SendAmountRow extends Component { primaryCurrency, sendToken, tokenBalance, - }) + }); } } updateAmount(amount) { - const { updateSendAmount, setMaxModeTo } = this.props + const { updateSendAmount, setMaxModeTo } = this.props; - setMaxModeTo(false) - updateSendAmount(amount) + setMaxModeTo(false); + updateSendAmount(amount); } updateGas(amount) { - const { sendToken, updateGas } = this.props + const { sendToken, updateGas } = this.props; if (sendToken) { - updateGas({ amount }) + updateGas({ amount }); } } handleChange = (newAmount) => { - this.validateAmount(newAmount) - this.updateGas(newAmount) - this.updateAmount(newAmount) - } + this.validateAmount(newAmount); + this.updateGas(newAmount); + this.updateAmount(newAmount); + }; renderInput() { - const { amount, inError, sendToken } = this.props + const { amount, inError, sendToken } = this.props; return sendToken ? ( - ) + ); } render() { - const { gasTotal, inError } = this.props + const { gasTotal, inError } = this.props; return ( } {this.renderInput()} - ) + ); } } diff --git a/ui/app/pages/send/send-content/send-amount-row/send-amount-row.container.js b/ui/app/pages/send/send-content/send-amount-row/send-amount-row.container.js index 3c73c20ca6..f2d5b2e06a 100644 --- a/ui/app/pages/send/send-content/send-amount-row/send-amount-row.container.js +++ b/ui/app/pages/send/send-content/send-amount-row/send-amount-row.container.js @@ -1,4 +1,4 @@ -import { connect } from 'react-redux' +import { connect } from 'react-redux'; import { getConversionRate, getGasTotal, @@ -9,13 +9,13 @@ import { getTokenBalance, getSendMaxModeState, sendAmountIsInError, -} from '../../../../selectors' -import { getAmountErrorObject, getGasFeeErrorObject } from '../../send.utils' -import { setMaxModeTo, updateSendAmount } from '../../../../store/actions' -import { updateSendErrors } from '../../../../ducks/send/send.duck' -import SendAmountRow from './send-amount-row.component' +} from '../../../../selectors'; +import { getAmountErrorObject, getGasFeeErrorObject } from '../../send.utils'; +import { setMaxModeTo, updateSendAmount } from '../../../../store/actions'; +import { updateSendErrors } from '../../../../ducks/send/send.duck'; +import SendAmountRow from './send-amount-row.component'; -export default connect(mapStateToProps, mapDispatchToProps)(SendAmountRow) +export default connect(mapStateToProps, mapDispatchToProps)(SendAmountRow); function mapStateToProps(state) { return { @@ -28,7 +28,7 @@ function mapStateToProps(state) { sendToken: getSendToken(state), tokenBalance: getTokenBalance(state), maxModeOn: getSendMaxModeState(state), - } + }; } function mapDispatchToProps(dispatch) { @@ -36,10 +36,10 @@ function mapDispatchToProps(dispatch) { setMaxModeTo: (bool) => dispatch(setMaxModeTo(bool)), updateSendAmount: (newAmount) => dispatch(updateSendAmount(newAmount)), updateGasFeeError: (amountDataObject) => { - dispatch(updateSendErrors(getGasFeeErrorObject(amountDataObject))) + dispatch(updateSendErrors(getGasFeeErrorObject(amountDataObject))); }, updateSendAmountError: (amountDataObject) => { - dispatch(updateSendErrors(getAmountErrorObject(amountDataObject))) + dispatch(updateSendErrors(getAmountErrorObject(amountDataObject))); }, - } + }; } diff --git a/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-component.test.js b/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-component.test.js index 27c4b3bd94..fd78890047 100644 --- a/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-component.test.js +++ b/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-component.test.js @@ -1,12 +1,12 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import sinon from 'sinon' -import SendAmountRow from '../send-amount-row.component' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import SendAmountRow from '../send-amount-row.component'; -import SendRowWrapper from '../../send-row-wrapper/send-row-wrapper.component' -import AmountMaxButton from '../amount-max-button/amount-max-button.container' -import UserPreferencedTokenInput from '../../../../../components/app/user-preferenced-token-input' +import SendRowWrapper from '../../send-row-wrapper/send-row-wrapper.component'; +import AmountMaxButton from '../amount-max-button/amount-max-button.container'; +import UserPreferencedTokenInput from '../../../../../components/app/user-preferenced-token-input'; describe('SendAmountRow Component', function () { describe('validateAmount', function () { @@ -14,11 +14,11 @@ describe('SendAmountRow Component', function () { const { instance, propsMethodSpies: { updateSendAmountError }, - } = shallowRenderSendAmountRow() + } = shallowRenderSendAmountRow(); - assert.strictEqual(updateSendAmountError.callCount, 0) + assert.strictEqual(updateSendAmountError.callCount, 0); - instance.validateAmount('someAmount') + instance.validateAmount('someAmount'); assert.ok( updateSendAmountError.calledOnceWithExactly({ @@ -30,18 +30,18 @@ describe('SendAmountRow Component', function () { sendToken: { address: 'mockTokenAddress' }, tokenBalance: 'mockTokenBalance', }), - ) - }) + ); + }); it('should call updateGasFeeError if sendToken is truthy', function () { const { instance, propsMethodSpies: { updateGasFeeError }, - } = shallowRenderSendAmountRow() + } = shallowRenderSendAmountRow(); - assert.strictEqual(updateGasFeeError.callCount, 0) + assert.strictEqual(updateGasFeeError.callCount, 0); - instance.validateAmount('someAmount') + instance.validateAmount('someAmount'); assert.ok( updateGasFeeError.calledOnceWithExactly({ @@ -52,116 +52,116 @@ describe('SendAmountRow Component', function () { sendToken: { address: 'mockTokenAddress' }, tokenBalance: 'mockTokenBalance', }), - ) - }) + ); + }); it('should call not updateGasFeeError if sendToken is falsey', function () { const { wrapper, instance, propsMethodSpies: { updateGasFeeError }, - } = shallowRenderSendAmountRow() + } = shallowRenderSendAmountRow(); - wrapper.setProps({ sendToken: null }) + wrapper.setProps({ sendToken: null }); - assert.strictEqual(updateGasFeeError.callCount, 0) + assert.strictEqual(updateGasFeeError.callCount, 0); - instance.validateAmount('someAmount') + instance.validateAmount('someAmount'); - assert.strictEqual(updateGasFeeError.callCount, 0) - }) - }) + assert.strictEqual(updateGasFeeError.callCount, 0); + }); + }); describe('updateAmount', function () { it('should call setMaxModeTo', function () { const { instance, propsMethodSpies: { setMaxModeTo }, - } = shallowRenderSendAmountRow() + } = shallowRenderSendAmountRow(); - assert.strictEqual(setMaxModeTo.callCount, 0) + assert.strictEqual(setMaxModeTo.callCount, 0); - instance.updateAmount('someAmount') + instance.updateAmount('someAmount'); - assert.ok(setMaxModeTo.calledOnceWithExactly(false)) - }) + assert.ok(setMaxModeTo.calledOnceWithExactly(false)); + }); it('should call updateSendAmount', function () { const { instance, propsMethodSpies: { updateSendAmount }, - } = shallowRenderSendAmountRow() + } = shallowRenderSendAmountRow(); - assert.strictEqual(updateSendAmount.callCount, 0) + assert.strictEqual(updateSendAmount.callCount, 0); - instance.updateAmount('someAmount') + instance.updateAmount('someAmount'); - assert.ok(updateSendAmount.calledOnceWithExactly('someAmount')) - }) - }) + assert.ok(updateSendAmount.calledOnceWithExactly('someAmount')); + }); + }); describe('render', function () { it('should render a SendRowWrapper component', function () { - const { wrapper } = shallowRenderSendAmountRow() + const { wrapper } = shallowRenderSendAmountRow(); - assert.strictEqual(wrapper.find(SendRowWrapper).length, 1) - }) + assert.strictEqual(wrapper.find(SendRowWrapper).length, 1); + }); it('should pass the correct props to SendRowWrapper', function () { - const { wrapper } = shallowRenderSendAmountRow() + const { wrapper } = shallowRenderSendAmountRow(); const { errorType, label, showError } = wrapper .find(SendRowWrapper) - .props() + .props(); - assert.strictEqual(errorType, 'amount') - assert.strictEqual(label, 'amount_t:') - assert.strictEqual(showError, false) - }) + assert.strictEqual(errorType, 'amount'); + assert.strictEqual(label, 'amount_t:'); + assert.strictEqual(showError, false); + }); it('should render an AmountMaxButton as the first child of the SendRowWrapper', function () { - const { wrapper } = shallowRenderSendAmountRow() + const { wrapper } = shallowRenderSendAmountRow(); - assert(wrapper.find(SendRowWrapper).childAt(0).is(AmountMaxButton)) - }) + assert(wrapper.find(SendRowWrapper).childAt(0).is(AmountMaxButton)); + }); it('should render a UserPreferencedTokenInput as the second child of the SendRowWrapper', function () { - const { wrapper } = shallowRenderSendAmountRow() + const { wrapper } = shallowRenderSendAmountRow(); assert( wrapper.find(SendRowWrapper).childAt(1).is(UserPreferencedTokenInput), - ) - }) + ); + }); it('should render the UserPreferencedTokenInput with the correct props', function () { const { wrapper, instanceSpies: { updateGas, updateAmount, validateAmount }, - } = shallowRenderSendAmountRow() + } = shallowRenderSendAmountRow(); const { onChange, error, value } = wrapper .find(SendRowWrapper) .childAt(1) - .props() + .props(); - assert.strictEqual(error, false) - assert.strictEqual(value, 'mockAmount') - assert.strictEqual(updateGas.callCount, 0) - assert.strictEqual(updateAmount.callCount, 0) - assert.strictEqual(validateAmount.callCount, 0) + assert.strictEqual(error, false); + assert.strictEqual(value, 'mockAmount'); + assert.strictEqual(updateGas.callCount, 0); + assert.strictEqual(updateAmount.callCount, 0); + assert.strictEqual(validateAmount.callCount, 0); - onChange('mockNewAmount') + onChange('mockNewAmount'); - assert.ok(updateGas.calledOnceWithExactly('mockNewAmount')) - assert.ok(updateAmount.calledOnceWithExactly('mockNewAmount')) - assert.ok(validateAmount.calledOnceWithExactly('mockNewAmount')) - }) - }) -}) + assert.ok(updateGas.calledOnceWithExactly('mockNewAmount')); + assert.ok(updateAmount.calledOnceWithExactly('mockNewAmount')); + assert.ok(validateAmount.calledOnceWithExactly('mockNewAmount')); + }); + }); +}); function shallowRenderSendAmountRow() { - const setMaxModeTo = sinon.spy() - const updateGasFeeError = sinon.spy() - const updateSendAmount = sinon.spy() - const updateSendAmountError = sinon.spy() + const setMaxModeTo = sinon.spy(); + const updateGasFeeError = sinon.spy(); + const updateSendAmount = sinon.spy(); + const updateSendAmountError = sinon.spy(); const wrapper = shallow( undefined} />, { context: { t: (str) => `${str}_t` } }, - ) - const instance = wrapper.instance() - const updateAmount = sinon.spy(instance, 'updateAmount') - const updateGas = sinon.spy(instance, 'updateGas') - const validateAmount = sinon.spy(instance, 'validateAmount') + ); + const instance = wrapper.instance(); + const updateAmount = sinon.spy(instance, 'updateAmount'); + const updateGas = sinon.spy(instance, 'updateGas'); + const validateAmount = sinon.spy(instance, 'validateAmount'); return { instance, @@ -200,5 +200,5 @@ function shallowRenderSendAmountRow() { updateGas, validateAmount, }, - } + }; } diff --git a/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-container.test.js b/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-container.test.js index 3137ef1b45..5e29554ba0 100644 --- a/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-container.test.js +++ b/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-container.test.js @@ -1,22 +1,22 @@ -import assert from 'assert' -import proxyquire from 'proxyquire' -import sinon from 'sinon' +import assert from 'assert'; +import proxyquire from 'proxyquire'; +import sinon from 'sinon'; -let mapDispatchToProps +let mapDispatchToProps; const actionSpies = { setMaxModeTo: sinon.spy(), updateSendAmount: sinon.spy(), -} +}; const duckActionSpies = { updateSendErrors: sinon.spy(), -} +}; proxyquire('../send-amount-row.container.js', { 'react-redux': { connect: (_, md) => { - mapDispatchToProps = md - return () => ({}) + mapDispatchToProps = md; + return () => ({}); }, }, '../../../../selectors': { sendAmountIsInError: (s) => `mockInError:${s}` }, @@ -32,71 +32,71 @@ proxyquire('../send-amount-row.container.js', { }, '../../../../store/actions': actionSpies, '../../../../ducks/send/send.duck': duckActionSpies, -}) +}); describe('send-amount-row container', function () { describe('mapDispatchToProps()', function () { - let dispatchSpy - let mapDispatchToPropsObject + let dispatchSpy; + let mapDispatchToPropsObject; beforeEach(function () { - dispatchSpy = sinon.spy() - mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy) - duckActionSpies.updateSendErrors.resetHistory() - }) + dispatchSpy = sinon.spy(); + mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy); + duckActionSpies.updateSendErrors.resetHistory(); + }); describe('setMaxModeTo()', function () { it('should dispatch an action', function () { - mapDispatchToPropsObject.setMaxModeTo('mockBool') - assert(dispatchSpy.calledOnce) - assert(actionSpies.setMaxModeTo.calledOnce) + mapDispatchToPropsObject.setMaxModeTo('mockBool'); + assert(dispatchSpy.calledOnce); + assert(actionSpies.setMaxModeTo.calledOnce); assert.strictEqual( actionSpies.setMaxModeTo.getCall(0).args[0], 'mockBool', - ) - }) - }) + ); + }); + }); describe('updateSendAmount()', function () { it('should dispatch an action', function () { - mapDispatchToPropsObject.updateSendAmount('mockAmount') - assert(dispatchSpy.calledOnce) - assert(actionSpies.updateSendAmount.calledOnce) + mapDispatchToPropsObject.updateSendAmount('mockAmount'); + assert(dispatchSpy.calledOnce); + assert(actionSpies.updateSendAmount.calledOnce); assert.strictEqual( actionSpies.updateSendAmount.getCall(0).args[0], 'mockAmount', - ) - }) - }) + ); + }); + }); describe('updateGasFeeError()', function () { it('should dispatch an action', function () { - mapDispatchToPropsObject.updateGasFeeError({ some: 'data' }) - assert(dispatchSpy.calledOnce) - assert(duckActionSpies.updateSendErrors.calledOnce) + mapDispatchToPropsObject.updateGasFeeError({ some: 'data' }); + assert(dispatchSpy.calledOnce); + assert(duckActionSpies.updateSendErrors.calledOnce); assert.deepStrictEqual( duckActionSpies.updateSendErrors.getCall(0).args[0], { some: 'data', mockGasFeeErrorChange: true, }, - ) - }) - }) + ); + }); + }); describe('updateSendAmountError()', function () { it('should dispatch an action', function () { - mapDispatchToPropsObject.updateSendAmountError({ some: 'data' }) - assert(dispatchSpy.calledOnce) - assert(duckActionSpies.updateSendErrors.calledOnce) + mapDispatchToPropsObject.updateSendAmountError({ some: 'data' }); + assert(dispatchSpy.calledOnce); + assert(duckActionSpies.updateSendErrors.calledOnce); assert.deepStrictEqual( duckActionSpies.updateSendErrors.getCall(0).args[0], { some: 'data', mockChange: true, }, - ) - }) - }) - }) -}) + ); + }); + }); + }); +}); diff --git a/ui/app/pages/send/send-content/send-asset-row/index.js b/ui/app/pages/send/send-content/send-asset-row/index.js index ba424a0836..0d1d458921 100644 --- a/ui/app/pages/send/send-content/send-asset-row/index.js +++ b/ui/app/pages/send/send-content/send-asset-row/index.js @@ -1 +1 @@ -export { default } from './send-asset-row.container' +export { default } from './send-asset-row.container'; diff --git a/ui/app/pages/send/send-content/send-asset-row/send-asset-row.component.js b/ui/app/pages/send/send-content/send-asset-row/send-asset-row.component.js index abd6d14583..870ff79e81 100644 --- a/ui/app/pages/send/send-content/send-asset-row/send-asset-row.component.js +++ b/ui/app/pages/send/send-content/send-asset-row/send-asset-row.component.js @@ -1,10 +1,10 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import SendRowWrapper from '../send-row-wrapper' -import Identicon from '../../../../components/ui/identicon/identicon.component' -import TokenBalance from '../../../../components/ui/token-balance' -import UserPreferencedCurrencyDisplay from '../../../../components/app/user-preferenced-currency-display' -import { PRIMARY } from '../../../../helpers/constants/common' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import SendRowWrapper from '../send-row-wrapper'; +import Identicon from '../../../../components/ui/identicon/identicon.component'; +import TokenBalance from '../../../../components/ui/token-balance'; +import UserPreferencedCurrencyDisplay from '../../../../components/app/user-preferenced-currency-display'; +import { PRIMARY } from '../../../../helpers/constants/common'; export default class SendAssetRow extends Component { static propTypes = { @@ -19,20 +19,20 @@ export default class SendAssetRow extends Component { selectedAddress: PropTypes.string.isRequired, sendTokenAddress: PropTypes.string, setSendToken: PropTypes.func.isRequired, - } + }; static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; state = { isShowingDropdown: false, - } + }; - openDropdown = () => this.setState({ isShowingDropdown: true }) + openDropdown = () => this.setState({ isShowingDropdown: true }); - closeDropdown = () => this.setState({ isShowingDropdown: false }) + closeDropdown = () => this.setState({ isShowingDropdown: false }); selectToken = (token) => { this.setState( @@ -49,14 +49,14 @@ export default class SendAssetRow extends Component { customVariables: { assetSelected: token ? 'ERC20' : 'ETH', }, - }) - this.props.setSendToken(token) + }); + this.props.setSendToken(token); }, - ) - } + ); + }; render() { - const { t } = this.context + const { t } = this.context; return ( @@ -65,14 +65,14 @@ export default class SendAssetRow extends Component { {this.props.tokens.length > 0 ? this.renderAssetDropdown() : null} - ) + ); } renderSendToken() { - const { sendTokenAddress } = this.props + const { sendTokenAddress } = this.props; const token = this.props.tokens.find( ({ address }) => address === sendTokenAddress, - ) + ); return (
    {token ? this.renderAsset(token) : this.renderEth()}
    - ) + ); } renderAssetDropdown() { @@ -97,16 +97,16 @@ export default class SendAssetRow extends Component { ) - ) + ); } renderEth(insideDropdown = false) { - const { t } = this.context - const { accounts, selectedAddress } = this.props + const { t } = this.context; + const { accounts, selectedAddress } = this.props; const balanceValue = accounts[selectedAddress] ? accounts[selectedAddress].balance - : '' + : ''; return (
    )}
    - ) + ); } renderAsset(token, insideDropdown = false) { - const { address, symbol } = token - const { t } = this.context + const { address, symbol } = token; + const { t } = this.context; return (
    )}
    - ) + ); } } diff --git a/ui/app/pages/send/send-content/send-asset-row/send-asset-row.container.js b/ui/app/pages/send/send-content/send-asset-row/send-asset-row.container.js index 1fe7f7bf48..05a2d4a233 100644 --- a/ui/app/pages/send/send-content/send-asset-row/send-asset-row.container.js +++ b/ui/app/pages/send/send-content/send-asset-row/send-asset-row.container.js @@ -1,7 +1,10 @@ -import { connect } from 'react-redux' -import { getMetaMaskAccounts, getSendTokenAddress } from '../../../../selectors' -import { updateSendToken } from '../../../../store/actions' -import SendAssetRow from './send-asset-row.component' +import { connect } from 'react-redux'; +import { + getMetaMaskAccounts, + getSendTokenAddress, +} from '../../../../selectors'; +import { updateSendToken } from '../../../../store/actions'; +import SendAssetRow from './send-asset-row.component'; function mapStateToProps(state) { return { @@ -9,13 +12,13 @@ function mapStateToProps(state) { selectedAddress: state.metamask.selectedAddress, sendTokenAddress: getSendTokenAddress(state), accounts: getMetaMaskAccounts(state), - } + }; } function mapDispatchToProps(dispatch) { return { setSendToken: (token) => dispatch(updateSendToken(token)), - } + }; } -export default connect(mapStateToProps, mapDispatchToProps)(SendAssetRow) +export default connect(mapStateToProps, mapDispatchToProps)(SendAssetRow); diff --git a/ui/app/pages/send/send-content/send-content.component.js b/ui/app/pages/send/send-content/send-content.component.js index 4a4aaad40d..2dee77e658 100644 --- a/ui/app/pages/send/send-content/send-content.component.js +++ b/ui/app/pages/send/send-content/send-content.component.js @@ -1,16 +1,16 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import PageContainerContent from '../../../components/ui/page-container/page-container-content.component' -import Dialog from '../../../components/ui/dialog' -import SendAmountRow from './send-amount-row' -import SendGasRow from './send-gas-row' -import SendHexDataRow from './send-hex-data-row' -import SendAssetRow from './send-asset-row' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import PageContainerContent from '../../../components/ui/page-container/page-container-content.component'; +import Dialog from '../../../components/ui/dialog'; +import SendAmountRow from './send-amount-row'; +import SendGasRow from './send-gas-row'; +import SendHexDataRow from './send-hex-data-row'; +import SendAssetRow from './send-asset-row'; export default class SendContent extends Component { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { updateGas: PropTypes.func, @@ -19,12 +19,12 @@ export default class SendContent extends Component { contact: PropTypes.object, isOwnedAccount: PropTypes.bool, warning: PropTypes.string, - } + }; - updateGas = (updateData) => this.props.updateGas(updateData) + updateGas = (updateData) => this.props.updateGas(updateData); render() { - const { warning } = this.props + const { warning } = this.props; return (
    @@ -38,19 +38,19 @@ export default class SendContent extends Component { )}
    - ) + ); } maybeRenderAddContact() { - const { t } = this.context + const { t } = this.context; const { isOwnedAccount, showAddToAddressBookModal, contact = {}, - } = this.props + } = this.props; if (isOwnedAccount || contact.name) { - return null + return null; } return ( @@ -61,17 +61,17 @@ export default class SendContent extends Component { > {t('newAccountDetectedDialogMessage')} - ) + ); } renderWarning() { - const { t } = this.context - const { warning } = this.props + const { t } = this.context; + const { warning } = this.props; return ( {t(warning)} - ) + ); } } diff --git a/ui/app/pages/send/send-content/send-content.container.js b/ui/app/pages/send/send-content/send-content.container.js index 6ba44cf0c9..42e115b94d 100644 --- a/ui/app/pages/send/send-content/send-content.container.js +++ b/ui/app/pages/send/send-content/send-content.container.js @@ -1,16 +1,16 @@ -import { connect } from 'react-redux' +import { connect } from 'react-redux'; import { getSendTo, accountsWithSendEtherInfoSelector, getAddressBookEntry, -} from '../../../selectors' +} from '../../../selectors'; -import * as actions from '../../../store/actions' -import SendContent from './send-content.component' +import * as actions from '../../../store/actions'; +import SendContent from './send-content.component'; function mapStateToProps(state) { - const ownedAccounts = accountsWithSendEtherInfoSelector(state) - const to = getSendTo(state) + const ownedAccounts = accountsWithSendEtherInfoSelector(state); + const to = getSendTo(state); return { isOwnedAccount: Boolean( ownedAccounts.find( @@ -19,7 +19,7 @@ function mapStateToProps(state) { ), contact: getAddressBookEntry(state, to), to, - } + }; } function mapDispatchToProps(dispatch) { @@ -31,21 +31,21 @@ function mapDispatchToProps(dispatch) { recipient, }), ), - } + }; } function mergeProps(stateProps, dispatchProps, ownProps) { - const { to, ...restStateProps } = stateProps + const { to, ...restStateProps } = stateProps; return { ...ownProps, ...restStateProps, showAddToAddressBookModal: () => dispatchProps.showAddToAddressBookModal(to), - } + }; } export default connect( mapStateToProps, mapDispatchToProps, mergeProps, -)(SendContent) +)(SendContent); diff --git a/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/gas-fee-display.component.js b/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/gas-fee-display.component.js index f016b794c0..8e61794e67 100644 --- a/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/gas-fee-display.component.js +++ b/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/gas-fee-display.component.js @@ -1,21 +1,21 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import UserPreferencedCurrencyDisplay from '../../../../../components/app/user-preferenced-currency-display' -import { PRIMARY, SECONDARY } from '../../../../../helpers/constants/common' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import UserPreferencedCurrencyDisplay from '../../../../../components/app/user-preferenced-currency-display'; +import { PRIMARY, SECONDARY } from '../../../../../helpers/constants/common'; export default class GasFeeDisplay extends Component { static propTypes = { gasLoadingError: PropTypes.bool, gasTotal: PropTypes.string, onReset: PropTypes.func, - } + }; static contextTypes = { t: PropTypes.func, - } + }; render() { - const { gasTotal, gasLoadingError, onReset } = this.props + const { gasTotal, gasLoadingError, onReset } = this.props; return (
    @@ -40,6 +40,6 @@ export default class GasFeeDisplay extends Component { {this.context.t('reset')}
    - ) + ); } } diff --git a/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/index.js b/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/index.js index dba0edb7be..e8c5d464f8 100644 --- a/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/index.js +++ b/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/index.js @@ -1 +1 @@ -export { default } from './gas-fee-display.component' +export { default } from './gas-fee-display.component'; diff --git a/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/tests/gas-fee-display.component.test.js b/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/tests/gas-fee-display.component.test.js index 817c324eaa..15fb6b5a29 100644 --- a/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/tests/gas-fee-display.component.test.js +++ b/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/tests/gas-fee-display.component.test.js @@ -1,17 +1,17 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import sinon from 'sinon' -import GasFeeDisplay from '../gas-fee-display.component' -import UserPreferencedCurrencyDisplay from '../../../../../../components/app/user-preferenced-currency-display' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import GasFeeDisplay from '../gas-fee-display.component'; +import UserPreferencedCurrencyDisplay from '../../../../../../components/app/user-preferenced-currency-display'; const propsMethodSpies = { showCustomizeGasModal: sinon.spy(), onReset: sinon.spy(), -} +}; describe('GasFeeDisplay Component', function () { - let wrapper + let wrapper; describe('render', function () { beforeEach(function () { @@ -25,36 +25,39 @@ describe('GasFeeDisplay Component', function () { onReset={propsMethodSpies.onReset} />, { context: { t: (str) => `${str}_t` } }, - ) - }) + ); + }); afterEach(function () { - propsMethodSpies.showCustomizeGasModal.resetHistory() - }) + propsMethodSpies.showCustomizeGasModal.resetHistory(); + }); it('should render a CurrencyDisplay component', function () { - assert.strictEqual(wrapper.find(UserPreferencedCurrencyDisplay).length, 2) - }) + assert.strictEqual( + wrapper.find(UserPreferencedCurrencyDisplay).length, + 2, + ); + }); it('should render the CurrencyDisplay with the correct props', function () { const { type, value } = wrapper .find(UserPreferencedCurrencyDisplay) .at(0) - .props() - assert.strictEqual(type, 'PRIMARY') - assert.strictEqual(value, 'mockGasTotal') - }) + .props(); + assert.strictEqual(type, 'PRIMARY'); + assert.strictEqual(value, 'mockGasTotal'); + }); it('should render the reset button with the correct props', function () { - const { onClick, className } = wrapper.find('button').props() - assert.strictEqual(className, 'gas-fee-reset') - assert.strictEqual(propsMethodSpies.onReset.callCount, 0) - onClick() - assert.strictEqual(propsMethodSpies.onReset.callCount, 1) - }) + const { onClick, className } = wrapper.find('button').props(); + assert.strictEqual(className, 'gas-fee-reset'); + assert.strictEqual(propsMethodSpies.onReset.callCount, 0); + onClick(); + assert.strictEqual(propsMethodSpies.onReset.callCount, 1); + }); it('should render the reset button with the correct text', function () { - assert.strictEqual(wrapper.find('button').text(), 'reset_t') - }) - }) -}) + assert.strictEqual(wrapper.find('button').text(), 'reset_t'); + }); + }); +}); diff --git a/ui/app/pages/send/send-content/send-gas-row/index.js b/ui/app/pages/send/send-content/send-gas-row/index.js index 3c7ff1d5f7..eb18bf2af2 100644 --- a/ui/app/pages/send/send-content/send-gas-row/index.js +++ b/ui/app/pages/send/send-content/send-gas-row/index.js @@ -1 +1 @@ -export { default } from './send-gas-row.container' +export { default } from './send-gas-row.container'; diff --git a/ui/app/pages/send/send-content/send-gas-row/send-gas-row.component.js b/ui/app/pages/send/send-content/send-gas-row/send-gas-row.component.js index 07f7d728a8..cf74ee0f3e 100644 --- a/ui/app/pages/send/send-content/send-gas-row/send-gas-row.component.js +++ b/ui/app/pages/send/send-content/send-gas-row/send-gas-row.component.js @@ -1,9 +1,9 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import SendRowWrapper from '../send-row-wrapper' -import GasPriceButtonGroup from '../../../../components/app/gas-customization/gas-price-button-group' -import AdvancedGasInputs from '../../../../components/app/gas-customization/advanced-gas-inputs' -import GasFeeDisplay from './gas-fee-display/gas-fee-display.component' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import SendRowWrapper from '../send-row-wrapper'; +import GasPriceButtonGroup from '../../../../components/app/gas-customization/gas-price-button-group'; +import AdvancedGasInputs from '../../../../components/app/gas-customization/advanced-gas-inputs'; +import GasFeeDisplay from './gas-fee-display/gas-fee-display.component'; export default class SendGasRow extends Component { static propTypes = { @@ -26,19 +26,19 @@ export default class SendGasRow extends Component { gasLimit: PropTypes.string, insufficientBalance: PropTypes.bool, isMainnet: PropTypes.bool, - } + }; static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; renderAdvancedOptionsButton() { - const { metricsEvent } = this.context - const { showCustomizeGasModal, isMainnet } = this.props + const { metricsEvent } = this.context; + const { showCustomizeGasModal, isMainnet } = this.props; // Tests should behave in same way as mainnet, but are using Localhost if (!isMainnet && !process.env.IN_TEST) { - return null + return null; } return (
    {this.context.t('advancedOptions')}
    - ) + ); } setMaxAmount() { @@ -66,14 +66,14 @@ export default class SendGasRow extends Component { sendToken, setAmountToMax, tokenBalance, - } = this.props + } = this.props; setAmountToMax({ balance, gasTotal, sendToken, tokenBalance, - }) + }); } renderContent() { @@ -92,8 +92,8 @@ export default class SendGasRow extends Component { gasLimit, insufficientBalance, isMainnet, - } = this.props - const { metricsEvent } = this.context + } = this.props; + const { metricsEvent } = this.context; const gasPriceButtonGroup = (
    @@ -108,28 +108,28 @@ export default class SendGasRow extends Component { action: 'Edit Screen', name: 'Changed Gas Button', }, - }) - await gasPriceButtonGroupProps.handleGasPriceSelection(opts) + }); + await gasPriceButtonGroupProps.handleGasPriceSelection(opts); if (maxModeOn) { - this.setMaxAmount() + this.setMaxAmount(); } }} />
    - ) + ); const gasFeeDisplay = ( { - resetGasButtons() + resetGasButtons(); if (maxModeOn) { - this.setMaxAmount() + this.setMaxAmount(); } }} onClick={() => showCustomizeGasModal()} /> - ) + ); const advancedGasInputs = (
    - ) + ); // Tests should behave in same way as mainnet, but are using Localhost if (advancedInlineGasShown || (!isMainnet && !process.env.IN_TEST)) { - return advancedGasInputs + return advancedGasInputs; } else if (gasButtonGroupShown) { - return gasPriceButtonGroup + return gasPriceButtonGroup; } - return gasFeeDisplay + return gasFeeDisplay; } render() { @@ -161,7 +161,7 @@ export default class SendGasRow extends Component { gasFeeError, gasButtonGroupShown, advancedInlineGasShown, - } = this.props + } = this.props; return ( <> @@ -176,6 +176,6 @@ export default class SendGasRow extends Component { {this.renderAdvancedOptionsButton()} ) : null} - ) + ); } } diff --git a/ui/app/pages/send/send-content/send-gas-row/send-gas-row.container.js b/ui/app/pages/send/send-content/send-gas-row/send-gas-row.container.js index 7387fd93f8..210819f079 100644 --- a/ui/app/pages/send/send-content/send-gas-row/send-gas-row.container.js +++ b/ui/app/pages/send/send-content/send-gas-row/send-gas-row.container.js @@ -1,4 +1,4 @@ -import { connect } from 'react-redux' +import { connect } from 'react-redux'; import { getConversionRate, getGasTotal, @@ -18,49 +18,52 @@ import { getRenderableEstimateDataForSmallButtonsFromGWEI, getDefaultActiveButtonIndex, getIsMainnet, -} from '../../../../selectors' -import { isBalanceSufficient, calcGasTotal } from '../../send.utils' -import { calcMaxAmount } from '../send-amount-row/amount-max-button/amount-max-button.utils' +} from '../../../../selectors'; +import { isBalanceSufficient, calcGasTotal } from '../../send.utils'; +import { calcMaxAmount } from '../send-amount-row/amount-max-button/amount-max-button.utils'; import { showGasButtonGroup, updateSendErrors, -} from '../../../../ducks/send/send.duck' +} from '../../../../ducks/send/send.duck'; import { resetCustomData, setCustomGasPrice, setCustomGasLimit, -} from '../../../../ducks/gas/gas.duck' +} from '../../../../ducks/gas/gas.duck'; import { showModal, setGasPrice, setGasLimit, setGasTotal, updateSendAmount, -} from '../../../../store/actions' -import SendGasRow from './send-gas-row.component' +} from '../../../../store/actions'; +import SendGasRow from './send-gas-row.component'; export default connect( mapStateToProps, mapDispatchToProps, mergeProps, -)(SendGasRow) +)(SendGasRow); function mapStateToProps(state) { - const gasButtonInfo = getRenderableEstimateDataForSmallButtonsFromGWEI(state) - const gasPrice = getGasPrice(state) - const gasLimit = getGasLimit(state) - const activeButtonIndex = getDefaultActiveButtonIndex(gasButtonInfo, gasPrice) + const gasButtonInfo = getRenderableEstimateDataForSmallButtonsFromGWEI(state); + const gasPrice = getGasPrice(state); + const gasLimit = getGasLimit(state); + const activeButtonIndex = getDefaultActiveButtonIndex( + gasButtonInfo, + gasPrice, + ); - const gasTotal = getGasTotal(state) - const conversionRate = getConversionRate(state) - const balance = getCurrentEthBalance(state) + const gasTotal = getGasTotal(state); + const conversionRate = getConversionRate(state); + const balance = getCurrentEthBalance(state); const insufficientBalance = !isBalanceSufficient({ amount: getSendToken(state) ? '0x0' : getSendAmount(state), gasTotal, balance, conversionRate, - }) + }); return { balance: getSendFromBalance(state), @@ -82,7 +85,7 @@ function mapStateToProps(state) { sendToken: getSendToken(state), tokenBalance: getTokenBalance(state), isMainnet: getIsMainnet(state), - } + }; } function mapDispatchToProps(dispatch) { @@ -90,37 +93,37 @@ function mapDispatchToProps(dispatch) { showCustomizeGasModal: () => dispatch(showModal({ name: 'CUSTOMIZE_GAS', hideBasic: true })), setGasPrice: ({ gasPrice, gasLimit }) => { - dispatch(setGasPrice(gasPrice)) - dispatch(setCustomGasPrice(gasPrice)) + dispatch(setGasPrice(gasPrice)); + dispatch(setCustomGasPrice(gasPrice)); if (gasLimit) { - dispatch(setGasTotal(calcGasTotal(gasLimit, gasPrice))) + dispatch(setGasTotal(calcGasTotal(gasLimit, gasPrice))); } }, setGasLimit: (newLimit, gasPrice) => { - dispatch(setGasLimit(newLimit)) - dispatch(setCustomGasLimit(newLimit)) + dispatch(setGasLimit(newLimit)); + dispatch(setCustomGasLimit(newLimit)); if (gasPrice) { - dispatch(setGasTotal(calcGasTotal(newLimit, gasPrice))) + dispatch(setGasTotal(calcGasTotal(newLimit, gasPrice))); } }, setAmountToMax: (maxAmountDataObject) => { - dispatch(updateSendErrors({ amount: null })) - dispatch(updateSendAmount(calcMaxAmount(maxAmountDataObject))) + dispatch(updateSendErrors({ amount: null })); + dispatch(updateSendAmount(calcMaxAmount(maxAmountDataObject))); }, showGasButtonGroup: () => dispatch(showGasButtonGroup()), resetCustomData: () => dispatch(resetCustomData()), - } + }; } function mergeProps(stateProps, dispatchProps, ownProps) { - const { gasPriceButtonGroupProps } = stateProps - const { gasButtonInfo } = gasPriceButtonGroupProps + const { gasPriceButtonGroupProps } = stateProps; + const { gasButtonInfo } = gasPriceButtonGroupProps; const { setGasPrice: dispatchSetGasPrice, showGasButtonGroup: dispatchShowGasButtonGroup, resetCustomData: dispatchResetCustomData, ...otherDispatchProps - } = dispatchProps + } = dispatchProps; return { ...stateProps, @@ -131,10 +134,10 @@ function mergeProps(stateProps, dispatchProps, ownProps) { handleGasPriceSelection: dispatchSetGasPrice, }, resetGasButtons: () => { - dispatchResetCustomData() - dispatchSetGasPrice(gasButtonInfo[1].priceInHexWei) - dispatchShowGasButtonGroup() + dispatchResetCustomData(); + dispatchSetGasPrice(gasButtonInfo[1].priceInHexWei); + dispatchShowGasButtonGroup(); }, setGasPrice: dispatchSetGasPrice, - } + }; } diff --git a/ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-component.test.js b/ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-component.test.js index 926e9ae028..12bb6d7bfa 100644 --- a/ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-component.test.js +++ b/ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-component.test.js @@ -1,20 +1,20 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import sinon from 'sinon' -import SendGasRow from '../send-gas-row.component' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import SendGasRow from '../send-gas-row.component'; -import SendRowWrapper from '../../send-row-wrapper/send-row-wrapper.component' -import GasFeeDisplay from '../gas-fee-display/gas-fee-display.component' -import GasPriceButtonGroup from '../../../../../components/app/gas-customization/gas-price-button-group' +import SendRowWrapper from '../../send-row-wrapper/send-row-wrapper.component'; +import GasFeeDisplay from '../gas-fee-display/gas-fee-display.component'; +import GasPriceButtonGroup from '../../../../../components/app/gas-customization/gas-price-button-group'; const propsMethodSpies = { showCustomizeGasModal: sinon.spy(), resetGasButtons: sinon.spy(), -} +}; describe('SendGasRow Component', function () { - let wrapper + let wrapper; describe('render', function () { beforeEach(function () { @@ -34,77 +34,77 @@ describe('SendGasRow Component', function () { }} />, { context: { t: (str) => `${str}_t`, metricsEvent: () => ({}) } }, - ) - wrapper.setProps({ isMainnet: true }) - }) + ); + wrapper.setProps({ isMainnet: true }); + }); afterEach(function () { - propsMethodSpies.resetGasButtons.resetHistory() - }) + propsMethodSpies.resetGasButtons.resetHistory(); + }); it('should render a SendRowWrapper component', function () { - assert.strictEqual(wrapper.name(), 'Fragment') - assert.strictEqual(wrapper.at(0).find(SendRowWrapper).length, 1) - }) + assert.strictEqual(wrapper.name(), 'Fragment'); + assert.strictEqual(wrapper.at(0).find(SendRowWrapper).length, 1); + }); it('should pass the correct props to SendRowWrapper', function () { const { label, showError, errorType } = wrapper .find(SendRowWrapper) .first() - .props() + .props(); - assert.strictEqual(label, 'transactionFee_t:') - assert.strictEqual(showError, true) - assert.strictEqual(errorType, 'gasFee') - }) + assert.strictEqual(label, 'transactionFee_t:'); + assert.strictEqual(showError, true); + assert.strictEqual(errorType, 'gasFee'); + }); it('should render a GasFeeDisplay as a child of the SendRowWrapper', function () { - assert(wrapper.find(SendRowWrapper).first().childAt(0).is(GasFeeDisplay)) - }) + assert(wrapper.find(SendRowWrapper).first().childAt(0).is(GasFeeDisplay)); + }); it('should render the GasFeeDisplay', function () { const { gasLoadingError, gasTotal, onReset } = wrapper .find(SendRowWrapper) .first() .childAt(0) - .props() - assert.strictEqual(gasLoadingError, false) - assert.strictEqual(gasTotal, 'mockGasTotal') - assert.strictEqual(propsMethodSpies.resetGasButtons.callCount, 0) - onReset() - assert.strictEqual(propsMethodSpies.resetGasButtons.callCount, 1) - }) + .props(); + assert.strictEqual(gasLoadingError, false); + assert.strictEqual(gasTotal, 'mockGasTotal'); + assert.strictEqual(propsMethodSpies.resetGasButtons.callCount, 0); + onReset(); + assert.strictEqual(propsMethodSpies.resetGasButtons.callCount, 1); + }); it('should render the GasPriceButtonGroup if gasButtonGroupShown is true', function () { - wrapper.setProps({ gasButtonGroupShown: true }) - const rendered = wrapper.find(SendRowWrapper).first().childAt(0) - assert.strictEqual(wrapper.children().length, 2) + wrapper.setProps({ gasButtonGroupShown: true }); + const rendered = wrapper.find(SendRowWrapper).first().childAt(0); + assert.strictEqual(wrapper.children().length, 2); - const gasPriceButtonGroup = rendered.childAt(0) - assert(gasPriceButtonGroup.is(GasPriceButtonGroup)) - assert(gasPriceButtonGroup.hasClass('gas-price-button-group--small')) - assert.strictEqual(gasPriceButtonGroup.props().showCheck, false) + const gasPriceButtonGroup = rendered.childAt(0); + assert(gasPriceButtonGroup.is(GasPriceButtonGroup)); + assert(gasPriceButtonGroup.hasClass('gas-price-button-group--small')); + assert.strictEqual(gasPriceButtonGroup.props().showCheck, false); assert.strictEqual( gasPriceButtonGroup.props().someGasPriceButtonGroupProp, 'foo', - ) + ); assert.strictEqual( gasPriceButtonGroup.props().anotherGasPriceButtonGroupProp, 'bar', - ) - }) + ); + }); it('should render an advanced options button if gasButtonGroupShown is true', function () { - wrapper.setProps({ gasButtonGroupShown: true }) - const rendered = wrapper.find(SendRowWrapper).last() - assert.strictEqual(wrapper.children().length, 2) + wrapper.setProps({ gasButtonGroupShown: true }); + const rendered = wrapper.find(SendRowWrapper).last(); + assert.strictEqual(wrapper.children().length, 2); - const advancedOptionsButton = rendered.childAt(0) - assert.strictEqual(advancedOptionsButton.text(), 'advancedOptions_t') + const advancedOptionsButton = rendered.childAt(0); + assert.strictEqual(advancedOptionsButton.text(), 'advancedOptions_t'); - assert.strictEqual(propsMethodSpies.showCustomizeGasModal.callCount, 0) - advancedOptionsButton.props().onClick() - assert.strictEqual(propsMethodSpies.showCustomizeGasModal.callCount, 1) - }) - }) -}) + assert.strictEqual(propsMethodSpies.showCustomizeGasModal.callCount, 0); + advancedOptionsButton.props().onClick(); + assert.strictEqual(propsMethodSpies.showCustomizeGasModal.callCount, 1); + }); + }); +}); diff --git a/ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-container.test.js b/ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-container.test.js index ffaa877781..157082f765 100644 --- a/ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-container.test.js +++ b/ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-container.test.js @@ -1,33 +1,33 @@ -import assert from 'assert' -import proxyquire from 'proxyquire' -import sinon from 'sinon' +import assert from 'assert'; +import proxyquire from 'proxyquire'; +import sinon from 'sinon'; -let mapDispatchToProps -let mergeProps +let mapDispatchToProps; +let mergeProps; const actionSpies = { showModal: sinon.spy(), setGasPrice: sinon.spy(), setGasTotal: sinon.spy(), setGasLimit: sinon.spy(), -} +}; const sendDuckSpies = { showGasButtonGroup: sinon.spy(), -} +}; const gasDuckSpies = { resetCustomData: sinon.spy(), setCustomGasPrice: sinon.spy(), setCustomGasLimit: sinon.spy(), -} +}; proxyquire('../send-gas-row.container.js', { 'react-redux': { connect: (_, md, mp) => { - mapDispatchToProps = md - mergeProps = mp - return () => ({}) + mapDispatchToProps = md; + mergeProps = mp; + return () => ({}); }, }, '../../../../selectors': { @@ -41,91 +41,91 @@ proxyquire('../send-gas-row.container.js', { '../../../../store/actions': actionSpies, '../../../../ducks/send/send.duck': sendDuckSpies, '../../../../ducks/gas/gas.duck': gasDuckSpies, -}) +}); describe('send-gas-row container', function () { describe('mapDispatchToProps()', function () { - let dispatchSpy - let mapDispatchToPropsObject + let dispatchSpy; + let mapDispatchToPropsObject; beforeEach(function () { - dispatchSpy = sinon.spy() - mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy) - actionSpies.setGasTotal.resetHistory() - }) + dispatchSpy = sinon.spy(); + mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy); + actionSpies.setGasTotal.resetHistory(); + }); describe('showCustomizeGasModal()', function () { it('should dispatch an action', function () { - mapDispatchToPropsObject.showCustomizeGasModal() - assert(dispatchSpy.calledOnce) + mapDispatchToPropsObject.showCustomizeGasModal(); + assert(dispatchSpy.calledOnce); assert.deepStrictEqual(actionSpies.showModal.getCall(0).args[0], { name: 'CUSTOMIZE_GAS', hideBasic: true, - }) - }) - }) + }); + }); + }); describe('setGasPrice()', function () { it('should dispatch an action', function () { mapDispatchToPropsObject.setGasPrice({ gasPrice: 'mockNewPrice', gasLimit: 'mockLimit', - }) - assert(dispatchSpy.calledThrice) - assert(actionSpies.setGasPrice.calledOnce) + }); + assert(dispatchSpy.calledThrice); + assert(actionSpies.setGasPrice.calledOnce); assert.strictEqual( actionSpies.setGasPrice.getCall(0).args[0], 'mockNewPrice', - ) + ); assert.strictEqual( gasDuckSpies.setCustomGasPrice.getCall(0).args[0], 'mockNewPrice', - ) - assert(actionSpies.setGasTotal.calledOnce) + ); + assert(actionSpies.setGasTotal.calledOnce); assert.strictEqual( actionSpies.setGasTotal.getCall(0).args[0], 'mockLimitmockNewPrice', - ) - }) - }) + ); + }); + }); describe('setGasLimit()', function () { it('should dispatch an action', function () { - mapDispatchToPropsObject.setGasLimit('mockNewLimit', 'mockPrice') - assert(dispatchSpy.calledThrice) - assert(actionSpies.setGasLimit.calledOnce) + mapDispatchToPropsObject.setGasLimit('mockNewLimit', 'mockPrice'); + assert(dispatchSpy.calledThrice); + assert(actionSpies.setGasLimit.calledOnce); assert.strictEqual( actionSpies.setGasLimit.getCall(0).args[0], 'mockNewLimit', - ) + ); assert.strictEqual( gasDuckSpies.setCustomGasLimit.getCall(0).args[0], 'mockNewLimit', - ) - assert(actionSpies.setGasTotal.calledOnce) + ); + assert(actionSpies.setGasTotal.calledOnce); assert.strictEqual( actionSpies.setGasTotal.getCall(0).args[0], 'mockNewLimitmockPrice', - ) - }) - }) + ); + }); + }); describe('showGasButtonGroup()', function () { it('should dispatch an action', function () { - mapDispatchToPropsObject.showGasButtonGroup() - assert(dispatchSpy.calledOnce) - assert(sendDuckSpies.showGasButtonGroup.calledOnce) - }) - }) + mapDispatchToPropsObject.showGasButtonGroup(); + assert(dispatchSpy.calledOnce); + assert(sendDuckSpies.showGasButtonGroup.calledOnce); + }); + }); describe('resetCustomData()', function () { it('should dispatch an action', function () { - mapDispatchToPropsObject.resetCustomData() - assert(dispatchSpy.calledOnce) - assert(gasDuckSpies.resetCustomData.calledOnce) - }) - }) - }) + mapDispatchToPropsObject.resetCustomData(); + assert(dispatchSpy.calledOnce); + assert(gasDuckSpies.resetCustomData.calledOnce); + }); + }); + }); describe('mergeProps', function () { it('should return the expected props when isConfirm is true', function () { @@ -135,32 +135,32 @@ describe('send-gas-row container', function () { anotherGasPriceButtonGroupProp: 'bar', }, someOtherStateProp: 'baz', - } + }; const dispatchProps = { setGasPrice: sinon.spy(), someOtherDispatchProp: sinon.spy(), - } - const ownProps = { someOwnProp: 123 } - const result = mergeProps(stateProps, dispatchProps, ownProps) + }; + const ownProps = { someOwnProp: 123 }; + const result = mergeProps(stateProps, dispatchProps, ownProps); - assert.strictEqual(result.someOtherStateProp, 'baz') + assert.strictEqual(result.someOtherStateProp, 'baz'); assert.strictEqual( result.gasPriceButtonGroupProps.someGasPriceButtonGroupProp, 'foo', - ) + ); assert.strictEqual( result.gasPriceButtonGroupProps.anotherGasPriceButtonGroupProp, 'bar', - ) - assert.strictEqual(result.someOwnProp, 123) - - assert.strictEqual(dispatchProps.setGasPrice.callCount, 0) - result.gasPriceButtonGroupProps.handleGasPriceSelection() - assert.strictEqual(dispatchProps.setGasPrice.callCount, 1) - - assert.strictEqual(dispatchProps.someOtherDispatchProp.callCount, 0) - result.someOtherDispatchProp() - assert.strictEqual(dispatchProps.someOtherDispatchProp.callCount, 1) - }) - }) -}) + ); + assert.strictEqual(result.someOwnProp, 123); + + assert.strictEqual(dispatchProps.setGasPrice.callCount, 0); + result.gasPriceButtonGroupProps.handleGasPriceSelection(); + assert.strictEqual(dispatchProps.setGasPrice.callCount, 1); + + assert.strictEqual(dispatchProps.someOtherDispatchProp.callCount, 0); + result.someOtherDispatchProp(); + assert.strictEqual(dispatchProps.someOtherDispatchProp.callCount, 1); + }); + }); +}); diff --git a/ui/app/pages/send/send-content/send-hex-data-row/index.js b/ui/app/pages/send/send-content/send-hex-data-row/index.js index 08c3410671..9ea3d437a3 100644 --- a/ui/app/pages/send/send-content/send-hex-data-row/index.js +++ b/ui/app/pages/send/send-content/send-hex-data-row/index.js @@ -1 +1 @@ -export { default } from './send-hex-data-row.container' +export { default } from './send-hex-data-row.container'; diff --git a/ui/app/pages/send/send-content/send-hex-data-row/send-hex-data-row.component.js b/ui/app/pages/send/send-content/send-hex-data-row/send-hex-data-row.component.js index 2299f33bc3..080b97b37b 100644 --- a/ui/app/pages/send/send-content/send-hex-data-row/send-hex-data-row.component.js +++ b/ui/app/pages/send/send-content/send-hex-data-row/send-hex-data-row.component.js @@ -1,28 +1,28 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import SendRowWrapper from '../send-row-wrapper' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import SendRowWrapper from '../send-row-wrapper'; export default class SendHexDataRow extends Component { static propTypes = { inError: PropTypes.bool, updateSendHexData: PropTypes.func.isRequired, updateGas: PropTypes.func.isRequired, - } + }; static contextTypes = { t: PropTypes.func, - } + }; onInput = (event) => { - const { updateSendHexData, updateGas } = this.props - const data = event.target.value.replace(/\n/gu, '') || null - updateSendHexData(data) - updateGas({ data }) - } + const { updateSendHexData, updateGas } = this.props; + const data = event.target.value.replace(/\n/gu, '') || null; + updateSendHexData(data); + updateGas({ data }); + }; render() { - const { inError } = this.props - const { t } = this.context + const { inError } = this.props; + const { t } = this.context; return ( - ) + ); } } diff --git a/ui/app/pages/send/send-content/send-hex-data-row/send-hex-data-row.container.js b/ui/app/pages/send/send-content/send-hex-data-row/send-hex-data-row.container.js index f20d97b51c..20a8cad437 100644 --- a/ui/app/pages/send/send-content/send-hex-data-row/send-hex-data-row.container.js +++ b/ui/app/pages/send/send-content/send-hex-data-row/send-hex-data-row.container.js @@ -1,19 +1,19 @@ -import { connect } from 'react-redux' -import { updateSendHexData } from '../../../../store/actions' -import SendHexDataRow from './send-hex-data-row.component' +import { connect } from 'react-redux'; +import { updateSendHexData } from '../../../../store/actions'; +import SendHexDataRow from './send-hex-data-row.component'; -export default connect(mapStateToProps, mapDispatchToProps)(SendHexDataRow) +export default connect(mapStateToProps, mapDispatchToProps)(SendHexDataRow); function mapStateToProps(state) { return { data: state.metamask.send.data, - } + }; } function mapDispatchToProps(dispatch) { return { updateSendHexData(data) { - return dispatch(updateSendHexData(data)) + return dispatch(updateSendHexData(data)); }, - } + }; } diff --git a/ui/app/pages/send/send-content/send-row-wrapper/index.js b/ui/app/pages/send/send-content/send-row-wrapper/index.js index d17545dcc1..ceda93d7ab 100644 --- a/ui/app/pages/send/send-content/send-row-wrapper/index.js +++ b/ui/app/pages/send/send-content/send-row-wrapper/index.js @@ -1 +1 @@ -export { default } from './send-row-wrapper.component' +export { default } from './send-row-wrapper.component'; diff --git a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/index.js b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/index.js index c00617f83a..b66d6bfa79 100644 --- a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/index.js +++ b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/index.js @@ -1 +1 @@ -export { default } from './send-row-error-message.container' +export { default } from './send-row-error-message.container'; diff --git a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.component.js b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.component.js index bdae808a7e..41bf9fadb6 100644 --- a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.component.js +++ b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.component.js @@ -1,21 +1,21 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; export default class SendRowErrorMessage extends Component { static propTypes = { errors: PropTypes.object, errorType: PropTypes.string, - } + }; static contextTypes = { t: PropTypes.func, - } + }; render() { - const { errors, errorType } = this.props + const { errors, errorType } = this.props; - const errorMessage = errors[errorType] + const errorMessage = errors[errorType]; return errorMessage ? (
    {this.context.t(errorMessage)}
    - ) : null + ) : null; } } diff --git a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.container.js b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.container.js index b9969c5afa..f857183f32 100644 --- a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.container.js +++ b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.container.js @@ -1,12 +1,12 @@ -import { connect } from 'react-redux' -import { getSendErrors } from '../../../../../selectors' -import SendRowErrorMessage from './send-row-error-message.component' +import { connect } from 'react-redux'; +import { getSendErrors } from '../../../../../selectors'; +import SendRowErrorMessage from './send-row-error-message.component'; -export default connect(mapStateToProps)(SendRowErrorMessage) +export default connect(mapStateToProps)(SendRowErrorMessage); function mapStateToProps(state, ownProps) { return { errors: getSendErrors(state), errorType: ownProps.errorType, - } + }; } diff --git a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-component.test.js b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-component.test.js index 41d318ffd8..c8c0f5c612 100644 --- a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-component.test.js +++ b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-component.test.js @@ -1,10 +1,10 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import SendRowErrorMessage from '../send-row-error-message.component' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import SendRowErrorMessage from '../send-row-error-message.component'; describe('SendRowErrorMessage Component', function () { - let wrapper + let wrapper; describe('render', function () { beforeEach(function () { @@ -14,20 +14,20 @@ describe('SendRowErrorMessage Component', function () { errorType="error3" />, { context: { t: (str) => `${str}_t` } }, - ) - }) + ); + }); it('should render null if the passed errors do not contain an error of errorType', function () { - assert.strictEqual(wrapper.find('.send-v2__error').length, 0) - assert.strictEqual(wrapper.html(), null) - }) + assert.strictEqual(wrapper.find('.send-v2__error').length, 0); + assert.strictEqual(wrapper.html(), null); + }); it('should render an error message if the passed errors contain an error of errorType', function () { wrapper.setProps({ errors: { error1: 'abc', error2: 'def', error3: 'xyz' }, - }) - assert.strictEqual(wrapper.find('.send-v2__error').length, 1) - assert.strictEqual(wrapper.find('.send-v2__error').text(), 'xyz_t') - }) - }) -}) + }); + assert.strictEqual(wrapper.find('.send-v2__error').length, 1); + assert.strictEqual(wrapper.find('.send-v2__error').text(), 'xyz_t'); + }); + }); +}); diff --git a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-container.test.js b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-container.test.js index dd3a4da8fb..f231b7734a 100644 --- a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-container.test.js +++ b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-container.test.js @@ -1,17 +1,17 @@ -import assert from 'assert' -import proxyquire from 'proxyquire' +import assert from 'assert'; +import proxyquire from 'proxyquire'; -let mapStateToProps +let mapStateToProps; proxyquire('../send-row-error-message.container.js', { 'react-redux': { connect: (ms) => { - mapStateToProps = ms - return () => ({}) + mapStateToProps = ms; + return () => ({}); }, }, '../../../../../selectors': { getSendErrors: (s) => `mockErrors:${s}` }, -}) +}); describe('send-row-error-message container', function () { describe('mapStateToProps()', function () { @@ -22,7 +22,7 @@ describe('send-row-error-message container', function () { errors: 'mockErrors:mockState', errorType: 'someType', }, - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/ui/app/pages/send/send-content/send-row-wrapper/send-row-wrapper.component.js b/ui/app/pages/send/send-content/send-row-wrapper/send-row-wrapper.component.js index e66d726c9b..9499171717 100644 --- a/ui/app/pages/send/send-content/send-row-wrapper/send-row-wrapper.component.js +++ b/ui/app/pages/send/send-content/send-row-wrapper/send-row-wrapper.component.js @@ -1,6 +1,6 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import SendRowErrorMessage from './send-row-error-message' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import SendRowErrorMessage from './send-row-error-message'; export default class SendRowWrapper extends Component { static propTypes = { @@ -8,18 +8,18 @@ export default class SendRowWrapper extends Component { errorType: PropTypes.string, label: PropTypes.string, showError: PropTypes.bool, - } + }; static contextTypes = { t: PropTypes.func, - } + }; renderAmountFormRow() { - const { children, errorType = '', label, showError = false } = this.props + const { children, errorType = '', label, showError = false } = this.props; const formField = Array.isArray(children) ? children[1] || children[0] - : children - const customLabelContent = children.length > 1 ? children[0] : null + : children; + const customLabelContent = children.length > 1 ? children[0] : null; return (
    @@ -34,17 +34,17 @@ export default class SendRowWrapper extends Component {
    - ) + ); } renderFormRow() { - const { children, errorType = '', label, showError = false } = this.props + const { children, errorType = '', label, showError = false } = this.props; const formField = Array.isArray(children) ? children[1] || children[0] - : children + : children; const customLabelContent = - (Array.isArray(children) && children.length) > 1 ? children[0] : null + (Array.isArray(children) && children.length) > 1 ? children[0] : null; return (
    @@ -55,14 +55,14 @@ export default class SendRowWrapper extends Component {
    {formField}
    - ) + ); } render() { - const { errorType = '' } = this.props + const { errorType = '' } = this.props; return errorType === 'amount' ? this.renderAmountFormRow() - : this.renderFormRow() + : this.renderFormRow(); } } diff --git a/ui/app/pages/send/send-content/send-row-wrapper/tests/send-row-wrapper-component.test.js b/ui/app/pages/send/send-content/send-row-wrapper/tests/send-row-wrapper-component.test.js index 4a4b3189a1..722168698b 100644 --- a/ui/app/pages/send/send-content/send-row-wrapper/tests/send-row-wrapper-component.test.js +++ b/ui/app/pages/send/send-content/send-row-wrapper/tests/send-row-wrapper-component.test.js @@ -1,12 +1,12 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import SendRowWrapper from '../send-row-wrapper.component' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import SendRowWrapper from '../send-row-wrapper.component'; -import SendRowErrorMessage from '../send-row-error-message/send-row-error-message.container' +import SendRowErrorMessage from '../send-row-error-message/send-row-error-message.container'; describe('SendContent Component', function () { - let wrapper + let wrapper; describe('render', function () { beforeEach(function () { @@ -18,23 +18,23 @@ describe('SendContent Component', function () { > Mock Form Field , - ) - }) + ); + }); it('should render a div with a send-v2__form-row class', function () { - assert.strictEqual(wrapper.find('div.send-v2__form-row').length, 1) - }) + assert.strictEqual(wrapper.find('div.send-v2__form-row').length, 1); + }); it('should render two children of the root div, with send-v2_form label and field classes', function () { assert.strictEqual( wrapper.find('.send-v2__form-row > .send-v2__form-label').length, 1, - ) + ); assert.strictEqual( wrapper.find('.send-v2__form-row > .send-v2__form-field').length, 1, - ) - }) + ); + }); it('should render the label as a child of the send-v2__form-label', function () { assert.strictEqual( @@ -43,8 +43,8 @@ describe('SendContent Component', function () { .childAt(0) .text(), 'mockLabel', - ) - }) + ); + }); it('should render its first child as a child of the send-v2__form-field', function () { assert.strictEqual( @@ -53,25 +53,25 @@ describe('SendContent Component', function () { .childAt(0) .text(), 'Mock Form Field', - ) - }) + ); + }); it('should not render a SendRowErrorMessage if showError is false', function () { - assert.strictEqual(wrapper.find(SendRowErrorMessage).length, 0) - }) + assert.strictEqual(wrapper.find(SendRowErrorMessage).length, 0); + }); it('should render a SendRowErrorMessage with and errorType props if showError is true', function () { - wrapper.setProps({ showError: true }) - assert.strictEqual(wrapper.find(SendRowErrorMessage).length, 1) + wrapper.setProps({ showError: true }); + assert.strictEqual(wrapper.find(SendRowErrorMessage).length, 1); const expectedSendRowErrorMessage = wrapper .find('.send-v2__form-row > .send-v2__form-label') - .childAt(1) - assert(expectedSendRowErrorMessage.is(SendRowErrorMessage)) + .childAt(1); + assert(expectedSendRowErrorMessage.is(SendRowErrorMessage)); assert.deepStrictEqual(expectedSendRowErrorMessage.props(), { errorType: 'mockErrorType', - }) - }) + }); + }); it('should render its second child as a child of the send-v2__form-field, if it has two children', function () { wrapper = shallow( @@ -83,15 +83,15 @@ describe('SendContent Component', function () { Mock Custom Label Content Mock Form Field , - ) + ); assert.strictEqual( wrapper .find('.send-v2__form-row > .send-v2__form-field') .childAt(0) .text(), 'Mock Form Field', - ) - }) + ); + }); it('should render its first child as the last child of the send-v2__form-label, if it has two children', function () { wrapper = shallow( @@ -103,14 +103,14 @@ describe('SendContent Component', function () { Mock Custom Label Content Mock Form Field , - ) + ); assert.strictEqual( wrapper .find('.send-v2__form-row > .send-v2__form-label') .childAt(1) .text(), 'Mock Custom Label Content', - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/ui/app/pages/send/send-content/tests/send-content-component.test.js b/ui/app/pages/send/send-content/tests/send-content-component.test.js index 2628c516ab..b652d369f7 100644 --- a/ui/app/pages/send/send-content/tests/send-content-component.test.js +++ b/ui/app/pages/send/send-content/tests/send-content-component.test.js @@ -1,157 +1,157 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import SendContent from '../send-content.component' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import SendContent from '../send-content.component'; -import PageContainerContent from '../../../../components/ui/page-container/page-container-content.component' -import SendAmountRow from '../send-amount-row/send-amount-row.container' -import SendGasRow from '../send-gas-row/send-gas-row.container' -import SendHexDataRow from '../send-hex-data-row/send-hex-data-row.container' -import SendAssetRow from '../send-asset-row/send-asset-row.container' -import Dialog from '../../../../components/ui/dialog' +import PageContainerContent from '../../../../components/ui/page-container/page-container-content.component'; +import SendAmountRow from '../send-amount-row/send-amount-row.container'; +import SendGasRow from '../send-gas-row/send-gas-row.container'; +import SendHexDataRow from '../send-hex-data-row/send-hex-data-row.container'; +import SendAssetRow from '../send-asset-row/send-asset-row.container'; +import Dialog from '../../../../components/ui/dialog'; describe('SendContent Component', function () { - let wrapper + let wrapper; beforeEach(function () { wrapper = shallow(, { context: { t: (str) => `${str}_t` }, - }) - }) + }); + }); describe('render', function () { it('should render a PageContainerContent component', function () { - assert.strictEqual(wrapper.find(PageContainerContent).length, 1) - }) + assert.strictEqual(wrapper.find(PageContainerContent).length, 1); + }); it('should render a div with a .send-v2__form class as a child of PageContainerContent', function () { const PageContainerContentChild = wrapper .find(PageContainerContent) - .children() - PageContainerContentChild.is('div') - PageContainerContentChild.is('.send-v2__form') - }) + .children(); + PageContainerContentChild.is('div'); + PageContainerContentChild.is('.send-v2__form'); + }); it('should render the correct row components as grandchildren of the PageContainerContent component', function () { const PageContainerContentChild = wrapper .find(PageContainerContent) - .children() + .children(); assert( PageContainerContentChild.childAt(0).is(Dialog), 'row[0] should be Dialog', - ) + ); assert( PageContainerContentChild.childAt(1).is(SendAssetRow), 'row[1] should be SendAssetRow', - ) + ); assert( PageContainerContentChild.childAt(2).is(SendAmountRow), 'row[2] should be SendAmountRow', - ) + ); assert( PageContainerContentChild.childAt(3).is(SendGasRow), 'row[3] should be SendGasRow', - ) + ); assert( PageContainerContentChild.childAt(4).is(SendHexDataRow), 'row[4] should be SendHexDataRow', - ) - }) + ); + }); it('should not render the SendHexDataRow if props.showHexData is false', function () { - wrapper.setProps({ showHexData: false }) + wrapper.setProps({ showHexData: false }); const PageContainerContentChild = wrapper .find(PageContainerContent) - .children() + .children(); assert( PageContainerContentChild.childAt(0).is(Dialog), 'row[0] should be Dialog', - ) + ); assert( PageContainerContentChild.childAt(1).is(SendAssetRow), 'row[1] should be SendAssetRow', - ) + ); assert( PageContainerContentChild.childAt(2).is(SendAmountRow), 'row[2] should be SendAmountRow', - ) + ); assert( PageContainerContentChild.childAt(3).is(SendGasRow), 'row[3] should be SendGasRow', - ) - assert.strictEqual(PageContainerContentChild.childAt(4).exists(), false) - }) + ); + assert.strictEqual(PageContainerContentChild.childAt(4).exists(), false); + }); it('should not render the Dialog if contact has a name', function () { wrapper.setProps({ showHexData: false, contact: { name: 'testName' }, - }) + }); const PageContainerContentChild = wrapper .find(PageContainerContent) - .children() + .children(); assert( PageContainerContentChild.childAt(0).is(SendAssetRow), 'row[1] should be SendAssetRow', - ) + ); assert( PageContainerContentChild.childAt(1).is(SendAmountRow), 'row[2] should be SendAmountRow', - ) + ); assert( PageContainerContentChild.childAt(2).is(SendGasRow), 'row[3] should be SendGasRow', - ) - assert.strictEqual(PageContainerContentChild.childAt(3).exists(), false) - }) + ); + assert.strictEqual(PageContainerContentChild.childAt(3).exists(), false); + }); it('should not render the Dialog if it is an ownedAccount', function () { wrapper.setProps({ showHexData: false, isOwnedAccount: true, - }) + }); const PageContainerContentChild = wrapper .find(PageContainerContent) - .children() + .children(); assert( PageContainerContentChild.childAt(0).is(SendAssetRow), 'row[1] should be SendAssetRow', - ) + ); assert( PageContainerContentChild.childAt(1).is(SendAmountRow), 'row[2] should be SendAmountRow', - ) + ); assert( PageContainerContentChild.childAt(2).is(SendGasRow), 'row[3] should be SendGasRow', - ) - assert.strictEqual(PageContainerContentChild.childAt(3).exists(), false) - }) - }) + ); + assert.strictEqual(PageContainerContentChild.childAt(3).exists(), false); + }); + }); it('should not render the asset dropdown if token length is 0 ', function () { - wrapper.setProps({ tokens: [] }) + wrapper.setProps({ tokens: [] }); const PageContainerContentChild = wrapper .find(PageContainerContent) - .children() - assert(PageContainerContentChild.childAt(1).is(SendAssetRow)) + .children(); + assert(PageContainerContentChild.childAt(1).is(SendAssetRow)); assert( PageContainerContentChild.childAt(1).find( 'send-v2__asset-dropdown__single-asset', ), true, - ) - }) + ); + }); it('should render warning', function () { wrapper.setProps({ warning: 'watchout', - }) + }); - const dialog = wrapper.find(Dialog).at(0) + const dialog = wrapper.find(Dialog).at(0); - assert.strictEqual(dialog.props().type, 'warning') - assert.strictEqual(dialog.props().children, 'watchout_t') - assert.strictEqual(dialog.length, 1) - }) -}) + assert.strictEqual(dialog.props().type, 'warning'); + assert.strictEqual(dialog.props().children, 'watchout_t'); + assert.strictEqual(dialog.length, 1); + }); +}); diff --git a/ui/app/pages/send/send-footer/index.js b/ui/app/pages/send/send-footer/index.js index 58e91d6222..cbada59c05 100644 --- a/ui/app/pages/send/send-footer/index.js +++ b/ui/app/pages/send/send-footer/index.js @@ -1 +1 @@ -export { default } from './send-footer.container' +export { default } from './send-footer.container'; diff --git a/ui/app/pages/send/send-footer/send-footer.component.js b/ui/app/pages/send/send-footer/send-footer.component.js index 938b7ce5a4..425c76086f 100644 --- a/ui/app/pages/send/send-footer/send-footer.component.js +++ b/ui/app/pages/send/send-footer/send-footer.component.js @@ -1,7 +1,7 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import PageContainerFooter from '../../../components/ui/page-container/page-container-footer' -import { CONFIRM_TRANSACTION_ROUTE } from '../../../helpers/constants/routes' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import PageContainerFooter from '../../../components/ui/page-container/page-container-footer'; +import { CONFIRM_TRANSACTION_ROUTE } from '../../../helpers/constants/routes'; export default class SendFooter extends Component { static propTypes = { @@ -27,21 +27,21 @@ export default class SendFooter extends Component { gasEstimateType: PropTypes.string, gasIsLoading: PropTypes.bool, mostRecentOverviewPage: PropTypes.string.isRequired, - } + }; static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; onCancel() { - const { clearSend, history, mostRecentOverviewPage } = this.props - clearSend() - history.push(mostRecentOverviewPage) + const { clearSend, history, mostRecentOverviewPage } = this.props; + clearSend(); + history.push(mostRecentOverviewPage); } async onSubmit(event) { - event.preventDefault() + event.preventDefault(); const { addToAddressBookIfNew, amount, @@ -59,8 +59,8 @@ export default class SendFooter extends Component { toAccounts, history, gasEstimateType, - } = this.props - const { metricsEvent } = this.context + } = this.props; + const { metricsEvent } = this.context; // Should not be needed because submit should be disabled if there are errors. // const noErrors = !amountError && toError === null @@ -70,7 +70,7 @@ export default class SendFooter extends Component { // } // TODO: add nickname functionality - await addToAddressBookIfNew(to, toAccounts) + await addToAddressBookIfNew(to, toAccounts); const promise = editingTransactionId ? update({ amount, @@ -83,7 +83,7 @@ export default class SendFooter extends Component { to, unapprovedTxs, }) - : sign({ data, sendToken, to, amount, from, gas, gasPrice }) + : sign({ data, sendToken, to, amount, from, gas, gasPrice }); Promise.resolve(promise).then(() => { metricsEvent({ @@ -95,9 +95,9 @@ export default class SendFooter extends Component { customVariables: { gasChanged: gasEstimateType, }, - }) - history.push(CONFIRM_TRANSACTION_ROUTE) - }) + }); + history.push(CONFIRM_TRANSACTION_ROUTE); + }); } formShouldBeDisabled() { @@ -110,25 +110,25 @@ export default class SendFooter extends Component { to, gasLimit, gasIsLoading, - } = this.props - const missingTokenBalance = sendToken && !tokenBalance - const gasLimitTooLow = gasLimit < 5208 // 5208 is hex value of 21000, minimum gas limit + } = this.props; + const missingTokenBalance = sendToken && !tokenBalance; + const gasLimitTooLow = gasLimit < 5208; // 5208 is hex value of 21000, minimum gas limit const shouldBeDisabled = inError || !gasTotal || missingTokenBalance || !(data || to) || gasLimitTooLow || - gasIsLoading - return shouldBeDisabled + gasIsLoading; + return shouldBeDisabled; } componentDidUpdate(prevProps) { - const { inError, sendErrors } = this.props - const { metricsEvent } = this.context + const { inError, sendErrors } = this.props; + const { metricsEvent } = this.context; if (!prevProps.inError && inError) { - const errorField = Object.keys(sendErrors).find((key) => sendErrors[key]) - const errorMessage = sendErrors[errorField] + const errorField = Object.keys(sendErrors).find((key) => sendErrors[key]); + const errorMessage = sendErrors[errorField]; metricsEvent({ eventOpts: { @@ -140,7 +140,7 @@ export default class SendFooter extends Component { errorField, errorMessage, }, - }) + }); } } @@ -151,6 +151,6 @@ export default class SendFooter extends Component { onSubmit={(e) => this.onSubmit(e)} disabled={this.formShouldBeDisabled()} /> - ) + ); } } diff --git a/ui/app/pages/send/send-footer/send-footer.container.js b/ui/app/pages/send/send-footer/send-footer.container.js index e03af32285..ff7b475bc0 100644 --- a/ui/app/pages/send/send-footer/send-footer.container.js +++ b/ui/app/pages/send/send-footer/send-footer.container.js @@ -1,11 +1,11 @@ -import { connect } from 'react-redux' +import { connect } from 'react-redux'; import { addToAddressBook, clearSend, signTokenTx, signTx, updateTransaction, -} from '../../../store/actions' +} from '../../../store/actions'; import { getGasLimit, getGasPrice, @@ -24,27 +24,30 @@ import { getGasIsLoading, getRenderableEstimateDataForSmallButtonsFromGWEI, getDefaultActiveButtonIndex, -} from '../../../selectors' -import { getMostRecentOverviewPage } from '../../../ducks/history/history' -import { addHexPrefix } from '../../../../../app/scripts/lib/util' -import SendFooter from './send-footer.component' +} from '../../../selectors'; +import { getMostRecentOverviewPage } from '../../../ducks/history/history'; +import { addHexPrefix } from '../../../../../app/scripts/lib/util'; +import SendFooter from './send-footer.component'; import { addressIsNew, constructTxParams, constructUpdatedTx, -} from './send-footer.utils' +} from './send-footer.utils'; -export default connect(mapStateToProps, mapDispatchToProps)(SendFooter) +export default connect(mapStateToProps, mapDispatchToProps)(SendFooter); function mapStateToProps(state) { - const gasButtonInfo = getRenderableEstimateDataForSmallButtonsFromGWEI(state) - const gasPrice = getGasPrice(state) - const activeButtonIndex = getDefaultActiveButtonIndex(gasButtonInfo, gasPrice) + const gasButtonInfo = getRenderableEstimateDataForSmallButtonsFromGWEI(state); + const gasPrice = getGasPrice(state); + const activeButtonIndex = getDefaultActiveButtonIndex( + gasButtonInfo, + gasPrice, + ); const gasEstimateType = activeButtonIndex >= 0 ? gasButtonInfo[activeButtonIndex].gasEstimateType - : 'custom' - const editingTransactionId = getSendEditingTransactionId(state) + : 'custom'; + const editingTransactionId = getSendEditingTransactionId(state); return { amount: getSendAmount(state), @@ -64,7 +67,7 @@ function mapStateToProps(state) { gasEstimateType, gasIsLoading: getGasIsLoading(state), mostRecentOverviewPage: getMostRecentOverviewPage(state), - } + }; } function mapDispatchToProps(dispatch) { @@ -79,11 +82,11 @@ function mapDispatchToProps(dispatch) { gasPrice, sendToken, to, - }) + }); sendToken ? dispatch(signTokenTx(sendToken.address, to, amount, txParams)) - : dispatch(signTx(txParams)) + : dispatch(signTx(txParams)); }, update: ({ amount, @@ -106,17 +109,17 @@ function mapDispatchToProps(dispatch) { sendToken, to, unapprovedTxs, - }) + }); - return dispatch(updateTransaction(editingTx)) + return dispatch(updateTransaction(editingTx)); }, addToAddressBookIfNew: (newAddress, toAccounts, nickname = '') => { - const hexPrefixedAddress = addHexPrefix(newAddress) + const hexPrefixedAddress = addHexPrefix(newAddress); if (addressIsNew(toAccounts, hexPrefixedAddress)) { // TODO: nickname, i.e. addToAddressBook(recipient, nickname) - dispatch(addToAddressBook(hexPrefixedAddress, nickname)) + dispatch(addToAddressBook(hexPrefixedAddress, nickname)); } }, - } + }; } diff --git a/ui/app/pages/send/send-footer/send-footer.utils.js b/ui/app/pages/send/send-footer/send-footer.utils.js index a09331da74..52be9143fa 100644 --- a/ui/app/pages/send/send-footer/send-footer.utils.js +++ b/ui/app/pages/send/send-footer/send-footer.utils.js @@ -1,7 +1,7 @@ -import ethAbi from 'ethereumjs-abi' -import { TOKEN_TRANSFER_FUNCTION_SIGNATURE } from '../send.constants' -import { addHexPrefix } from '../../../../../app/scripts/lib/util' -import { addHexPrefixToObjectValues } from '../../../helpers/utils/util' +import ethAbi from 'ethereumjs-abi'; +import { TOKEN_TRANSFER_FUNCTION_SIGNATURE } from '../send.constants'; +import { addHexPrefix } from '../../../../../app/scripts/lib/util'; +import { addHexPrefixToObjectValues } from '../../../helpers/utils/util'; export function constructTxParams({ sendToken, @@ -18,14 +18,14 @@ export function constructTxParams({ value: '0', gas, gasPrice, - } + }; if (!sendToken) { - txParams.value = amount - txParams.to = to + txParams.value = amount; + txParams.to = to; } - return addHexPrefixToObjectValues(txParams) + return addHexPrefixToObjectValues(txParams); } export function constructUpdatedTx({ @@ -39,10 +39,10 @@ export function constructUpdatedTx({ to, unapprovedTxs, }) { - const unapprovedTx = unapprovedTxs[editingTransactionId] + const unapprovedTx = unapprovedTxs[editingTransactionId]; const txParamsData = unapprovedTx.txParams.data ? unapprovedTx.txParams.data - : data + : data; const editingTx = { ...unapprovedTx, @@ -57,7 +57,7 @@ export function constructUpdatedTx({ value: amount, }), ), - } + }; if (sendToken) { Object.assign( @@ -77,20 +77,20 @@ export function constructUpdatedTx({ ) .join(''), }), - ) + ); } if (typeof editingTx.txParams.data === 'undefined') { - delete editingTx.txParams.data + delete editingTx.txParams.data; } - return editingTx + return editingTx; } export function addressIsNew(toAccounts, newAddress) { - const newAddressNormalized = newAddress.toLowerCase() + const newAddressNormalized = newAddress.toLowerCase(); const foundMatching = toAccounts.some( ({ address }) => address.toLowerCase() === newAddressNormalized, - ) - return !foundMatching + ); + return !foundMatching; } diff --git a/ui/app/pages/send/send-footer/tests/send-footer-component.test.js b/ui/app/pages/send/send-footer/tests/send-footer-component.test.js index d77b7fe878..a1f5a6ccdd 100644 --- a/ui/app/pages/send/send-footer/tests/send-footer-component.test.js +++ b/ui/app/pages/send/send-footer/tests/send-footer-component.test.js @@ -1,29 +1,29 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import sinon from 'sinon' -import { CONFIRM_TRANSACTION_ROUTE } from '../../../../helpers/constants/routes' -import SendFooter from '../send-footer.component' -import PageContainerFooter from '../../../../components/ui/page-container/page-container-footer' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import { CONFIRM_TRANSACTION_ROUTE } from '../../../../helpers/constants/routes'; +import SendFooter from '../send-footer.component'; +import PageContainerFooter from '../../../../components/ui/page-container/page-container-footer'; describe('SendFooter Component', function () { - let wrapper + let wrapper; const propsMethodSpies = { addToAddressBookIfNew: sinon.spy(), clearSend: sinon.spy(), sign: sinon.spy(), update: sinon.spy(), - } + }; const historySpies = { push: sinon.spy(), - } - const MOCK_EVENT = { preventDefault: () => undefined } + }; + const MOCK_EVENT = { preventDefault: () => undefined }; before(function () { - sinon.spy(SendFooter.prototype, 'onCancel') - sinon.spy(SendFooter.prototype, 'onSubmit') - }) + sinon.spy(SendFooter.prototype, 'onCancel'); + sinon.spy(SendFooter.prototype, 'onSubmit'); + }); beforeEach(function () { wrapper = shallow( @@ -51,41 +51,41 @@ describe('SendFooter Component', function () { mostRecentOverviewPage="mostRecentOverviewPage" />, { context: { t: (str) => str, metricsEvent: () => ({}) } }, - ) - }) + ); + }); afterEach(function () { - propsMethodSpies.clearSend.resetHistory() - propsMethodSpies.addToAddressBookIfNew.resetHistory() - propsMethodSpies.clearSend.resetHistory() - propsMethodSpies.sign.resetHistory() - propsMethodSpies.update.resetHistory() - historySpies.push.resetHistory() - SendFooter.prototype.onCancel.resetHistory() - SendFooter.prototype.onSubmit.resetHistory() - }) + propsMethodSpies.clearSend.resetHistory(); + propsMethodSpies.addToAddressBookIfNew.resetHistory(); + propsMethodSpies.clearSend.resetHistory(); + propsMethodSpies.sign.resetHistory(); + propsMethodSpies.update.resetHistory(); + historySpies.push.resetHistory(); + SendFooter.prototype.onCancel.resetHistory(); + SendFooter.prototype.onSubmit.resetHistory(); + }); after(function () { - sinon.restore() - }) + sinon.restore(); + }); describe('onCancel', function () { it('should call clearSend', function () { - assert.strictEqual(propsMethodSpies.clearSend.callCount, 0) - wrapper.instance().onCancel() - assert.strictEqual(propsMethodSpies.clearSend.callCount, 1) - }) + assert.strictEqual(propsMethodSpies.clearSend.callCount, 0); + wrapper.instance().onCancel(); + assert.strictEqual(propsMethodSpies.clearSend.callCount, 1); + }); it('should call history.push', function () { - assert.strictEqual(historySpies.push.callCount, 0) - wrapper.instance().onCancel() - assert.strictEqual(historySpies.push.callCount, 1) + assert.strictEqual(historySpies.push.callCount, 0); + wrapper.instance().onCancel(); + assert.strictEqual(historySpies.push.callCount, 1); assert.strictEqual( historySpies.push.getCall(0).args[0], 'mostRecentOverviewPage', - ) - }) - }) + ); + }); + }); describe('formShouldBeDisabled()', function () { const config = { @@ -129,31 +129,31 @@ describe('SendFooter Component', function () { expectedResult: false, gasIsLoading: false, }, - } + }; Object.entries(config).forEach(([description, obj]) => { it(description, function () { - wrapper.setProps(obj) + wrapper.setProps(obj); assert.strictEqual( wrapper.instance().formShouldBeDisabled(), obj.expectedResult, - ) - }) - }) - }) + ); + }); + }); + }); describe('onSubmit', function () { it('should call addToAddressBookIfNew with the correct params', function () { - wrapper.instance().onSubmit(MOCK_EVENT) - assert(propsMethodSpies.addToAddressBookIfNew.calledOnce) + wrapper.instance().onSubmit(MOCK_EVENT); + assert(propsMethodSpies.addToAddressBookIfNew.calledOnce); assert.deepStrictEqual( propsMethodSpies.addToAddressBookIfNew.getCall(0).args, ['mockTo', ['mockAccount']], - ) - }) + ); + }); it('should call props.update if editingTransactionId is truthy', async function () { - await wrapper.instance().onSubmit(MOCK_EVENT) - assert(propsMethodSpies.update.calledOnce) + await wrapper.instance().onSubmit(MOCK_EVENT); + assert(propsMethodSpies.update.calledOnce); assert.deepStrictEqual(propsMethodSpies.update.getCall(0).args[0], { data: undefined, amount: 'mockAmount', @@ -164,17 +164,17 @@ describe('SendFooter Component', function () { sendToken: { mockProp: 'mockSendTokenProp' }, to: 'mockTo', unapprovedTxs: {}, - }) - }) + }); + }); it('should not call props.sign if editingTransactionId is truthy', function () { - assert.strictEqual(propsMethodSpies.sign.callCount, 0) - }) + assert.strictEqual(propsMethodSpies.sign.callCount, 0); + }); it('should call props.sign if editingTransactionId is falsy', async function () { - wrapper.setProps({ editingTransactionId: null }) - await wrapper.instance().onSubmit(MOCK_EVENT) - assert(propsMethodSpies.sign.calledOnce) + wrapper.setProps({ editingTransactionId: null }); + await wrapper.instance().onSubmit(MOCK_EVENT); + assert(propsMethodSpies.sign.calledOnce); assert.deepStrictEqual(propsMethodSpies.sign.getCall(0).args[0], { data: undefined, amount: 'mockAmount', @@ -183,26 +183,26 @@ describe('SendFooter Component', function () { gasPrice: 'mockGasPrice', sendToken: { mockProp: 'mockSendTokenProp' }, to: 'mockTo', - }) - }) + }); + }); it('should not call props.update if editingTransactionId is falsy', function () { - assert.strictEqual(propsMethodSpies.update.callCount, 0) - }) + assert.strictEqual(propsMethodSpies.update.callCount, 0); + }); it('should call history.push', async function () { - await wrapper.instance().onSubmit(MOCK_EVENT) - assert.strictEqual(historySpies.push.callCount, 1) + await wrapper.instance().onSubmit(MOCK_EVENT); + assert.strictEqual(historySpies.push.callCount, 1); assert.strictEqual( historySpies.push.getCall(0).args[0], CONFIRM_TRANSACTION_ROUTE, - ) - }) - }) + ); + }); + }); describe('render', function () { beforeEach(function () { - sinon.stub(SendFooter.prototype, 'formShouldBeDisabled').returns(true) + sinon.stub(SendFooter.prototype, 'formShouldBeDisabled').returns(true); wrapper = shallow( , { context: { t: (str) => str, metricsEvent: () => ({}) } }, - ) - }) + ); + }); afterEach(function () { - SendFooter.prototype.formShouldBeDisabled.restore() - }) + SendFooter.prototype.formShouldBeDisabled.restore(); + }); it('should render a PageContainerFooter component', function () { - assert.strictEqual(wrapper.find(PageContainerFooter).length, 1) - }) + assert.strictEqual(wrapper.find(PageContainerFooter).length, 1); + }); it('should pass the correct props to PageContainerFooter', function () { const { onCancel, onSubmit, disabled } = wrapper .find(PageContainerFooter) - .props() - assert.strictEqual(disabled, true) - - assert.strictEqual(SendFooter.prototype.onSubmit.callCount, 0) - onSubmit(MOCK_EVENT) - assert.strictEqual(SendFooter.prototype.onSubmit.callCount, 1) - - assert.strictEqual(SendFooter.prototype.onCancel.callCount, 0) - onCancel() - assert.strictEqual(SendFooter.prototype.onCancel.callCount, 1) - }) - }) -}) + .props(); + assert.strictEqual(disabled, true); + + assert.strictEqual(SendFooter.prototype.onSubmit.callCount, 0); + onSubmit(MOCK_EVENT); + assert.strictEqual(SendFooter.prototype.onSubmit.callCount, 1); + + assert.strictEqual(SendFooter.prototype.onCancel.callCount, 0); + onCancel(); + assert.strictEqual(SendFooter.prototype.onCancel.callCount, 1); + }); + }); +}); diff --git a/ui/app/pages/send/send-footer/tests/send-footer-container.test.js b/ui/app/pages/send/send-footer/tests/send-footer-container.test.js index e037fe7cc4..88523ee278 100644 --- a/ui/app/pages/send/send-footer/tests/send-footer-container.test.js +++ b/ui/app/pages/send/send-footer/tests/send-footer-container.test.js @@ -1,8 +1,8 @@ -import assert from 'assert' -import proxyquire from 'proxyquire' -import sinon from 'sinon' +import assert from 'assert'; +import proxyquire from 'proxyquire'; +import sinon from 'sinon'; -let mapDispatchToProps +let mapDispatchToProps; const actionSpies = { addToAddressBook: sinon.spy(), @@ -10,20 +10,20 @@ const actionSpies = { signTokenTx: sinon.spy(), signTx: sinon.spy(), updateTransaction: sinon.spy(), -} +}; const utilsStubs = { addressIsNew: sinon.stub().returns(true), constructTxParams: sinon.stub().returns({ value: 'mockAmount', }), constructUpdatedTx: sinon.stub().returns('mockConstructedUpdatedTxParams'), -} +}; proxyquire('../send-footer.container.js', { 'react-redux': { connect: (_, md) => { - mapDispatchToProps = md - return () => ({}) + mapDispatchToProps = md; + return () => ({}); }, }, '../../../store/actions': actionSpies, @@ -49,25 +49,25 @@ proxyquire('../send-footer.container.js', { getDefaultActiveButtonIndex: () => 0, }, './send-footer.utils': utilsStubs, -}) +}); describe('send-footer container', function () { describe('mapDispatchToProps()', function () { - let dispatchSpy - let mapDispatchToPropsObject + let dispatchSpy; + let mapDispatchToPropsObject; beforeEach(function () { - dispatchSpy = sinon.spy() - mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy) - }) + dispatchSpy = sinon.spy(); + mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy); + }); describe('clearSend()', function () { it('should dispatch an action', function () { - mapDispatchToPropsObject.clearSend() - assert(dispatchSpy.calledOnce) - assert(actionSpies.clearSend.calledOnce) - }) - }) + mapDispatchToPropsObject.clearSend(); + assert(dispatchSpy.calledOnce); + assert(actionSpies.clearSend.calledOnce); + }); + }); describe('sign()', function () { it('should dispatch a signTokenTx action if sendToken is defined', function () { @@ -80,8 +80,8 @@ describe('send-footer container', function () { from: 'mockFrom', gas: 'mockGas', gasPrice: 'mockGasPrice', - }) - assert(dispatchSpy.calledOnce) + }); + assert(dispatchSpy.calledOnce); assert.deepStrictEqual( utilsStubs.constructTxParams.getCall(0).args[0], { @@ -95,25 +95,25 @@ describe('send-footer container', function () { gas: 'mockGas', gasPrice: 'mockGasPrice', }, - ) + ); assert.deepStrictEqual(actionSpies.signTokenTx.getCall(0).args, [ '0xabc', 'mockTo', 'mockAmount', { value: 'mockAmount' }, - ]) - }) + ]); + }); it('should dispatch a sign action if sendToken is not defined', function () { - utilsStubs.constructTxParams.resetHistory() + utilsStubs.constructTxParams.resetHistory(); mapDispatchToPropsObject.sign({ to: 'mockTo', amount: 'mockAmount', from: 'mockFrom', gas: 'mockGas', gasPrice: 'mockGasPrice', - }) - assert(dispatchSpy.calledOnce) + }); + assert(dispatchSpy.calledOnce); assert.deepStrictEqual( utilsStubs.constructTxParams.getCall(0).args[0], { @@ -125,12 +125,12 @@ describe('send-footer container', function () { gas: 'mockGas', gasPrice: 'mockGasPrice', }, - ) + ); assert.deepStrictEqual(actionSpies.signTx.getCall(0).args, [ { value: 'mockAmount' }, - ]) - }) - }) + ]); + }); + }); describe('update()', function () { it('should dispatch an updateTransaction action', function () { @@ -143,8 +143,8 @@ describe('send-footer container', function () { editingTransactionId: 'mockEditingTransactionId', sendToken: { address: 'mockAddress' }, unapprovedTxs: 'mockUnapprovedTxs', - }) - assert(dispatchSpy.calledOnce) + }); + assert(dispatchSpy.calledOnce); assert.deepStrictEqual( utilsStubs.constructUpdatedTx.getCall(0).args[0], { @@ -158,13 +158,13 @@ describe('send-footer container', function () { sendToken: { address: 'mockAddress' }, unapprovedTxs: 'mockUnapprovedTxs', }, - ) + ); assert.strictEqual( actionSpies.updateTransaction.getCall(0).args[0], 'mockConstructedUpdatedTxParams', - ) - }) - }) + ); + }); + }); describe('addToAddressBookIfNew()', function () { it('should dispatch an action', function () { @@ -172,17 +172,17 @@ describe('send-footer container', function () { 'mockNewAddress', 'mockToAccounts', 'mockNickname', - ) - assert(dispatchSpy.calledOnce) + ); + assert(dispatchSpy.calledOnce); assert.strictEqual( utilsStubs.addressIsNew.getCall(0).args[0], 'mockToAccounts', - ) + ); assert.deepStrictEqual(actionSpies.addToAddressBook.getCall(0).args, [ '0xmockNewAddress', 'mockNickname', - ]) - }) - }) - }) -}) + ]); + }); + }); + }); +}); diff --git a/ui/app/pages/send/send-footer/tests/send-footer-utils.test.js b/ui/app/pages/send/send-footer/tests/send-footer-utils.test.js index 52a84a9932..9d7507f578 100644 --- a/ui/app/pages/send/send-footer/tests/send-footer-utils.test.js +++ b/ui/app/pages/send/send-footer/tests/send-footer-utils.test.js @@ -1,20 +1,20 @@ -import assert from 'assert' -import proxyquire from 'proxyquire' -import sinon from 'sinon' -import { TOKEN_TRANSFER_FUNCTION_SIGNATURE } from '../../send.constants' +import assert from 'assert'; +import proxyquire from 'proxyquire'; +import sinon from 'sinon'; +import { TOKEN_TRANSFER_FUNCTION_SIGNATURE } from '../../send.constants'; const stubs = { rawEncode: sinon.stub().callsFake((arr1, arr2) => { - return [...arr1, ...arr2] + return [...arr1, ...arr2]; }), -} +}; const sendUtils = proxyquire('../send-footer.utils.js', { 'ethereumjs-abi': { rawEncode: stubs.rawEncode, }, -}) -const { addressIsNew, constructTxParams, constructUpdatedTx } = sendUtils +}); +const { addressIsNew, constructTxParams, constructUpdatedTx } = sendUtils; describe('send-footer utils', function () { describe('addressIsNew()', function () { @@ -25,8 +25,8 @@ describe('send-footer utils', function () { '0xdef', ), false, - ) - }) + ); + }); it('should return true if the address does not exists in toAccounts', function () { assert.strictEqual( @@ -35,9 +35,9 @@ describe('send-footer utils', function () { '0xxyz', ), true, - ) - }) - }) + ); + }); + }); describe('constructTxParams()', function () { it('should return a new txParams object with data if there data is given', function () { @@ -59,8 +59,8 @@ describe('send-footer utils', function () { gas: '0xmockGas', gasPrice: '0xmockGasPrice', }, - ) - }) + ); + }); it('should return a new txParams object with value and to properties if there is no sendToken', function () { assert.deepStrictEqual( @@ -80,8 +80,8 @@ describe('send-footer utils', function () { gas: '0xmockGas', gasPrice: '0xmockGasPrice', }, - ) - }) + ); + }); it('should return a new txParams object without a to property and a 0 value if there is a sendToken', function () { assert.deepStrictEqual( @@ -100,9 +100,9 @@ describe('send-footer utils', function () { gas: '0xmockGas', gasPrice: '0xmockGasPrice', }, - ) - }) - }) + ); + }); + }); describe('constructUpdatedTx()', function () { it('should return a new object with an updated txParams', function () { @@ -123,7 +123,7 @@ describe('send-footer utils', function () { }, }, }, - }) + }); assert.deepStrictEqual(result, { unapprovedTxParam: 'someOtherParam', txParams: { @@ -134,8 +134,8 @@ describe('send-footer utils', function () { to: '0xmockTo', data: '0xsomeData', }, - }) - }) + }); + }); it('should not have data property if there is non in the original tx', function () { const result = constructUpdatedTx({ @@ -157,7 +157,7 @@ describe('send-footer utils', function () { }, }, }, - }) + }); assert.deepStrictEqual(result, { unapprovedTxParam: 'someOtherParam', @@ -168,8 +168,8 @@ describe('send-footer utils', function () { value: '0xmockAmount', to: '0xmockTo', }, - }) - }) + }); + }); it('should have token property values if sendToken is truthy', function () { const result = constructUpdatedTx({ @@ -189,7 +189,7 @@ describe('send-footer utils', function () { txParams: {}, }, }, - }) + }); assert.deepStrictEqual(result, { unapprovedTxParam: 'someOtherParam', @@ -201,7 +201,7 @@ describe('send-footer utils', function () { to: '0xmockTokenAddress', data: `${TOKEN_TRANSFER_FUNCTION_SIGNATURE}ss56Tont`, }, - }) - }) - }) -}) + }); + }); + }); +}); diff --git a/ui/app/pages/send/send-header/index.js b/ui/app/pages/send/send-header/index.js index 0b17f0b7d2..cfb4823032 100644 --- a/ui/app/pages/send/send-header/index.js +++ b/ui/app/pages/send/send-header/index.js @@ -1 +1 @@ -export { default } from './send-header.container' +export { default } from './send-header.container'; diff --git a/ui/app/pages/send/send-header/send-header.component.js b/ui/app/pages/send/send-header/send-header.component.js index 2f69883c5f..303ef4c7ae 100644 --- a/ui/app/pages/send/send-header/send-header.component.js +++ b/ui/app/pages/send/send-header/send-header.component.js @@ -1,6 +1,6 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import PageContainerHeader from '../../../components/ui/page-container/page-container-header' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import PageContainerHeader from '../../../components/ui/page-container/page-container-header'; export default class SendHeader extends Component { static propTypes = { @@ -8,16 +8,16 @@ export default class SendHeader extends Component { history: PropTypes.object, mostRecentOverviewPage: PropTypes.string, titleKey: PropTypes.string, - } + }; static contextTypes = { t: PropTypes.func, - } + }; onClose() { - const { clearSend, history, mostRecentOverviewPage } = this.props - clearSend() - history.push(mostRecentOverviewPage) + const { clearSend, history, mostRecentOverviewPage } = this.props; + clearSend(); + history.push(mostRecentOverviewPage); } render() { @@ -28,6 +28,6 @@ export default class SendHeader extends Component { title={this.context.t(this.props.titleKey)} headerCloseText={this.context.t('cancel')} /> - ) + ); } } diff --git a/ui/app/pages/send/send-header/send-header.container.js b/ui/app/pages/send/send-header/send-header.container.js index be805b55a1..9f67cb2af0 100644 --- a/ui/app/pages/send/send-header/send-header.container.js +++ b/ui/app/pages/send/send-header/send-header.container.js @@ -1,20 +1,20 @@ -import { connect } from 'react-redux' -import { clearSend } from '../../../store/actions' -import { getTitleKey } from '../../../selectors' -import { getMostRecentOverviewPage } from '../../../ducks/history/history' -import SendHeader from './send-header.component' +import { connect } from 'react-redux'; +import { clearSend } from '../../../store/actions'; +import { getTitleKey } from '../../../selectors'; +import { getMostRecentOverviewPage } from '../../../ducks/history/history'; +import SendHeader from './send-header.component'; -export default connect(mapStateToProps, mapDispatchToProps)(SendHeader) +export default connect(mapStateToProps, mapDispatchToProps)(SendHeader); function mapStateToProps(state) { return { mostRecentOverviewPage: getMostRecentOverviewPage(state), titleKey: getTitleKey(state), - } + }; } function mapDispatchToProps(dispatch) { return { clearSend: () => dispatch(clearSend()), - } + }; } diff --git a/ui/app/pages/send/send-header/tests/send-header-component.test.js b/ui/app/pages/send/send-header/tests/send-header-component.test.js index 03168bed10..14cde996ac 100644 --- a/ui/app/pages/send/send-header/tests/send-header-component.test.js +++ b/ui/app/pages/send/send-header/tests/send-header-component.test.js @@ -1,23 +1,23 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import sinon from 'sinon' -import SendHeader from '../send-header.component' -import PageContainerHeader from '../../../../components/ui/page-container/page-container-header' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import SendHeader from '../send-header.component'; +import PageContainerHeader from '../../../../components/ui/page-container/page-container-header'; describe('SendHeader Component', function () { - let wrapper + let wrapper; const propsMethodSpies = { clearSend: sinon.spy(), - } + }; const historySpies = { push: sinon.spy(), - } + }; before(function () { - sinon.spy(SendHeader.prototype, 'onClose') - }) + sinon.spy(SendHeader.prototype, 'onClose'); + }); beforeEach(function () { wrapper = shallow( @@ -28,48 +28,48 @@ describe('SendHeader Component', function () { titleKey="mockTitleKey" />, { context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) } }, - ) - }) + ); + }); afterEach(function () { - propsMethodSpies.clearSend.resetHistory() - historySpies.push.resetHistory() - SendHeader.prototype.onClose.resetHistory() - }) + propsMethodSpies.clearSend.resetHistory(); + historySpies.push.resetHistory(); + SendHeader.prototype.onClose.resetHistory(); + }); after(function () { - sinon.restore() - }) + sinon.restore(); + }); describe('onClose', function () { it('should call clearSend', function () { - assert.strictEqual(propsMethodSpies.clearSend.callCount, 0) - wrapper.instance().onClose() - assert.strictEqual(propsMethodSpies.clearSend.callCount, 1) - }) + assert.strictEqual(propsMethodSpies.clearSend.callCount, 0); + wrapper.instance().onClose(); + assert.strictEqual(propsMethodSpies.clearSend.callCount, 1); + }); it('should call history.push', function () { - assert.strictEqual(historySpies.push.callCount, 0) - wrapper.instance().onClose() - assert.strictEqual(historySpies.push.callCount, 1) + assert.strictEqual(historySpies.push.callCount, 0); + wrapper.instance().onClose(); + assert.strictEqual(historySpies.push.callCount, 1); assert.strictEqual( historySpies.push.getCall(0).args[0], 'mostRecentOverviewPage', - ) - }) - }) + ); + }); + }); describe('render', function () { it('should render a PageContainerHeader component', function () { - assert.strictEqual(wrapper.find(PageContainerHeader).length, 1) - }) + assert.strictEqual(wrapper.find(PageContainerHeader).length, 1); + }); it('should pass the correct props to PageContainerHeader', function () { - const { onClose, title } = wrapper.find(PageContainerHeader).props() - assert.strictEqual(title, 'mockTitleKey') - assert.strictEqual(SendHeader.prototype.onClose.callCount, 0) - onClose() - assert.strictEqual(SendHeader.prototype.onClose.callCount, 1) - }) - }) -}) + const { onClose, title } = wrapper.find(PageContainerHeader).props(); + assert.strictEqual(title, 'mockTitleKey'); + assert.strictEqual(SendHeader.prototype.onClose.callCount, 0); + onClose(); + assert.strictEqual(SendHeader.prototype.onClose.callCount, 1); + }); + }); +}); diff --git a/ui/app/pages/send/send.component.js b/ui/app/pages/send/send.component.js index 31540e3122..74d4f86f4a 100644 --- a/ui/app/pages/send/send.component.js +++ b/ui/app/pages/send/send.component.js @@ -1,23 +1,23 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import ethUtil from 'ethereumjs-util' -import { debounce } from 'lodash' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import ethUtil from 'ethereumjs-util'; +import { debounce } from 'lodash'; import { getAmountErrorObject, getGasFeeErrorObject, getToAddressForGasUpdate, doesAmountErrorRequireUpdate, -} from './send.utils' +} from './send.utils'; import { getToWarningObject, getToErrorObject, -} from './send-content/add-recipient/add-recipient' -import SendHeader from './send-header' -import AddRecipient from './send-content/add-recipient' -import SendContent from './send-content' -import SendFooter from './send-footer' -import EnsInput from './send-content/add-recipient/ens-input' -import { INVALID_RECIPIENT_ADDRESS_ERROR } from './send.constants' +} from './send-content/add-recipient/add-recipient'; +import SendHeader from './send-header'; +import AddRecipient from './send-content/add-recipient'; +import SendContent from './send-content'; +import SendFooter from './send-footer'; +import EnsInput from './send-content/add-recipient/ens-input'; +import { INVALID_RECIPIENT_ADDRESS_ERROR } from './send.constants'; export default class SendTransactionScreen extends Component { static propTypes = { @@ -54,23 +54,23 @@ export default class SendTransactionScreen extends Component { scanQrCode: PropTypes.func.isRequired, qrCodeDetected: PropTypes.func.isRequired, qrCodeData: PropTypes.object, - } + }; static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; state = { query: '', toError: null, toWarning: null, internalSearch: false, - } + }; constructor(props) { - super(props) - this.dValidate = debounce(this.validate, 1000) + super(props); + this.dValidate = debounce(this.validate, 1000); } componentDidUpdate(prevProps) { @@ -93,9 +93,9 @@ export default class SendTransactionScreen extends Component { updateToNicknameIfNecessary, qrCodeData, qrCodeDetected, - } = this.props + } = this.props; - let updateGas = false + let updateGas = false; const { from: { balance: prevBalance }, gasTotal: prevGasTotal, @@ -103,9 +103,9 @@ export default class SendTransactionScreen extends Component { network: prevNetwork, sendToken: prevSendToken, to: prevTo, - } = prevProps + } = prevProps; - const uninitialized = [prevBalance, prevGasTotal].every((n) => n === null) + const uninitialized = [prevBalance, prevGasTotal].every((n) => n === null); const amountErrorRequiresUpdate = doesAmountErrorRequireUpdate({ balance, @@ -115,7 +115,7 @@ export default class SendTransactionScreen extends Component { prevTokenBalance, sendToken, tokenBalance, - }) + }); if (amountErrorRequiresUpdate) { const amountErrorObject = getAmountErrorObject({ @@ -126,7 +126,7 @@ export default class SendTransactionScreen extends Component { primaryCurrency, sendToken, tokenBalance, - }) + }); const gasFeeErrorObject = sendToken ? getGasFeeErrorObject({ balance, @@ -135,8 +135,8 @@ export default class SendTransactionScreen extends Component { primaryCurrency, sendToken, }) - : { gasFee: null } - updateSendErrors(Object.assign(amountErrorObject, gasFeeErrorObject)) + : { gasFee: null }; + updateSendErrors(Object.assign(amountErrorObject, gasFeeErrorObject)); } if (!uninitialized) { @@ -145,110 +145,110 @@ export default class SendTransactionScreen extends Component { sendToken, tokenContract, address, - }) - updateToNicknameIfNecessary(to, toNickname, addressBook) - updateGas = true + }); + updateToNicknameIfNecessary(to, toNickname, addressBook); + updateGas = true; } } - const prevTokenAddress = prevSendToken && prevSendToken.address - const sendTokenAddress = sendToken && sendToken.address + const prevTokenAddress = prevSendToken && prevSendToken.address; + const sendTokenAddress = sendToken && sendToken.address; if (sendTokenAddress && prevTokenAddress !== sendTokenAddress) { - this.updateSendToken() - this.validate(this.state.query) - updateGas = true + this.updateSendToken(); + this.validate(this.state.query); + updateGas = true; } - let scannedAddress + let scannedAddress; if (qrCodeData) { if (qrCodeData.type === 'address') { - scannedAddress = qrCodeData.values.address.toLowerCase() + scannedAddress = qrCodeData.values.address.toLowerCase(); if (ethUtil.isValidAddress(scannedAddress)) { - const currentAddress = prevTo?.toLowerCase() + const currentAddress = prevTo?.toLowerCase(); if (currentAddress !== scannedAddress) { - updateSendTo(scannedAddress) - updateGas = true + updateSendTo(scannedAddress); + updateGas = true; // Clean up QR code data after handling - qrCodeDetected(null) + qrCodeDetected(null); } } else { - scannedAddress = null - qrCodeDetected(null) - this.setState({ toError: INVALID_RECIPIENT_ADDRESS_ERROR }) + scannedAddress = null; + qrCodeDetected(null); + this.setState({ toError: INVALID_RECIPIENT_ADDRESS_ERROR }); } } } if (updateGas) { if (scannedAddress) { - this.updateGas({ to: scannedAddress }) + this.updateGas({ to: scannedAddress }); } else { - this.updateGas() + this.updateGas(); } } } componentDidMount() { this.props.fetchBasicGasEstimates().then(() => { - this.updateGas() - }) + this.updateGas(); + }); } UNSAFE_componentWillMount() { - this.updateSendToken() + this.updateSendToken(); // Show QR Scanner modal if ?scan=true if (window.location.search === '?scan=true') { - this.props.scanQrCode() + this.props.scanQrCode(); // Clear the queryString param after showing the modal - const cleanUrl = window.location.href.split('?')[0] - window.history.pushState({}, null, `${cleanUrl}`) - window.location.hash = '#send' + const cleanUrl = window.location.href.split('?')[0]; + window.history.pushState({}, null, `${cleanUrl}`); + window.location.hash = '#send'; } } componentWillUnmount() { - this.props.resetSendState() + this.props.resetSendState(); } onRecipientInputChange = (query) => { - const { internalSearch } = this.state + const { internalSearch } = this.state; if (!internalSearch) { if (query) { - this.dValidate(query) + this.dValidate(query); } else { - this.dValidate.cancel() - this.validate(query) + this.dValidate.cancel(); + this.validate(query); } } - this.setState({ query }) - } + this.setState({ query }); + }; setInternalSearch(internalSearch) { - this.setState({ query: '', internalSearch }) + this.setState({ query: '', internalSearch }); } validate(query) { - const { hasHexData, tokens, sendToken, network } = this.props + const { hasHexData, tokens, sendToken, network } = this.props; - const { internalSearch } = this.state + const { internalSearch } = this.state; if (!query || internalSearch) { - this.setState({ toError: '', toWarning: '' }) - return + this.setState({ toError: '', toWarning: '' }); + return; } - const toErrorObject = getToErrorObject(query, hasHexData, network) - const toWarningObject = getToWarningObject(query, tokens, sendToken) + const toErrorObject = getToErrorObject(query, hasHexData, network); + const toWarningObject = getToWarningObject(query, tokens, sendToken); this.setState({ toError: toErrorObject.to, toWarning: toWarningObject.to, - }) + }); } updateSendToken() { @@ -257,13 +257,13 @@ export default class SendTransactionScreen extends Component { sendToken, tokenContract, updateSendTokenBalance, - } = this.props + } = this.props; updateSendTokenBalance({ sendToken, tokenContract, address, - }) + }); } updateGas({ to: updatedToAddress, amount: value, data } = {}) { @@ -277,7 +277,7 @@ export default class SendTransactionScreen extends Component { sendToken, to: currentToAddress, updateAndSetGasLimit, - } = this.props + } = this.props; updateAndSetGasLimit({ blockGasLimit, @@ -289,17 +289,17 @@ export default class SendTransactionScreen extends Component { to: getToAddressForGasUpdate(updatedToAddress, currentToAddress), value: value || amount, data, - }) + }); } render() { - const { history, to } = this.props - let content + const { history, to } = this.props; + let content; if (to) { - content = this.renderSendContent() + content = this.renderSendContent(); } else { - content = this.renderAddRecipient() + content = this.renderAddRecipient(); } return ( @@ -308,11 +308,11 @@ export default class SendTransactionScreen extends Component { {this.renderInput()} {content} - ) + ); } renderInput() { - const { internalSearch } = this.state + const { internalSearch } = this.state; return ( this.props.updateSendTo(address, '')} onPaste={(text) => { - this.props.updateSendTo(text) && this.updateGas() + this.props.updateSendTo(text) && this.updateGas(); }} onReset={() => this.props.updateSendTo('', '')} updateEnsResolution={this.props.updateSendEnsResolution} updateEnsResolutionError={this.props.updateSendEnsResolutionError} internalSearch={internalSearch} /> - ) + ); } renderAddRecipient() { - const { toError } = this.state + const { toError } = this.state; return ( @@ -352,12 +352,12 @@ export default class SendTransactionScreen extends Component { this.setInternalSearch(internalSearch) } /> - ) + ); } renderSendContent() { - const { history, showHexData } = this.props - const { toWarning } = this.state + const { history, showHexData } = this.props; + const { toWarning } = this.state; return [ , , - ] + ]; } } diff --git a/ui/app/pages/send/send.constants.js b/ui/app/pages/send/send.constants.js index 2f989bc37f..7b1a1f1a37 100644 --- a/ui/app/pages/send/send.constants.js +++ b/ui/app/pages/send/send.constants.js @@ -1,13 +1,13 @@ import { conversionUtil, multiplyCurrencies, -} from '../../helpers/utils/conversion-util' -import { addHexPrefix } from '../../../../app/scripts/lib/util' +} from '../../helpers/utils/conversion-util'; +import { addHexPrefix } from '../../../../app/scripts/lib/util'; -const MIN_GAS_PRICE_DEC = '0' -const MIN_GAS_PRICE_HEX = parseInt(MIN_GAS_PRICE_DEC, 10).toString(16) -const MIN_GAS_LIMIT_DEC = '21000' -const MIN_GAS_LIMIT_HEX = parseInt(MIN_GAS_LIMIT_DEC, 10).toString(16) +const MIN_GAS_PRICE_DEC = '0'; +const MIN_GAS_PRICE_HEX = parseInt(MIN_GAS_PRICE_DEC, 10).toString(16); +const MIN_GAS_LIMIT_DEC = '21000'; +const MIN_GAS_LIMIT_HEX = parseInt(MIN_GAS_LIMIT_DEC, 10).toString(16); const MIN_GAS_PRICE_GWEI = addHexPrefix( conversionUtil(MIN_GAS_PRICE_HEX, { @@ -17,27 +17,27 @@ const MIN_GAS_PRICE_GWEI = addHexPrefix( toNumericBase: 'hex', numberOfDecimals: 1, }), -) +); const MIN_GAS_TOTAL = multiplyCurrencies(MIN_GAS_LIMIT_HEX, MIN_GAS_PRICE_HEX, { toNumericBase: 'hex', multiplicandBase: 16, multiplierBase: 16, -}) +}); -const TOKEN_TRANSFER_FUNCTION_SIGNATURE = '0xa9059cbb' +const TOKEN_TRANSFER_FUNCTION_SIGNATURE = '0xa9059cbb'; -const INSUFFICIENT_FUNDS_ERROR = 'insufficientFunds' -const INSUFFICIENT_TOKENS_ERROR = 'insufficientTokens' -const NEGATIVE_ETH_ERROR = 'negativeETH' -const INVALID_RECIPIENT_ADDRESS_ERROR = 'invalidAddressRecipient' +const INSUFFICIENT_FUNDS_ERROR = 'insufficientFunds'; +const INSUFFICIENT_TOKENS_ERROR = 'insufficientTokens'; +const NEGATIVE_ETH_ERROR = 'negativeETH'; +const INVALID_RECIPIENT_ADDRESS_ERROR = 'invalidAddressRecipient'; const INVALID_RECIPIENT_ADDRESS_NOT_ETH_NETWORK_ERROR = - 'invalidAddressRecipientNotEthNetwork' -const REQUIRED_ERROR = 'required' -const KNOWN_RECIPIENT_ADDRESS_ERROR = 'knownAddressRecipient' + 'invalidAddressRecipientNotEthNetwork'; +const REQUIRED_ERROR = 'required'; +const KNOWN_RECIPIENT_ADDRESS_ERROR = 'knownAddressRecipient'; -const SIMPLE_GAS_COST = '0x5208' // Hex for 21000, cost of a simple send. -const BASE_TOKEN_GAS_COST = '0x186a0' // Hex for 100000, a base estimate for token transfers. +const SIMPLE_GAS_COST = '0x5208'; // Hex for 21000, cost of a simple send. +const BASE_TOKEN_GAS_COST = '0x186a0'; // Hex for 100000, a base estimate for token transfers. export { INSUFFICIENT_FUNDS_ERROR, @@ -56,4 +56,4 @@ export { SIMPLE_GAS_COST, TOKEN_TRANSFER_FUNCTION_SIGNATURE, BASE_TOKEN_GAS_COST, -} +}; diff --git a/ui/app/pages/send/send.container.js b/ui/app/pages/send/send.container.js index 0d9fe9219e..c460b4526f 100644 --- a/ui/app/pages/send/send.container.js +++ b/ui/app/pages/send/send.container.js @@ -1,6 +1,6 @@ -import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom' -import { compose } from 'redux' +import { connect } from 'react-redux'; +import { withRouter } from 'react-router-dom'; +import { compose } from 'redux'; import { getBlockGasLimit, @@ -22,7 +22,7 @@ import { getQrCodeData, getSelectedAddress, getAddressBook, -} from '../../selectors' +} from '../../selectors'; import { updateSendTo, @@ -33,16 +33,16 @@ import { qrCodeDetected, updateSendEnsResolution, updateSendEnsResolutionError, -} from '../../store/actions' -import { resetSendState, updateSendErrors } from '../../ducks/send/send.duck' -import { fetchBasicGasEstimates } from '../../ducks/gas/gas.duck' -import { getTokens } from '../../ducks/metamask/metamask' -import { isValidDomainName } from '../../helpers/utils/util' -import { calcGasTotal } from './send.utils' -import SendEther from './send.component' +} from '../../store/actions'; +import { resetSendState, updateSendErrors } from '../../ducks/send/send.duck'; +import { fetchBasicGasEstimates } from '../../ducks/gas/gas.duck'; +import { getTokens } from '../../ducks/metamask/metamask'; +import { isValidDomainName } from '../../helpers/utils/util'; +import { calcGasTotal } from './send.utils'; +import SendEther from './send.component'; function mapStateToProps(state) { - const editingTransactionId = getSendEditingTransactionId(state) + const editingTransactionId = getSendEditingTransactionId(state); return { addressBook: getAddressBook(state), @@ -65,7 +65,7 @@ function mapStateToProps(state) { tokens: getTokens(state), tokenBalance: getTokenBalance(state), tokenContract: getSendTokenContract(state), - } + }; } function mapDispatchToProps(dispatch) { @@ -93,7 +93,7 @@ function mapDispatchToProps(dispatch) { value, data, }), - ) + ); }, updateSendTokenBalance: ({ sendToken, tokenContract, address }) => { dispatch( @@ -102,7 +102,7 @@ function mapDispatchToProps(dispatch) { tokenContract, address, }), - ) + ); }, updateSendErrors: (newError) => dispatch(updateSendErrors(newError)), resetSendState: () => dispatch(resetSendState()), @@ -117,16 +117,16 @@ function mapDispatchToProps(dispatch) { updateToNicknameIfNecessary: (to, toNickname, addressBook) => { if (isValidDomainName(toNickname)) { const addressBookEntry = - addressBook.find(({ address }) => to === address) || {} + addressBook.find(({ address }) => to === address) || {}; if (!addressBookEntry.name !== toNickname) { - dispatch(updateSendTo(to, addressBookEntry.name || '')) + dispatch(updateSendTo(to, addressBookEntry.name || '')); } } }, - } + }; } export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps), -)(SendEther) +)(SendEther); diff --git a/ui/app/pages/send/send.utils.js b/ui/app/pages/send/send.utils.js index 08daeb6ab9..ffe76241d2 100644 --- a/ui/app/pages/send/send.utils.js +++ b/ui/app/pages/send/send.utils.js @@ -1,4 +1,4 @@ -import abi from 'ethereumjs-abi' +import abi from 'ethereumjs-abi'; import { addCurrencies, conversionUtil, @@ -6,10 +6,10 @@ import { multiplyCurrencies, conversionGreaterThan, conversionLessThan, -} from '../../helpers/utils/conversion-util' +} from '../../helpers/utils/conversion-util'; -import { calcTokenAmount } from '../../helpers/utils/token-util' -import { addHexPrefix } from '../../../../app/scripts/lib/util' +import { calcTokenAmount } from '../../helpers/utils/token-util'; +import { addHexPrefix } from '../../../../app/scripts/lib/util'; import { BASE_TOKEN_GAS_COST, @@ -19,7 +19,7 @@ import { NEGATIVE_ETH_ERROR, SIMPLE_GAS_COST, TOKEN_TRANSFER_FUNCTION_SIGNATURE, -} from './send.constants' +} from './send.constants'; export { addGasBuffer, @@ -35,14 +35,14 @@ export { isTokenBalanceSufficient, removeLeadingZeroes, ellipsify, -} +}; function calcGasTotal(gasLimit = '0', gasPrice = '0') { return multiplyCurrencies(gasLimit, gasPrice, { toNumericBase: 'hex', multiplicandBase: 16, multiplierBase: 16, - }) + }); } function isBalanceSufficient({ @@ -56,7 +56,7 @@ function isBalanceSufficient({ aBase: 16, bBase: 16, toNumericBase: 'hex', - }) + }); const balanceIsSufficient = conversionGTE( { @@ -71,15 +71,15 @@ function isBalanceSufficient({ conversionRate, fromCurrency: primaryCurrency, }, - ) + ); - return balanceIsSufficient + return balanceIsSufficient; } function isTokenBalanceSufficient({ amount = '0x0', tokenBalance, decimals }) { const amountInDec = conversionUtil(amount, { fromNumericBase: 'hex', - }) + }); const tokenBalanceIsSufficient = conversionGTE( { @@ -89,9 +89,9 @@ function isTokenBalanceSufficient({ amount = '0x0', tokenBalance, decimals }) { { value: calcTokenAmount(amountInDec, decimals), }, - ) + ); - return tokenBalanceIsSufficient + return tokenBalanceIsSufficient; } function getAmountErrorObject({ @@ -103,7 +103,7 @@ function getAmountErrorObject({ sendToken, tokenBalance, }) { - let insufficientFunds = false + let insufficientFunds = false; if (gasTotal && conversionRate && !sendToken) { insufficientFunds = !isBalanceSufficient({ amount, @@ -111,35 +111,35 @@ function getAmountErrorObject({ conversionRate, gasTotal, primaryCurrency, - }) + }); } - let inSufficientTokens = false + let inSufficientTokens = false; if (sendToken && tokenBalance !== null) { - const { decimals } = sendToken + const { decimals } = sendToken; inSufficientTokens = !isTokenBalanceSufficient({ tokenBalance, amount, decimals, - }) + }); } const amountLessThanZero = conversionGreaterThan( { value: 0, fromNumericBase: 'dec' }, { value: amount, fromNumericBase: 'hex' }, - ) + ); - let amountError = null + let amountError = null; if (insufficientFunds) { - amountError = INSUFFICIENT_FUNDS_ERROR + amountError = INSUFFICIENT_FUNDS_ERROR; } else if (inSufficientTokens) { - amountError = INSUFFICIENT_TOKENS_ERROR + amountError = INSUFFICIENT_TOKENS_ERROR; } else if (amountLessThanZero) { - amountError = NEGATIVE_ETH_ERROR + amountError = NEGATIVE_ETH_ERROR; } - return { amount: amountError } + return { amount: amountError }; } function getGasFeeErrorObject({ @@ -148,7 +148,7 @@ function getGasFeeErrorObject({ gasTotal, primaryCurrency, }) { - let gasFeeError = null + let gasFeeError = null; if (gasTotal && conversionRate) { const insufficientFunds = !isBalanceSufficient({ @@ -157,19 +157,19 @@ function getGasFeeErrorObject({ conversionRate, gasTotal, primaryCurrency, - }) + }); if (insufficientFunds) { - gasFeeError = INSUFFICIENT_FUNDS_ERROR + gasFeeError = INSUFFICIENT_FUNDS_ERROR; } } - return { gasFee: gasFeeError } + return { gasFee: gasFeeError }; } function calcTokenBalance({ sendToken, usersToken }) { - const { decimals } = sendToken || {} - return calcTokenAmount(usersToken.balance.toString(), decimals).toString(16) + const { decimals } = sendToken || {}; + return calcTokenAmount(usersToken.balance.toString(), decimals).toString(16); } function doesAmountErrorRequireUpdate({ @@ -181,13 +181,13 @@ function doesAmountErrorRequireUpdate({ sendToken, tokenBalance, }) { - const balanceHasChanged = balance !== prevBalance - const gasTotalHasChange = gasTotal !== prevGasTotal - const tokenBalanceHasChanged = sendToken && tokenBalance !== prevTokenBalance + const balanceHasChanged = balance !== prevBalance; + const gasTotalHasChange = gasTotal !== prevGasTotal; + const tokenBalanceHasChanged = sendToken && tokenBalance !== prevTokenBalance; const amountErrorRequiresUpdate = - balanceHasChanged || gasTotalHasChange || tokenBalanceHasChanged + balanceHasChanged || gasTotalHasChange || tokenBalanceHasChanged; - return amountErrorRequiresUpdate + return amountErrorRequiresUpdate; } async function estimateGasForSend({ @@ -200,46 +200,46 @@ async function estimateGasForSend({ gasPrice, estimateGasMethod, }) { - const paramsForGasEstimate = { from: selectedAddress, value, gasPrice } + const paramsForGasEstimate = { from: selectedAddress, value, gasPrice }; // if recipient has no code, gas is 21k max: if (!sendToken && !data) { - const code = Boolean(to) && (await global.eth.getCode(to)) + const code = Boolean(to) && (await global.eth.getCode(to)); // Geth will return '0x', and ganache-core v2.2.1 will return '0x0' - const codeIsEmpty = !code || code === '0x' || code === '0x0' + const codeIsEmpty = !code || code === '0x' || code === '0x0'; if (codeIsEmpty) { - return SIMPLE_GAS_COST + return SIMPLE_GAS_COST; } } else if (sendToken && !to) { - return BASE_TOKEN_GAS_COST + return BASE_TOKEN_GAS_COST; } if (sendToken) { - paramsForGasEstimate.value = '0x0' + paramsForGasEstimate.value = '0x0'; paramsForGasEstimate.data = generateTokenTransferData({ toAddress: to, amount: value, sendToken, - }) - paramsForGasEstimate.to = sendToken.address + }); + paramsForGasEstimate.to = sendToken.address; } else { if (data) { - paramsForGasEstimate.data = data + paramsForGasEstimate.data = data; } if (to) { - paramsForGasEstimate.to = to + paramsForGasEstimate.to = to; } if (!value || value === '0') { - paramsForGasEstimate.value = '0xff' + paramsForGasEstimate.value = '0xff'; } } // if not, fall back to block gasLimit if (!blockGasLimit) { // eslint-disable-next-line no-param-reassign - blockGasLimit = MIN_GAS_LIMIT_HEX + blockGasLimit = MIN_GAS_LIMIT_HEX; } paramsForGasEstimate.gas = addHexPrefix( @@ -249,32 +249,32 @@ async function estimateGasForSend({ roundDown: '0', toNumericBase: 'hex', }), - ) + ); // run tx try { - const estimatedGas = await estimateGasMethod(paramsForGasEstimate) + const estimatedGas = await estimateGasMethod(paramsForGasEstimate); const estimateWithBuffer = addGasBuffer( estimatedGas.toString(16), blockGasLimit, 1.5, - ) - return addHexPrefix(estimateWithBuffer) + ); + return addHexPrefix(estimateWithBuffer); } catch (error) { const simulationFailed = error.message.includes('Transaction execution error.') || error.message.includes( 'gas required exceeds allowance or always failing transaction', - ) + ); if (simulationFailed) { const estimateWithBuffer = addGasBuffer( paramsForGasEstimate.gas, blockGasLimit, 1.5, - ) - return addHexPrefix(estimateWithBuffer) + ); + return addHexPrefix(estimateWithBuffer); } - throw error + throw error; } } @@ -288,7 +288,7 @@ function addGasBuffer( multiplicandBase: 16, multiplierBase: 10, numberOfDecimals: '0', - }) + }); const bufferedGasLimit = multiplyCurrencies( initialGasLimitHex, bufferMultiplier, @@ -298,7 +298,7 @@ function addGasBuffer( multiplierBase: 10, numberOfDecimals: '0', }, - ) + ); // if initialGasLimit is above blockGasLimit, dont modify it if ( @@ -307,7 +307,7 @@ function addGasBuffer( { value: upperGasLimit, fromNumericBase: 'hex' }, ) ) { - return initialGasLimitHex + return initialGasLimitHex; } // if bufferedGasLimit is below blockGasLimit, use bufferedGasLimit if ( @@ -316,10 +316,10 @@ function addGasBuffer( { value: upperGasLimit, fromNumericBase: 'hex' }, ) ) { - return bufferedGasLimit + return bufferedGasLimit; } // otherwise use blockGasLimit - return upperGasLimit + return upperGasLimit; } function generateTokenTransferData({ @@ -328,7 +328,7 @@ function generateTokenTransferData({ sendToken, }) { if (!sendToken) { - return undefined + return undefined; } return ( TOKEN_TRANSFER_FUNCTION_SIGNATURE + @@ -341,19 +341,19 @@ function generateTokenTransferData({ (x) => `00${x.toString(16)}`.slice(-2), ) .join('') - ) + ); } function getToAddressForGasUpdate(...addresses) { return [...addresses, ''] .find((str) => str !== undefined && str !== null) - .toLowerCase() + .toLowerCase(); } function removeLeadingZeroes(str) { - return str.replace(/^0*(?=\d)/u, '') + return str.replace(/^0*(?=\d)/u, ''); } function ellipsify(text, first = 6, last = 4) { - return `${text.slice(0, first)}...${text.slice(-last)}` + return `${text.slice(0, first)}...${text.slice(-last)}`; } diff --git a/ui/app/pages/send/tests/send-component.test.js b/ui/app/pages/send/tests/send-component.test.js index 458082e7dd..9a529d4802 100644 --- a/ui/app/pages/send/tests/send-component.test.js +++ b/ui/app/pages/send/tests/send-component.test.js @@ -1,21 +1,21 @@ -import assert from 'assert' -import React from 'react' -import proxyquire from 'proxyquire' -import { shallow } from 'enzyme' -import sinon from 'sinon' -import timeout from '../../../../lib/test-timeout' - -import AddRecipient from '../send-content/add-recipient/add-recipient.container' -import SendHeader from '../send-header/send-header.container' -import SendContent from '../send-content/send-content.container' -import SendFooter from '../send-footer/send-footer.container' +import assert from 'assert'; +import React from 'react'; +import proxyquire from 'proxyquire'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import timeout from '../../../../lib/test-timeout'; + +import AddRecipient from '../send-content/add-recipient/add-recipient.container'; +import SendHeader from '../send-header/send-header.container'; +import SendContent from '../send-content/send-content.container'; +import SendFooter from '../send-footer/send-footer.container'; describe('Send Component', function () { - let wrapper + let wrapper; const mockBasicGasEstimates = { blockTime: 'mockBlockTime', - } + }; const propsMethodSpies = { updateAndSetGasLimit: sinon.spy(), @@ -27,23 +27,23 @@ describe('Send Component', function () { .returns(Promise.resolve(mockBasicGasEstimates)), fetchGasEstimates: sinon.spy(), updateToNicknameIfNecessary: sinon.spy(), - } + }; const utilsMethodStubs = { getAmountErrorObject: sinon.stub().returns({ amount: 'mockAmountError' }), getGasFeeErrorObject: sinon.stub().returns({ gasFee: 'mockGasFeeError' }), doesAmountErrorRequireUpdate: sinon .stub() .callsFake((obj) => obj.balance !== obj.prevBalance), - } + }; const SendTransactionScreen = proxyquire('../send.component.js', { './send.utils': utilsMethodStubs, - }).default + }).default; before(function () { - sinon.spy(SendTransactionScreen.prototype, 'componentDidMount') - sinon.spy(SendTransactionScreen.prototype, 'updateGas') - }) + sinon.spy(SendTransactionScreen.prototype, 'componentDidMount'); + sinon.spy(SendTransactionScreen.prototype, 'updateGas'); + }); beforeEach(function () { wrapper = shallow( @@ -79,66 +79,72 @@ describe('Send Component', function () { propsMethodSpies.updateToNicknameIfNecessary } />, - ) - }) + ); + }); afterEach(function () { - SendTransactionScreen.prototype.componentDidMount.resetHistory() - SendTransactionScreen.prototype.updateGas.resetHistory() - utilsMethodStubs.doesAmountErrorRequireUpdate.resetHistory() - utilsMethodStubs.getAmountErrorObject.resetHistory() - utilsMethodStubs.getGasFeeErrorObject.resetHistory() - propsMethodSpies.fetchBasicGasEstimates.resetHistory() - propsMethodSpies.updateAndSetGasLimit.resetHistory() - propsMethodSpies.updateSendErrors.resetHistory() - propsMethodSpies.updateSendTokenBalance.resetHistory() - propsMethodSpies.updateToNicknameIfNecessary.resetHistory() - }) + SendTransactionScreen.prototype.componentDidMount.resetHistory(); + SendTransactionScreen.prototype.updateGas.resetHistory(); + utilsMethodStubs.doesAmountErrorRequireUpdate.resetHistory(); + utilsMethodStubs.getAmountErrorObject.resetHistory(); + utilsMethodStubs.getGasFeeErrorObject.resetHistory(); + propsMethodSpies.fetchBasicGasEstimates.resetHistory(); + propsMethodSpies.updateAndSetGasLimit.resetHistory(); + propsMethodSpies.updateSendErrors.resetHistory(); + propsMethodSpies.updateSendTokenBalance.resetHistory(); + propsMethodSpies.updateToNicknameIfNecessary.resetHistory(); + }); after(function () { - sinon.restore() - }) + sinon.restore(); + }); it('should call componentDidMount', function () { - assert(SendTransactionScreen.prototype.componentDidMount.calledOnce) - }) + assert(SendTransactionScreen.prototype.componentDidMount.calledOnce); + }); describe('componentDidMount', function () { it('should call props.fetchBasicGasAndTimeEstimates', function () { - propsMethodSpies.fetchBasicGasEstimates.resetHistory() - assert.strictEqual(propsMethodSpies.fetchBasicGasEstimates.callCount, 0) - wrapper.instance().componentDidMount() - assert.strictEqual(propsMethodSpies.fetchBasicGasEstimates.callCount, 1) - }) + propsMethodSpies.fetchBasicGasEstimates.resetHistory(); + assert.strictEqual(propsMethodSpies.fetchBasicGasEstimates.callCount, 0); + wrapper.instance().componentDidMount(); + assert.strictEqual(propsMethodSpies.fetchBasicGasEstimates.callCount, 1); + }); it('should call this.updateGas', async function () { - SendTransactionScreen.prototype.updateGas.resetHistory() - propsMethodSpies.updateSendErrors.resetHistory() - assert.strictEqual(SendTransactionScreen.prototype.updateGas.callCount, 0) - wrapper.instance().componentDidMount() - await timeout(250) - assert.strictEqual(SendTransactionScreen.prototype.updateGas.callCount, 1) - }) - }) + SendTransactionScreen.prototype.updateGas.resetHistory(); + propsMethodSpies.updateSendErrors.resetHistory(); + assert.strictEqual( + SendTransactionScreen.prototype.updateGas.callCount, + 0, + ); + wrapper.instance().componentDidMount(); + await timeout(250); + assert.strictEqual( + SendTransactionScreen.prototype.updateGas.callCount, + 1, + ); + }); + }); describe('componentWillUnmount', function () { it('should call this.props.resetSendState', function () { - propsMethodSpies.resetSendState.resetHistory() - assert.strictEqual(propsMethodSpies.resetSendState.callCount, 0) - wrapper.instance().componentWillUnmount() - assert.strictEqual(propsMethodSpies.resetSendState.callCount, 1) - }) - }) + propsMethodSpies.resetSendState.resetHistory(); + assert.strictEqual(propsMethodSpies.resetSendState.callCount, 0); + wrapper.instance().componentWillUnmount(); + assert.strictEqual(propsMethodSpies.resetSendState.callCount, 1); + }); + }); describe('componentDidUpdate', function () { it('should call doesAmountErrorRequireUpdate with the expected params', function () { - utilsMethodStubs.getAmountErrorObject.resetHistory() + utilsMethodStubs.getAmountErrorObject.resetHistory(); wrapper.instance().componentDidUpdate({ from: { balance: '', }, - }) - assert(utilsMethodStubs.doesAmountErrorRequireUpdate.calledTwice) + }); + assert(utilsMethodStubs.doesAmountErrorRequireUpdate.calledTwice); assert.deepStrictEqual( utilsMethodStubs.doesAmountErrorRequireUpdate.getCall(0).args[0], { @@ -154,27 +160,27 @@ describe('Send Component', function () { }, tokenBalance: 'mockTokenBalance', }, - ) - }) + ); + }); it('should not call getAmountErrorObject if doesAmountErrorRequireUpdate returns false', function () { - utilsMethodStubs.getAmountErrorObject.resetHistory() + utilsMethodStubs.getAmountErrorObject.resetHistory(); wrapper.instance().componentDidUpdate({ from: { balance: 'mockBalance', }, - }) - assert.strictEqual(utilsMethodStubs.getAmountErrorObject.callCount, 0) - }) + }); + assert.strictEqual(utilsMethodStubs.getAmountErrorObject.callCount, 0); + }); it('should call getAmountErrorObject if doesAmountErrorRequireUpdate returns true', function () { - utilsMethodStubs.getAmountErrorObject.resetHistory() + utilsMethodStubs.getAmountErrorObject.resetHistory(); wrapper.instance().componentDidUpdate({ from: { balance: 'balanceChanged', }, - }) - assert.strictEqual(utilsMethodStubs.getAmountErrorObject.callCount, 1) + }); + assert.strictEqual(utilsMethodStubs.getAmountErrorObject.callCount, 1); assert.deepStrictEqual( utilsMethodStubs.getAmountErrorObject.getCall(0).args[0], { @@ -190,17 +196,17 @@ describe('Send Component', function () { }, tokenBalance: 'mockTokenBalance', }, - ) - }) + ); + }); it('should call getGasFeeErrorObject if doesAmountErrorRequireUpdate returns true and sendToken is truthy', function () { - utilsMethodStubs.getGasFeeErrorObject.resetHistory() + utilsMethodStubs.getGasFeeErrorObject.resetHistory(); wrapper.instance().componentDidUpdate({ from: { balance: 'balanceChanged', }, - }) - assert.strictEqual(utilsMethodStubs.getGasFeeErrorObject.callCount, 1) + }); + assert.strictEqual(utilsMethodStubs.getGasFeeErrorObject.callCount, 1); assert.deepStrictEqual( utilsMethodStubs.getGasFeeErrorObject.getCall(0).args[0], { @@ -214,106 +220,112 @@ describe('Send Component', function () { symbol: 'TST', }, }, - ) - }) + ); + }); it('should not call getGasFeeErrorObject if doesAmountErrorRequireUpdate returns false', function () { - utilsMethodStubs.getGasFeeErrorObject.resetHistory() + utilsMethodStubs.getGasFeeErrorObject.resetHistory(); wrapper.instance().componentDidUpdate({ from: { address: 'mockAddress', balance: 'mockBalance' }, - }) - assert.strictEqual(utilsMethodStubs.getGasFeeErrorObject.callCount, 0) - }) + }); + assert.strictEqual(utilsMethodStubs.getGasFeeErrorObject.callCount, 0); + }); it('should not call getGasFeeErrorObject if doesAmountErrorRequireUpdate returns true but sendToken is falsy', function () { - utilsMethodStubs.getGasFeeErrorObject.resetHistory() - wrapper.setProps({ sendToken: null }) + utilsMethodStubs.getGasFeeErrorObject.resetHistory(); + wrapper.setProps({ sendToken: null }); wrapper.instance().componentDidUpdate({ from: { balance: 'balanceChanged', }, - }) - assert.strictEqual(utilsMethodStubs.getGasFeeErrorObject.callCount, 0) - }) + }); + assert.strictEqual(utilsMethodStubs.getGasFeeErrorObject.callCount, 0); + }); it('should call updateSendErrors with the expected params if sendToken is falsy', function () { - propsMethodSpies.updateSendErrors.resetHistory() - wrapper.setProps({ sendToken: null }) + propsMethodSpies.updateSendErrors.resetHistory(); + wrapper.setProps({ sendToken: null }); wrapper.instance().componentDidUpdate({ from: { balance: 'balanceChanged', }, - }) - assert.strictEqual(propsMethodSpies.updateSendErrors.callCount, 1) + }); + assert.strictEqual(propsMethodSpies.updateSendErrors.callCount, 1); assert.deepStrictEqual( propsMethodSpies.updateSendErrors.getCall(0).args[0], { amount: 'mockAmountError', gasFee: null, }, - ) - }) + ); + }); it('should call updateSendErrors with the expected params if sendToken is truthy', function () { - propsMethodSpies.updateSendErrors.resetHistory() + propsMethodSpies.updateSendErrors.resetHistory(); wrapper.setProps({ sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }, - }) + }); wrapper.instance().componentDidUpdate({ from: { balance: 'balanceChanged', }, - }) - assert.strictEqual(propsMethodSpies.updateSendErrors.callCount, 1) + }); + assert.strictEqual(propsMethodSpies.updateSendErrors.callCount, 1); assert.deepStrictEqual( propsMethodSpies.updateSendErrors.getCall(0).args[0], { amount: 'mockAmountError', gasFee: 'mockGasFeeError', }, - ) - }) + ); + }); it('should not call updateSendTokenBalance or this.updateGas if network === prevNetwork', function () { - SendTransactionScreen.prototype.updateGas.resetHistory() - propsMethodSpies.updateSendTokenBalance.resetHistory() + SendTransactionScreen.prototype.updateGas.resetHistory(); + propsMethodSpies.updateSendTokenBalance.resetHistory(); wrapper.instance().componentDidUpdate({ from: { balance: 'balanceChanged', }, network: '3', sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }, // Make sure not to hit updateGas when changing asset - }) - assert.strictEqual(propsMethodSpies.updateSendTokenBalance.callCount, 0) - assert.strictEqual(SendTransactionScreen.prototype.updateGas.callCount, 0) - }) + }); + assert.strictEqual(propsMethodSpies.updateSendTokenBalance.callCount, 0); + assert.strictEqual( + SendTransactionScreen.prototype.updateGas.callCount, + 0, + ); + }); it('should not call updateSendTokenBalance or this.updateGas if network === loading', function () { - wrapper.setProps({ network: 'loading' }) - SendTransactionScreen.prototype.updateGas.resetHistory() - propsMethodSpies.updateSendTokenBalance.resetHistory() + wrapper.setProps({ network: 'loading' }); + SendTransactionScreen.prototype.updateGas.resetHistory(); + propsMethodSpies.updateSendTokenBalance.resetHistory(); wrapper.instance().componentDidUpdate({ from: { balance: 'balanceChanged', }, network: '3', sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }, // Make sure not to hit updateGas when changing asset - }) - assert.strictEqual(propsMethodSpies.updateSendTokenBalance.callCount, 0) - assert.strictEqual(SendTransactionScreen.prototype.updateGas.callCount, 0) - }) + }); + assert.strictEqual(propsMethodSpies.updateSendTokenBalance.callCount, 0); + assert.strictEqual( + SendTransactionScreen.prototype.updateGas.callCount, + 0, + ); + }); it('should call updateSendTokenBalance and this.updateGas with the correct params', function () { - SendTransactionScreen.prototype.updateGas.resetHistory() - propsMethodSpies.updateSendTokenBalance.resetHistory() + SendTransactionScreen.prototype.updateGas.resetHistory(); + propsMethodSpies.updateSendTokenBalance.resetHistory(); wrapper.instance().componentDidUpdate({ from: { balance: 'balanceChanged', }, network: '2', sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }, // Make sure not to hit updateGas when changing asset - }) - assert.strictEqual(propsMethodSpies.updateSendTokenBalance.callCount, 1) + }); + assert.strictEqual(propsMethodSpies.updateSendTokenBalance.callCount, 1); assert.deepStrictEqual( propsMethodSpies.updateSendTokenBalance.getCall(0).args[0], { @@ -325,37 +337,40 @@ describe('Send Component', function () { tokenContract: { method: 'mockTokenMethod' }, address: 'mockAddress', }, - ) - assert.strictEqual(SendTransactionScreen.prototype.updateGas.callCount, 1) + ); + assert.strictEqual( + SendTransactionScreen.prototype.updateGas.callCount, + 1, + ); assert.deepStrictEqual( SendTransactionScreen.prototype.updateGas.getCall(0).args, [], - ) - }) + ); + }); it('should call updateGas when sendToken.address is changed', function () { - SendTransactionScreen.prototype.updateGas.resetHistory() - propsMethodSpies.updateAndSetGasLimit.resetHistory() + SendTransactionScreen.prototype.updateGas.resetHistory(); + propsMethodSpies.updateAndSetGasLimit.resetHistory(); wrapper.instance().componentDidUpdate({ from: { balance: 'balancedChanged', }, network: '3', // Make sure not to hit updateGas when changing network sendToken: { address: 'newSelectedToken' }, - }) + }); assert.strictEqual( propsMethodSpies.updateToNicknameIfNecessary.callCount, 0, - ) // Network did not change - assert.strictEqual(propsMethodSpies.updateAndSetGasLimit.callCount, 1) - }) - }) + ); // Network did not change + assert.strictEqual(propsMethodSpies.updateAndSetGasLimit.callCount, 1); + }); + }); describe('updateGas', function () { it('should call updateAndSetGasLimit with the correct params if no to prop is passed', function () { - propsMethodSpies.updateAndSetGasLimit.resetHistory() - wrapper.instance().updateGas() - assert.strictEqual(propsMethodSpies.updateAndSetGasLimit.callCount, 1) + propsMethodSpies.updateAndSetGasLimit.resetHistory(); + wrapper.instance().updateGas(); + assert.strictEqual(propsMethodSpies.updateAndSetGasLimit.callCount, 1); assert.deepStrictEqual( propsMethodSpies.updateAndSetGasLimit.getCall(0).args[0], { @@ -373,153 +388,153 @@ describe('Send Component', function () { value: 'mockAmount', data: undefined, }, - ) - }) + ); + }); it('should call updateAndSetGasLimit with the correct params if a to prop is passed', function () { - propsMethodSpies.updateAndSetGasLimit.resetHistory() - wrapper.setProps({ to: 'someAddress' }) - wrapper.instance().updateGas() + propsMethodSpies.updateAndSetGasLimit.resetHistory(); + wrapper.setProps({ to: 'someAddress' }); + wrapper.instance().updateGas(); assert.strictEqual( propsMethodSpies.updateAndSetGasLimit.getCall(0).args[0].to, 'someaddress', - ) - }) + ); + }); it('should call updateAndSetGasLimit with to set to lowercase if passed', function () { - propsMethodSpies.updateAndSetGasLimit.resetHistory() - wrapper.instance().updateGas({ to: '0xABC' }) + propsMethodSpies.updateAndSetGasLimit.resetHistory(); + wrapper.instance().updateGas({ to: '0xABC' }); assert.strictEqual( propsMethodSpies.updateAndSetGasLimit.getCall(0).args[0].to, '0xabc', - ) - }) - }) + ); + }); + }); describe('render', function () { it('should render a page-container class', function () { - assert.strictEqual(wrapper.find('.page-container').length, 1) - }) + assert.strictEqual(wrapper.find('.page-container').length, 1); + }); it('should render SendHeader and AddRecipient', function () { - assert.strictEqual(wrapper.find(SendHeader).length, 1) - assert.strictEqual(wrapper.find(AddRecipient).length, 1) - }) + assert.strictEqual(wrapper.find(SendHeader).length, 1); + assert.strictEqual(wrapper.find(AddRecipient).length, 1); + }); it('should pass the history prop to SendHeader and SendFooter', function () { wrapper.setProps({ to: '0x80F061544cC398520615B5d3e7A3BedD70cd4510', - }) - assert.strictEqual(wrapper.find(SendHeader).length, 1) - assert.strictEqual(wrapper.find(SendContent).length, 1) - assert.strictEqual(wrapper.find(SendFooter).length, 1) + }); + assert.strictEqual(wrapper.find(SendHeader).length, 1); + assert.strictEqual(wrapper.find(SendContent).length, 1); + assert.strictEqual(wrapper.find(SendFooter).length, 1); assert.deepStrictEqual(wrapper.find(SendFooter).props(), { history: { mockProp: 'history-abc' }, - }) - }) + }); + }); it('should pass showHexData to SendContent', function () { wrapper.setProps({ to: '0x80F061544cC398520615B5d3e7A3BedD70cd4510', - }) - assert.strictEqual(wrapper.find(SendContent).props().showHexData, true) - }) - }) + }); + assert.strictEqual(wrapper.find(SendContent).props().showHexData, true); + }); + }); describe('validate when input change', function () { - let clock + let clock; beforeEach(function () { - clock = sinon.useFakeTimers() - }) + clock = sinon.useFakeTimers(); + }); afterEach(function () { - clock.restore() - }) + clock.restore(); + }); it('should validate when input changes', function () { - const instance = wrapper.instance() + const instance = wrapper.instance(); instance.onRecipientInputChange( '0x80F061544cC398520615B5d3e7A3BedD70cd4510', - ) + ); assert.deepStrictEqual(instance.state, { internalSearch: false, query: '0x80F061544cC398520615B5d3e7A3BedD70cd4510', toError: null, toWarning: null, - }) - }) + }); + }); it('should validate when input changes and has error', function () { - const instance = wrapper.instance() + const instance = wrapper.instance(); instance.onRecipientInputChange( '0x80F061544cC398520615B5d3e7a3BedD70cd4510', - ) + ); - clock.tick(1001) + clock.tick(1001); assert.deepStrictEqual(instance.state, { internalSearch: false, query: '0x80F061544cC398520615B5d3e7a3BedD70cd4510', toError: 'invalidAddressRecipient', toWarning: null, - }) - }) + }); + }); it('should validate when input changes and has error on a bad network', function () { - wrapper.setProps({ network: 'bad' }) - const instance = wrapper.instance() + wrapper.setProps({ network: 'bad' }); + const instance = wrapper.instance(); instance.onRecipientInputChange( '0x80F061544cC398520615B5d3e7a3BedD70cd4510', - ) + ); - clock.tick(1001) + clock.tick(1001); assert.deepStrictEqual(instance.state, { internalSearch: false, query: '0x80F061544cC398520615B5d3e7a3BedD70cd4510', toError: 'invalidAddressRecipientNotEthNetwork', toWarning: null, - }) - }) + }); + }); it('should synchronously validate when input changes to ""', function () { - wrapper.setProps({ network: 'bad' }) - const instance = wrapper.instance() + wrapper.setProps({ network: 'bad' }); + const instance = wrapper.instance(); instance.onRecipientInputChange( '0x80F061544cC398520615B5d3e7a3BedD70cd4510', - ) + ); - clock.tick(1001) + clock.tick(1001); assert.deepStrictEqual(instance.state, { internalSearch: false, query: '0x80F061544cC398520615B5d3e7a3BedD70cd4510', toError: 'invalidAddressRecipientNotEthNetwork', toWarning: null, - }) + }); - instance.onRecipientInputChange('') + instance.onRecipientInputChange(''); assert.deepStrictEqual(instance.state, { internalSearch: false, query: '', toError: '', toWarning: '', - }) - }) + }); + }); it('should warn when send to a known token contract address', function () { - wrapper.setProps({ address: '0x888', decimals: 18, symbol: '888' }) - const instance = wrapper.instance() + wrapper.setProps({ address: '0x888', decimals: 18, symbol: '888' }); + const instance = wrapper.instance(); instance.onRecipientInputChange( '0x13cb85823f78Cff38f0B0E90D3e975b8CB3AAd64', - ) + ); - clock.tick(1001) + clock.tick(1001); assert.deepStrictEqual(instance.state, { internalSearch: false, query: '0x13cb85823f78Cff38f0B0E90D3e975b8CB3AAd64', toError: null, toWarning: 'knownAddressRecipient', - }) - }) - }) -}) + }); + }); + }); +}); diff --git a/ui/app/pages/send/tests/send-container.test.js b/ui/app/pages/send/tests/send-container.test.js index 3a9f4a8079..377118920c 100644 --- a/ui/app/pages/send/tests/send-container.test.js +++ b/ui/app/pages/send/tests/send-container.test.js @@ -1,24 +1,24 @@ -import assert from 'assert' -import proxyquire from 'proxyquire' -import sinon from 'sinon' +import assert from 'assert'; +import proxyquire from 'proxyquire'; +import sinon from 'sinon'; -let mapDispatchToProps +let mapDispatchToProps; const actionSpies = { updateSendTokenBalance: sinon.spy(), updateGasData: sinon.spy(), setGasTotal: sinon.spy(), -} +}; const duckActionSpies = { updateSendErrors: sinon.spy(), resetSendState: sinon.spy(), -} +}; proxyquire('../send.container.js', { 'react-redux': { connect: (_, md) => { - mapDispatchToProps = md - return () => ({}) + mapDispatchToProps = md; + return () => ({}); }, }, 'react-router-dom': { withRouter: () => undefined }, @@ -28,17 +28,17 @@ proxyquire('../send.container.js', { './send.utils.js': { calcGasTotal: (gasLimit, gasPrice) => gasLimit + gasPrice, }, -}) +}); describe('send container', function () { describe('mapDispatchToProps()', function () { - let dispatchSpy - let mapDispatchToPropsObject + let dispatchSpy; + let mapDispatchToPropsObject; beforeEach(function () { - dispatchSpy = sinon.spy() - mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy) - }) + dispatchSpy = sinon.spy(); + mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy); + }); describe('updateAndSetGasLimit()', function () { const mockProps = { @@ -51,13 +51,16 @@ describe('send container', function () { to: 'mockTo', value: 'mockValue', data: undefined, - } + }; it('should dispatch a setGasTotal action when editingTransactionId is truthy', function () { - mapDispatchToPropsObject.updateAndSetGasLimit(mockProps) - assert(dispatchSpy.calledOnce) - assert.strictEqual(actionSpies.setGasTotal.getCall(0).args[0], '0x30x4') - }) + mapDispatchToPropsObject.updateAndSetGasLimit(mockProps); + assert(dispatchSpy.calledOnce); + assert.strictEqual( + actionSpies.setGasTotal.getCall(0).args[0], + '0x30x4', + ); + }); it('should dispatch an updateGasData action when editingTransactionId is falsy', function () { const { @@ -68,12 +71,12 @@ describe('send container', function () { to, value, data, - } = mockProps + } = mockProps; mapDispatchToPropsObject.updateAndSetGasLimit({ ...mockProps, editingTransactionId: false, - }) - assert(dispatchSpy.calledOnce) + }); + assert(dispatchSpy.calledOnce); assert.deepStrictEqual(actionSpies.updateGasData.getCall(0).args[0], { gasPrice, selectedAddress, @@ -82,47 +85,47 @@ describe('send container', function () { to, value, data, - }) - }) - }) + }); + }); + }); describe('updateSendTokenBalance()', function () { const mockProps = { address: '0x10', tokenContract: '0x00a', sendToken: { address: '0x1' }, - } + }; it('should dispatch an action', function () { - mapDispatchToPropsObject.updateSendTokenBalance({ ...mockProps }) - assert(dispatchSpy.calledOnce) + mapDispatchToPropsObject.updateSendTokenBalance({ ...mockProps }); + assert(dispatchSpy.calledOnce); assert.deepStrictEqual( actionSpies.updateSendTokenBalance.getCall(0).args[0], mockProps, - ) - }) - }) + ); + }); + }); describe('updateSendErrors()', function () { it('should dispatch an action', function () { - mapDispatchToPropsObject.updateSendErrors('mockError') - assert(dispatchSpy.calledOnce) + mapDispatchToPropsObject.updateSendErrors('mockError'); + assert(dispatchSpy.calledOnce); assert.strictEqual( duckActionSpies.updateSendErrors.getCall(0).args[0], 'mockError', - ) - }) - }) + ); + }); + }); describe('resetSendState()', function () { it('should dispatch an action', function () { - mapDispatchToPropsObject.resetSendState() - assert(dispatchSpy.calledOnce) + mapDispatchToPropsObject.resetSendState(); + assert(dispatchSpy.calledOnce); assert.strictEqual( duckActionSpies.resetSendState.getCall(0).args.length, 0, - ) - }) - }) - }) -}) + ); + }); + }); + }); +}); diff --git a/ui/app/pages/send/tests/send-utils.test.js b/ui/app/pages/send/tests/send-utils.test.js index 853581e961..6f51b3fd17 100644 --- a/ui/app/pages/send/tests/send-utils.test.js +++ b/ui/app/pages/send/tests/send-utils.test.js @@ -1,23 +1,23 @@ -import assert from 'assert' -import sinon from 'sinon' -import proxyquire from 'proxyquire' +import assert from 'assert'; +import sinon from 'sinon'; +import proxyquire from 'proxyquire'; import { BASE_TOKEN_GAS_COST, SIMPLE_GAS_COST, INSUFFICIENT_FUNDS_ERROR, INSUFFICIENT_TOKENS_ERROR, -} from '../send.constants' +} from '../send.constants'; const stubs = { addCurrencies: sinon.stub().callsFake((a, b) => { - let [a1, b1] = [a, b] + let [a1, b1] = [a, b]; if (String(a).match(/^0x.+/u)) { - a1 = Number(String(a).slice(2)) + a1 = Number(String(a).slice(2)); } if (String(b).match(/^0x.+/u)) { - b1 = Number(String(b).slice(2)) + b1 = Number(String(b).slice(2)); } - return a1 + b1 + return a1 + b1; }), conversionUtil: sinon.stub().callsFake((val) => parseInt(val, 16)), conversionGTE: sinon @@ -32,7 +32,7 @@ const stubs = { conversionLessThan: sinon .stub() .callsFake((obj1, obj2) => obj1.value < obj2.value), -} +}; const sendUtils = proxyquire('../send.utils.js', { '../../helpers/utils/conversion-util': { @@ -47,7 +47,7 @@ const sendUtils = proxyquire('../send.utils.js', { 'ethereumjs-abi': { rawEncode: stubs.rawEncode, }, -}) +}); const { calcGasTotal, @@ -61,14 +61,14 @@ const { isBalanceSufficient, isTokenBalanceSufficient, removeLeadingZeroes, -} = sendUtils +} = sendUtils; describe('send utils', function () { describe('calcGasTotal()', function () { it('should call multiplyCurrencies with the correct params and return the multiplyCurrencies return', function () { - const result = calcGasTotal(12, 15) - assert.strictEqual(result, '12x15') - const call_ = stubs.multiplyCurrencies.getCall(0).args + const result = calcGasTotal(12, 15); + assert.strictEqual(result, '12x15'); + const call_ = stubs.multiplyCurrencies.getCall(0).args; assert.deepStrictEqual(call_, [ 12, 15, @@ -77,9 +77,9 @@ describe('send utils', function () { multiplicandBase: 16, multiplierBase: 16, }, - ]) - }) - }) + ]); + }); + }); describe('doesAmountErrorRequireUpdate()', function () { const config = { @@ -109,16 +109,16 @@ describe('send utils', function () { sendToken: { address: '0x0' }, expectedResult: false, }, - } + }; Object.entries(config).forEach(([description, obj]) => { it(description, function () { assert.strictEqual( doesAmountErrorRequireUpdate(obj), obj.expectedResult, - ) - }) - }) - }) + ); + }); + }); + }); describe('generateTokenTransferData()', function () { it('should return undefined if not passed a send token', function () { @@ -129,21 +129,21 @@ describe('send utils', function () { sendToken: undefined, }), undefined, - ) - }) + ); + }); it('should call abi.rawEncode with the correct params', function () { - stubs.rawEncode.resetHistory() + stubs.rawEncode.resetHistory(); generateTokenTransferData({ toAddress: 'mockAddress', amount: 'ab', sendToken: { address: '0x0' }, - }) + }); assert.deepStrictEqual(stubs.rawEncode.getCall(0).args, [ ['address', 'uint256'], ['mockAddress', '0xab'], - ]) - }) + ]); + }); it('should return encoded token transfer data', function () { assert.strictEqual( @@ -153,9 +153,9 @@ describe('send utils', function () { sendToken: { address: '0x0' }, }), '0xa9059cbb104c', - ) - }) - }) + ); + }); + }); describe('getAmountErrorObject()', function () { const config = { @@ -189,13 +189,13 @@ describe('send utils', function () { tokenBalance: 123, expectedResult: { amount: INSUFFICIENT_TOKENS_ERROR }, }, - } + }; Object.entries(config).forEach(([description, obj]) => { it(description, function () { - assert.deepStrictEqual(getAmountErrorObject(obj), obj.expectedResult) - }) - }) - }) + assert.deepStrictEqual(getAmountErrorObject(obj), obj.expectedResult); + }); + }); + }); describe('getGasFeeErrorObject()', function () { const config = { @@ -213,13 +213,13 @@ describe('send utils', function () { primaryCurrency: 'ABC', expectedResult: { gasFee: null }, }, - } + }; Object.entries(config).forEach(([description, obj]) => { it(description, function () { - assert.deepStrictEqual(getGasFeeErrorObject(obj), obj.expectedResult) - }) - }) - }) + assert.deepStrictEqual(getGasFeeErrorObject(obj), obj.expectedResult); + }); + }); + }); describe('calcTokenBalance()', function () { it('should return the calculated token balance', function () { @@ -234,20 +234,20 @@ describe('send utils', function () { }, }), 'calc:2011', - ) - }) - }) + ); + }); + }); describe('isBalanceSufficient()', function () { it('should correctly call addCurrencies and return the result of calling conversionGTE', function () { - stubs.conversionGTE.resetHistory() + stubs.conversionGTE.resetHistory(); const result = isBalanceSufficient({ amount: 15, balance: 100, conversionRate: 3, gasTotal: 17, primaryCurrency: 'ABC', - }) + }); assert.deepStrictEqual(stubs.addCurrencies.getCall(0).args, [ 15, 17, @@ -256,7 +256,7 @@ describe('send utils', function () { bBase: 16, toNumericBase: 'hex', }, - ]) + ]); assert.deepStrictEqual(stubs.conversionGTE.getCall(0).args, [ { value: 100, @@ -270,27 +270,27 @@ describe('send utils', function () { conversionRate: 3, fromCurrency: 'ABC', }, - ]) + ]); - assert.strictEqual(result, true) - }) - }) + assert.strictEqual(result, true); + }); + }); describe('isTokenBalanceSufficient()', function () { it('should correctly call conversionUtil and return the result of calling conversionGTE', function () { - stubs.conversionGTE.resetHistory() - stubs.conversionUtil.resetHistory() + stubs.conversionGTE.resetHistory(); + stubs.conversionUtil.resetHistory(); const result = isTokenBalanceSufficient({ amount: '0x10', tokenBalance: 123, decimals: 10, - }) + }); assert.deepStrictEqual(stubs.conversionUtil.getCall(0).args, [ '0x10', { fromNumericBase: 'hex', }, - ]) + ]); assert.deepStrictEqual(stubs.conversionGTE.getCall(0).args, [ { value: 123, @@ -299,11 +299,11 @@ describe('send utils', function () { { value: 'calc:1610', }, - ]) + ]); - assert.strictEqual(result, false) - }) - }) + assert.strictEqual(result, false); + }); + }); describe('estimateGasForSend', function () { const baseMockParams = { @@ -312,17 +312,17 @@ describe('send utils', function () { to: '0xisContract', estimateGasMethod: sinon.stub().callsFake(({ to }) => { if (typeof to === 'string' && to.match(/willFailBecauseOf:/u)) { - throw new Error(to.match(/:(.+)$/u)[1]) + throw new Error(to.match(/:(.+)$/u)[1]); } - return { toString: (n) => `0xabc${n}` } + return { toString: (n) => `0xabc${n}` }; }), - } + }; const baseExpectedCall = { from: 'mockAddress', gas: '0x64x0.95', to: '0xisContract', value: '0xff', - } + }; beforeEach(function () { global.eth = { @@ -331,17 +331,17 @@ describe('send utils', function () { .callsFake((address) => Promise.resolve(address.match(/isContract/u) ? 'not-0x' : '0x'), ), - } - }) + }; + }); afterEach(function () { - baseMockParams.estimateGasMethod.resetHistory() - global.eth.getCode.resetHistory() - }) + baseMockParams.estimateGasMethod.resetHistory(); + global.eth.getCode.resetHistory(); + }); it('should call ethQuery.estimateGasForSend with the expected params', async function () { - const result = await estimateGasForSend(baseMockParams) - assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 1) + const result = await estimateGasForSend(baseMockParams); + assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 1); assert.deepStrictEqual( baseMockParams.estimateGasMethod.getCall(0).args[0], { @@ -349,16 +349,16 @@ describe('send utils', function () { value: undefined, ...baseExpectedCall, }, - ) - assert.strictEqual(result, '0xabc16') - }) + ); + assert.strictEqual(result, '0xabc16'); + }); it('should call ethQuery.estimateGasForSend with the expected params when initialGasLimitHex is lower than the upperGasLimit', async function () { const result = await estimateGasForSend({ ...baseMockParams, blockGasLimit: '0xbcd', - }) - assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 1) + }); + assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 1); assert.deepStrictEqual( baseMockParams.estimateGasMethod.getCall(0).args[0], { @@ -367,17 +367,17 @@ describe('send utils', function () { ...baseExpectedCall, gas: '0xbcdx0.95', }, - ) - assert.strictEqual(result, '0xabc16x1.5') - }) + ); + assert.strictEqual(result, '0xabc16x1.5'); + }); it('should call ethQuery.estimateGasForSend with a value of 0x0 and the expected data and to if passed a sendToken', async function () { const result = await estimateGasForSend({ data: 'mockData', sendToken: { address: 'mockAddress' }, ...baseMockParams, - }) - assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 1) + }); + assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 1); assert.deepStrictEqual( baseMockParams.estimateGasMethod.getCall(0).args[0], { @@ -387,15 +387,15 @@ describe('send utils', function () { data: '0xa9059cbb104c', to: 'mockAddress', }, - ) - assert.strictEqual(result, '0xabc16') - }) + ); + assert.strictEqual(result, '0xabc16'); + }); it('should call ethQuery.estimateGasForSend without a recipient if the recipient is empty and data passed', async function () { - const data = 'mockData' - const to = '' - const result = await estimateGasForSend({ ...baseMockParams, data, to }) - assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 1) + const data = 'mockData'; + const to = ''; + const result = await estimateGasForSend({ ...baseMockParams, data, to }); + assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 1); assert.deepStrictEqual( baseMockParams.estimateGasMethod.getCall(0).args[0], { @@ -405,106 +405,106 @@ describe('send utils', function () { from: baseExpectedCall.from, gas: baseExpectedCall.gas, }, - ) - assert.strictEqual(result, '0xabc16') - }) + ); + assert.strictEqual(result, '0xabc16'); + }); it(`should return ${SIMPLE_GAS_COST} if ethQuery.getCode does not return '0x'`, async function () { - assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 0) + assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 0); const result = await estimateGasForSend({ ...baseMockParams, to: '0x123', - }) - assert.strictEqual(result, SIMPLE_GAS_COST) - }) + }); + assert.strictEqual(result, SIMPLE_GAS_COST); + }); it(`should return ${SIMPLE_GAS_COST} if not passed a sendToken or truthy to address`, async function () { - assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 0) - const result = await estimateGasForSend({ ...baseMockParams, to: null }) - assert.strictEqual(result, SIMPLE_GAS_COST) - }) + assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 0); + const result = await estimateGasForSend({ ...baseMockParams, to: null }); + assert.strictEqual(result, SIMPLE_GAS_COST); + }); it(`should not return ${SIMPLE_GAS_COST} if passed a sendToken`, async function () { - assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 0) + assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 0); const result = await estimateGasForSend({ ...baseMockParams, to: '0x123', sendToken: { address: '0x0' }, - }) - assert.notStrictEqual(result, SIMPLE_GAS_COST) - }) + }); + assert.notStrictEqual(result, SIMPLE_GAS_COST); + }); it(`should return ${BASE_TOKEN_GAS_COST} if passed a sendToken but no to address`, async function () { const result = await estimateGasForSend({ ...baseMockParams, to: null, sendToken: { address: '0x0' }, - }) - assert.strictEqual(result, BASE_TOKEN_GAS_COST) - }) + }); + assert.strictEqual(result, BASE_TOKEN_GAS_COST); + }); it(`should return the adjusted blockGasLimit if it fails with a 'Transaction execution error.'`, async function () { const result = await estimateGasForSend({ ...baseMockParams, to: 'isContract willFailBecauseOf:Transaction execution error.', - }) - assert.strictEqual(result, '0x64x0.95') - }) + }); + assert.strictEqual(result, '0x64x0.95'); + }); it(`should return the adjusted blockGasLimit if it fails with a 'gas required exceeds allowance or always failing transaction.'`, async function () { const result = await estimateGasForSend({ ...baseMockParams, to: 'isContract willFailBecauseOf:gas required exceeds allowance or always failing transaction.', - }) - assert.strictEqual(result, '0x64x0.95') - }) + }); + assert.strictEqual(result, '0x64x0.95'); + }); it(`should reject other errors`, async function () { try { await estimateGasForSend({ ...baseMockParams, to: 'isContract willFailBecauseOf:some other error', - }) + }); } catch (err) { - assert.strictEqual(err.message, 'some other error') + assert.strictEqual(err.message, 'some other error'); } - }) - }) + }); + }); describe('getToAddressForGasUpdate()', function () { it('should return empty string if all params are undefined or null', function () { - assert.strictEqual(getToAddressForGasUpdate(undefined, null), '') - }) + assert.strictEqual(getToAddressForGasUpdate(undefined, null), ''); + }); it('should return the first string that is not defined or null in lower case', function () { - assert.strictEqual(getToAddressForGasUpdate('A', null), 'a') - assert.strictEqual(getToAddressForGasUpdate(undefined, 'B'), 'b') - }) - }) + assert.strictEqual(getToAddressForGasUpdate('A', null), 'a'); + assert.strictEqual(getToAddressForGasUpdate(undefined, 'B'), 'b'); + }); + }); describe('removeLeadingZeroes()', function () { it('should remove leading zeroes from int when user types', function () { - assert.strictEqual(removeLeadingZeroes('0'), '0') - assert.strictEqual(removeLeadingZeroes('1'), '1') - assert.strictEqual(removeLeadingZeroes('00'), '0') - assert.strictEqual(removeLeadingZeroes('01'), '1') - }) + assert.strictEqual(removeLeadingZeroes('0'), '0'); + assert.strictEqual(removeLeadingZeroes('1'), '1'); + assert.strictEqual(removeLeadingZeroes('00'), '0'); + assert.strictEqual(removeLeadingZeroes('01'), '1'); + }); it('should remove leading zeroes from int when user copy/paste', function () { - assert.strictEqual(removeLeadingZeroes('001'), '1') - }) + assert.strictEqual(removeLeadingZeroes('001'), '1'); + }); it('should remove leading zeroes from float when user types', function () { - assert.strictEqual(removeLeadingZeroes('0.'), '0.') - assert.strictEqual(removeLeadingZeroes('0.0'), '0.0') - assert.strictEqual(removeLeadingZeroes('0.00'), '0.00') - assert.strictEqual(removeLeadingZeroes('0.001'), '0.001') - assert.strictEqual(removeLeadingZeroes('0.10'), '0.10') - }) + assert.strictEqual(removeLeadingZeroes('0.'), '0.'); + assert.strictEqual(removeLeadingZeroes('0.0'), '0.0'); + assert.strictEqual(removeLeadingZeroes('0.00'), '0.00'); + assert.strictEqual(removeLeadingZeroes('0.001'), '0.001'); + assert.strictEqual(removeLeadingZeroes('0.10'), '0.10'); + }); it('should remove leading zeroes from float when user copy/paste', function () { - assert.strictEqual(removeLeadingZeroes('00.1'), '0.1') - }) - }) -}) + assert.strictEqual(removeLeadingZeroes('00.1'), '0.1'); + }); + }); +}); diff --git a/ui/app/pages/settings/advanced-tab/advanced-tab.component.js b/ui/app/pages/settings/advanced-tab/advanced-tab.component.js index 25aefece05..742d1c2334 100644 --- a/ui/app/pages/settings/advanced-tab/advanced-tab.component.js +++ b/ui/app/pages/settings/advanced-tab/advanced-tab.component.js @@ -1,17 +1,17 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { exportAsFile } from '../../../helpers/utils/util' -import ToggleButton from '../../../components/ui/toggle-button' -import TextField from '../../../components/ui/text-field' -import Button from '../../../components/ui/button' -import { MOBILE_SYNC_ROUTE } from '../../../helpers/constants/routes' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import { exportAsFile } from '../../../helpers/utils/util'; +import ToggleButton from '../../../components/ui/toggle-button'; +import TextField from '../../../components/ui/text-field'; +import Button from '../../../components/ui/button'; +import { MOBILE_SYNC_ROUTE } from '../../../helpers/constants/routes'; export default class AdvancedTab extends PureComponent { static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; static propTypes = { setUseNonceField: PropTypes.func, @@ -33,18 +33,18 @@ export default class AdvancedTab extends PureComponent { threeBoxDisabled: PropTypes.bool.isRequired, setIpfsGateway: PropTypes.func.isRequired, ipfsGateway: PropTypes.string.isRequired, - } + }; state = { autoLockTimeLimit: this.props.autoLockTimeLimit, lockTimeError: '', ipfsGateway: this.props.ipfsGateway, ipfsGatewayError: '', - } + }; renderMobileSync() { - const { t } = this.context - const { history } = this.props + const { t } = this.context; + const { history } = this.props; return (
    { - event.preventDefault() - history.push(MOBILE_SYNC_ROUTE) + event.preventDefault(); + history.push(MOBILE_SYNC_ROUTE); }} > {t('syncWithMobile')} @@ -69,12 +69,12 @@ export default class AdvancedTab extends PureComponent {
    - ) + ); } renderStateLogs() { - const { t } = this.context - const { displayWarning } = this.props + const { t } = this.context; + const { displayWarning } = this.props; return (
    { window.logStateString((err, result) => { if (err) { - displayWarning(t('stateLogError')) + displayWarning(t('stateLogError')); } else { - exportAsFile(`${t('stateLogFileName')}.json`, result) + exportAsFile(`${t('stateLogFileName')}.json`, result); } - }) + }); }} > {t('downloadStateLogs')} @@ -107,12 +107,12 @@ export default class AdvancedTab extends PureComponent {
    - ) + ); } renderResetAccount() { - const { t } = this.context - const { showResetAccountConfirmationModal } = this.props + const { t } = this.context; + const { showResetAccountConfirmationModal } = this.props; return (
    { - event.preventDefault() + event.preventDefault(); this.context.metricsEvent({ eventOpts: { category: 'Settings', action: 'Reset Account', name: 'Reset Account', }, - }) - showResetAccountConfirmationModal() + }); + showResetAccountConfirmationModal(); }} > {t('resetAccount')} @@ -148,12 +148,12 @@ export default class AdvancedTab extends PureComponent {
    - ) + ); } renderHexDataOptIn() { - const { t } = this.context - const { sendHexData, setHexDataFeatureFlag } = this.props + const { t } = this.context; + const { sendHexData, setHexDataFeatureFlag } = this.props; return (
    - ) + ); } renderAdvancedGasInputInline() { - const { t } = this.context - const { advancedInlineGas, setAdvancedInlineGasFeatureFlag } = this.props + const { t } = this.context; + const { advancedInlineGas, setAdvancedInlineGasFeatureFlag } = this.props; return (
    - ) + ); } renderShowConversionInTestnets() { - const { t } = this.context + const { t } = this.context; const { showFiatInTestnets, setShowFiatConversionOnTestnetsPreference, - } = this.props + } = this.props; return (
    - ) + ); } renderUseNonceOptIn() { - const { t } = this.context - const { useNonceField, setUseNonceField } = this.props + const { t } = this.context; + const { useNonceField, setUseNonceField } = this.props; return (
    - ) + ); } handleLockChange(time) { - const { t } = this.context - const autoLockTimeLimit = Math.max(Number(time), 0) + const { t } = this.context; + const autoLockTimeLimit = Math.max(Number(time), 0); this.setState(() => { - let lockTimeError = '' + let lockTimeError = ''; if (autoLockTimeLimit > 10080) { - lockTimeError = t('lockTimeTooGreat') + lockTimeError = t('lockTimeTooGreat'); } return { autoLockTimeLimit, lockTimeError, - } - }) + }; + }); } renderAutoLockTimeLimit() { - const { t } = this.context - const { lockTimeError } = this.state - const { autoLockTimeLimit, setAutoLockTimeLimit } = this.props + const { t } = this.context; + const { lockTimeError } = this.state; + const { autoLockTimeLimit, setAutoLockTimeLimit } = this.props; return (
    { - setAutoLockTimeLimit(this.state.autoLockTimeLimit) + setAutoLockTimeLimit(this.state.autoLockTimeLimit); }} > {t('save')} @@ -333,23 +333,23 @@ export default class AdvancedTab extends PureComponent {
    - ) + ); } renderThreeBoxControl() { - const { t } = this.context + const { t } = this.context; const { threeBoxSyncingAllowed, setThreeBoxSyncingPermission, threeBoxDisabled, - } = this.props + } = this.props; - let allowed = threeBoxSyncingAllowed - let description = t('syncWithThreeBoxDescription') + let allowed = threeBoxSyncingAllowed; + let description = t('syncWithThreeBoxDescription'); if (threeBoxDisabled) { - allowed = false - description = t('syncWithThreeBoxDisabled') + allowed = false; + description = t('syncWithThreeBoxDisabled'); } return (
    { if (!threeBoxDisabled) { - setThreeBoxSyncingPermission(!value) + setThreeBoxSyncingPermission(!value); } }} offLabel={t('off')} @@ -381,49 +381,49 @@ export default class AdvancedTab extends PureComponent {
    - ) + ); } handleIpfsGatewayChange(url) { - const { t } = this.context + const { t } = this.context; this.setState(() => { - let ipfsGatewayError = '' + let ipfsGatewayError = ''; try { - const urlObj = new URL(addUrlProtocolPrefix(url)) + const urlObj = new URL(addUrlProtocolPrefix(url)); if (!urlObj.host) { - throw new Error() + throw new Error(); } // don't allow the use of this gateway if (urlObj.host === 'gateway.ipfs.io') { - throw new Error('Forbidden gateway') + throw new Error('Forbidden gateway'); } } catch (error) { ipfsGatewayError = error.message === 'Forbidden gateway' ? t('forbiddenIpfsGateway') - : t('invalidIpfsGateway') + : t('invalidIpfsGateway'); } return { ipfsGateway: url, ipfsGatewayError, - } - }) + }; + }); } handleIpfsGatewaySave() { - const url = new URL(addUrlProtocolPrefix(this.state.ipfsGateway)) - const { host } = url + const url = new URL(addUrlProtocolPrefix(this.state.ipfsGateway)); + const { host } = url; - this.props.setIpfsGateway(host) + this.props.setIpfsGateway(host); } renderIpfsGatewayControl() { - const { t } = this.context - const { ipfsGatewayError } = this.state + const { t } = this.context; + const { ipfsGatewayError } = this.state; return (
    { - this.handleIpfsGatewaySave() + this.handleIpfsGatewaySave(); }} > {t('save')} @@ -459,11 +459,11 @@ export default class AdvancedTab extends PureComponent {
    - ) + ); } render() { - const { warning } = this.props + const { warning } = this.props; return (
    @@ -479,13 +479,13 @@ export default class AdvancedTab extends PureComponent { {this.renderThreeBoxControl()} {this.renderIpfsGatewayControl()}
    - ) + ); } } function addUrlProtocolPrefix(urlString) { if (!urlString.match(/(^http:\/\/)|(^https:\/\/)/u)) { - return `https://${urlString}` + return `https://${urlString}`; } - return urlString + return urlString; } diff --git a/ui/app/pages/settings/advanced-tab/advanced-tab.container.js b/ui/app/pages/settings/advanced-tab/advanced-tab.container.js index fc4fd8db1c..1bfa82f300 100644 --- a/ui/app/pages/settings/advanced-tab/advanced-tab.container.js +++ b/ui/app/pages/settings/advanced-tab/advanced-tab.container.js @@ -1,6 +1,6 @@ -import { compose } from 'redux' -import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom' +import { compose } from 'redux'; +import { connect } from 'react-redux'; +import { withRouter } from 'react-router-dom'; import { displayWarning, setFeatureFlag, @@ -11,23 +11,23 @@ import { turnThreeBoxSyncingOnAndInitialize, setUseNonceField, setIpfsGateway, -} from '../../../store/actions' -import { getPreferences } from '../../../selectors' -import AdvancedTab from './advanced-tab.component' +} from '../../../store/actions'; +import { getPreferences } from '../../../selectors'; +import AdvancedTab from './advanced-tab.component'; export const mapStateToProps = (state) => { const { appState: { warning }, metamask, - } = state + } = state; const { featureFlags: { sendHexData, advancedInlineGas } = {}, threeBoxSyncingAllowed, threeBoxDisabled, useNonceField, ipfsGateway, - } = metamask - const { showFiatInTestnets, autoLockTimeLimit } = getPreferences(state) + } = metamask; + const { showFiatInTestnets, autoLockTimeLimit } = getPreferences(state); return { warning, @@ -39,8 +39,8 @@ export const mapStateToProps = (state) => { threeBoxDisabled, useNonceField, ipfsGateway, - } -} + }; +}; export const mapDispatchToProps = (dispatch) => { return { @@ -53,25 +53,25 @@ export const mapDispatchToProps = (dispatch) => { dispatch(setFeatureFlag('advancedInlineGas', shouldShow)), setUseNonceField: (value) => dispatch(setUseNonceField(value)), setShowFiatConversionOnTestnetsPreference: (value) => { - return dispatch(setShowFiatConversionOnTestnetsPreference(value)) + return dispatch(setShowFiatConversionOnTestnetsPreference(value)); }, setAutoLockTimeLimit: (value) => { - return dispatch(setAutoLockTimeLimit(value)) + return dispatch(setAutoLockTimeLimit(value)); }, setThreeBoxSyncingPermission: (newThreeBoxSyncingState) => { if (newThreeBoxSyncingState) { - dispatch(turnThreeBoxSyncingOnAndInitialize()) + dispatch(turnThreeBoxSyncingOnAndInitialize()); } else { - dispatch(setThreeBoxSyncingPermission(newThreeBoxSyncingState)) + dispatch(setThreeBoxSyncingPermission(newThreeBoxSyncingState)); } }, setIpfsGateway: (value) => { - return dispatch(setIpfsGateway(value)) + return dispatch(setIpfsGateway(value)); }, - } -} + }; +}; export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps), -)(AdvancedTab) +)(AdvancedTab); diff --git a/ui/app/pages/settings/advanced-tab/index.js b/ui/app/pages/settings/advanced-tab/index.js index 85955174e9..f8ead6ef92 100644 --- a/ui/app/pages/settings/advanced-tab/index.js +++ b/ui/app/pages/settings/advanced-tab/index.js @@ -1 +1 @@ -export { default } from './advanced-tab.container' +export { default } from './advanced-tab.container'; diff --git a/ui/app/pages/settings/advanced-tab/tests/advanced-tab-component.test.js b/ui/app/pages/settings/advanced-tab/tests/advanced-tab-component.test.js index 024702ae37..76b9360f3b 100644 --- a/ui/app/pages/settings/advanced-tab/tests/advanced-tab-component.test.js +++ b/ui/app/pages/settings/advanced-tab/tests/advanced-tab-component.test.js @@ -1,9 +1,9 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import { shallow } from 'enzyme' -import AdvancedTab from '../advanced-tab.component' -import TextField from '../../../../components/ui/text-field' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import { shallow } from 'enzyme'; +import AdvancedTab from '../advanced-tab.component'; +import TextField from '../../../../components/ui/text-field'; describe('AdvancedTab Component', function () { it('should render correctly when threeBoxFeatureFlag', function () { @@ -22,13 +22,13 @@ describe('AdvancedTab Component', function () { t: (s) => `_${s}`, }, }, - ) + ); - assert.strictEqual(root.find('.settings-page__content-row').length, 10) - }) + assert.strictEqual(root.find('.settings-page__content-row').length, 10); + }); it('should update autoLockTimeLimit', function () { - const setAutoLockTimeLimitSpy = sinon.spy() + const setAutoLockTimeLimitSpy = sinon.spy(); const root = shallow( `_${s}`, }, }, - ) + ); - const autoTimeout = root.find('.settings-page__content-row').at(7) - const textField = autoTimeout.find(TextField) + const autoTimeout = root.find('.settings-page__content-row').at(7); + const textField = autoTimeout.find(TextField); - textField.props().onChange({ target: { value: 1440 } }) - assert.strictEqual(root.state().autoLockTimeLimit, 1440) + textField.props().onChange({ target: { value: 1440 } }); + assert.strictEqual(root.state().autoLockTimeLimit, 1440); - autoTimeout.find('.settings-tab__rpc-save-button').simulate('click') - assert.strictEqual(setAutoLockTimeLimitSpy.args[0][0], 1440) - }) -}) + autoTimeout.find('.settings-tab__rpc-save-button').simulate('click'); + assert.strictEqual(setAutoLockTimeLimitSpy.args[0][0], 1440); + }); +}); diff --git a/ui/app/pages/settings/alerts-tab/alerts-tab.js b/ui/app/pages/settings/alerts-tab/alerts-tab.js index 832a4ec179..cdf77c7a58 100644 --- a/ui/app/pages/settings/alerts-tab/alerts-tab.js +++ b/ui/app/pages/settings/alerts-tab/alerts-tab.js @@ -1,17 +1,17 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { useSelector } from 'react-redux' +import React from 'react'; +import PropTypes from 'prop-types'; +import { useSelector } from 'react-redux'; -import { ALERT_TYPES } from '../../../../../shared/constants/alerts' -import Tooltip from '../../../components/ui/tooltip' -import ToggleButton from '../../../components/ui/toggle-button' -import { setAlertEnabledness } from '../../../store/actions' -import { getAlertEnabledness } from '../../../ducks/metamask/metamask' -import { useI18nContext } from '../../../hooks/useI18nContext' +import { ALERT_TYPES } from '../../../../../shared/constants/alerts'; +import Tooltip from '../../../components/ui/tooltip'; +import ToggleButton from '../../../components/ui/toggle-button'; +import { setAlertEnabledness } from '../../../store/actions'; +import { getAlertEnabledness } from '../../../ducks/metamask/metamask'; +import { useI18nContext } from '../../../hooks/useI18nContext'; const AlertSettingsEntry = ({ alertId, description, title }) => { - const t = useI18nContext() - const isEnabled = useSelector((state) => getAlertEnabledness(state)[alertId]) + const t = useI18nContext(); + const isEnabled = useSelector((state) => getAlertEnabledness(state)[alertId]); return ( <> @@ -30,17 +30,17 @@ const AlertSettingsEntry = ({ alertId, description, title }) => { value={isEnabled} /> - ) -} + ); +}; AlertSettingsEntry.propTypes = { alertId: PropTypes.string.isRequired, description: PropTypes.string.isRequired, title: PropTypes.string.isRequired, -} +}; const AlertsTab = () => { - const t = useI18nContext() + const t = useI18nContext(); const alertConfig = { [ALERT_TYPES.unconnectedAccount]: { @@ -51,7 +51,7 @@ const AlertsTab = () => { title: t('alertSettingsWeb3ShimUsage'), description: t('alertSettingsWeb3ShimUsageDescription'), }, - } + }; return (
    @@ -64,7 +64,7 @@ const AlertsTab = () => { /> ))}
    - ) -} + ); +}; -export default AlertsTab +export default AlertsTab; diff --git a/ui/app/pages/settings/alerts-tab/index.js b/ui/app/pages/settings/alerts-tab/index.js index 691d542301..f6aa526da7 100644 --- a/ui/app/pages/settings/alerts-tab/index.js +++ b/ui/app/pages/settings/alerts-tab/index.js @@ -1 +1 @@ -export { default } from './alerts-tab' +export { default } from './alerts-tab'; diff --git a/ui/app/pages/settings/contact-list-tab/add-contact/add-contact.component.js b/ui/app/pages/settings/contact-list-tab/add-contact/add-contact.component.js index 5fad37d532..8961805179 100644 --- a/ui/app/pages/settings/contact-list-tab/add-contact/add-contact.component.js +++ b/ui/app/pages/settings/contact-list-tab/add-contact/add-contact.component.js @@ -1,20 +1,20 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import { debounce } from 'lodash' -import Identicon from '../../../../components/ui/identicon' -import TextField from '../../../../components/ui/text-field' -import { CONTACT_LIST_ROUTE } from '../../../../helpers/constants/routes' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { debounce } from 'lodash'; +import Identicon from '../../../../components/ui/identicon'; +import TextField from '../../../../components/ui/text-field'; +import { CONTACT_LIST_ROUTE } from '../../../../helpers/constants/routes'; import { isValidAddress, isValidDomainName, -} from '../../../../helpers/utils/util' -import EnsInput from '../../../send/send-content/add-recipient/ens-input' -import PageContainerFooter from '../../../../components/ui/page-container/page-container-footer' +} from '../../../../helpers/utils/util'; +import EnsInput from '../../../send/send-content/add-recipient/ens-input'; +import PageContainerFooter from '../../../../components/ui/page-container/page-container-footer'; export default class AddContact extends PureComponent { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { addToAddressBook: PropTypes.func, @@ -23,7 +23,7 @@ export default class AddContact extends PureComponent { qrCodeData: PropTypes.object /* eslint-disable-line react/no-unused-prop-types */, qrCodeDetected: PropTypes.func, - } + }; state = { newName: '', @@ -31,64 +31,64 @@ export default class AddContact extends PureComponent { ensAddress: '', error: '', ensError: '', - } + }; constructor(props) { - super(props) - this.dValidate = debounce(this.validate, 1000) + super(props); + this.dValidate = debounce(this.validate, 1000); } UNSAFE_componentWillReceiveProps(nextProps) { if (nextProps.qrCodeData) { if (nextProps.qrCodeData.type === 'address') { - const scannedAddress = nextProps.qrCodeData.values.address.toLowerCase() - const currentAddress = this.state.ensAddress || this.state.ethAddress + const scannedAddress = nextProps.qrCodeData.values.address.toLowerCase(); + const currentAddress = this.state.ensAddress || this.state.ethAddress; if (currentAddress.toLowerCase() !== scannedAddress) { - this.setState({ ethAddress: scannedAddress, ensAddress: '' }) + this.setState({ ethAddress: scannedAddress, ensAddress: '' }); // Clean up QR code data after handling - this.props.qrCodeDetected(null) + this.props.qrCodeDetected(null); } } } } validate = (address) => { - const valid = isValidAddress(address) - const validEnsAddress = isValidDomainName(address) + const valid = isValidAddress(address); + const validEnsAddress = isValidDomainName(address); if (valid || validEnsAddress || address === '') { - this.setState({ error: '', ethAddress: address }) + this.setState({ error: '', ethAddress: address }); } else { - this.setState({ error: 'Invalid Address' }) + this.setState({ error: 'Invalid Address' }); } - } + }; renderInput() { return ( { - this.props.scanQrCode() + this.props.scanQrCode(); }} onChange={this.dValidate} onPaste={(text) => this.setState({ ethAddress: text })} onReset={() => this.setState({ ethAddress: '', ensAddress: '' })} updateEnsResolution={(address) => { - this.setState({ ensAddress: address, error: '', ensError: '' }) + this.setState({ ensAddress: address, error: '', ensError: '' }); }} updateEnsResolutionError={(message) => this.setState({ ensError: message }) } value={this.state.ethAddress || ''} /> - ) + ); } render() { - const { t } = this.context - const { history, addToAddressBook } = this.props + const { t } = this.context; + const { history, addToAddressBook } = this.props; - const errorToRender = this.state.ensError || this.state.error + const errorToRender = this.state.ensError || this.state.error; return (
    @@ -134,16 +134,16 @@ export default class AddContact extends PureComponent { await addToAddressBook( this.state.ensAddress || this.state.ethAddress, this.state.newName, - ) - history.push(CONTACT_LIST_ROUTE) + ); + history.push(CONTACT_LIST_ROUTE); }} onCancel={() => { - history.push(CONTACT_LIST_ROUTE) + history.push(CONTACT_LIST_ROUTE); }} submitText={this.context.t('save')} submitButtonType="confirm" />
    - ) + ); } } diff --git a/ui/app/pages/settings/contact-list-tab/add-contact/add-contact.container.js b/ui/app/pages/settings/contact-list-tab/add-contact/add-contact.container.js index 51cbd2ec91..8d3c63c5f1 100644 --- a/ui/app/pages/settings/contact-list-tab/add-contact/add-contact.container.js +++ b/ui/app/pages/settings/contact-list-tab/add-contact/add-contact.container.js @@ -1,19 +1,19 @@ -import { compose } from 'redux' -import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom' +import { compose } from 'redux'; +import { connect } from 'react-redux'; +import { withRouter } from 'react-router-dom'; import { addToAddressBook, showQrScanner, qrCodeDetected, -} from '../../../../store/actions' -import { getQrCodeData } from '../../../../selectors' -import AddContact from './add-contact.component' +} from '../../../../store/actions'; +import { getQrCodeData } from '../../../../selectors'; +import AddContact from './add-contact.component'; const mapStateToProps = (state) => { return { qrCodeData: getQrCodeData(state), - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { @@ -21,10 +21,10 @@ const mapDispatchToProps = (dispatch) => { dispatch(addToAddressBook(recipient, nickname)), scanQrCode: () => dispatch(showQrScanner()), qrCodeDetected: (data) => dispatch(qrCodeDetected(data)), - } -} + }; +}; export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps), -)(AddContact) +)(AddContact); diff --git a/ui/app/pages/settings/contact-list-tab/add-contact/index.js b/ui/app/pages/settings/contact-list-tab/add-contact/index.js index ce73025a3b..232ca93628 100644 --- a/ui/app/pages/settings/contact-list-tab/add-contact/index.js +++ b/ui/app/pages/settings/contact-list-tab/add-contact/index.js @@ -1 +1 @@ -export { default } from './add-contact.container' +export { default } from './add-contact.container'; diff --git a/ui/app/pages/settings/contact-list-tab/contact-list-tab.component.js b/ui/app/pages/settings/contact-list-tab/contact-list-tab.component.js index 068dc3dafc..d16db37b93 100644 --- a/ui/app/pages/settings/contact-list-tab/contact-list-tab.component.js +++ b/ui/app/pages/settings/contact-list-tab/contact-list-tab.component.js @@ -1,20 +1,20 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import ContactList from '../../../components/app/contact-list' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import ContactList from '../../../components/app/contact-list'; import { CONTACT_ADD_ROUTE, CONTACT_VIEW_ROUTE, CONTACT_MY_ACCOUNTS_ROUTE, -} from '../../../helpers/constants/routes' -import EditContact from './edit-contact' -import AddContact from './add-contact' -import ViewContact from './view-contact' -import MyAccounts from './my-accounts' +} from '../../../helpers/constants/routes'; +import EditContact from './edit-contact'; +import AddContact from './add-contact'; +import ViewContact from './view-contact'; +import MyAccounts from './my-accounts'; export default class ContactListTab extends Component { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { addressBook: PropTypes.array, @@ -26,12 +26,12 @@ export default class ContactListTab extends Component { showContactContent: PropTypes.bool, hideAddressBook: PropTypes.bool, showingMyAccounts: PropTypes.bool, - } + }; renderAddresses() { - const { addressBook, history, selectedAddress } = this.props - const contacts = addressBook.filter(({ name }) => Boolean(name)) - const nonContacts = addressBook.filter(({ name }) => !name) + const { addressBook, history, selectedAddress } = this.props; + const contacts = addressBook.filter(({ name }) => Boolean(name)); + const nonContacts = addressBook.filter(({ name }) => !name); return (
    @@ -39,22 +39,22 @@ export default class ContactListTab extends Component { searchForContacts={() => contacts} searchForRecents={() => nonContacts} selectRecipient={(address) => { - history.push(`${CONTACT_VIEW_ROUTE}/${address}`) + history.push(`${CONTACT_VIEW_ROUTE}/${address}`); }} selectedAddress={selectedAddress} />
    - ) + ); } renderAddButton() { - const { history } = this.props + const { history } = this.props; return (
    { - history.push(CONTACT_ADD_ROUTE) + history.push(CONTACT_ADD_ROUTE); }} > {this.context.t('addAccount')}
    - ) + ); } renderMyAccountsButton() { - const { history } = this.props - const { t } = this.context + const { history } = this.props; + const { t } = this.context; return (
    { - history.push(CONTACT_MY_ACCOUNTS_ROUTE) + history.push(CONTACT_MY_ACCOUNTS_ROUTE); }} >
    @@ -86,7 +86,7 @@ export default class ContactListTab extends Component {
    - ) + ); } renderContactContent() { @@ -95,19 +95,19 @@ export default class ContactListTab extends Component { editingContact, addingContact, showContactContent, - } = this.props + } = this.props; if (!showContactContent) { - return null + return null; } - let ContactContentComponent = null + let ContactContentComponent = null; if (viewingContact) { - ContactContentComponent = ViewContact + ContactContentComponent = ViewContact; } else if (editingContact) { - ContactContentComponent = EditContact + ContactContentComponent = EditContact; } else if (addingContact) { - ContactContentComponent = AddContact + ContactContentComponent = AddContact; } return ( @@ -116,11 +116,11 @@ export default class ContactListTab extends Component {
    ) - ) + ); } renderAddressBookContent() { - const { hideAddressBook, showingMyAccounts } = this.props + const { hideAddressBook, showingMyAccounts } = this.props; if (!hideAddressBook && !showingMyAccounts) { return ( @@ -128,15 +128,15 @@ export default class ContactListTab extends Component { {this.renderMyAccountsButton()} {this.renderAddresses()} - ) + ); } else if (!hideAddressBook && showingMyAccounts) { - return + return ; } - return null + return null; } render() { - const { addingContact } = this.props + const { addingContact } = this.props; return (
    @@ -148,6 +148,6 @@ export default class ContactListTab extends Component {
    )} - ) + ); } } diff --git a/ui/app/pages/settings/contact-list-tab/contact-list-tab.container.js b/ui/app/pages/settings/contact-list-tab/contact-list-tab.container.js index 101daf7aba..19749eafd3 100644 --- a/ui/app/pages/settings/contact-list-tab/contact-list-tab.container.js +++ b/ui/app/pages/settings/contact-list-tab/contact-list-tab.container.js @@ -1,9 +1,9 @@ -import { compose } from 'redux' -import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom' -import { getAddressBook } from '../../../selectors' -import { ENVIRONMENT_TYPE_POPUP } from '../../../../../shared/constants/app' -import { getEnvironmentType } from '../../../../../app/scripts/lib/util' +import { compose } from 'redux'; +import { connect } from 'react-redux'; +import { withRouter } from 'react-router-dom'; +import { getAddressBook } from '../../../selectors'; +import { ENVIRONMENT_TYPE_POPUP } from '../../../../../shared/constants/app'; +import { getEnvironmentType } from '../../../../../app/scripts/lib/util'; import { CONTACT_ADD_ROUTE, @@ -12,34 +12,34 @@ import { CONTACT_MY_ACCOUNTS_ROUTE, CONTACT_MY_ACCOUNTS_VIEW_ROUTE, CONTACT_MY_ACCOUNTS_EDIT_ROUTE, -} from '../../../helpers/constants/routes' -import ContactListTab from './contact-list-tab.component' +} from '../../../helpers/constants/routes'; +import ContactListTab from './contact-list-tab.component'; const mapStateToProps = (state, ownProps) => { - const { location } = ownProps - const { pathname } = location + const { location } = ownProps; + const { pathname } = location; - const pathNameTail = pathname.match(/[^/]+$/u)[0] - const pathNameTailIsAddress = pathNameTail.includes('0x') + const pathNameTail = pathname.match(/[^/]+$/u)[0]; + const pathNameTailIsAddress = pathNameTail.includes('0x'); const viewingContact = Boolean( pathname.match(CONTACT_VIEW_ROUTE) || pathname.match(CONTACT_MY_ACCOUNTS_VIEW_ROUTE), - ) + ); const editingContact = Boolean( pathname.match(CONTACT_EDIT_ROUTE) || pathname.match(CONTACT_MY_ACCOUNTS_EDIT_ROUTE), - ) - const addingContact = Boolean(pathname.match(CONTACT_ADD_ROUTE)) + ); + const addingContact = Boolean(pathname.match(CONTACT_ADD_ROUTE)); const showingMyAccounts = Boolean( pathname.match(CONTACT_MY_ACCOUNTS_ROUTE) || pathname.match(CONTACT_MY_ACCOUNTS_VIEW_ROUTE) || pathname.match(CONTACT_MY_ACCOUNTS_EDIT_ROUTE), - ) - const envIsPopup = getEnvironmentType() === ENVIRONMENT_TYPE_POPUP + ); + const envIsPopup = getEnvironmentType() === ENVIRONMENT_TYPE_POPUP; const hideAddressBook = - envIsPopup && (viewingContact || editingContact || addingContact) + envIsPopup && (viewingContact || editingContact || addingContact); return { viewingContact, @@ -51,7 +51,7 @@ const mapStateToProps = (state, ownProps) => { hideAddressBook, envIsPopup, showContactContent: !envIsPopup || hideAddressBook, - } -} + }; +}; -export default compose(withRouter, connect(mapStateToProps))(ContactListTab) +export default compose(withRouter, connect(mapStateToProps))(ContactListTab); diff --git a/ui/app/pages/settings/contact-list-tab/edit-contact/edit-contact.component.js b/ui/app/pages/settings/contact-list-tab/edit-contact/edit-contact.component.js index e8c3c00f5f..e705dd7fbd 100644 --- a/ui/app/pages/settings/contact-list-tab/edit-contact/edit-contact.component.js +++ b/ui/app/pages/settings/contact-list-tab/edit-contact/edit-contact.component.js @@ -1,16 +1,16 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import { Redirect } from 'react-router-dom' -import Identicon from '../../../../components/ui/identicon' -import Button from '../../../../components/ui/button/button.component' -import TextField from '../../../../components/ui/text-field' -import { isValidAddress } from '../../../../helpers/utils/util' -import PageContainerFooter from '../../../../components/ui/page-container/page-container-footer' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { Redirect } from 'react-router-dom'; +import Identicon from '../../../../components/ui/identicon'; +import Button from '../../../../components/ui/button/button.component'; +import TextField from '../../../../components/ui/text-field'; +import { isValidAddress } from '../../../../helpers/utils/util'; +import PageContainerFooter from '../../../../components/ui/page-container/page-container-footer'; export default class EditContact extends PureComponent { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { addToAddressBook: PropTypes.func, @@ -24,22 +24,22 @@ export default class EditContact extends PureComponent { listRoute: PropTypes.string, setAccountLabel: PropTypes.func, showingMyAccounts: PropTypes.bool.isRequired, - } + }; static defaultProps = { name: '', memo: '', - } + }; state = { newName: this.props.name, newAddress: this.props.address, newMemo: this.props.memo, error: '', - } + }; render() { - const { t } = this.context + const { t } = this.context; const { address, addToAddressBook, @@ -52,10 +52,10 @@ export default class EditContact extends PureComponent { setAccountLabel, showingMyAccounts, viewRoute, - } = this.props + } = this.props; if (!address) { - return + return ; } return ( @@ -67,7 +67,7 @@ export default class EditContact extends PureComponent { type="link" className="settings-page__address-book-button" onClick={async () => { - await removeFromAddressBook(chainId, address) + await removeFromAddressBook(chainId, address); }} > {t('deleteAccount')} @@ -135,21 +135,21 @@ export default class EditContact extends PureComponent { ) { // if the user makes a valid change to the address field, remove the original address if (isValidAddress(this.state.newAddress)) { - await removeFromAddressBook(chainId, address) + await removeFromAddressBook(chainId, address); await addToAddressBook( this.state.newAddress, this.state.newName || name, this.state.newMemo || memo, - ) + ); if (showingMyAccounts) { setAccountLabel( this.state.newAddress, this.state.newName || name, - ) + ); } - history.push(listRoute) + history.push(listRoute); } else { - this.setState({ error: this.context.t('invalidAddress') }) + this.setState({ error: this.context.t('invalidAddress') }); } } else { // update name @@ -157,20 +157,20 @@ export default class EditContact extends PureComponent { address, this.state.newName || name, this.state.newMemo || memo, - ) + ); if (showingMyAccounts) { - setAccountLabel(address, this.state.newName || name) + setAccountLabel(address, this.state.newName || name); } - history.push(listRoute) + history.push(listRoute); } }} onCancel={() => { - history.push(`${viewRoute}/${address}`) + history.push(`${viewRoute}/${address}`); }} submitText={this.context.t('save')} submitButtonType="confirm" /> - ) + ); } } diff --git a/ui/app/pages/settings/contact-list-tab/edit-contact/edit-contact.container.js b/ui/app/pages/settings/contact-list-tab/edit-contact/edit-contact.container.js index ff038e4b37..dfb23aabdd 100644 --- a/ui/app/pages/settings/contact-list-tab/edit-contact/edit-contact.container.js +++ b/ui/app/pages/settings/contact-list-tab/edit-contact/edit-contact.container.js @@ -1,39 +1,39 @@ -import { compose } from 'redux' -import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom' -import { getAddressBookEntry } from '../../../../selectors' +import { compose } from 'redux'; +import { connect } from 'react-redux'; +import { withRouter } from 'react-router-dom'; +import { getAddressBookEntry } from '../../../../selectors'; import { CONTACT_VIEW_ROUTE, CONTACT_MY_ACCOUNTS_ROUTE, CONTACT_MY_ACCOUNTS_VIEW_ROUTE, CONTACT_MY_ACCOUNTS_EDIT_ROUTE, CONTACT_LIST_ROUTE, -} from '../../../../helpers/constants/routes' +} from '../../../../helpers/constants/routes'; import { addToAddressBook, removeFromAddressBook, setAccountLabel, -} from '../../../../store/actions' -import EditContact from './edit-contact.component' +} from '../../../../store/actions'; +import EditContact from './edit-contact.component'; const mapStateToProps = (state, ownProps) => { - const { location } = ownProps - const { pathname } = location - const pathNameTail = pathname.match(/[^/]+$/u)[0] - const pathNameTailIsAddress = pathNameTail.includes('0x') + const { location } = ownProps; + const { pathname } = location; + const pathNameTail = pathname.match(/[^/]+$/u)[0]; + const pathNameTailIsAddress = pathNameTail.includes('0x'); const address = pathNameTailIsAddress ? pathNameTail.toLowerCase() - : ownProps.match.params.id + : ownProps.match.params.id; const contact = - getAddressBookEntry(state, address) || state.metamask.identities[address] - const { memo, name } = contact || {} + getAddressBookEntry(state, address) || state.metamask.identities[address]; + const { memo, name } = contact || {}; - const { chainId } = state.metamask.provider + const { chainId } = state.metamask.provider; const showingMyAccounts = Boolean( pathname.match(CONTACT_MY_ACCOUNTS_EDIT_ROUTE), - ) + ); return { address: contact ? address : null, @@ -47,8 +47,8 @@ const mapStateToProps = (state, ownProps) => { ? CONTACT_MY_ACCOUNTS_ROUTE : CONTACT_LIST_ROUTE, showingMyAccounts, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { @@ -58,10 +58,10 @@ const mapDispatchToProps = (dispatch) => { dispatch(removeFromAddressBook(chainId, addressToRemove)), setAccountLabel: (address, label) => dispatch(setAccountLabel(address, label)), - } -} + }; +}; export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps), -)(EditContact) +)(EditContact); diff --git a/ui/app/pages/settings/contact-list-tab/edit-contact/index.js b/ui/app/pages/settings/contact-list-tab/edit-contact/index.js index fe5ee206a0..ba1254ba9f 100644 --- a/ui/app/pages/settings/contact-list-tab/edit-contact/index.js +++ b/ui/app/pages/settings/contact-list-tab/edit-contact/index.js @@ -1 +1 @@ -export { default } from './edit-contact.container' +export { default } from './edit-contact.container'; diff --git a/ui/app/pages/settings/contact-list-tab/index.js b/ui/app/pages/settings/contact-list-tab/index.js index c09e9787b9..2662ef2bf1 100644 --- a/ui/app/pages/settings/contact-list-tab/index.js +++ b/ui/app/pages/settings/contact-list-tab/index.js @@ -1 +1 @@ -export { default } from './contact-list-tab.container' +export { default } from './contact-list-tab.container'; diff --git a/ui/app/pages/settings/contact-list-tab/my-accounts/index.js b/ui/app/pages/settings/contact-list-tab/my-accounts/index.js index 13a7a9cbfe..e5bde65303 100644 --- a/ui/app/pages/settings/contact-list-tab/my-accounts/index.js +++ b/ui/app/pages/settings/contact-list-tab/my-accounts/index.js @@ -1 +1 @@ -export { default } from './my-accounts.container' +export { default } from './my-accounts.container'; diff --git a/ui/app/pages/settings/contact-list-tab/my-accounts/my-accounts.component.js b/ui/app/pages/settings/contact-list-tab/my-accounts/my-accounts.component.js index d9cac45445..bb7702c566 100644 --- a/ui/app/pages/settings/contact-list-tab/my-accounts/my-accounts.component.js +++ b/ui/app/pages/settings/contact-list-tab/my-accounts/my-accounts.component.js @@ -1,34 +1,34 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import ContactList from '../../../../components/app/contact-list' -import { CONTACT_MY_ACCOUNTS_VIEW_ROUTE } from '../../../../helpers/constants/routes' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import ContactList from '../../../../components/app/contact-list'; +import { CONTACT_MY_ACCOUNTS_VIEW_ROUTE } from '../../../../helpers/constants/routes'; export default class ViewContact extends PureComponent { static contextTypes = { t: PropTypes.func, - } + }; static propTypes = { myAccounts: PropTypes.array, history: PropTypes.object, - } + }; renderMyAccounts() { - const { myAccounts, history } = this.props + const { myAccounts, history } = this.props; return (
    myAccounts} selectRecipient={(address) => { - history.push(`${CONTACT_MY_ACCOUNTS_VIEW_ROUTE}/${address}`) + history.push(`${CONTACT_MY_ACCOUNTS_VIEW_ROUTE}/${address}`); }} />
    - ) + ); } render() { - return
    {this.renderMyAccounts()}
    + return
    {this.renderMyAccounts()}
    ; } } diff --git a/ui/app/pages/settings/contact-list-tab/my-accounts/my-accounts.container.js b/ui/app/pages/settings/contact-list-tab/my-accounts/my-accounts.container.js index 605d6dd89f..82ac4b4efc 100644 --- a/ui/app/pages/settings/contact-list-tab/my-accounts/my-accounts.container.js +++ b/ui/app/pages/settings/contact-list-tab/my-accounts/my-accounts.container.js @@ -1,15 +1,15 @@ -import { compose } from 'redux' -import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom' -import { accountsWithSendEtherInfoSelector } from '../../../../selectors' -import ViewContact from './my-accounts.component' +import { compose } from 'redux'; +import { connect } from 'react-redux'; +import { withRouter } from 'react-router-dom'; +import { accountsWithSendEtherInfoSelector } from '../../../../selectors'; +import ViewContact from './my-accounts.component'; const mapStateToProps = (state) => { - const myAccounts = accountsWithSendEtherInfoSelector(state) + const myAccounts = accountsWithSendEtherInfoSelector(state); return { myAccounts, - } -} + }; +}; -export default compose(withRouter, connect(mapStateToProps))(ViewContact) +export default compose(withRouter, connect(mapStateToProps))(ViewContact); diff --git a/ui/app/pages/settings/contact-list-tab/view-contact/index.js b/ui/app/pages/settings/contact-list-tab/view-contact/index.js index 78bf19d186..6b8fe106af 100644 --- a/ui/app/pages/settings/contact-list-tab/view-contact/index.js +++ b/ui/app/pages/settings/contact-list-tab/view-contact/index.js @@ -1 +1 @@ -export { default } from './view-contact.container' +export { default } from './view-contact.container'; diff --git a/ui/app/pages/settings/contact-list-tab/view-contact/view-contact.component.js b/ui/app/pages/settings/contact-list-tab/view-contact/view-contact.component.js index aada6d13a7..bcc6e9adce 100644 --- a/ui/app/pages/settings/contact-list-tab/view-contact/view-contact.component.js +++ b/ui/app/pages/settings/contact-list-tab/view-contact/view-contact.component.js @@ -1,20 +1,20 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { Redirect } from 'react-router-dom' +import React from 'react'; +import PropTypes from 'prop-types'; +import { Redirect } from 'react-router-dom'; -import Identicon from '../../../../components/ui/identicon' -import Copy from '../../../../components/ui/icon/copy-icon.component' -import Button from '../../../../components/ui/button/button.component' +import Identicon from '../../../../components/ui/identicon'; +import Copy from '../../../../components/ui/icon/copy-icon.component'; +import Button from '../../../../components/ui/button/button.component'; -import Tooltip from '../../../../components/ui/tooltip' -import { useI18nContext } from '../../../../hooks/useI18nContext' -import { useCopyToClipboard } from '../../../../hooks/useCopyToClipboard' +import Tooltip from '../../../../components/ui/tooltip'; +import { useI18nContext } from '../../../../hooks/useI18nContext'; +import { useCopyToClipboard } from '../../../../hooks/useCopyToClipboard'; function quadSplit(address) { return `0x ${address .slice(2) .match(/.{1,4}/gu) - .join(' ')}` + .join(' ')}`; } function ViewContact({ @@ -26,11 +26,11 @@ function ViewContact({ editRoute, listRoute, }) { - const t = useI18nContext() - const [copied, handleCopy] = useCopyToClipboard() + const t = useI18nContext(); + const [copied, handleCopy] = useCopyToClipboard(); if (!address) { - return + return ; } return ( @@ -44,7 +44,7 @@ function ViewContact({ - ) + ); } render() { - const { t } = this.context + const { t } = this.context; return (
    @@ -113,6 +113,6 @@ export default class InfoTab extends PureComponent {
    - ) + ); } } diff --git a/ui/app/pages/settings/networks-tab/index.js b/ui/app/pages/settings/networks-tab/index.js index 362004498e..fc436c9a40 100644 --- a/ui/app/pages/settings/networks-tab/index.js +++ b/ui/app/pages/settings/networks-tab/index.js @@ -1 +1 @@ -export { default } from './networks-tab.container' +export { default } from './networks-tab.container'; diff --git a/ui/app/pages/settings/networks-tab/network-form/index.js b/ui/app/pages/settings/networks-tab/network-form/index.js index 89d9de42bf..bd21ef354d 100644 --- a/ui/app/pages/settings/networks-tab/network-form/index.js +++ b/ui/app/pages/settings/networks-tab/network-form/index.js @@ -1 +1 @@ -export { default } from './network-form.component' +export { default } from './network-form.component'; diff --git a/ui/app/pages/settings/networks-tab/network-form/network-form.component.js b/ui/app/pages/settings/networks-tab/network-form/network-form.component.js index a20aa55341..4d9e10a6e1 100644 --- a/ui/app/pages/settings/networks-tab/network-form/network-form.component.js +++ b/ui/app/pages/settings/networks-tab/network-form/network-form.component.js @@ -1,15 +1,15 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import validUrl from 'valid-url' -import log from 'loglevel' -import TextField from '../../../../components/ui/text-field' -import Button from '../../../../components/ui/button' -import Tooltip from '../../../../components/ui/tooltip' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import validUrl from 'valid-url'; +import log from 'loglevel'; +import TextField from '../../../../components/ui/text-field'; +import Button from '../../../../components/ui/button'; +import Tooltip from '../../../../components/ui/tooltip'; import { isPrefixedFormattedHexString, isSafeChainId, -} from '../../../../../../shared/modules/utils' -import { jsonRpcRequest } from '../../../../helpers/utils/util' +} from '../../../../../../shared/modules/utils'; +import { jsonRpcRequest } from '../../../../helpers/utils/util'; const FORM_STATE_KEYS = [ 'rpcUrl', @@ -17,13 +17,13 @@ const FORM_STATE_KEYS = [ 'ticker', 'networkName', 'blockExplorerUrl', -] +]; export default class NetworkForm extends PureComponent { static contextTypes = { t: PropTypes.func.isRequired, metricsEvent: PropTypes.func.isRequired, - } + }; static propTypes = { editRpc: PropTypes.func.isRequired, @@ -41,7 +41,7 @@ export default class NetworkForm extends PureComponent { rpcPrefs: PropTypes.object, rpcUrls: PropTypes.array, isFullScreen: PropTypes.bool, - } + }; state = { rpcUrl: this.props.rpcUrl, @@ -51,11 +51,11 @@ export default class NetworkForm extends PureComponent { blockExplorerUrl: this.props.blockExplorerUrl, errors: {}, isSubmitting: false, - } + }; componentDidUpdate(prevProps) { - const { networksTabIsInAddMode: prevAddMode } = prevProps - const { networksTabIsInAddMode } = this.props + const { networksTabIsInAddMode: prevAddMode } = prevProps; + const { networksTabIsInAddMode } = this.props; if (!prevAddMode && networksTabIsInAddMode) { this.setState({ @@ -66,12 +66,12 @@ export default class NetworkForm extends PureComponent { blockExplorerUrl: '', errors: {}, isSubmitting: false, - }) + }); } else { for (const key of FORM_STATE_KEYS) { if (prevProps[key] !== this.props[key]) { - this.resetForm() - break + this.resetForm(); + break; } } } @@ -85,12 +85,12 @@ export default class NetworkForm extends PureComponent { networkName: '', blockExplorerUrl: '', errors: {}, - }) + }); // onClear will push the network settings route unless was pass false. // Since we call onClear to cause this component to be unmounted, the // route will already have been updated, and we avoid setting it twice. - this.props.onClear(false) + this.props.onClear(false); } resetForm() { @@ -100,7 +100,7 @@ export default class NetworkForm extends PureComponent { ticker, networkName, blockExplorerUrl, - } = this.props + } = this.props; this.setState({ rpcUrl, @@ -110,7 +110,7 @@ export default class NetworkForm extends PureComponent { blockExplorerUrl, errors: {}, isSubmitting: false, - }) + }); } /** @@ -126,15 +126,15 @@ export default class NetworkForm extends PureComponent { */ getDisplayChainId(chainId) { if (!chainId || typeof chainId !== 'string' || !chainId.startsWith('0x')) { - return chainId + return chainId; } - return parseInt(chainId, 16).toString(10) + return parseInt(chainId, 16).toString(10); } onSubmit = async () => { this.setState({ isSubmitting: true, - }) + }); try { const { @@ -144,27 +144,27 @@ export default class NetworkForm extends PureComponent { rpcPrefs = {}, onClear, networksTabIsInAddMode, - } = this.props + } = this.props; const { networkName, rpcUrl, chainId: stateChainId, ticker, blockExplorerUrl, - } = this.state + } = this.state; - const formChainId = stateChainId.trim().toLowerCase() + const formChainId = stateChainId.trim().toLowerCase(); // Ensure chainId is a 0x-prefixed, lowercase hex string - let chainId = formChainId + let chainId = formChainId; if (!chainId.startsWith('0x')) { - chainId = `0x${parseInt(chainId, 10).toString(16)}` + chainId = `0x${parseInt(chainId, 10).toString(16)}`; } if (!(await this.validateChainIdOnSubmit(formChainId, chainId, rpcUrl))) { this.setState({ isSubmitting: false, - }) - return + }); + return; } // After this point, isSubmitting will be reset in componentDidUpdate @@ -172,48 +172,48 @@ export default class NetworkForm extends PureComponent { await editRpc(propsRpcUrl, rpcUrl, chainId, ticker, networkName, { ...rpcPrefs, blockExplorerUrl: blockExplorerUrl || rpcPrefs.blockExplorerUrl, - }) + }); } else { await setRpcTarget(rpcUrl, chainId, ticker, networkName, { ...rpcPrefs, blockExplorerUrl: blockExplorerUrl || rpcPrefs.blockExplorerUrl, - }) + }); } if (networksTabIsInAddMode) { - onClear() + onClear(); } } catch (error) { this.setState({ isSubmitting: false, - }) - throw error + }); + throw error; } - } + }; onCancel = () => { - const { isFullScreen, networksTabIsInAddMode, onClear } = this.props + const { isFullScreen, networksTabIsInAddMode, onClear } = this.props; if (networksTabIsInAddMode || !isFullScreen) { - onClear() + onClear(); } else { - this.resetForm() + this.resetForm(); } - } + }; onDelete = () => { - const { showConfirmDeleteNetworkModal, rpcUrl, onClear } = this.props + const { showConfirmDeleteNetworkModal, rpcUrl, onClear } = this.props; showConfirmDeleteNetworkModal({ target: rpcUrl, onConfirm: () => { - this.resetForm() - onClear() + this.resetForm(); + onClear(); }, - }) - } + }); + }; isSubmitting() { - return this.state.isSubmitting + return this.state.isSubmitting; } stateIsUnchanged() { @@ -223,7 +223,7 @@ export default class NetworkForm extends PureComponent { ticker, networkName, blockExplorerUrl, - } = this.props + } = this.props; const { rpcUrl: stateRpcUrl, @@ -231,7 +231,7 @@ export default class NetworkForm extends PureComponent { ticker: stateTicker, networkName: stateNetworkName, blockExplorerUrl: stateBlockExplorerUrl, - } = this.state + } = this.state; // These added conditions are in case the saved chainId is invalid, which // was possible in versions <8.1 of the extension. @@ -239,7 +239,7 @@ export default class NetworkForm extends PureComponent { const chainIdIsUnchanged = typeof propsChainId === 'string' && propsChainId.toLowerCase().startsWith('0x') && - stateChainId === this.getDisplayChainId(propsChainId) + stateChainId === this.getDisplayChainId(propsChainId); return ( stateRpcUrl === rpcUrl && @@ -247,7 +247,7 @@ export default class NetworkForm extends PureComponent { stateTicker === ticker && stateNetworkName === networkName && stateBlockExplorerUrl === blockExplorerUrl - ) + ); } renderFormTextField( @@ -258,8 +258,8 @@ export default class NetworkForm extends PureComponent { optionalTextFieldKey, tooltipText, ) { - const { errors } = this.state - const { viewOnly } = this.props + const { errors } = this.state; + const { viewOnly } = this.props; return (
    @@ -288,15 +288,15 @@ export default class NetworkForm extends PureComponent { error={errors[fieldKey]} />
    - ) + ); } setStateWithValue = (stateKey, validator) => { return (e) => { - validator?.(e.target.value, stateKey) - this.setState({ [stateKey]: e.target.value }) - } - } + validator?.(e.target.value, stateKey); + this.setState({ [stateKey]: e.target.value }); + }; + }; setErrorTo = (errorKey, errorVal) => { this.setState({ @@ -304,31 +304,31 @@ export default class NetworkForm extends PureComponent { ...this.state.errors, [errorKey]: errorVal, }, - }) - } + }); + }; validateChainIdOnChange = (chainIdArg = '') => { - const chainId = chainIdArg.trim() - let errorMessage = '' - let radix = 10 + const chainId = chainIdArg.trim(); + let errorMessage = ''; + let radix = 10; if (chainId.startsWith('0x')) { - radix = 16 + radix = 16; if (!/^0x[0-9a-f]+$/iu.test(chainId)) { - errorMessage = this.context.t('invalidHexNumber') + errorMessage = this.context.t('invalidHexNumber'); } else if (!isPrefixedFormattedHexString(chainId)) { - errorMessage = this.context.t('invalidHexNumberLeadingZeros') + errorMessage = this.context.t('invalidHexNumberLeadingZeros'); } } else if (!/^[0-9]+$/u.test(chainId)) { - errorMessage = this.context.t('invalidNumber') + errorMessage = this.context.t('invalidNumber'); } else if (chainId.startsWith('0')) { - errorMessage = this.context.t('invalidNumberLeadingZeros') + errorMessage = this.context.t('invalidNumberLeadingZeros'); } else if (!isSafeChainId(parseInt(chainId, radix))) { - errorMessage = this.context.t('invalidChainIdTooBig') + errorMessage = this.context.t('invalidChainIdTooBig'); } - this.setErrorTo('chainId', errorMessage) - } + this.setErrorTo('chainId', errorMessage); + }; /** * Validates the chain ID by checking it against the `eth_chainId` return @@ -341,20 +341,20 @@ export default class NetworkForm extends PureComponent { * @param {string} rpcUrl - The RPC URL from the form. */ validateChainIdOnSubmit = async (formChainId, parsedChainId, rpcUrl) => { - const { t } = this.context - let errorMessage - let endpointChainId - let providerError + const { t } = this.context; + let errorMessage; + let endpointChainId; + let providerError; try { - endpointChainId = await jsonRpcRequest(rpcUrl, 'eth_chainId') + endpointChainId = await jsonRpcRequest(rpcUrl, 'eth_chainId'); } catch (err) { - log.warn('Failed to fetch the chainId from the endpoint.', err) - providerError = err + log.warn('Failed to fetch the chainId from the endpoint.', err); + providerError = err; } if (providerError || typeof endpointChainId !== 'string') { - errorMessage = t('failedToFetchChainId') + errorMessage = t('failedToFetchChainId'); } else if (parsedChainId !== endpointChainId) { // Here, we are in an error state. The endpoint should always return a // hexadecimal string. If the user entered a decimal string, we attempt @@ -362,12 +362,12 @@ export default class NetworkForm extends PureComponent { // in an error message in the form. if (!formChainId.startsWith('0x')) { try { - endpointChainId = parseInt(endpointChainId, 16).toString(10) + endpointChainId = parseInt(endpointChainId, 16).toString(10); } catch (err) { log.warn( 'Failed to convert endpoint chain ID to decimal', endpointChainId, - ) + ); } } @@ -375,20 +375,20 @@ export default class NetworkForm extends PureComponent { endpointChainId.length <= 12 ? endpointChainId : `${endpointChainId.slice(0, 9)}...`, - ]) + ]); } if (errorMessage) { - this.setErrorTo('chainId', errorMessage) - return false + this.setErrorTo('chainId', errorMessage); + return false; } - return true - } + return true; + }; isValidWhenAppended = (url) => { - const appendedRpc = `http://${url}` - return validUrl.isWebUri(appendedRpc) && !url.match(/^https?:\/\/$/u) - } + const appendedRpc = `http://${url}`; + return validUrl.isWebUri(appendedRpc) && !url.match(/^https?:\/\/$/u); + }; validateBlockExplorerURL = (url, stateKey) => { if (!validUrl.isWebUri(url) && url !== '') { @@ -399,14 +399,14 @@ export default class NetworkForm extends PureComponent { ? 'urlErrorMsg' : 'invalidBlockExplorerURL', ), - ) + ); } else { - this.setErrorTo(stateKey, '') + this.setErrorTo(stateKey, ''); } - } + }; validateUrlRpcUrl = (url, stateKey) => { - const { rpcUrls } = this.props + const { rpcUrls } = this.props; if (!validUrl.isWebUri(url) && url !== '') { this.setErrorTo( @@ -414,26 +414,26 @@ export default class NetworkForm extends PureComponent { this.context.t( this.isValidWhenAppended(url) ? 'urlErrorMsg' : 'invalidRPC', ), - ) + ); } else if (rpcUrls.includes(url)) { - this.setErrorTo(stateKey, this.context.t('urlExistsErrorMsg')) + this.setErrorTo(stateKey, this.context.t('urlExistsErrorMsg')); } else { - this.setErrorTo(stateKey, '') + this.setErrorTo(stateKey, ''); } - } + }; renderWarning() { - const { t } = this.context + const { t } = this.context; return (
    {t('onlyAddTrustedNetworks')}
    - ) + ); } render() { - const { t } = this.context - const { viewOnly, isCurrentRpcTarget, networksTabIsInAddMode } = this.props + const { t } = this.context; + const { viewOnly, isCurrentRpcTarget, networksTabIsInAddMode } = this.props; const { networkName, rpcUrl, @@ -441,17 +441,17 @@ export default class NetworkForm extends PureComponent { ticker, blockExplorerUrl, errors, - } = this.state + } = this.state; const deletable = - !networksTabIsInAddMode && !isCurrentRpcTarget && !viewOnly + !networksTabIsInAddMode && !isCurrentRpcTarget && !viewOnly; const isSubmitDisabled = this.isSubmitting() || this.stateIsUnchanged() || !rpcUrl || !chainId || - Object.values(errors).some((x) => x) + Object.values(errors).some((x) => x); return (
    @@ -519,6 +519,6 @@ export default class NetworkForm extends PureComponent { )}
    - ) + ); } } diff --git a/ui/app/pages/settings/networks-tab/networks-tab.component.js b/ui/app/pages/settings/networks-tab/networks-tab.component.js index bac21f93ec..f62a407900 100644 --- a/ui/app/pages/settings/networks-tab/networks-tab.component.js +++ b/ui/app/pages/settings/networks-tab/networks-tab.component.js @@ -1,22 +1,22 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network' -import Button from '../../../components/ui/button' -import LockIcon from '../../../components/ui/lock-icon' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network'; +import Button from '../../../components/ui/button'; +import LockIcon from '../../../components/ui/lock-icon'; import { NETWORKS_ROUTE, NETWORKS_FORM_ROUTE, -} from '../../../helpers/constants/routes' -import ColorIndicator from '../../../components/ui/color-indicator' -import { COLORS, SIZES } from '../../../helpers/constants/design-system' -import NetworkForm from './network-form' +} from '../../../helpers/constants/routes'; +import ColorIndicator from '../../../components/ui/color-indicator'; +import { COLORS, SIZES } from '../../../helpers/constants/design-system'; +import NetworkForm from './network-form'; export default class NetworksTab extends PureComponent { static contextTypes = { t: PropTypes.func.isRequired, metricsEvent: PropTypes.func.isRequired, - } + }; static propTypes = { editRpc: PropTypes.func.isRequired, @@ -35,18 +35,18 @@ export default class NetworksTab extends PureComponent { history: PropTypes.object.isRequired, shouldRenderNetworkForm: PropTypes.bool.isRequired, isFullScreen: PropTypes.bool.isRequired, - } + }; componentWillUnmount() { - this.props.setSelectedSettingsRpcUrl('') + this.props.setSelectedSettingsRpcUrl(''); } isCurrentPath(pathname) { - return this.props.location.pathname === pathname + return this.props.location.pathname === pathname; } renderSubHeader() { - const { setSelectedSettingsRpcUrl, setNetworksTabAddMode } = this.props + const { setSelectedSettingsRpcUrl, setNetworksTabAddMode } = this.props; return (
    @@ -57,16 +57,16 @@ export default class NetworksTab extends PureComponent {
    - ) + ); } renderNetworkListItem(network, selectRpcUrl) { @@ -79,34 +79,34 @@ export default class NetworksTab extends PureComponent { networksTabIsInAddMode, history, isFullScreen, - } = this.props + } = this.props; const { label, labelKey, rpcUrl, providerType: currentProviderType, - } = network + } = network; - const listItemNetworkIsSelected = selectRpcUrl && selectRpcUrl === rpcUrl - const listItemUrlIsProviderUrl = rpcUrl === providerUrl + const listItemNetworkIsSelected = selectRpcUrl && selectRpcUrl === rpcUrl; + const listItemUrlIsProviderUrl = rpcUrl === providerUrl; const listItemTypeIsProviderNonRpcType = - providerType !== NETWORK_TYPE_RPC && currentProviderType === providerType + providerType !== NETWORK_TYPE_RPC && currentProviderType === providerType; const listItemNetworkIsCurrentProvider = !networkIsSelected && !networksTabIsInAddMode && - (listItemUrlIsProviderUrl || listItemTypeIsProviderNonRpcType) + (listItemUrlIsProviderUrl || listItemTypeIsProviderNonRpcType); const displayNetworkListItemAsSelected = - listItemNetworkIsSelected || listItemNetworkIsCurrentProvider + listItemNetworkIsSelected || listItemNetworkIsCurrentProvider; return (
    { - setNetworksTabAddMode(false) - setSelectedSettingsRpcUrl(rpcUrl) + setNetworksTabAddMode(false); + setSelectedSettingsRpcUrl(rpcUrl); if (!isFullScreen) { - history.push(NETWORKS_FORM_ROUTE) + history.push(NETWORKS_FORM_ROUTE); } }} > @@ -130,7 +130,7 @@ export default class NetworksTab extends PureComponent {
    - ) + ); } renderNetworksList() { @@ -140,7 +140,7 @@ export default class NetworksTab extends PureComponent { networkIsSelected, networksTabIsInAddMode, networkDefaultedToProvider, - } = this.props + } = this.props; return (
    )}
    - ) + ); } renderNetworksTabContent() { - const { t } = this.context + const { t } = this.context; const { setRpcTarget, showConfirmDeleteNetworkModal, @@ -195,7 +195,7 @@ export default class NetworksTab extends PureComponent { history, isFullScreen, shouldRenderNetworkForm, - } = this.props + } = this.props; return ( <> @@ -210,10 +210,10 @@ export default class NetworksTab extends PureComponent { chainId={chainId} ticker={ticker} onClear={(shouldUpdateHistory = true) => { - setNetworksTabAddMode(false) - setSelectedSettingsRpcUrl('') + setNetworksTabAddMode(false); + setSelectedSettingsRpcUrl(''); if (shouldUpdateHistory && !isFullScreen) { - history.push(NETWORKS_ROUTE) + history.push(NETWORKS_ROUTE); } }} showConfirmDeleteNetworkModal={showConfirmDeleteNetworkModal} @@ -226,7 +226,7 @@ export default class NetworksTab extends PureComponent { /> ) : null} - ) + ); } render() { @@ -236,7 +236,7 @@ export default class NetworksTab extends PureComponent { history, isFullScreen, shouldRenderNetworkForm, - } = this.props + } = this.props; return (
    @@ -248,10 +248,10 @@ export default class NetworksTab extends PureComponent {
    - ) + ); } } diff --git a/ui/app/pages/settings/networks-tab/networks-tab.constants.js b/ui/app/pages/settings/networks-tab/networks-tab.constants.js index 9a9eb96994..52f6514d7c 100644 --- a/ui/app/pages/settings/networks-tab/networks-tab.constants.js +++ b/ui/app/pages/settings/networks-tab/networks-tab.constants.js @@ -9,7 +9,7 @@ import { RINKEBY_CHAIN_ID, ROPSTEN, ROPSTEN_CHAIN_ID, -} from '../../../../../shared/constants/network' +} from '../../../../../shared/constants/network'; const defaultNetworksData = [ { @@ -57,6 +57,6 @@ const defaultNetworksData = [ ticker: 'ETH', blockExplorerUrl: 'https://kovan.etherscan.io', }, -] +]; -export { defaultNetworksData } +export { defaultNetworksData }; diff --git a/ui/app/pages/settings/networks-tab/networks-tab.container.js b/ui/app/pages/settings/networks-tab/networks-tab.container.js index 14f5d39299..75b6371592 100644 --- a/ui/app/pages/settings/networks-tab/networks-tab.container.js +++ b/ui/app/pages/settings/networks-tab/networks-tab.container.js @@ -1,6 +1,6 @@ -import { compose } from 'redux' -import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom' +import { compose } from 'redux'; +import { connect } from 'react-redux'; +import { withRouter } from 'react-router-dom'; import { setSelectedSettingsRpcUrl, updateAndSetCustomRpc, @@ -8,31 +8,31 @@ import { setNetworksTabAddMode, editRpc, showModal, -} from '../../../store/actions' -import { NETWORKS_FORM_ROUTE } from '../../../helpers/constants/routes' -import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../../shared/constants/app' -import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network' -import { getEnvironmentType } from '../../../../../app/scripts/lib/util' -import NetworksTab from './networks-tab.component' -import { defaultNetworksData } from './networks-tab.constants' +} from '../../../store/actions'; +import { NETWORKS_FORM_ROUTE } from '../../../helpers/constants/routes'; +import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../../shared/constants/app'; +import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network'; +import { getEnvironmentType } from '../../../../../app/scripts/lib/util'; +import NetworksTab from './networks-tab.component'; +import { defaultNetworksData } from './networks-tab.constants'; const defaultNetworks = defaultNetworksData.map((network) => ({ ...network, viewOnly: true, -})) +})); const mapStateToProps = (state, ownProps) => { const { location: { pathname }, - } = ownProps + } = ownProps; - const environmentType = getEnvironmentType() - const isFullScreen = environmentType === ENVIRONMENT_TYPE_FULLSCREEN + const environmentType = getEnvironmentType(); + const isFullScreen = environmentType === ENVIRONMENT_TYPE_FULLSCREEN; const shouldRenderNetworkForm = - isFullScreen || Boolean(pathname.match(NETWORKS_FORM_ROUTE)) + isFullScreen || Boolean(pathname.match(NETWORKS_FORM_ROUTE)); - const { frequentRpcListDetail, provider } = state.metamask - const { networksTabSelectedRpcUrl, networksTabIsInAddMode } = state.appState + const { frequentRpcListDetail, provider } = state.metamask; + const { networksTabSelectedRpcUrl, networksTabIsInAddMode } = state.appState; const frequentRpcNetworkListDetails = frequentRpcListDetail.map((rpc) => { return { @@ -43,20 +43,20 @@ const mapStateToProps = (state, ownProps) => { chainId: rpc.chainId, ticker: rpc.ticker, blockExplorerUrl: rpc.rpcPrefs?.blockExplorerUrl || '', - } - }) + }; + }); const networksToRender = [ ...defaultNetworks, ...frequentRpcNetworkListDetails, - ] + ]; let selectedNetwork = networksToRender.find( (network) => network.rpcUrl === networksTabSelectedRpcUrl, - ) || {} - const networkIsSelected = Boolean(selectedNetwork.rpcUrl) + ) || {}; + const networkIsSelected = Boolean(selectedNetwork.rpcUrl); - let networkDefaultedToProvider = false + let networkDefaultedToProvider = false; if (!networkIsSelected && !networksTabIsInAddMode) { selectedNetwork = networksToRender.find((network) => { @@ -64,9 +64,9 @@ const mapStateToProps = (state, ownProps) => { network.rpcUrl === provider.rpcUrl || (network.providerType !== NETWORK_TYPE_RPC && network.providerType === provider.type) - ) - }) || {} - networkDefaultedToProvider = true + ); + }) || {}; + networkDefaultedToProvider = true; } return { @@ -79,8 +79,8 @@ const mapStateToProps = (state, ownProps) => { networkDefaultedToProvider, isFullScreen, shouldRenderNetworkForm, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { @@ -89,12 +89,12 @@ const mapDispatchToProps = (dispatch) => { setRpcTarget: (newRpc, chainId, ticker, nickname, rpcPrefs) => { return dispatch( updateAndSetCustomRpc(newRpc, chainId, ticker, nickname, rpcPrefs), - ) + ); }, showConfirmDeleteNetworkModal: ({ target, onConfirm }) => { return dispatch( showModal({ name: 'CONFIRM_DELETE_NETWORK', target, onConfirm }), - ) + ); }, displayWarning: (warning) => dispatch(displayWarning(warning)), setNetworksTabAddMode: (isInAddMode) => @@ -102,12 +102,12 @@ const mapDispatchToProps = (dispatch) => { editRpc: (oldRpc, newRpc, chainId, ticker, nickname, rpcPrefs) => { return dispatch( editRpc(oldRpc, newRpc, chainId, ticker, nickname, rpcPrefs), - ) + ); }, - } -} + }; +}; export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps), -)(NetworksTab) +)(NetworksTab); diff --git a/ui/app/pages/settings/security-tab/index.js b/ui/app/pages/settings/security-tab/index.js index 7ffc291a26..8f812e16ce 100644 --- a/ui/app/pages/settings/security-tab/index.js +++ b/ui/app/pages/settings/security-tab/index.js @@ -1 +1 @@ -export { default } from './security-tab.container' +export { default } from './security-tab.container'; diff --git a/ui/app/pages/settings/security-tab/security-tab.component.js b/ui/app/pages/settings/security-tab/security-tab.component.js index bf322f528a..8eab40ec2e 100644 --- a/ui/app/pages/settings/security-tab/security-tab.component.js +++ b/ui/app/pages/settings/security-tab/security-tab.component.js @@ -1,14 +1,14 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import ToggleButton from '../../../components/ui/toggle-button' -import { REVEAL_SEED_ROUTE } from '../../../helpers/constants/routes' -import Button from '../../../components/ui/button' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import ToggleButton from '../../../components/ui/toggle-button'; +import { REVEAL_SEED_ROUTE } from '../../../helpers/constants/routes'; +import Button from '../../../components/ui/button'; export default class SecurityTab extends PureComponent { static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; static propTypes = { warning: PropTypes.string, @@ -19,11 +19,11 @@ export default class SecurityTab extends PureComponent { setShowIncomingTransactionsFeatureFlag: PropTypes.func.isRequired, setUsePhishDetect: PropTypes.func.isRequired, usePhishDetect: PropTypes.bool.isRequired, - } + }; renderSeedWords() { - const { t } = this.context - const { history } = this.props + const { t } = this.context; + const { history } = this.props; return (
    @@ -36,15 +36,15 @@ export default class SecurityTab extends PureComponent { type="danger" large onClick={(event) => { - event.preventDefault() + event.preventDefault(); this.context.metricsEvent({ eventOpts: { category: 'Settings', action: 'Reveal Seed Phrase', name: 'Reveal Seed Phrase', }, - }) - history.push(REVEAL_SEED_ROUTE) + }); + history.push(REVEAL_SEED_ROUTE); }} > {t('revealSeedWords')} @@ -52,12 +52,15 @@ export default class SecurityTab extends PureComponent {
    - ) + ); } renderMetaMetricsOptIn() { - const { t } = this.context - const { participateInMetaMetrics, setParticipateInMetaMetrics } = this.props + const { t } = this.context; + const { + participateInMetaMetrics, + setParticipateInMetaMetrics, + } = this.props; return (
    @@ -78,15 +81,15 @@ export default class SecurityTab extends PureComponent {
    - ) + ); } renderIncomingTransactionsOptIn() { - const { t } = this.context + const { t } = this.context; const { showIncomingTransactions, setShowIncomingTransactionsFeatureFlag, - } = this.props + } = this.props; return (
    @@ -109,12 +112,12 @@ export default class SecurityTab extends PureComponent {
    - ) + ); } renderPhishingDetectionToggle() { - const { t } = this.context - const { usePhishDetect, setUsePhishDetect } = this.props + const { t } = this.context; + const { usePhishDetect, setUsePhishDetect } = this.props; return (
    @@ -135,11 +138,11 @@ export default class SecurityTab extends PureComponent {
    - ) + ); } render() { - const { warning } = this.props + const { warning } = this.props; return (
    @@ -149,6 +152,6 @@ export default class SecurityTab extends PureComponent { {this.renderPhishingDetectionToggle()} {this.renderMetaMetricsOptIn()}
    - ) + ); } } diff --git a/ui/app/pages/settings/security-tab/security-tab.container.js b/ui/app/pages/settings/security-tab/security-tab.container.js index 7860cff2df..e6060f45b7 100644 --- a/ui/app/pages/settings/security-tab/security-tab.container.js +++ b/ui/app/pages/settings/security-tab/security-tab.container.js @@ -1,31 +1,31 @@ -import { compose } from 'redux' -import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom' +import { compose } from 'redux'; +import { connect } from 'react-redux'; +import { withRouter } from 'react-router-dom'; import { setFeatureFlag, setParticipateInMetaMetrics, setUsePhishDetect, -} from '../../../store/actions' -import SecurityTab from './security-tab.component' +} from '../../../store/actions'; +import SecurityTab from './security-tab.component'; const mapStateToProps = (state) => { const { appState: { warning }, metamask, - } = state + } = state; const { featureFlags: { showIncomingTransactions } = {}, participateInMetaMetrics, usePhishDetect, - } = metamask + } = metamask; return { warning, showIncomingTransactions, participateInMetaMetrics, usePhishDetect, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { @@ -34,10 +34,10 @@ const mapDispatchToProps = (dispatch) => { setShowIncomingTransactionsFeatureFlag: (shouldShow) => dispatch(setFeatureFlag('showIncomingTransactions', shouldShow)), setUsePhishDetect: (val) => dispatch(setUsePhishDetect(val)), - } -} + }; +}; export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps), -)(SecurityTab) +)(SecurityTab); diff --git a/ui/app/pages/settings/security-tab/tests/security-tab.test.js b/ui/app/pages/settings/security-tab/tests/security-tab.test.js index d45a47d357..78b785c4f3 100644 --- a/ui/app/pages/settings/security-tab/tests/security-tab.test.js +++ b/ui/app/pages/settings/security-tab/tests/security-tab.test.js @@ -1,11 +1,11 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import { mount } from 'enzyme' -import SecurityTab from '..' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import { mount } from 'enzyme'; +import SecurityTab from '..'; describe('Security Tab', function () { - let wrapper + let wrapper; const props = { revealSeedConfirmation: sinon.spy(), @@ -21,7 +21,7 @@ describe('Security Tab', function () { participateInMetaMetrics: false, setUsePhishDetect: sinon.spy(), usePhishDetect: true, - } + }; beforeEach(function () { wrapper = mount(, { @@ -29,33 +29,33 @@ describe('Security Tab', function () { t: (str) => str, metricsEvent: () => undefined, }, - }) - }) + }); + }); it('navigates to reveal seed words page', function () { - const seedWords = wrapper.find('.button.btn-danger.btn--large') + const seedWords = wrapper.find('.button.btn-danger.btn--large'); - seedWords.simulate('click') - assert(props.history.push.calledOnce) - assert.strictEqual(props.history.push.getCall(0).args[0], '/seed') - }) + seedWords.simulate('click'); + assert(props.history.push.calledOnce); + assert.strictEqual(props.history.push.getCall(0).args[0], '/seed'); + }); it('toggles incoming txs', function () { - const incomingTxs = wrapper.find({ type: 'checkbox' }).at(0) - incomingTxs.simulate('click') - assert(props.setShowIncomingTransactionsFeatureFlag.calledOnce) - }) + const incomingTxs = wrapper.find({ type: 'checkbox' }).at(0); + incomingTxs.simulate('click'); + assert(props.setShowIncomingTransactionsFeatureFlag.calledOnce); + }); it('toggles phishing detection', function () { - const phishDetect = wrapper.find({ type: 'checkbox' }).at(1) - phishDetect.simulate('click') - assert(props.setUsePhishDetect.calledOnce) - }) + const phishDetect = wrapper.find({ type: 'checkbox' }).at(1); + phishDetect.simulate('click'); + assert(props.setUsePhishDetect.calledOnce); + }); it('toggles metaMetrics', function () { - const metaMetrics = wrapper.find({ type: 'checkbox' }).at(2) + const metaMetrics = wrapper.find({ type: 'checkbox' }).at(2); - metaMetrics.simulate('click') - assert(props.setParticipateInMetaMetrics.calledOnce) - }) -}) + metaMetrics.simulate('click'); + assert(props.setParticipateInMetaMetrics.calledOnce); + }); +}); diff --git a/ui/app/pages/settings/settings-tab/index.js b/ui/app/pages/settings/settings-tab/index.js index 9fdaafd3f0..4c8fcab383 100644 --- a/ui/app/pages/settings/settings-tab/index.js +++ b/ui/app/pages/settings/settings-tab/index.js @@ -1 +1 @@ -export { default } from './settings-tab.container' +export { default } from './settings-tab.container'; diff --git a/ui/app/pages/settings/settings-tab/settings-tab.component.js b/ui/app/pages/settings/settings-tab/settings-tab.component.js index 65f926c3fa..6c1452c02f 100644 --- a/ui/app/pages/settings/settings-tab/settings-tab.component.js +++ b/ui/app/pages/settings/settings-tab/settings-tab.component.js @@ -1,35 +1,35 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import availableCurrencies from '../../../helpers/constants/available-conversions.json' -import SimpleDropdown from '../../../components/app/dropdowns/simple-dropdown' -import ToggleButton from '../../../components/ui/toggle-button' -import locales from '../../../../../app/_locales/index.json' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import availableCurrencies from '../../../helpers/constants/available-conversions.json'; +import SimpleDropdown from '../../../components/app/dropdowns/simple-dropdown'; +import ToggleButton from '../../../components/ui/toggle-button'; +import locales from '../../../../../app/_locales/index.json'; const sortedCurrencies = availableCurrencies.sort((a, b) => { - return a.name.toLocaleLowerCase().localeCompare(b.name.toLocaleLowerCase()) -}) + return a.name.toLocaleLowerCase().localeCompare(b.name.toLocaleLowerCase()); +}); const currencyOptions = sortedCurrencies.map(({ code, name }) => { return { displayValue: `${code.toUpperCase()} - ${name}`, key: code, value: code, - } -}) + }; +}); const localeOptions = locales.map((locale) => { return { displayValue: `${locale.name}`, key: locale.code, value: locale.code, - } -}) + }; +}); export default class SettingsTab extends PureComponent { static contextTypes = { t: PropTypes.func, metricsEvent: PropTypes.func, - } + }; static propTypes = { setUseBlockie: PropTypes.func, @@ -43,11 +43,11 @@ export default class SettingsTab extends PureComponent { nativeCurrency: PropTypes.string, useNativeCurrencyAsPrimaryCurrency: PropTypes.bool, setUseNativeCurrencyAsPrimaryCurrencyPreference: PropTypes.func, - } + }; renderCurrentConversion() { - const { t } = this.context - const { currentCurrency, conversionDate, setCurrentCurrency } = this.props + const { t } = this.context; + const { currentCurrency, conversionDate, setCurrentCurrency } = this.props; return (
    @@ -68,16 +68,16 @@ export default class SettingsTab extends PureComponent {
    - ) + ); } renderCurrentLocale() { - const { t } = this.context - const { updateCurrentLocale, currentLocale } = this.props + const { t } = this.context; + const { updateCurrentLocale, currentLocale } = this.props; const currentLocaleMeta = locales.find( (locale) => locale.code === currentLocale, - ) - const currentLocaleName = currentLocaleMeta ? currentLocaleMeta.name : '' + ); + const currentLocaleName = currentLocaleMeta ? currentLocaleMeta.name : ''; return (
    @@ -100,12 +100,12 @@ export default class SettingsTab extends PureComponent {
    - ) + ); } renderBlockieOptIn() { - const { t } = this.context - const { useBlockie, setUseBlockie } = this.props + const { t } = this.context; + const { useBlockie, setUseBlockie } = this.props; return (
    @@ -123,16 +123,16 @@ export default class SettingsTab extends PureComponent {
    - ) + ); } renderUsePrimaryCurrencyOptions() { - const { t } = this.context + const { t } = this.context; const { nativeCurrency, setUseNativeCurrencyAsPrimaryCurrencyPreference, useNativeCurrencyAsPrimaryCurrency, - } = this.props + } = this.props; return (
    @@ -181,11 +181,11 @@ export default class SettingsTab extends PureComponent {
    - ) + ); } render() { - const { warning } = this.props + const { warning } = this.props; return (
    @@ -195,6 +195,6 @@ export default class SettingsTab extends PureComponent { {this.renderCurrentLocale()} {this.renderBlockieOptIn()}
    - ) + ); } } diff --git a/ui/app/pages/settings/settings-tab/settings-tab.container.js b/ui/app/pages/settings/settings-tab/settings-tab.container.js index 3ebf2627d0..ce8de1363f 100644 --- a/ui/app/pages/settings/settings-tab/settings-tab.container.js +++ b/ui/app/pages/settings/settings-tab/settings-tab.container.js @@ -1,27 +1,27 @@ -import { connect } from 'react-redux' +import { connect } from 'react-redux'; import { setCurrentCurrency, setUseBlockie, updateCurrentLocale, setUseNativeCurrencyAsPrimaryCurrencyPreference, setParticipateInMetaMetrics, -} from '../../../store/actions' -import { getPreferences } from '../../../selectors' -import SettingsTab from './settings-tab.component' +} from '../../../store/actions'; +import { getPreferences } from '../../../selectors'; +import SettingsTab from './settings-tab.component'; const mapStateToProps = (state) => { const { appState: { warning }, metamask, - } = state + } = state; const { currentCurrency, conversionDate, nativeCurrency, useBlockie, currentLocale, - } = metamask - const { useNativeCurrencyAsPrimaryCurrency } = getPreferences(state) + } = metamask; + const { useNativeCurrencyAsPrimaryCurrency } = getPreferences(state); return { warning, @@ -31,8 +31,8 @@ const mapStateToProps = (state) => { nativeCurrency, useBlockie, useNativeCurrencyAsPrimaryCurrency, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { @@ -40,11 +40,11 @@ const mapDispatchToProps = (dispatch) => { setUseBlockie: (value) => dispatch(setUseBlockie(value)), updateCurrentLocale: (key) => dispatch(updateCurrentLocale(key)), setUseNativeCurrencyAsPrimaryCurrencyPreference: (value) => { - return dispatch(setUseNativeCurrencyAsPrimaryCurrencyPreference(value)) + return dispatch(setUseNativeCurrencyAsPrimaryCurrencyPreference(value)); }, setParticipateInMetaMetrics: (val) => dispatch(setParticipateInMetaMetrics(val)), - } -} + }; +}; -export default connect(mapStateToProps, mapDispatchToProps)(SettingsTab) +export default connect(mapStateToProps, mapDispatchToProps)(SettingsTab); diff --git a/ui/app/pages/settings/settings-tab/tests/settings-tab.test.js b/ui/app/pages/settings/settings-tab/tests/settings-tab.test.js index 31b8d96c6a..1d1a0b42c0 100644 --- a/ui/app/pages/settings/settings-tab/tests/settings-tab.test.js +++ b/ui/app/pages/settings/settings-tab/tests/settings-tab.test.js @@ -1,11 +1,11 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import { mount } from 'enzyme' -import SettingsTab from '..' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import { mount } from 'enzyme'; +import SettingsTab from '..'; describe('Settings Tab', function () { - let wrapper + let wrapper; const props = { setCurrentCurrency: sinon.spy(), @@ -20,40 +20,40 @@ describe('Settings Tab', function () { conversionDate: 1, nativeCurrency: 'eth', useNativeCurrencyAsPrimaryCurrency: true, - } + }; beforeEach(function () { wrapper = mount(, { context: { t: (str) => str, }, - }) - }) + }); + }); it('selects currency', async function () { - const selectCurrency = wrapper.find({ placeholder: 'selectCurrency' }) + const selectCurrency = wrapper.find({ placeholder: 'selectCurrency' }); - selectCurrency.props().onSelect('eur') - assert(props.setCurrentCurrency.calledOnce) - }) + selectCurrency.props().onSelect('eur'); + assert(props.setCurrentCurrency.calledOnce); + }); it('selects locale', async function () { - const selectLocale = wrapper.find({ placeholder: 'selectLocale' }) + const selectLocale = wrapper.find({ placeholder: 'selectLocale' }); - await selectLocale.props().onSelect('ja') - assert(props.updateCurrentLocale.calledOnce) - }) + await selectLocale.props().onSelect('ja'); + assert(props.updateCurrentLocale.calledOnce); + }); it('sets fiat primary currency', function () { - const selectFiat = wrapper.find('#fiat-primary-currency') + const selectFiat = wrapper.find('#fiat-primary-currency'); - selectFiat.simulate('change') - assert(props.setUseNativeCurrencyAsPrimaryCurrencyPreference.calledOnce) - }) + selectFiat.simulate('change'); + assert(props.setUseNativeCurrencyAsPrimaryCurrencyPreference.calledOnce); + }); it('toggles blockies', function () { - const toggleBlockies = wrapper.find({ type: 'checkbox' }) + const toggleBlockies = wrapper.find({ type: 'checkbox' }); - toggleBlockies.simulate('click') - assert(props.setUseBlockie.calledOnce) - }) -}) + toggleBlockies.simulate('click'); + assert(props.setUseBlockie.calledOnce); + }); +}); diff --git a/ui/app/pages/settings/settings.component.js b/ui/app/pages/settings/settings.component.js index 6229b95fae..2b02eccfd0 100644 --- a/ui/app/pages/settings/settings.component.js +++ b/ui/app/pages/settings/settings.component.js @@ -1,8 +1,8 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import { Switch, Route, matchPath } from 'react-router-dom' -import classnames from 'classnames' -import TabBar from '../../components/app/tab-bar' +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { Switch, Route, matchPath } from 'react-router-dom'; +import classnames from 'classnames'; +import TabBar from '../../components/app/tab-bar'; import { ALERTS_ROUTE, ADVANCED_ROUTE, @@ -18,14 +18,14 @@ import { CONTACT_MY_ACCOUNTS_ROUTE, CONTACT_MY_ACCOUNTS_VIEW_ROUTE, CONTACT_MY_ACCOUNTS_EDIT_ROUTE, -} from '../../helpers/constants/routes' -import SettingsTab from './settings-tab' -import AlertsTab from './alerts-tab' -import NetworksTab from './networks-tab' -import AdvancedTab from './advanced-tab' -import InfoTab from './info-tab' -import SecurityTab from './security-tab' -import ContactListTab from './contact-list-tab' +} from '../../helpers/constants/routes'; +import SettingsTab from './settings-tab'; +import AlertsTab from './alerts-tab'; +import NetworksTab from './networks-tab'; +import AdvancedTab from './advanced-tab'; +import InfoTab from './info-tab'; +import SecurityTab from './security-tab'; +import ContactListTab from './contact-list-tab'; class SettingsPage extends PureComponent { static propTypes = { @@ -40,11 +40,11 @@ class SettingsPage extends PureComponent { breadCrumbTextKey: PropTypes.string, initialBreadCrumbKey: PropTypes.string, mostRecentOverviewPage: PropTypes.string.isRequired, - } + }; static contextTypes = { t: PropTypes.func, - } + }; render() { const { @@ -52,7 +52,7 @@ class SettingsPage extends PureComponent { backRoute, currentPath, mostRecentOverviewPage, - } = this.props + } = this.props; return (
    - ) + ); } renderTitle() { - const { t } = this.context - const { isPopup, pathnameI18nKey, addressName } = this.props + const { t } = this.context; + const { isPopup, pathnameI18nKey, addressName } = this.props; - let titleText + let titleText; if (isPopup && addressName) { - titleText = addressName + titleText = addressName; } else if (pathnameI18nKey && isPopup) { - titleText = t(pathnameI18nKey) + titleText = t(pathnameI18nKey); } else { - titleText = t('settings') + titleText = t('settings'); } - return
    {titleText}
    + return
    {titleText}
    ; } renderSubHeader() { - const { t } = this.context + const { t } = this.context; const { currentPath, isPopup, @@ -115,16 +115,16 @@ class SettingsPage extends PureComponent { breadCrumbTextKey, history, initialBreadCrumbKey, - } = this.props + } = this.props; - let subheaderText + let subheaderText; if (isPopup && isAddressEntryPage) { - subheaderText = t('settings') + subheaderText = t('settings'); } else if (initialBreadCrumbKey) { - subheaderText = t(initialBreadCrumbKey) + subheaderText = t(initialBreadCrumbKey); } else { - subheaderText = t(pathnameI18nKey || 'general') + subheaderText = t(pathnameI18nKey || 'general'); } return ( @@ -154,12 +154,12 @@ class SettingsPage extends PureComponent { )} ) - ) + ); } renderTabs() { - const { history, currentPath } = this.props - const { t } = this.context + const { history, currentPath } = this.props; + const { t } = this.context; return ( { if (key === GENERAL_ROUTE && currentPath === SETTINGS_ROUTE) { - return true + return true; } - return matchPath(currentPath, { path: key, exact: true }) + return matchPath(currentPath, { path: key, exact: true }); }} onSelect={(key) => history.push(key)} /> - ) + ); } renderContent() { @@ -249,8 +249,8 @@ class SettingsPage extends PureComponent { /> - ) + ); } } -export default SettingsPage +export default SettingsPage; diff --git a/ui/app/pages/settings/settings.container.js b/ui/app/pages/settings/settings.container.js index d35fbbe6d1..f965e525c2 100644 --- a/ui/app/pages/settings/settings.container.js +++ b/ui/app/pages/settings/settings.container.js @@ -1,11 +1,11 @@ -import { compose } from 'redux' -import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom' -import { getAddressBookEntryName } from '../../selectors' -import { isValidAddress } from '../../helpers/utils/util' -import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app' -import { getEnvironmentType } from '../../../../app/scripts/lib/util' -import { getMostRecentOverviewPage } from '../../ducks/history/history' +import { compose } from 'redux'; +import { connect } from 'react-redux'; +import { withRouter } from 'react-router-dom'; +import { getAddressBookEntryName } from '../../selectors'; +import { isValidAddress } from '../../helpers/utils/util'; +import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app'; +import { getEnvironmentType } from '../../../../app/scripts/lib/util'; +import { getMostRecentOverviewPage } from '../../ducks/history/history'; import { ABOUT_US_ROUTE, @@ -23,8 +23,8 @@ import { NETWORKS_ROUTE, SECURITY_ROUTE, SETTINGS_ROUTE, -} from '../../helpers/constants/routes' -import Settings from './settings.component' +} from '../../helpers/constants/routes'; +import Settings from './settings.component'; const ROUTES_TO_I18N_KEYS = { [ABOUT_US_ROUTE]: 'about', @@ -39,51 +39,51 @@ const ROUTES_TO_I18N_KEYS = { [NETWORKS_ROUTE]: 'networks', [NETWORKS_FORM_ROUTE]: 'networks', [SECURITY_ROUTE]: 'securityAndPrivacy', -} +}; const mapStateToProps = (state, ownProps) => { - const { location } = ownProps - const { pathname } = location - const pathNameTail = pathname.match(/[^/]+$/u)[0] + const { location } = ownProps; + const { pathname } = location; + const pathNameTail = pathname.match(/[^/]+$/u)[0]; - const isAddressEntryPage = pathNameTail.includes('0x') - const isMyAccountsPage = pathname.match('my-accounts') - const isAddContactPage = Boolean(pathname.match(CONTACT_ADD_ROUTE)) - const isEditContactPage = Boolean(pathname.match(CONTACT_EDIT_ROUTE)) + const isAddressEntryPage = pathNameTail.includes('0x'); + const isMyAccountsPage = pathname.match('my-accounts'); + const isAddContactPage = Boolean(pathname.match(CONTACT_ADD_ROUTE)); + const isEditContactPage = Boolean(pathname.match(CONTACT_EDIT_ROUTE)); const isEditMyAccountsContactPage = Boolean( pathname.match(CONTACT_MY_ACCOUNTS_EDIT_ROUTE), - ) - const isNetworksFormPage = Boolean(pathname.match(NETWORKS_FORM_ROUTE)) + ); + const isNetworksFormPage = Boolean(pathname.match(NETWORKS_FORM_ROUTE)); - const isPopup = getEnvironmentType() === ENVIRONMENT_TYPE_POPUP - const pathnameI18nKey = ROUTES_TO_I18N_KEYS[pathname] + const isPopup = getEnvironmentType() === ENVIRONMENT_TYPE_POPUP; + const pathnameI18nKey = ROUTES_TO_I18N_KEYS[pathname]; - let backRoute = SETTINGS_ROUTE + let backRoute = SETTINGS_ROUTE; if (isMyAccountsPage && isAddressEntryPage) { - backRoute = CONTACT_MY_ACCOUNTS_ROUTE + backRoute = CONTACT_MY_ACCOUNTS_ROUTE; } else if (isEditContactPage) { - backRoute = `${CONTACT_VIEW_ROUTE}/${pathNameTail}` + backRoute = `${CONTACT_VIEW_ROUTE}/${pathNameTail}`; } else if (isEditMyAccountsContactPage) { - backRoute = `${CONTACT_MY_ACCOUNTS_VIEW_ROUTE}/${pathNameTail}` + backRoute = `${CONTACT_MY_ACCOUNTS_VIEW_ROUTE}/${pathNameTail}`; } else if (isAddressEntryPage || isMyAccountsPage || isAddContactPage) { - backRoute = CONTACT_LIST_ROUTE + backRoute = CONTACT_LIST_ROUTE; } else if (isNetworksFormPage) { - backRoute = NETWORKS_ROUTE + backRoute = NETWORKS_ROUTE; } - let initialBreadCrumbRoute - let breadCrumbTextKey - let initialBreadCrumbKey + let initialBreadCrumbRoute; + let breadCrumbTextKey; + let initialBreadCrumbKey; if (isMyAccountsPage) { - initialBreadCrumbRoute = CONTACT_LIST_ROUTE - breadCrumbTextKey = 'myWalletAccounts' - initialBreadCrumbKey = ROUTES_TO_I18N_KEYS[initialBreadCrumbRoute] + initialBreadCrumbRoute = CONTACT_LIST_ROUTE; + breadCrumbTextKey = 'myWalletAccounts'; + initialBreadCrumbKey = ROUTES_TO_I18N_KEYS[initialBreadCrumbRoute]; } const addressName = getAddressBookEntryName( state, isValidAddress(pathNameTail) ? pathNameTail : '', - ) + ); return { isAddressEntryPage, @@ -97,7 +97,7 @@ const mapStateToProps = (state, ownProps) => { breadCrumbTextKey, initialBreadCrumbKey, mostRecentOverviewPage: getMostRecentOverviewPage(state), - } -} + }; +}; -export default compose(withRouter, connect(mapStateToProps))(Settings) +export default compose(withRouter, connect(mapStateToProps))(Settings); diff --git a/ui/app/pages/swaps/actionable-message/actionable-message.js b/ui/app/pages/swaps/actionable-message/actionable-message.js index bdb46c371c..cf24ff9f6f 100644 --- a/ui/app/pages/swaps/actionable-message/actionable-message.js +++ b/ui/app/pages/swaps/actionable-message/actionable-message.js @@ -1,6 +1,6 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; export default function ActionableMessage({ message = '', @@ -38,7 +38,7 @@ export default function ActionableMessage({ )} - ) + ); } ActionableMessage.propTypes = { @@ -52,4 +52,4 @@ ActionableMessage.propTypes = { onClick: PropTypes.func, }), className: PropTypes.string, -} +}; diff --git a/ui/app/pages/swaps/actionable-message/actionable-message.stories.js b/ui/app/pages/swaps/actionable-message/actionable-message.stories.js index 66ab6031df..b56b79e56f 100644 --- a/ui/app/pages/swaps/actionable-message/actionable-message.stories.js +++ b/ui/app/pages/swaps/actionable-message/actionable-message.stories.js @@ -1,11 +1,11 @@ -import React from 'react' -import { action } from '@storybook/addon-actions' -import { text } from '@storybook/addon-knobs' -import ActionableMessage from '.' +import React from 'react'; +import { action } from '@storybook/addon-actions'; +import { text } from '@storybook/addon-knobs'; +import ActionableMessage from '.'; export default { title: 'ActionableMessage', -} +}; export const NoAction = () => (
    @@ -16,7 +16,7 @@ export const NoAction = () => ( )} />
    -) +); export const OneAction = () => (
    @@ -31,7 +31,7 @@ export const OneAction = () => ( }} />
    -) +); export const TwoActions = () => (
    @@ -51,7 +51,7 @@ export const TwoActions = () => ( className="actionable-message--warning" />
    -) +); export const LeftAligned = () => (
    @@ -67,4 +67,4 @@ export const LeftAligned = () => ( className="actionable-message--left-aligned" />
    -) +); diff --git a/ui/app/pages/swaps/actionable-message/index.js b/ui/app/pages/swaps/actionable-message/index.js index c6edbc3596..83a781bcd5 100644 --- a/ui/app/pages/swaps/actionable-message/index.js +++ b/ui/app/pages/swaps/actionable-message/index.js @@ -1 +1 @@ -export { default } from './actionable-message' +export { default } from './actionable-message'; diff --git a/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js b/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js index 5a35c724eb..b5908d0ee9 100644 --- a/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js +++ b/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js @@ -1,12 +1,12 @@ -import EventEmitter from 'events' -import React, { useContext, useRef, useState } from 'react' -import { useDispatch, useSelector } from 'react-redux' -import PropTypes from 'prop-types' -import { useHistory } from 'react-router-dom' -import { I18nContext } from '../../../contexts/i18n' -import { useNewMetricEvent } from '../../../hooks/useMetricEvent' -import { MetaMetricsContext } from '../../../contexts/metametrics.new' -import { getCurrentCurrency, getUSDConversionRate } from '../../../selectors' +import EventEmitter from 'events'; +import React, { useContext, useRef, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import PropTypes from 'prop-types'; +import { useHistory } from 'react-router-dom'; +import { I18nContext } from '../../../contexts/i18n'; +import { useNewMetricEvent } from '../../../hooks/useMetricEvent'; +import { MetaMetricsContext } from '../../../contexts/metametrics.new'; +import { getCurrentCurrency, getUSDConversionRate } from '../../../selectors'; import { getUsedQuote, getFetchParams, @@ -16,25 +16,25 @@ import { navigateBackToBuildQuote, prepareForRetryGetQuotes, prepareToLeaveSwaps, -} from '../../../ducks/swaps/swaps' -import Mascot from '../../../components/ui/mascot' -import PulseLoader from '../../../components/ui/pulse-loader' -import { getBlockExplorerUrlForTx } from '../../../helpers/utils/transactions.util' +} from '../../../ducks/swaps/swaps'; +import Mascot from '../../../components/ui/mascot'; +import PulseLoader from '../../../components/ui/pulse-loader'; +import { getBlockExplorerUrlForTx } from '../../../helpers/utils/transactions.util'; import { QUOTES_EXPIRED_ERROR, SWAP_FAILED_ERROR, ERROR_FETCHING_QUOTES, QUOTES_NOT_AVAILABLE_ERROR, OFFLINE_FOR_MAINTENANCE, -} from '../../../helpers/constants/swaps' -import { ASSET_ROUTE, DEFAULT_ROUTE } from '../../../helpers/constants/routes' +} from '../../../helpers/constants/swaps'; +import { ASSET_ROUTE, DEFAULT_ROUTE } from '../../../helpers/constants/routes'; -import { getRenderableNetworkFeesForQuote } from '../swaps.util' -import SwapsFooter from '../swaps-footer' -import SwapFailureIcon from './swap-failure-icon' -import SwapSuccessIcon from './swap-success-icon' -import QuotesTimeoutIcon from './quotes-timeout-icon' -import ViewOnEtherScanLink from './view-on-ether-scan-link' +import { getRenderableNetworkFeesForQuote } from '../swaps.util'; +import SwapsFooter from '../swaps-footer'; +import SwapFailureIcon from './swap-failure-icon'; +import SwapSuccessIcon from './swap-success-icon'; +import QuotesTimeoutIcon from './quotes-timeout-icon'; +import ViewOnEtherScanLink from './view-on-ether-scan-link'; export default function AwaitingSwap({ swapComplete, @@ -47,25 +47,25 @@ export default function AwaitingSwap({ inputValue, maxSlippage, }) { - const t = useContext(I18nContext) - const metaMetricsEvent = useContext(MetaMetricsContext) - const history = useHistory() - const dispatch = useDispatch() - const animationEventEmitter = useRef(new EventEmitter()) + const t = useContext(I18nContext); + const metaMetricsEvent = useContext(MetaMetricsContext); + const history = useHistory(); + const dispatch = useDispatch(); + const animationEventEmitter = useRef(new EventEmitter()); - const fetchParams = useSelector(getFetchParams) - const { destinationTokenInfo, sourceTokenInfo } = fetchParams?.metaData || {} - const usedQuote = useSelector(getUsedQuote) - const approveTxParams = useSelector(getApproveTxParams) - const swapsGasPrice = useSelector(getUsedSwapsGasPrice) - const currentCurrency = useSelector(getCurrentCurrency) - const usdConversionRate = useSelector(getUSDConversionRate) + const fetchParams = useSelector(getFetchParams); + const { destinationTokenInfo, sourceTokenInfo } = fetchParams?.metaData || {}; + const usedQuote = useSelector(getUsedQuote); + const approveTxParams = useSelector(getApproveTxParams); + const swapsGasPrice = useSelector(getUsedSwapsGasPrice); + const currentCurrency = useSelector(getCurrentCurrency); + const usdConversionRate = useSelector(getUSDConversionRate); const [trackedQuotesExpiredEvent, setTrackedQuotesExpiredEvent] = useState( false, - ) + ); - let feeinUnformattedFiat + let feeinUnformattedFiat; if (usedQuote && swapsGasPrice) { const renderableNetworkFees = getRenderableNetworkFeesForQuote( @@ -77,8 +77,8 @@ export default function AwaitingSwap({ usedQuote?.trade?.value, sourceTokenInfo?.symbol, usedQuote.sourceAmount, - ) - feeinUnformattedFiat = renderableNetworkFees.rawNetworkFees + ); + feeinUnformattedFiat = renderableNetworkFees.rawNetworkFees; } const quotesExpiredEvent = useNewMetricEvent({ @@ -93,58 +93,58 @@ export default function AwaitingSwap({ gas_fees: feeinUnformattedFiat, }, category: 'swaps', - }) + }); const blockExplorerUrl = - txHash && getBlockExplorerUrlForTx(networkId, txHash, rpcPrefs) + txHash && getBlockExplorerUrlForTx(networkId, txHash, rpcPrefs); - let headerText - let statusImage - let descriptionText - let submitText - let content + let headerText; + let statusImage; + let descriptionText; + let submitText; + let content; if (errorKey === OFFLINE_FOR_MAINTENANCE) { - headerText = t('offlineForMaintenance') - descriptionText = t('metamaskSwapsOfflineDescription') - submitText = t('close') - statusImage = + headerText = t('offlineForMaintenance'); + descriptionText = t('metamaskSwapsOfflineDescription'); + submitText = t('close'); + statusImage = ; } else if (errorKey === SWAP_FAILED_ERROR) { - headerText = t('swapFailedErrorTitle') - descriptionText = t('swapFailedErrorDescription') - submitText = t('tryAgain') - statusImage = + headerText = t('swapFailedErrorTitle'); + descriptionText = t('swapFailedErrorDescription'); + submitText = t('tryAgain'); + statusImage = ; content = blockExplorerUrl && ( - ) + ); } else if (errorKey === QUOTES_EXPIRED_ERROR) { - headerText = t('swapQuotesExpiredErrorTitle') - descriptionText = t('swapQuotesExpiredErrorDescription') - submitText = t('tryAgain') - statusImage = + headerText = t('swapQuotesExpiredErrorTitle'); + descriptionText = t('swapQuotesExpiredErrorDescription'); + submitText = t('tryAgain'); + statusImage = ; if (!trackedQuotesExpiredEvent) { - setTrackedQuotesExpiredEvent(true) - quotesExpiredEvent() + setTrackedQuotesExpiredEvent(true); + quotesExpiredEvent(); } } else if (errorKey === ERROR_FETCHING_QUOTES) { - headerText = t('swapFetchingQuotesErrorTitle') - descriptionText = t('swapFetchingQuotesErrorDescription') - submitText = t('back') - statusImage = + headerText = t('swapFetchingQuotesErrorTitle'); + descriptionText = t('swapFetchingQuotesErrorDescription'); + submitText = t('back'); + statusImage = ; } else if (errorKey === QUOTES_NOT_AVAILABLE_ERROR) { - headerText = t('swapQuotesNotAvailableErrorTitle') - descriptionText = t('swapQuotesNotAvailableErrorDescription') - submitText = t('tryAgain') - statusImage = + headerText = t('swapQuotesNotAvailableErrorTitle'); + descriptionText = t('swapQuotesNotAvailableErrorDescription'); + submitText = t('tryAgain'); + statusImage = ; } else if (!errorKey && !swapComplete) { - headerText = t('swapProcessing') - statusImage = - submitText = t('swapsViewInActivity') + headerText = t('swapProcessing'); + statusImage = ; + submitText = t('swapsViewInActivity'); descriptionText = t('swapOnceTransactionHasProcess', [ {destinationTokenInfo.symbol} , - ]) + ]); content = blockExplorerUrl && ( - ) + ); } else if (!errorKey && swapComplete) { - headerText = t('swapTransactionComplete') - statusImage = - submitText = t('swapViewToken', [destinationTokenInfo.symbol]) + headerText = t('swapTransactionComplete'); + statusImage = ; + submitText = t('swapViewToken', [destinationTokenInfo.symbol]); descriptionText = t('swapTokenAvailable', [ {`${tokensReceived || ''} ${destinationTokenInfo.symbol}`} , - ]) + ]); content = blockExplorerUrl && ( - ) + ); } return ( @@ -199,10 +199,10 @@ export default function AwaitingSwap({ { if (errorKey === OFFLINE_FOR_MAINTENANCE) { - await dispatch(prepareToLeaveSwaps()) - history.push(DEFAULT_ROUTE) + await dispatch(prepareToLeaveSwaps()); + history.push(DEFAULT_ROUTE); } else if (errorKey === QUOTES_EXPIRED_ERROR) { - dispatch(prepareForRetryGetQuotes()) + dispatch(prepareForRetryGetQuotes()); await dispatch( fetchQuotesAndSetQuoteState( history, @@ -210,13 +210,13 @@ export default function AwaitingSwap({ maxSlippage, metaMetricsEvent, ), - ) + ); } else if (errorKey) { - await dispatch(navigateBackToBuildQuote(history)) + await dispatch(navigateBackToBuildQuote(history)); } else if (destinationTokenInfo?.symbol === 'ETH') { - history.push(DEFAULT_ROUTE) + history.push(DEFAULT_ROUTE); } else { - history.push(`${ASSET_ROUTE}/${destinationTokenInfo?.address}`) + history.push(`${ASSET_ROUTE}/${destinationTokenInfo?.address}`); } }} onCancel={async () => await dispatch(navigateBackToBuildQuote(history))} @@ -225,7 +225,7 @@ export default function AwaitingSwap({ hideCancel={errorKey !== QUOTES_EXPIRED_ERROR} /> - ) + ); } AwaitingSwap.propTypes = { @@ -244,4 +244,4 @@ AwaitingSwap.propTypes = { submittingSwap: PropTypes.bool, inputValue: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), maxSlippage: PropTypes.number, -} +}; diff --git a/ui/app/pages/swaps/awaiting-swap/index.js b/ui/app/pages/swaps/awaiting-swap/index.js index c82d6690ce..12efcc4aa5 100644 --- a/ui/app/pages/swaps/awaiting-swap/index.js +++ b/ui/app/pages/swaps/awaiting-swap/index.js @@ -1 +1 @@ -export { default } from './awaiting-swap' +export { default } from './awaiting-swap'; diff --git a/ui/app/pages/swaps/awaiting-swap/quotes-timeout-icon.js b/ui/app/pages/swaps/awaiting-swap/quotes-timeout-icon.js index ae21dbee85..7a2783e4ba 100644 --- a/ui/app/pages/swaps/awaiting-swap/quotes-timeout-icon.js +++ b/ui/app/pages/swaps/awaiting-swap/quotes-timeout-icon.js @@ -1,4 +1,4 @@ -import React from 'react' +import React from 'react'; export default function QuotesTimeoutIcon() { return ( @@ -14,5 +14,5 @@ export default function QuotesTimeoutIcon() { fill="#037DD6" /> - ) + ); } diff --git a/ui/app/pages/swaps/awaiting-swap/swap-failure-icon.js b/ui/app/pages/swaps/awaiting-swap/swap-failure-icon.js index a195663f5d..a5cb34480f 100644 --- a/ui/app/pages/swaps/awaiting-swap/swap-failure-icon.js +++ b/ui/app/pages/swaps/awaiting-swap/swap-failure-icon.js @@ -1,4 +1,4 @@ -import React from 'react' +import React from 'react'; export default function SwapFailureIcon() { return ( @@ -14,5 +14,5 @@ export default function SwapFailureIcon() { fill="#D73A49" /> - ) + ); } diff --git a/ui/app/pages/swaps/awaiting-swap/swap-success-icon.js b/ui/app/pages/swaps/awaiting-swap/swap-success-icon.js index 471e4414f9..ffe46d5cb1 100644 --- a/ui/app/pages/swaps/awaiting-swap/swap-success-icon.js +++ b/ui/app/pages/swaps/awaiting-swap/swap-success-icon.js @@ -1,4 +1,4 @@ -import React from 'react' +import React from 'react'; export default function SwapSuccessIcon() { return ( @@ -14,5 +14,5 @@ export default function SwapSuccessIcon() { fill="#28A745" /> - ) + ); } diff --git a/ui/app/pages/swaps/awaiting-swap/view-on-ether-scan-link/index.js b/ui/app/pages/swaps/awaiting-swap/view-on-ether-scan-link/index.js index a8767653af..6aa4a33471 100644 --- a/ui/app/pages/swaps/awaiting-swap/view-on-ether-scan-link/index.js +++ b/ui/app/pages/swaps/awaiting-swap/view-on-ether-scan-link/index.js @@ -1 +1 @@ -export { default } from './view-on-ether-scan-link' +export { default } from './view-on-ether-scan-link'; diff --git a/ui/app/pages/swaps/awaiting-swap/view-on-ether-scan-link/view-on-ether-scan-link.js b/ui/app/pages/swaps/awaiting-swap/view-on-ether-scan-link/view-on-ether-scan-link.js index 10354800c4..bb3d07cdae 100644 --- a/ui/app/pages/swaps/awaiting-swap/view-on-ether-scan-link/view-on-ether-scan-link.js +++ b/ui/app/pages/swaps/awaiting-swap/view-on-ether-scan-link/view-on-ether-scan-link.js @@ -1,14 +1,14 @@ -import React, { useContext } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { I18nContext } from '../../../../contexts/i18n' +import React, { useContext } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import { I18nContext } from '../../../../contexts/i18n'; export default function ViewOnEtherScanLink({ txHash, blockExplorerUrl, isCustomBlockExplorerUrl, }) { - const t = useContext(I18nContext) + const t = useContext(I18nContext); return (
    - ) + ); } ViewOnEtherScanLink.propTypes = { txHash: PropTypes.string, blockExplorerUrl: PropTypes.string, isCustomBlockExplorerUrl: PropTypes.bool, -} +}; diff --git a/ui/app/pages/swaps/build-quote/build-quote.js b/ui/app/pages/swaps/build-quote/build-quote.js index c8ce65e881..4b09756735 100644 --- a/ui/app/pages/swaps/build-quote/build-quote.js +++ b/ui/app/pages/swaps/build-quote/build-quote.js @@ -1,19 +1,19 @@ -import React, { useContext, useEffect, useState, useCallback } from 'react' -import PropTypes from 'prop-types' -import { useDispatch, useSelector } from 'react-redux' -import classnames from 'classnames' -import { uniqBy } from 'lodash' -import { useHistory } from 'react-router-dom' -import { MetaMetricsContext } from '../../../contexts/metametrics.new' -import { useTokensToSearch } from '../../../hooks/useTokensToSearch' -import { useEqualityCheck } from '../../../hooks/useEqualityCheck' -import { useSwapsEthToken } from '../../../hooks/useSwapsEthToken' -import { I18nContext } from '../../../contexts/i18n' -import DropdownInputPair from '../dropdown-input-pair' -import DropdownSearchList from '../dropdown-search-list' -import SlippageButtons from '../slippage-buttons' -import { getTokens } from '../../../ducks/metamask/metamask' -import InfoTooltip from '../../../components/ui/info-tooltip' +import React, { useContext, useEffect, useState, useCallback } from 'react'; +import PropTypes from 'prop-types'; +import { useDispatch, useSelector } from 'react-redux'; +import classnames from 'classnames'; +import { uniqBy } from 'lodash'; +import { useHistory } from 'react-router-dom'; +import { MetaMetricsContext } from '../../../contexts/metametrics.new'; +import { useTokensToSearch } from '../../../hooks/useTokensToSearch'; +import { useEqualityCheck } from '../../../hooks/useEqualityCheck'; +import { useSwapsEthToken } from '../../../hooks/useSwapsEthToken'; +import { I18nContext } from '../../../contexts/i18n'; +import DropdownInputPair from '../dropdown-input-pair'; +import DropdownSearchList from '../dropdown-search-list'; +import SlippageButtons from '../slippage-buttons'; +import { getTokens } from '../../../ducks/metamask/metamask'; +import InfoTooltip from '../../../components/ui/info-tooltip'; import { fetchQuotesAndSetQuoteState, @@ -24,30 +24,30 @@ import { getBalanceError, getTopAssets, getFetchParams, -} from '../../../ducks/swaps/swaps' +} from '../../../ducks/swaps/swaps'; import { getValueFromWeiHex, hexToDecimal, -} from '../../../helpers/utils/conversions.util' -import { calcTokenAmount } from '../../../helpers/utils/token-util' -import { usePrevious } from '../../../hooks/usePrevious' -import { useTokenTracker } from '../../../hooks/useTokenTracker' -import { useTokenFiatAmount } from '../../../hooks/useTokenFiatAmount' -import { useEthFiatAmount } from '../../../hooks/useEthFiatAmount' +} from '../../../helpers/utils/conversions.util'; +import { calcTokenAmount } from '../../../helpers/utils/token-util'; +import { usePrevious } from '../../../hooks/usePrevious'; +import { useTokenTracker } from '../../../hooks/useTokenTracker'; +import { useTokenFiatAmount } from '../../../hooks/useTokenFiatAmount'; +import { useEthFiatAmount } from '../../../hooks/useEthFiatAmount'; -import { ETH_SWAPS_TOKEN_OBJECT } from '../../../helpers/constants/swaps' +import { ETH_SWAPS_TOKEN_OBJECT } from '../../../helpers/constants/swaps'; -import { resetSwapsPostFetchState, removeToken } from '../../../store/actions' -import { fetchTokenPrice, fetchTokenBalance } from '../swaps.util' -import SwapsFooter from '../swaps-footer' +import { resetSwapsPostFetchState, removeToken } from '../../../store/actions'; +import { fetchTokenPrice, fetchTokenBalance } from '../swaps.util'; +import SwapsFooter from '../swaps-footer'; const fuseSearchKeys = [ { name: 'name', weight: 0.499 }, { name: 'symbol', weight: 0.499 }, { name: 'address', weight: 0.002 }, -] +]; -const MAX_ALLOWED_SLIPPAGE = 15 +const MAX_ALLOWED_SLIPPAGE = 15; export default function BuildQuote({ inputValue, @@ -57,39 +57,39 @@ export default function BuildQuote({ maxSlippage, selectedAccountAddress, }) { - const t = useContext(I18nContext) - const dispatch = useDispatch() - const history = useHistory() - const metaMetricsEvent = useContext(MetaMetricsContext) + const t = useContext(I18nContext); + const dispatch = useDispatch(); + const history = useHistory(); + const metaMetricsEvent = useContext(MetaMetricsContext); const [fetchedTokenExchangeRate, setFetchedTokenExchangeRate] = useState( undefined, - ) + ); - const balanceError = useSelector(getBalanceError) - const fetchParams = useSelector(getFetchParams) + const balanceError = useSelector(getBalanceError); + const fetchParams = useSelector(getFetchParams); const { sourceTokenInfo = {}, destinationTokenInfo = {} } = - fetchParams?.metaData || {} - const tokens = useSelector(getTokens) - const topAssets = useSelector(getTopAssets) - const fromToken = useSelector(getFromToken) - const toToken = useSelector(getToToken) || destinationTokenInfo - const swapsEthToken = useSwapsEthToken() + fetchParams?.metaData || {}; + const tokens = useSelector(getTokens); + const topAssets = useSelector(getTopAssets); + const fromToken = useSelector(getFromToken); + const toToken = useSelector(getToToken) || destinationTokenInfo; + const swapsEthToken = useSwapsEthToken(); const fetchParamsFromToken = - sourceTokenInfo?.symbol === 'ETH' ? swapsEthToken : sourceTokenInfo + sourceTokenInfo?.symbol === 'ETH' ? swapsEthToken : sourceTokenInfo; - const { loading, tokensWithBalances } = useTokenTracker(tokens) + const { loading, tokensWithBalances } = useTokenTracker(tokens); // If the fromToken was set in a call to `onFromSelect` (see below), and that from token has a balance // but is not in tokensWithBalances or tokens, then we want to add it to the usersTokens array so that // the balance of the token can appear in the from token selection dropdown const fromTokenArray = - fromToken?.symbol !== 'ETH' && fromToken?.balance ? [fromToken] : [] + fromToken?.symbol !== 'ETH' && fromToken?.balance ? [fromToken] : []; const usersTokens = uniqBy( [...tokensWithBalances, ...tokens, ...fromTokenArray], 'address', - ) - const memoizedUsersTokens = useEqualityCheck(usersTokens) + ); + const memoizedUsersTokens = useEqualityCheck(usersTokens); const selectedFromToken = useTokensToSearch({ providedTokens: @@ -99,15 +99,15 @@ export default function BuildQuote({ usersTokens: memoizedUsersTokens, onlyEth: (fromToken || fetchParamsFromToken)?.symbol === 'ETH', singleToken: true, - })[0] + })[0]; const tokensToSearch = useTokensToSearch({ usersTokens: memoizedUsersTokens, topTokens: topAssets, - }) + }); const selectedToToken = tokensToSearch.find(({ address }) => address === toToken?.address) || - toToken + toToken; const { address: fromTokenAddress, @@ -115,13 +115,13 @@ export default function BuildQuote({ string: fromTokenString, decimals: fromTokenDecimals, balance: rawFromTokenBalance, - } = selectedFromToken || {} + } = selectedFromToken || {}; const fromTokenBalance = rawFromTokenBalance && - calcTokenAmount(rawFromTokenBalance, fromTokenDecimals).toString(10) + calcTokenAmount(rawFromTokenBalance, fromTokenDecimals).toString(10); - const prevFromTokenBalance = usePrevious(fromTokenBalance) + const prevFromTokenBalance = usePrevious(fromTokenBalance); const swapFromTokenFiatValue = useTokenFiatAmount( fromTokenAddress, @@ -131,14 +131,14 @@ export default function BuildQuote({ showFiat: true, }, true, - ) + ); const swapFromEthFiatValue = useEthFiatAmount( inputValue || 0, { showFiat: true }, true, - ) + ); const swapFromFiatValue = - fromTokenSymbol === 'ETH' ? swapFromEthFiatValue : swapFromTokenFiatValue + fromTokenSymbol === 'ETH' ? swapFromEthFiatValue : swapFromTokenFiatValue; const onFromSelect = (token) => { if ( @@ -148,11 +148,11 @@ export default function BuildQuote({ ) { fetchTokenPrice(token.address).then((rate) => { if (rate !== null && rate !== undefined) { - setFetchedTokenExchangeRate(rate) + setFetchedTokenExchangeRate(rate); } - }) + }); } else { - setFetchedTokenExchangeRate(null) + setFetchedTokenExchangeRate(null); } if ( token?.address && @@ -163,63 +163,63 @@ export default function BuildQuote({ fetchTokenBalance(token.address, selectedAccountAddress).then( (fetchedBalance) => { if (fetchedBalance?.balance) { - const balanceAsDecString = fetchedBalance.balance.toString(10) + const balanceAsDecString = fetchedBalance.balance.toString(10); const userTokenBalance = calcTokenAmount( balanceAsDecString, token.decimals, - ) + ); dispatch( setSwapsFromToken({ ...token, string: userTokenBalance.toString(10), balance: balanceAsDecString, }), - ) + ); } }, - ) + ); } - dispatch(setSwapsFromToken(token)) + dispatch(setSwapsFromToken(token)); onInputChange( token?.address ? inputValue : '', token.string, token.decimals, - ) - } + ); + }; - const { destinationTokenAddedForSwap } = fetchParams || {} - const { address: toAddress } = toToken || {} + const { destinationTokenAddedForSwap } = fetchParams || {}; + const { address: toAddress } = toToken || {}; const onToSelect = useCallback( (token) => { if (destinationTokenAddedForSwap && token.address !== toAddress) { - dispatch(removeToken(toAddress)) + dispatch(removeToken(toAddress)); } - dispatch(setSwapToToken(token)) + dispatch(setSwapToToken(token)); }, [dispatch, destinationTokenAddedForSwap, toAddress], - ) + ); const hideDropdownItemIf = useCallback( (item) => item.address === fromTokenAddress, [fromTokenAddress], - ) + ); const tokensWithBalancesFromToken = tokensWithBalances.find( (token) => token.address === fromToken?.address, - ) + ); const previousTokensWithBalancesFromToken = usePrevious( tokensWithBalancesFromToken, - ) + ); useEffect(() => { const notEth = - tokensWithBalancesFromToken?.address !== ETH_SWAPS_TOKEN_OBJECT.address + tokensWithBalancesFromToken?.address !== ETH_SWAPS_TOKEN_OBJECT.address; const addressesAreTheSame = tokensWithBalancesFromToken?.address === - previousTokensWithBalancesFromToken?.address + previousTokensWithBalancesFromToken?.address; const balanceHasChanged = tokensWithBalancesFromToken?.balance !== - previousTokensWithBalancesFromToken?.balance + previousTokensWithBalancesFromToken?.balance; if (notEth && addressesAreTheSame && balanceHasChanged) { dispatch( setSwapsFromToken({ @@ -227,14 +227,14 @@ export default function BuildQuote({ balance: tokensWithBalancesFromToken?.balance, string: tokensWithBalancesFromToken?.string, }), - ) + ); } }, [ dispatch, tokensWithBalancesFromToken, previousTokensWithBalancesFromToken, fromToken, - ]) + ]); // If the eth balance changes while on build quote, we update the selected from token useEffect(() => { @@ -252,19 +252,19 @@ export default function BuildQuote({ toDenomination: 'ETH', }), }), - ) + ); } - }, [dispatch, fromToken, ethBalance]) + }, [dispatch, fromToken, ethBalance]); useEffect(() => { if (prevFromTokenBalance !== fromTokenBalance) { - onInputChange(inputValue, fromTokenBalance) + onInputChange(inputValue, fromTokenBalance); } - }, [onInputChange, prevFromTokenBalance, inputValue, fromTokenBalance]) + }, [onInputChange, prevFromTokenBalance, inputValue, fromTokenBalance]); useEffect(() => { - dispatch(resetSwapsPostFetchState()) - }, [dispatch]) + dispatch(resetSwapsPostFetchState()); + }, [dispatch]); return (
    @@ -286,7 +286,7 @@ export default function BuildQuote({ onSelect={onFromSelect} itemsToSearch={tokensToSearch} onInputChange={(value) => { - onInputChange(value, fromTokenBalance) + onInputChange(value, fromTokenBalance); }} inputValue={inputValue} leftValue={inputValue && swapFromFiatValue} @@ -332,8 +332,8 @@ export default function BuildQuote({
    - ) + ); } BuildQuote.propTypes = { @@ -431,4 +431,4 @@ BuildQuote.propTypes = { ethBalance: PropTypes.string, setMaxSlippage: PropTypes.func, selectedAccountAddress: PropTypes.string, -} +}; diff --git a/ui/app/pages/swaps/build-quote/build-quote.stories.js b/ui/app/pages/swaps/build-quote/build-quote.stories.js index 9a6eaf2217..65f16ab833 100644 --- a/ui/app/pages/swaps/build-quote/build-quote.stories.js +++ b/ui/app/pages/swaps/build-quote/build-quote.stories.js @@ -1,8 +1,8 @@ -import React, { useState } from 'react' -import { action } from '@storybook/addon-actions' -import { boolean } from '@storybook/addon-knobs' -import DropdownInputPair from '../dropdown-input-pair' -import DropdownSearchList from '../dropdown-search-list' +import React, { useState } from 'react'; +import { action } from '@storybook/addon-actions'; +import { boolean } from '@storybook/addon-knobs'; +import DropdownInputPair from '../dropdown-input-pair'; +import DropdownSearchList from '../dropdown-search-list'; const tokens = [ { @@ -113,7 +113,7 @@ const tokens = [ decimals: 8, address: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', }, -] +]; const tokensToSearch = tokens.map((token) => ({ ...token, @@ -123,18 +123,18 @@ const tokensToSearch = tokens.map((token) => ({ Math.floor(Math.random() * 6), )} ${token.symbol}`, rightSecondaryLabel: `$${(Math.random() * 1000).toFixed(2)}`, -})) +})); export default { title: 'BuildQuote', -} +}; export const Default = () => { - const [inputValue, onInputChange] = useState(null) - const [selectedFromToken, setSelectedFromToken] = useState(null) - const formattedSwapFromFiatValue = `$${(Number(inputValue) * 4).toFixed(2)}` - const loading = boolean('loading', false) - const selectedFromTokenIsNull = boolean('selectedFromTokenIsNull', false) + const [inputValue, onInputChange] = useState(null); + const [selectedFromToken, setSelectedFromToken] = useState(null); + const formattedSwapFromFiatValue = `$${(Number(inputValue) * 4).toFixed(2)}`; + const loading = boolean('loading', false); + const selectedFromTokenIsNull = boolean('selectedFromTokenIsNull', false); return (
    { />
    - ) -} + ); +}; diff --git a/ui/app/pages/swaps/build-quote/index.js b/ui/app/pages/swaps/build-quote/index.js index e8af5e4e86..772229f2a1 100644 --- a/ui/app/pages/swaps/build-quote/index.js +++ b/ui/app/pages/swaps/build-quote/index.js @@ -1 +1 @@ -export { default } from './build-quote' +export { default } from './build-quote'; diff --git a/ui/app/pages/swaps/countdown-timer/countdown-timer.js b/ui/app/pages/swaps/countdown-timer/countdown-timer.js index 393a518495..879eeff826 100644 --- a/ui/app/pages/swaps/countdown-timer/countdown-timer.js +++ b/ui/app/pages/swaps/countdown-timer/countdown-timer.js @@ -1,31 +1,31 @@ -import React, { useState, useEffect, useContext, useRef } from 'react' -import { useSelector } from 'react-redux' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { Duration } from 'luxon' -import { I18nContext } from '../../../contexts/i18n' -import InfoTooltip from '../../../components/ui/info-tooltip' -import { getSwapsQuoteRefreshTime } from '../../../ducks/swaps/swaps' +import React, { useState, useEffect, useContext, useRef } from 'react'; +import { useSelector } from 'react-redux'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import { Duration } from 'luxon'; +import { I18nContext } from '../../../contexts/i18n'; +import InfoTooltip from '../../../components/ui/info-tooltip'; +import { getSwapsQuoteRefreshTime } from '../../../ducks/swaps/swaps'; // Return the mm:ss start time of the countdown timer. // If time has elapsed between `timeStarted` the time current time, // then that elapsed time will be subtracted from the timer before // rendering function getNewTimer(currentTime, timeStarted, timeBaseStart) { - const timeAlreadyElapsed = currentTime - timeStarted - return timeBaseStart - timeAlreadyElapsed + const timeAlreadyElapsed = currentTime - timeStarted; + return timeBaseStart - timeAlreadyElapsed; } function decreaseTimerByOne(timer) { - return Math.max(timer - 1000, 0) + return Math.max(timer - 1000, 0); } function timeBelowWarningTime(timer, warningTime) { - const [warningTimeMinutes, warningTimeSeconds] = warningTime.split(':') + const [warningTimeMinutes, warningTimeSeconds] = warningTime.split(':'); return ( timer <= (Number(warningTimeMinutes) * 60 + Number(warningTimeSeconds)) * 1000 - ) + ); } export default function CountdownTimer({ @@ -36,59 +36,59 @@ export default function CountdownTimer({ labelKey, infoTooltipLabelKey, }) { - const t = useContext(I18nContext) - const intervalRef = useRef() - const initialTimeStartedRef = useRef() + const t = useContext(I18nContext); + const intervalRef = useRef(); + const initialTimeStartedRef = useRef(); - const swapsQuoteRefreshTime = useSelector(getSwapsQuoteRefreshTime) - const timerStart = Number(timerBase) || swapsQuoteRefreshTime + const swapsQuoteRefreshTime = useSelector(getSwapsQuoteRefreshTime); + const timerStart = Number(timerBase) || swapsQuoteRefreshTime; - const [currentTime, setCurrentTime] = useState(() => Date.now()) + const [currentTime, setCurrentTime] = useState(() => Date.now()); const [timer, setTimer] = useState(() => getNewTimer(currentTime, timeStarted, timerStart), - ) + ); useEffect(() => { if (intervalRef.current === undefined) { intervalRef.current = setInterval(() => { - setTimer(decreaseTimerByOne) - }, 1000) + setTimer(decreaseTimerByOne); + }, 1000); } return function cleanup() { - clearInterval(intervalRef.current) - } - }, []) + clearInterval(intervalRef.current); + }; + }, []); // Reset the timer that timer has hit '0:00' and the timeStarted prop has changed useEffect(() => { if (!initialTimeStartedRef.current) { - initialTimeStartedRef.current = timeStarted || Date.now() + initialTimeStartedRef.current = timeStarted || Date.now(); } if (timer === 0 && timeStarted !== initialTimeStartedRef.current) { - initialTimeStartedRef.current = timeStarted - const newCurrentTime = Date.now() - setCurrentTime(newCurrentTime) - setTimer(getNewTimer(newCurrentTime, timeStarted, timerStart)) + initialTimeStartedRef.current = timeStarted; + const newCurrentTime = Date.now(); + setCurrentTime(newCurrentTime); + setTimer(getNewTimer(newCurrentTime, timeStarted, timerStart)); - clearInterval(intervalRef.current) + clearInterval(intervalRef.current); intervalRef.current = setInterval(() => { - setTimer(decreaseTimerByOne) - }, 1000) + setTimer(decreaseTimerByOne); + }, 1000); } - }, [timeStarted, timer, timerStart]) + }, [timeStarted, timer, timerStart]); - const formattedTimer = Duration.fromMillis(timer).toFormat('m:ss') - let time + const formattedTimer = Duration.fromMillis(timer).toFormat('m:ss'); + let time; if (timeOnly) { - time =
    {formattedTimer}
    + time =
    {formattedTimer}
    ; } else if (labelKey) { time = t(labelKey, [
    {formattedTimer}
    , - ]) + ]); } return ( @@ -105,7 +105,7 @@ export default function CountdownTimer({ ) : null} - ) + ); } CountdownTimer.propTypes = { @@ -115,4 +115,4 @@ CountdownTimer.propTypes = { warningTime: PropTypes.string, labelKey: PropTypes.string, infoTooltipLabelKey: PropTypes.string, -} +}; diff --git a/ui/app/pages/swaps/countdown-timer/countdown-timer.stories.js b/ui/app/pages/swaps/countdown-timer/countdown-timer.stories.js index 6970a045ad..10d89ac7d7 100644 --- a/ui/app/pages/swaps/countdown-timer/countdown-timer.stories.js +++ b/ui/app/pages/swaps/countdown-timer/countdown-timer.stories.js @@ -1,19 +1,19 @@ -import React from 'react' -import { number } from '@storybook/addon-knobs' -import CountdownTimer from './countdown-timer' +import React from 'react'; +import { number } from '@storybook/addon-knobs'; +import CountdownTimer from './countdown-timer'; export default { title: 'CountdownTimer', -} +}; const getTimeStartedFromDecrimentSeconds = (seconds) => - Date.now() - seconds * 1000 + Date.now() - seconds * 1000; export const Default = () => { const timeStartedSecondDecriment = number( 'Set timeStarted to curren time minus X seconds', 10, - ) + ); return ( { )} timeOnly /> - ) -} + ); +}; export const CustomTimerBase = () => { const timeStartedSecondDecriment = number( 'Set timeStarted to curren time minus X seconds', 10, - ) + ); return ( { timerBase={150000} timeOnly /> - ) -} + ); +}; // Label keys used in below stories are just for demonstration purposes export const WithLabelInfoTooltipAndWarning = () => { const timeStartedSecondDecriment = number( 'Set timeStarted to curren time minus X seconds', 0, - ) + ); return ( { infoTooltipLabelKey="disconnectAllAccountsConfirmationDescription" warningTime="0:15" /> - ) -} + ); +}; diff --git a/ui/app/pages/swaps/countdown-timer/index.js b/ui/app/pages/swaps/countdown-timer/index.js index 162b37c926..d45f24fff3 100644 --- a/ui/app/pages/swaps/countdown-timer/index.js +++ b/ui/app/pages/swaps/countdown-timer/index.js @@ -1 +1 @@ -export { default } from './countdown-timer' +export { default } from './countdown-timer'; diff --git a/ui/app/pages/swaps/dropdown-input-pair/dropdown-input-pair.js b/ui/app/pages/swaps/dropdown-input-pair/dropdown-input-pair.js index 5299ba3ae2..92aa5190b1 100644 --- a/ui/app/pages/swaps/dropdown-input-pair/dropdown-input-pair.js +++ b/ui/app/pages/swaps/dropdown-input-pair/dropdown-input-pair.js @@ -1,8 +1,8 @@ -import React, { useState, useRef, useEffect } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import DropdownSearchList from '../dropdown-search-list' -import TextField from '../../../components/ui/text-field' +import React, { useState, useRef, useEffect } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import DropdownSearchList from '../dropdown-search-list'; +import TextField from '../../../components/ui/text-field'; const characterWidthMap = { 1: 5.86, @@ -16,16 +16,16 @@ const characterWidthMap = { 9: 10.06, 0: 11.22, '.': 4.55, -} +}; const getInputWidth = (value) => { - const valueString = String(value) - const charArray = valueString.split('') + const valueString = String(value); + const charArray = valueString.split(''); return charArray.reduce( (inputWidth, _char) => inputWidth + characterWidthMap[_char], 12, - ) -} + ); +}; export default function DropdownInputPair({ itemsToSearch = [], onInputChange, @@ -41,34 +41,34 @@ export default function DropdownInputPair({ listContainerClassName, autoFocus, }) { - const [isOpen, setIsOpen] = useState(false) - const open = () => setIsOpen(true) - const close = () => setIsOpen(false) - const inputRef = useRef() + const [isOpen, setIsOpen] = useState(false); + const open = () => setIsOpen(true); + const close = () => setIsOpen(false); + const inputRef = useRef(); const onTextFieldChange = (event) => { - event.stopPropagation() + event.stopPropagation(); // Automatically prefix value with 0. if user begins typing . - const valueToUse = event.target.value === '.' ? '0.' : event.target.value + const valueToUse = event.target.value === '.' ? '0.' : event.target.value; // Regex that validates strings with only numbers, 'x.', '.x', and 'x.x' - const regexp = /^(\.\d+|\d+(\.\d+)?|\d+\.)$/u + const regexp = /^(\.\d+|\d+(\.\d+)?|\d+\.)$/u; // If the value is either empty or contains only numbers and '.' and only has one '.', update input to match if (valueToUse === '' || regexp.test(valueToUse)) { - onInputChange(valueToUse) + onInputChange(valueToUse); } else { // otherwise, use the previously set inputValue (effectively denying the user from inputting the last char) // or an empty string if we do not yet have an inputValue - onInputChange(inputValue || '') + onInputChange(inputValue || ''); } - } - const [applyTwoLineStyle, setApplyTwoLineStyle] = useState(null) + }; + const [applyTwoLineStyle, setApplyTwoLineStyle] = useState(null); useEffect(() => { setApplyTwoLineStyle( (inputRef?.current?.getBoundingClientRect()?.width || 0) + getInputWidth(inputValue || '') > 137, - ) - }, [inputValue, inputRef]) + ); + }, [inputValue, inputRef]); return (
    @@ -118,7 +118,7 @@ export default function DropdownInputPair({
    )} - ) + ); } DropdownInputPair.propTypes = { @@ -135,4 +135,4 @@ DropdownInputPair.propTypes = { hideItemIf: PropTypes.func, listContainerClassName: PropTypes.string, autoFocus: PropTypes.bool, -} +}; diff --git a/ui/app/pages/swaps/dropdown-input-pair/dropdown-input-pair.stories.js b/ui/app/pages/swaps/dropdown-input-pair/dropdown-input-pair.stories.js index c3ea2575d6..16b32c3ef4 100644 --- a/ui/app/pages/swaps/dropdown-input-pair/dropdown-input-pair.stories.js +++ b/ui/app/pages/swaps/dropdown-input-pair/dropdown-input-pair.stories.js @@ -1,5 +1,5 @@ -import React, { useState } from 'react' -import DropdownInputPair from '.' +import React, { useState } from 'react'; +import DropdownInputPair from '.'; const tokens = [ { @@ -110,11 +110,11 @@ const tokens = [ decimals: 8, address: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', }, -] +]; export default { title: 'DropdownInputPair', -} +}; const tokensToSearch = tokens.map((token) => ({ ...token, @@ -124,10 +124,10 @@ const tokensToSearch = tokens.map((token) => ({ Math.floor(Math.random() * 6), )} ${token.symbol}`, rightSecondaryLabel: `$${(Math.random() * 1000).toFixed(2)}`, -})) +})); export const Basic = () => { - const [inputValue, setInputValue] = useState() + const [inputValue, setInputValue] = useState(); return (
    { inputValue={inputValue} />
    - ) -} + ); +}; diff --git a/ui/app/pages/swaps/dropdown-input-pair/index.js b/ui/app/pages/swaps/dropdown-input-pair/index.js index 84a01f8350..d89fc83b8d 100644 --- a/ui/app/pages/swaps/dropdown-input-pair/index.js +++ b/ui/app/pages/swaps/dropdown-input-pair/index.js @@ -1 +1 @@ -export { default } from './dropdown-input-pair' +export { default } from './dropdown-input-pair'; diff --git a/ui/app/pages/swaps/dropdown-search-list/dropdown-search-list.js b/ui/app/pages/swaps/dropdown-search-list/dropdown-search-list.js index b6d85400dd..5577d3517f 100644 --- a/ui/app/pages/swaps/dropdown-search-list/dropdown-search-list.js +++ b/ui/app/pages/swaps/dropdown-search-list/dropdown-search-list.js @@ -4,14 +4,14 @@ import React, { useEffect, useContext, useRef, -} from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { isEqual } from 'lodash' -import { I18nContext } from '../../../contexts/i18n' -import SearchableItemList from '../searchable-item-list' -import PulseLoader from '../../../components/ui/pulse-loader' -import UrlIcon from '../../../components/ui/url-icon' +} from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import { isEqual } from 'lodash'; +import { I18nContext } from '../../../contexts/i18n'; +import SearchableItemList from '../searchable-item-list'; +import PulseLoader from '../../../components/ui/pulse-loader'; +import UrlIcon from '../../../components/ui/url-icon'; export default function DropdownSearchList({ searchListClassName, @@ -32,54 +32,54 @@ export default function DropdownSearchList({ hideItemIf, listContainerClassName, }) { - const t = useContext(I18nContext) - const [isOpen, setIsOpen] = useState(false) - const [selectedItem, setSelectedItem] = useState(startingItem) + const t = useContext(I18nContext); + const [isOpen, setIsOpen] = useState(false); + const [selectedItem, setSelectedItem] = useState(startingItem); const close = useCallback(() => { - setIsOpen(false) - onClose?.() - }, [onClose]) + setIsOpen(false); + onClose?.(); + }, [onClose]); const onClickItem = useCallback( (item) => { - onSelect?.(item) - setSelectedItem(item) - close() + onSelect?.(item); + setSelectedItem(item); + close(); }, [onSelect, close], - ) + ); const onClickSelector = useCallback(() => { if (!isOpen) { - setIsOpen(true) - onOpen?.() + setIsOpen(true); + onOpen?.(); } - }, [isOpen, onOpen]) + }, [isOpen, onOpen]); - const prevExternallySelectedItemRef = useRef() + const prevExternallySelectedItemRef = useRef(); useEffect(() => { - prevExternallySelectedItemRef.current = externallySelectedItem - }) - const prevExternallySelectedItem = prevExternallySelectedItemRef.current + prevExternallySelectedItemRef.current = externallySelectedItem; + }); + const prevExternallySelectedItem = prevExternallySelectedItemRef.current; useEffect(() => { if ( externallySelectedItem && !isEqual(externallySelectedItem, selectedItem) ) { - setSelectedItem(externallySelectedItem) + setSelectedItem(externallySelectedItem); } else if (prevExternallySelectedItem && !externallySelectedItem) { - setSelectedItem(null) + setSelectedItem(null); } - }, [externallySelectedItem, selectedItem, prevExternallySelectedItem]) + }, [externallySelectedItem, selectedItem, prevExternallySelectedItem]); const onKeyUp = (e) => { if (e.key === 'Escape') { - close() + close(); } else if (e.key === 'Enter') { - onClickSelector(e) + onClickSelector(e); } - } + }; return (
    { - event.stopPropagation() - setIsOpen(false) - onClose?.() + event.stopPropagation(); + setIsOpen(false); + onClose?.(); }} /> )}
    - ) + ); } DropdownSearchList.propTypes = { @@ -197,4 +197,4 @@ DropdownSearchList.propTypes = { hideRightLabels: PropTypes.bool, hideItemIf: PropTypes.func, listContainerClassName: PropTypes.string, -} +}; diff --git a/ui/app/pages/swaps/dropdown-search-list/dropdown-search-list.stories.js b/ui/app/pages/swaps/dropdown-search-list/dropdown-search-list.stories.js index d889777531..dacbc21a69 100644 --- a/ui/app/pages/swaps/dropdown-search-list/dropdown-search-list.stories.js +++ b/ui/app/pages/swaps/dropdown-search-list/dropdown-search-list.stories.js @@ -1,5 +1,5 @@ -import React from 'react' -import DropdownSearchList from '.' +import React from 'react'; +import DropdownSearchList from '.'; const tokens = [ { @@ -110,11 +110,11 @@ const tokens = [ decimals: 8, address: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', }, -] +]; export default { title: 'DropdownSearchList', -} +}; const tokensToSearch = tokens.map((token) => ({ ...token, @@ -124,7 +124,7 @@ const tokensToSearch = tokens.map((token) => ({ Math.floor(Math.random() * 6), )} ${token.symbol}`, rightSecondaryLabel: `$${(Math.random() * 1000).toFixed(2)}`, -})) +})); export const TokenSearchDropdown = () => { return ( @@ -141,5 +141,5 @@ export const TokenSearchDropdown = () => { defaultToAll /> - ) -} + ); +}; diff --git a/ui/app/pages/swaps/dropdown-search-list/index.js b/ui/app/pages/swaps/dropdown-search-list/index.js index e507fe1441..3dd2e4ecf6 100644 --- a/ui/app/pages/swaps/dropdown-search-list/index.js +++ b/ui/app/pages/swaps/dropdown-search-list/index.js @@ -1 +1 @@ -export { default } from './dropdown-search-list' +export { default } from './dropdown-search-list'; diff --git a/ui/app/pages/swaps/exchange-rate-display/exchange-rate-display.js b/ui/app/pages/swaps/exchange-rate-display/exchange-rate-display.js index e70ffd8e77..4959902158 100644 --- a/ui/app/pages/swaps/exchange-rate-display/exchange-rate-display.js +++ b/ui/app/pages/swaps/exchange-rate-display/exchange-rate-display.js @@ -1,9 +1,9 @@ -import React, { useState } from 'react' -import PropTypes from 'prop-types' -import BigNumber from 'bignumber.js' -import classnames from 'classnames' -import { calcTokenAmount } from '../../../helpers/utils/token-util' -import { formatSwapsValueForDisplay } from '../swaps.util' +import React, { useState } from 'react'; +import PropTypes from 'prop-types'; +import BigNumber from 'bignumber.js'; +import classnames from 'classnames'; +import { calcTokenAmount } from '../../../helpers/utils/token-util'; +import { formatSwapsValueForDisplay } from '../swaps.util'; export default function ExchangeRateDisplay({ primaryTokenValue, @@ -16,49 +16,49 @@ export default function ExchangeRateDisplay({ boldSymbols = true, className, }) { - const [showPrimaryToSecondary, setShowPrimaryToSecondary] = useState(true) - const [rotating, setRotating] = useState(false) + const [showPrimaryToSecondary, setShowPrimaryToSecondary] = useState(true); + const [rotating, setRotating] = useState(false); const primaryTokenAmount = calcTokenAmount( primaryTokenValue, primaryTokenDecimals, - ) + ); const secondaryTokenAmount = calcTokenAmount( secondaryTokenValue, secondaryTokenDecimals, - ) + ); const conversionRateFromPrimaryToSecondary = new BigNumber( secondaryTokenAmount, ) .div(primaryTokenAmount) .round(9) - .toString(10) + .toString(10); const conversionRateFromSecondaryToPrimary = new BigNumber(primaryTokenAmount) .div(secondaryTokenAmount) .round(9) - .toString(10) + .toString(10); const baseSymbol = showPrimaryToSecondary ? primaryTokenSymbol - : secondaryTokenSymbol + : secondaryTokenSymbol; const ratiodSymbol = showPrimaryToSecondary ? secondaryTokenSymbol - : primaryTokenSymbol + : primaryTokenSymbol; const rate = showPrimaryToSecondary ? conversionRateFromPrimaryToSecondary - : conversionRateFromSecondaryToPrimary - let rateToDisplay - let comparisonSymbol = '=' + : conversionRateFromSecondaryToPrimary; + let rateToDisplay; + let comparisonSymbol = '='; if (new BigNumber(rate, 10).lt('0.00000001', 10)) { - rateToDisplay = '0.000000001' - comparisonSymbol = '<' + rateToDisplay = '0.000000001'; + comparisonSymbol = '<'; } else if (new BigNumber(rate, 10).lt('0.000001', 10)) { - rateToDisplay = rate + rateToDisplay = rate; } else { - rateToDisplay = formatSwapsValueForDisplay(rate) + rateToDisplay = formatSwapsValueForDisplay(rate); } return ( @@ -81,8 +81,8 @@ export default function ExchangeRateDisplay({ 'exchange-rate-display__switch-arrows-rotate': rotating, })} onClick={() => { - setShowPrimaryToSecondary(!showPrimaryToSecondary) - setRotating(true) + setShowPrimaryToSecondary(!showPrimaryToSecondary); + setRotating(true); }} onAnimationEnd={() => setRotating(false)} > @@ -100,7 +100,7 @@ export default function ExchangeRateDisplay({ - ) + ); } ExchangeRateDisplay.propTypes = { @@ -125,4 +125,4 @@ ExchangeRateDisplay.propTypes = { className: PropTypes.string, arrowColor: PropTypes.string, boldSymbols: PropTypes.bool, -} +}; diff --git a/ui/app/pages/swaps/exchange-rate-display/exchange-rate-display.stories.js b/ui/app/pages/swaps/exchange-rate-display/exchange-rate-display.stories.js index b28fa37720..d3193d6b5a 100644 --- a/ui/app/pages/swaps/exchange-rate-display/exchange-rate-display.stories.js +++ b/ui/app/pages/swaps/exchange-rate-display/exchange-rate-display.stories.js @@ -1,10 +1,10 @@ -import React from 'react' -import { text, number } from '@storybook/addon-knobs' -import ExchangeRateDisplay from './exchange-rate-display' +import React from 'react'; +import { text, number } from '@storybook/addon-knobs'; +import ExchangeRateDisplay from './exchange-rate-display'; export default { title: 'ExchangeRateDisplay', -} +}; export const Default = () => { return ( @@ -16,8 +16,8 @@ export const Default = () => { secondaryTokenDecimals={number('secondaryTokenDecimals', 18)} secondaryTokenSymbol={text('secondaryTokenSymbol', 'ABC')} /> - ) -} + ); +}; export const WhiteOnBlue = () => { return ( @@ -43,5 +43,5 @@ export const WhiteOnBlue = () => { arrowColor="white" /> - ) -} + ); +}; diff --git a/ui/app/pages/swaps/exchange-rate-display/index.js b/ui/app/pages/swaps/exchange-rate-display/index.js index e572fe6986..aeef508f8d 100644 --- a/ui/app/pages/swaps/exchange-rate-display/index.js +++ b/ui/app/pages/swaps/exchange-rate-display/index.js @@ -1 +1 @@ -export { default } from './exchange-rate-display' +export { default } from './exchange-rate-display'; diff --git a/ui/app/pages/swaps/fee-card/fee-card.js b/ui/app/pages/swaps/fee-card/fee-card.js index af48ff7bb5..cafbd97a3e 100644 --- a/ui/app/pages/swaps/fee-card/fee-card.js +++ b/ui/app/pages/swaps/fee-card/fee-card.js @@ -1,7 +1,7 @@ -import React, { useContext } from 'react' -import PropTypes from 'prop-types' -import { I18nContext } from '../../../contexts/i18n' -import InfoTooltip from '../../../components/ui/info-tooltip' +import React, { useContext } from 'react'; +import PropTypes from 'prop-types'; +import { I18nContext } from '../../../contexts/i18n'; +import InfoTooltip from '../../../components/ui/info-tooltip'; export default function FeeCard({ primaryFee, @@ -17,13 +17,13 @@ export default function FeeCard({ onQuotesClick, tokenConversionRate, }) { - const t = useContext(I18nContext) + const t = useContext(I18nContext); - let bestQuoteText = '' + let bestQuoteText = ''; if (isBestQuote && tokenConversionRate) { - bestQuoteText = t('swapUsingBestQuote') + bestQuoteText = t('swapUsingBestQuote'); } else if (tokenConversionRate) { - bestQuoteText = t('swapBetterQuoteAvailable') + bestQuoteText = t('swapBetterQuoteAvailable'); } return ( @@ -148,7 +148,7 @@ export default function FeeCard({ - ) + ); } FeeCard.propTypes = { @@ -170,4 +170,4 @@ FeeCard.propTypes = { onQuotesClick: PropTypes.func.isRequired, numberOfQuotes: PropTypes.number.isRequired, tokenConversionRate: PropTypes.number, -} +}; diff --git a/ui/app/pages/swaps/fee-card/fee-card.stories.js b/ui/app/pages/swaps/fee-card/fee-card.stories.js index aaaf43d0fd..32ea9caead 100644 --- a/ui/app/pages/swaps/fee-card/fee-card.stories.js +++ b/ui/app/pages/swaps/fee-card/fee-card.stories.js @@ -1,21 +1,21 @@ -import React from 'react' -import { action } from '@storybook/addon-actions' -import { text, boolean, number, object } from '@storybook/addon-knobs' -import FeeCard from './fee-card' +import React from 'react'; +import { action } from '@storybook/addon-actions'; +import { text, boolean, number, object } from '@storybook/addon-knobs'; +import FeeCard from './fee-card'; const tokenApprovalTextComponent = ( ABC -) +); const containerStyle = { width: '300px', -} +}; export default { title: 'FeeCard', -} +}; export const WithAllProps = () => { return ( @@ -44,8 +44,8 @@ export const WithAllProps = () => { currentCurrency="usd" /> - ) -} + ); +}; export const WithoutThirdRow = () => { return ( @@ -69,8 +69,8 @@ export const WithoutThirdRow = () => { metaMaskFee="0.875" /> - ) -} + ); +}; export const WithOnlyRequiredProps = () => { return ( @@ -87,5 +87,5 @@ export const WithOnlyRequiredProps = () => { numberOfQuotes={2} /> - ) -} + ); +}; diff --git a/ui/app/pages/swaps/fee-card/index.js b/ui/app/pages/swaps/fee-card/index.js index 84bc1acbb5..4cac493bf4 100644 --- a/ui/app/pages/swaps/fee-card/index.js +++ b/ui/app/pages/swaps/fee-card/index.js @@ -1 +1 @@ -export { default } from './fee-card' +export { default } from './fee-card'; diff --git a/ui/app/pages/swaps/fee-card/pig-icon.js b/ui/app/pages/swaps/fee-card/pig-icon.js index ef7677ae44..fe6a4278fa 100644 --- a/ui/app/pages/swaps/fee-card/pig-icon.js +++ b/ui/app/pages/swaps/fee-card/pig-icon.js @@ -1,4 +1,4 @@ -import React from 'react' +import React from 'react'; export default function PigIcon() { return ( @@ -50,5 +50,5 @@ export default function PigIcon() { stroke="#037DD6" /> - ) + ); } diff --git a/ui/app/pages/swaps/index.js b/ui/app/pages/swaps/index.js index ca720910dd..517e2b0a3e 100644 --- a/ui/app/pages/swaps/index.js +++ b/ui/app/pages/swaps/index.js @@ -1,19 +1,19 @@ -import React, { useState, useEffect, useRef, useContext } from 'react' -import { useDispatch, useSelector } from 'react-redux' +import React, { useState, useEffect, useRef, useContext } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; import { Switch, Route, useLocation, useHistory, Redirect, -} from 'react-router-dom' -import BigNumber from 'bignumber.js' -import { I18nContext } from '../../contexts/i18n' +} from 'react-router-dom'; +import BigNumber from 'bignumber.js'; +import { I18nContext } from '../../contexts/i18n'; import { getSelectedAccount, getCurrentNetworkId, getCurrentChainId, -} from '../../selectors/selectors' +} from '../../selectors/selectors'; import { getFromToken, getQuotes, @@ -31,7 +31,7 @@ import { getSwapsFeatureLiveness, prepareToLeaveSwaps, fetchAndSetSwapsGasPriceInfo, -} from '../../ducks/swaps/swaps' +} from '../../ducks/swaps/swaps'; import { AWAITING_SWAP_ROUTE, BUILD_QUOTE_ROUTE, @@ -40,15 +40,15 @@ import { SWAPS_ERROR_ROUTE, DEFAULT_ROUTE, SWAPS_MAINTENANCE_ROUTE, -} from '../../helpers/constants/routes' +} from '../../helpers/constants/routes'; import { ERROR_FETCHING_QUOTES, QUOTES_NOT_AVAILABLE_ERROR, ETH_SWAPS_TOKEN_OBJECT, SWAP_FAILED_ERROR, OFFLINE_FOR_MAINTENANCE, -} from '../../helpers/constants/swaps' -import { MAINNET_CHAIN_ID } from '../../../../shared/constants/network' +} from '../../helpers/constants/swaps'; +import { MAINNET_CHAIN_ID } from '../../../../shared/constants/network'; import { resetBackgroundSwapsState, @@ -56,61 +56,61 @@ import { removeToken, setBackgroundSwapRouteState, setSwapsErrorKey, -} from '../../store/actions' +} from '../../store/actions'; import { currentNetworkTxListSelector, getRpcPrefsForCurrentProvider, -} from '../../selectors' -import { useNewMetricEvent } from '../../hooks/useMetricEvent' -import { getValueFromWeiHex } from '../../helpers/utils/conversions.util' +} from '../../selectors'; +import { useNewMetricEvent } from '../../hooks/useMetricEvent'; +import { getValueFromWeiHex } from '../../helpers/utils/conversions.util'; -import FeatureToggledRoute from '../../helpers/higher-order-components/feature-toggled-route' -import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction' +import FeatureToggledRoute from '../../helpers/higher-order-components/feature-toggled-route'; +import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'; import { fetchTokens, fetchTopAssets, getSwapsTokensReceivedFromTxMeta, fetchAggregatorMetadata, -} from './swaps.util' -import AwaitingSwap from './awaiting-swap' -import LoadingQuote from './loading-swaps-quotes' -import BuildQuote from './build-quote' -import ViewQuote from './view-quote' +} from './swaps.util'; +import AwaitingSwap from './awaiting-swap'; +import LoadingQuote from './loading-swaps-quotes'; +import BuildQuote from './build-quote'; +import ViewQuote from './view-quote'; export default function Swap() { - const t = useContext(I18nContext) - const history = useHistory() - const dispatch = useDispatch() + const t = useContext(I18nContext); + const history = useHistory(); + const dispatch = useDispatch(); - const { pathname } = useLocation() - const isAwaitingSwapRoute = pathname === AWAITING_SWAP_ROUTE - const isSwapsErrorRoute = pathname === SWAPS_ERROR_ROUTE - const isLoadingQuotesRoute = pathname === LOADING_QUOTES_ROUTE + const { pathname } = useLocation(); + const isAwaitingSwapRoute = pathname === AWAITING_SWAP_ROUTE; + const isSwapsErrorRoute = pathname === SWAPS_ERROR_ROUTE; + const isLoadingQuotesRoute = pathname === LOADING_QUOTES_ROUTE; - const fetchParams = useSelector(getFetchParams) + const fetchParams = useSelector(getFetchParams); const { sourceTokenInfo = {}, destinationTokenInfo = {} } = - fetchParams?.metaData || {} + fetchParams?.metaData || {}; - const [inputValue, setInputValue] = useState(fetchParams?.value || '') - const [maxSlippage, setMaxSlippage] = useState(fetchParams?.slippage || 2) + const [inputValue, setInputValue] = useState(fetchParams?.value || ''); + const [maxSlippage, setMaxSlippage] = useState(fetchParams?.slippage || 2); - const routeState = useSelector(getBackgroundSwapRouteState) - const selectedAccount = useSelector(getSelectedAccount) - const quotes = useSelector(getQuotes) - const txList = useSelector(currentNetworkTxListSelector) - const tradeTxId = useSelector(getTradeTxId) - const approveTxId = useSelector(getApproveTxId) - const aggregatorMetadata = useSelector(getAggregatorMetadata) - const networkId = useSelector(getCurrentNetworkId) - const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider) - const fetchingQuotes = useSelector(getFetchingQuotes) - let swapsErrorKey = useSelector(getSwapsErrorKey) - const swapsEnabled = useSelector(getSwapsFeatureLiveness) + const routeState = useSelector(getBackgroundSwapRouteState); + const selectedAccount = useSelector(getSelectedAccount); + const quotes = useSelector(getQuotes); + const txList = useSelector(currentNetworkTxListSelector); + const tradeTxId = useSelector(getTradeTxId); + const approveTxId = useSelector(getApproveTxId); + const aggregatorMetadata = useSelector(getAggregatorMetadata); + const networkId = useSelector(getCurrentNetworkId); + const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider); + const fetchingQuotes = useSelector(getFetchingQuotes); + let swapsErrorKey = useSelector(getSwapsErrorKey); + const swapsEnabled = useSelector(getSwapsFeatureLiveness); const { balance: ethBalance, address: selectedAccountAddress, - } = selectedAccount + } = selectedAccount; const fetchParamsFromToken = sourceTokenInfo?.symbol === 'ETH' ? { @@ -122,14 +122,14 @@ export default function Swap() { }), balance: ethBalance, } - : sourceTokenInfo + : sourceTokenInfo; const selectedFromToken = - useSelector(getFromToken) || fetchParamsFromToken || {} - const { destinationTokenAddedForSwap } = fetchParams || {} + useSelector(getFromToken) || fetchParamsFromToken || {}; + const { destinationTokenAddedForSwap } = fetchParams || {}; const approveTxData = - approveTxId && txList.find(({ id }) => approveTxId === id) - const tradeTxData = tradeTxId && txList.find(({ id }) => tradeTxId === id) + approveTxId && txList.find(({ id }) => approveTxId === id); + const tradeTxData = tradeTxId && txList.find(({ id }) => tradeTxId === id); const tokensReceived = tradeTxData?.txReceipt && getSwapsTokensReceivedFromTxMeta( @@ -139,30 +139,30 @@ export default function Swap() { selectedAccountAddress, destinationTokenInfo?.decimals, approveTxData, - ) - const tradeConfirmed = tradeTxData?.status === TRANSACTION_STATUSES.CONFIRMED + ); + const tradeConfirmed = tradeTxData?.status === TRANSACTION_STATUSES.CONFIRMED; const approveError = approveTxData?.status === TRANSACTION_STATUSES.FAILED || - approveTxData?.txReceipt?.status === '0x0' + approveTxData?.txReceipt?.status === '0x0'; const tradeError = tradeTxData?.status === TRANSACTION_STATUSES.FAILED || - tradeTxData?.txReceipt?.status === '0x0' - const conversionError = approveError || tradeError + tradeTxData?.txReceipt?.status === '0x0'; + const conversionError = approveError || tradeError; if (conversionError) { - swapsErrorKey = SWAP_FAILED_ERROR + swapsErrorKey = SWAP_FAILED_ERROR; } - const clearTemporaryTokenRef = useRef() + const clearTemporaryTokenRef = useRef(); useEffect(() => { clearTemporaryTokenRef.current = () => { if ( destinationTokenAddedForSwap && (!isAwaitingSwapRoute || conversionError) ) { - dispatch(removeToken(destinationTokenInfo?.address)) + dispatch(removeToken(destinationTokenInfo?.address)); } - } + }; }, [ conversionError, dispatch, @@ -170,34 +170,34 @@ export default function Swap() { destinationTokenInfo, fetchParams, isAwaitingSwapRoute, - ]) + ]); useEffect(() => { return () => { - clearTemporaryTokenRef.current() - } - }, []) + clearTemporaryTokenRef.current(); + }; + }, []); useEffect(() => { fetchTokens() .then((tokens) => { - dispatch(setSwapsTokens(tokens)) + dispatch(setSwapsTokens(tokens)); }) - .catch((error) => console.error(error)) + .catch((error) => console.error(error)); fetchTopAssets().then((topAssets) => { - dispatch(setTopAssets(topAssets)) - }) + dispatch(setTopAssets(topAssets)); + }); fetchAggregatorMetadata().then((newAggregatorMetadata) => { - dispatch(setAggregatorMetadata(newAggregatorMetadata)) - }) + dispatch(setAggregatorMetadata(newAggregatorMetadata)); + }); - dispatch(fetchAndSetSwapsGasPriceInfo()) + dispatch(fetchAndSetSwapsGasPriceInfo()); return () => { - dispatch(prepareToLeaveSwaps()) - } - }, [dispatch]) + dispatch(prepareToLeaveSwaps()); + }; + }, [dispatch]); const exitedSwapsEvent = useNewMetricEvent({ event: 'Exited Swaps', @@ -211,45 +211,45 @@ export default function Swap() { custom_slippage: fetchParams?.slippage !== 2, current_screen: pathname.match(/\/swaps\/(.+)/u)[1], }, - }) - const exitEventRef = useRef() + }); + const exitEventRef = useRef(); useEffect(() => { exitEventRef.current = () => { - exitedSwapsEvent() - } - }) + exitedSwapsEvent(); + }; + }); useEffect(() => { return () => { - exitEventRef.current() - } - }, []) + exitEventRef.current(); + }; + }, []); useEffect(() => { if (swapsErrorKey && !isSwapsErrorRoute) { - history.push(SWAPS_ERROR_ROUTE) + history.push(SWAPS_ERROR_ROUTE); } - }, [history, swapsErrorKey, isSwapsErrorRoute]) + }, [history, swapsErrorKey, isSwapsErrorRoute]); - const beforeUnloadEventAddedRef = useRef() + const beforeUnloadEventAddedRef = useRef(); useEffect(() => { const fn = () => { - clearTemporaryTokenRef.current() + clearTemporaryTokenRef.current(); if (isLoadingQuotesRoute) { - dispatch(prepareToLeaveSwaps()) + dispatch(prepareToLeaveSwaps()); } - return null - } + return null; + }; if (isLoadingQuotesRoute && !beforeUnloadEventAddedRef.current) { - beforeUnloadEventAddedRef.current = true - window.addEventListener('beforeunload', fn) + beforeUnloadEventAddedRef.current = true; + window.addEventListener('beforeunload', fn); } - return () => window.removeEventListener('beforeunload', fn) - }, [dispatch, isLoadingQuotesRoute]) + return () => window.removeEventListener('beforeunload', fn); + }, [dispatch, isLoadingQuotesRoute]); - const chainId = useSelector(getCurrentChainId) + const chainId = useSelector(getCurrentChainId); if (chainId !== MAINNET_CHAIN_ID) { - return + return ; } return ( @@ -261,10 +261,10 @@ export default function Swap() {
    { - clearTemporaryTokenRef.current() - dispatch(clearSwapsState()) - await dispatch(resetBackgroundSwapsState()) - history.push(DEFAULT_ROUTE) + clearTemporaryTokenRef.current(); + dispatch(clearSwapsState()); + await dispatch(resetBackgroundSwapsState()); + history.push(DEFAULT_ROUTE); }} > {t('cancel')} @@ -280,21 +280,21 @@ export default function Swap() { exact render={() => { if (tradeTxData && !conversionError) { - return + return ; } else if (tradeTxData) { - return + return ; } else if (routeState === 'loading' && aggregatorMetadata) { - return + return ; } const onInputChange = (newInputValue, balance) => { - setInputValue(newInputValue) + setInputValue(newInputValue); dispatch( setBalanceError( new BigNumber(newInputValue || 0).gt(balance || 0), ), - ) - } + ); + }; return ( - ) + ); }} /> - ) + ); } else if (fetchParams) { - return + return ; } - return + return ; }} /> - ) + ); } - return + return ; }} /> { - await dispatch(setBackgroundSwapRouteState('')) + await dispatch(setBackgroundSwapRouteState('')); if ( swapsErrorKey === ERROR_FETCHING_QUOTES || swapsErrorKey === QUOTES_NOT_AVAILABLE_ERROR ) { - dispatch(setSwapsErrorKey(QUOTES_NOT_AVAILABLE_ERROR)) - history.push(SWAPS_ERROR_ROUTE) + dispatch(setSwapsErrorKey(QUOTES_NOT_AVAILABLE_ERROR)); + history.push(SWAPS_ERROR_ROUTE); } else { - history.push(VIEW_QUOTE_ROUTE) + history.push(VIEW_QUOTE_ROUTE); } }} aggregatorMetadata={aggregatorMetadata} /> ) : ( - ) + ); }} /> ) : ( - ) + ); }} /> ) : ( - ) + ); }} />
    - ) + ); } diff --git a/ui/app/pages/swaps/intro-popup/index.js b/ui/app/pages/swaps/intro-popup/index.js index 66dc3b0a58..6460538b97 100644 --- a/ui/app/pages/swaps/intro-popup/index.js +++ b/ui/app/pages/swaps/intro-popup/index.js @@ -1 +1 @@ -export { default } from './intro-popup' +export { default } from './intro-popup'; diff --git a/ui/app/pages/swaps/intro-popup/intro-popup.js b/ui/app/pages/swaps/intro-popup/intro-popup.js index 5d525b7eee..30d9348419 100644 --- a/ui/app/pages/swaps/intro-popup/intro-popup.js +++ b/ui/app/pages/swaps/intro-popup/intro-popup.js @@ -1,37 +1,37 @@ -import React, { useContext } from 'react' -import { useDispatch } from 'react-redux' -import { useHistory } from 'react-router-dom' -import PropTypes from 'prop-types' -import { setSwapsFromToken } from '../../../ducks/swaps/swaps' -import { I18nContext } from '../../../contexts/i18n' -import { BUILD_QUOTE_ROUTE } from '../../../helpers/constants/routes' -import { useNewMetricEvent } from '../../../hooks/useMetricEvent' -import { useSwapsEthToken } from '../../../hooks/useSwapsEthToken' -import Button from '../../../components/ui/button' -import Popover from '../../../components/ui/popover' +import React, { useContext } from 'react'; +import { useDispatch } from 'react-redux'; +import { useHistory } from 'react-router-dom'; +import PropTypes from 'prop-types'; +import { setSwapsFromToken } from '../../../ducks/swaps/swaps'; +import { I18nContext } from '../../../contexts/i18n'; +import { BUILD_QUOTE_ROUTE } from '../../../helpers/constants/routes'; +import { useNewMetricEvent } from '../../../hooks/useMetricEvent'; +import { useSwapsEthToken } from '../../../hooks/useSwapsEthToken'; +import Button from '../../../components/ui/button'; +import Popover from '../../../components/ui/popover'; export default function IntroPopup({ onClose }) { - const dispatch = useDispatch(useDispatch) - const history = useHistory() - const t = useContext(I18nContext) + const dispatch = useDispatch(useDispatch); + const history = useHistory(); + const t = useContext(I18nContext); const enteredSwapsEvent = useNewMetricEvent({ event: 'Swaps Opened', properties: { source: 'Intro popup', active_currency: 'ETH' }, category: 'swaps', - }) + }); const blogPostVisitedEvent = useNewMetricEvent({ event: 'Blog Post Visited ', category: 'swaps', - }) + }); const contractAuditVisitedEvent = useNewMetricEvent({ event: 'Contract Audit Visited', category: 'swaps', - }) + }); const productOverviewDismissedEvent = useNewMetricEvent({ event: 'Product Overview Dismissed', category: 'swaps', - }) - const swapsEthToken = useSwapsEthToken() + }); + const swapsEthToken = useSwapsEthToken(); return (
    @@ -40,8 +40,8 @@ export default function IntroPopup({ onClose }) { title={t('swapIntroPopupTitle')} subtitle={t('swapIntroPopupSubTitle')} onClose={() => { - productOverviewDismissedEvent() - onClose() + productOverviewDismissedEvent(); + onClose(); }} footerClassName="intro-popup__footer" footer={ @@ -49,10 +49,10 @@ export default function IntroPopup({ onClose }) { type="confirm" className="intro-popup__button" onClick={() => { - onClose() - enteredSwapsEvent() - dispatch(setSwapsFromToken(swapsEthToken)) - history.push(BUILD_QUOTE_ROUTE) + onClose(); + enteredSwapsEvent(); + dispatch(setSwapsFromToken(swapsEthToken)); + history.push(BUILD_QUOTE_ROUTE); }} > {t('swapStartSwapping')} @@ -75,8 +75,8 @@ export default function IntroPopup({ onClose }) { global.platform.openTab({ url: 'https://medium.com/metamask/introducing-metamask-swaps-84318c643785', - }) - blogPostVisitedEvent() + }); + blogPostVisitedEvent(); }} > {t('swapIntroLearnMoreLink')} @@ -87,8 +87,8 @@ export default function IntroPopup({ onClose }) { global.platform.openTab({ url: 'https://diligence.consensys.net/audits/private/lsjipyllnw2/', - }) - contractAuditVisitedEvent() + }); + contractAuditVisitedEvent(); }} > {t('swapLearnMoreContractsAuditReview')} @@ -96,9 +96,9 @@ export default function IntroPopup({ onClose }) {
    - ) + ); } IntroPopup.propTypes = { onClose: PropTypes.func.isRequired, -} +}; diff --git a/ui/app/pages/swaps/loading-swaps-quotes/aggregator-logo.js b/ui/app/pages/swaps/loading-swaps-quotes/aggregator-logo.js index 6b147c1c69..2d43d83a65 100644 --- a/ui/app/pages/swaps/loading-swaps-quotes/aggregator-logo.js +++ b/ui/app/pages/swaps/loading-swaps-quotes/aggregator-logo.js @@ -1,13 +1,13 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; // Inspired by https://stackoverflow.com/a/28056903/4727685 function hexToRGB(hex, alpha) { - const r = parseInt(hex.slice(1, 3), 16) - const g = parseInt(hex.slice(3, 5), 16) - const b = parseInt(hex.slice(5, 7), 16) + const r = parseInt(hex.slice(1, 3), 16); + const g = parseInt(hex.slice(3, 5), 16); + const b = parseInt(hex.slice(5, 7), 16); - return `rgba(${r}, ${g}, ${b}, ${alpha})` + return `rgba(${r}, ${g}, ${b}, ${alpha})`; } export default function AggregatorLogo({ icon, color }) { @@ -22,10 +22,10 @@ export default function AggregatorLogo({ icon, color }) { - ) + ); } AggregatorLogo.propTypes = { icon: PropTypes.string.isRequired, color: PropTypes.string.isRequired, -} +}; diff --git a/ui/app/pages/swaps/loading-swaps-quotes/background-animation.js b/ui/app/pages/swaps/loading-swaps-quotes/background-animation.js index d435247a07..3820bffd0e 100644 --- a/ui/app/pages/swaps/loading-swaps-quotes/background-animation.js +++ b/ui/app/pages/swaps/loading-swaps-quotes/background-animation.js @@ -1,4 +1,4 @@ -import React from 'react' +import React from 'react'; export default function BackgroundAnimation() { return ( @@ -203,5 +203,5 @@ export default function BackgroundAnimation() { - ) + ); } diff --git a/ui/app/pages/swaps/loading-swaps-quotes/index.js b/ui/app/pages/swaps/loading-swaps-quotes/index.js index 205fb024bb..0a79f9e562 100644 --- a/ui/app/pages/swaps/loading-swaps-quotes/index.js +++ b/ui/app/pages/swaps/loading-swaps-quotes/index.js @@ -1 +1 @@ -export { default } from './loading-swaps-quotes' +export { default } from './loading-swaps-quotes'; diff --git a/ui/app/pages/swaps/loading-swaps-quotes/loading-swaps-quotes-stories-metadata.js b/ui/app/pages/swaps/loading-swaps-quotes/loading-swaps-quotes-stories-metadata.js index 7ffb38bf1e..aae2acd8a0 100644 --- a/ui/app/pages/swaps/loading-swaps-quotes/loading-swaps-quotes-stories-metadata.js +++ b/ui/app/pages/swaps/loading-swaps-quotes/loading-swaps-quotes-stories-metadata.js @@ -29,4 +29,4 @@ export const storiesMetadata = { icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASkAAAB5CAYAAABlYNfBAAAACXBIWXMAACxLAAAsSwGlPZapAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAACQQSURBVHgB7Z0JfFTl1f/PnSwzk3VCAoFAYEjYDRAUSHCBoOBSFwK2wlurgNrW/pVCrcv/Uzdc2tpqy6J2UStY6/ZWIYhWrCgBPwIJCmGRLZAMS1hDMknInsx9z++ZucMkTCBAAmQ4Xz/jzNx7596ZkPnlnN9znvMQCYIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgnFc0ukSwZWTaaqpMM3WNUk2k23Uip+7Ss2rXZc0jQRAuWgJWpMJGZma6XOSs+TYr25w2aU60OXjWlJRkGpXYmb4/4qSXVm92kKaPtVjIWVlJ9iCdbI0aOevXZeWRIAgXDQEpUkqgNG0xufTpusk0dHBn26w3b0ijhKNOOtizC414/WN88DyOpmxR5hB7tDlUvW5feaVximxq1J+BwJEgCBeUgBQpS9rEwoevHGx/afWWhYlRYdM+HD+Suvzrv2R+YBKlffgVpZtM9KOYKErpEkMsUkRWM1WEWWhbaBB9sKWQPtu1j8pr64l0bXZN7qJnSBCEC0YQdXAs6Zn24B4DbA37tzs9zzNu7JM464pucSw2++3PpqdYrli0ioISOtO/GxvpwdXf0+2HnZSw9wgFb9tDpVsdtKGmjlZZQ6iWNfuyeBv1jI6gfWWVVF5XlxHcbcDKhgPbHca5g7sPXBCcyNs81xMEoX0xUQenZm2Wg1zabIiV2uCiDERIPRpdCBNt4w4cI72kgig2kq74+Bu13SA4JYmO/uR6umpoH5p2tJwmbi6g67Y4aFZkOC2aPI4So8JZxrWnvS9oJDtvy9B1bYP3eoIgtCsBke4hwuHUbAGMcBap2X/u13PqDVYLjdqxhzY6K5VIaZzS6dW13tfgudY9jly7ivyeM2hwEh3+QTpN/28OG+2lDp20PNL1jC+n3mR7ac1mWpa/P7smZ/FYEgShXQkYT8o8cmJpJ1uks7SswvF0eFjGtOIyur9HHP11UyGdLRAx8z030+clTpX+IUJLNwXRWlcjTfrgS7JY9RhndpakfYLQjnT4dM9AM+nz7r1tnM0WGZ6x5Wipip6mHS0jp0k7SUTKTRrNi7TSLV2iT3nO42ym1775KV23bgfdc7yWLv94NTUsy6UrE+PV/qpqbUzz15jTbp8pqaAgtB3BFCDU1NDcDTt2z/z7Ew/SI8/Op63HayjtYAl22YxjtoYE0XPRYUTDU2hbwT4ysVjRkbIWzxlRVUNL0gbQ1ys2UPoWd0RW1DmaDi5bqx4HkT7WMjxTnUDXaKhm0jKjzEEZFbWNvXnTLBIE4ZwJqBIEc1rm3P/+5bmZZRVVdN8jv6d3i8tpUH2j2geBun9wMj3xsym05Ks1NOvOCfSj+5+kvIOlpzxn0MgBdOQHo2jL0RIqr6mnKEsIoa4KNVWreYRw9b7D3voqRFjPjr2crvvnZ06NtCy1UXft4XA1LzSMsiU1FIQzJ6BECgb66GEpKx6/bzJx2sci9AS94jjkTKlrtI3uaqN33nqJFn+1mu6//UZatf57enTumzTiSCm9WFpJUbpO+4Pd2W+PBleT82qdIpWRrlnYfK+p9RjxoRQ8OpVM7FsZwJhHKtn/5Q9beovZbL4vrMnNeosEQWgVAZPugZq1WdmrdC37caKMnl270JiMdLp7Va5tBHtUaTdcQz3i42igvQe5WJB++8YHtPaff6K3P11BP3/1X/RecQWrDBHEbGZ5NU3ndBHCBSBKDSs3nnS9htztSsC0TlFKoIIS4mjZkCTqn9STFr3yO3XM9t176cCRo/Tlmm8pd/O2jAOHizMsaRNnYyRSlU90AAoLC5EyT9V5dJNvdk3TnHzvcLlcb/Xt2zebBKEd6fDFnM0J7jFw9t6DR2xdY21038QbqKyiko7FRNEj035IURFhNGpIf5r54us09orBNGbkEH4+gL4rLaOwLbsoyqXTR11jnZ3HX2l58dBh9dxIF32BMAWnJFNV+kBaWVdP2fuPUmeTiXZelUJPr91CkckpVGLuRAcrasgWHUVDkhPphqtHUOb4a8gSGkobdhbYXA2Ns4K7D6KGom0rfc+NaLBhv7t49GKABcrOYrSGRWkKPx3At658s/MtlcVq2syZM6Pnz5//OQlCOxFQIqXqpUibVXa8im4dk0afrMqlz1Z/R3/41b0qigJ19Q20ZtN2mnXXRPUYN1tUJH3w+SqV5u2+fKDlb0/OoOs58lqq6fTGviJKr2tQgqXSQQ6uzBw1uQ4UU8jhUup/5WDqftvV9FG4mZ5igXLFxNPga2+m0up62uespk0Hy2llwTFyVteRPS6SRl+eQj36DaLV6/Kovq4mw1eo1Kigri1uKNp+UXRm8AjUCnKLUkuMEqES2pOA8qSsaZMW33lzRmavbl1oeU4epXOUNG3CeIoKD2t+KAxs76jf9sJ99OxPf6PSu7QZd9P0zOvV9pCgIFqd9z39ds4C+v3mXapa/eedIlRqCO8JwgUQWWFeYFGQiSZ9sJxCeg+i6M7xZI2MVvchZov3wlfZO9G4Pp3ps+/30x//PJ/Kiw+jfmJazdqP3mKRms0i9fTFUn+1e/dujFDOacWhenl5eadhw4bJwEALFBUVUXV1dSZHpKkmk6kXb7JxJKp+B5E687Zsfriyd+/eDhKaEDAi5YlCCte+/Sea987H9PyMqad9TRiP0lXV1tGCrC9oa+FeSh88gG4fd1WTY6x8THnFcTUS+OqmfLqfBQl+FUQK9wYQKsvDU2g/R10QKp+OChQdF09JqSMoceAQ9TzGGkI/TetFC9bsovf+/ipVVpQ5rVa9d021toF329m2z6zLWbyEzoH8/PwM/hJk8i//UN/tHBltDAoKmtuaL8OuXbs28DlS6fTofN6H2J+aS8JJsAiRw+HozT+jgtMcWsrH3tOnT58sErwETDGnwdC+vWn8qGHe5/wlo9CQYFrLKd68d5ZQeWWVdx8EKNJq4chpPL3IKWFzgQLVLGJd4zrRS0/PoAXhFop0ueiL+Bjaz1FTDjooeIC5Xvfel5QYHU4LJo52z/vzUMbR0obln9Dyt16lqnKnSgVfz9lDY/olUOr4W9QcQ0Og1HsmvTedBTC4+fZ0QUHBChanFfzZZ3rMbu8N2/jLsoGPO62KG3/pWwH+2LX2WKFlYvhn/uaGDRvkZ+lDwIgURsr4D5Zz1fotdFlyL7UNAhVhMdNLCz+iP7z6okr7YiIjmryupKxciVVzgkwnfjSVNbXKS/qWDfAhLILVKf2onM89N9KdxhmlC42bC6j+81xK6RyjJij/7IoBNDkliW7s20Ptryovo9WL36H62holVOuLnNTD3pviuvfEbnuI2ex+39Q0+jkVHmGaCWFi8Snl22yI0WleZuPj5sJzIuFiwxYREdGa6PWSIaAiKY5Alny9/nvqk9hNPY8Ot9Lb/1lBBd9/TDmPB9Guwp0UGXbCHwoNDqKlq3LUcb6iBBCiR3m21ze4R/hs3ePJzFHabWNG0Ld9EqnvpOvdEVVoiDeqql+WyxHVcup+vJqeSb+M5t2YTjcl9/CeF0KFqAoUlFSRld9Dv7Rr1POuSf09R7nsdBqMqInFphCC0wphao6tsbHxdFXxre1SCnMum4Q2gf+42knwEmjpnmPjzkLlNcVGRZCJo51F/1lMtw7V6JF/N1Ifex+a//ZH6kCkgBgFXLpynTrOFnHCXMdzfOsqeRSvE6dtOBaMvvwyTgunU6+u8fTg5FtoaD+7EqcPw0K9URVo3FxIdYu/VingvrLjaFXc5E0eKthJxUV71GNEVHHde6loqv/IaygsEvMJNfupPiSLUypSNkRNdG5p1phT7eTzt3aU0SH1UkJ7EViRlGYa2qube/Lvd9t20WPzFtCwQYOJev6Cel32E6qtrqRrRw1X+yFkX2/YouqogJmFKNziTrdQ7BnFXhXunRVVFOMRsCfum6zubx0zkh6ccgtFR0QogTKPSqUdcTaVAhqE3DhSVaPPXJbTxEQ3OLR7Z5PnI27+IYVFRTcZCfSHpyxgMZ26LKBVnM5zgvDwtU7XmbSU/a9rSRDaiYASKRYV+62citU3NpK9e1caPqgfPXTP3TSCR+3GXT2S7v/xJOrRtbMSKNw27nSQ8/gJAUEqqHmEBqN+ECeca+/hYr/X69WtMx2yd6fXnpxBD3BktSDCJ5rK3UauomKad1O615Py5VDhCZFCrZZuckdrhi/VEpyiZVAbCFRrYaGCxzWdHzqa7+PtMOgvl2FzoT0JGJFCCQLrSyoM7kZP983MselubykiXN0gQPCYDF/qX5+uYCPc7j0H0rwwj4kOcXJ5fKng4GD6R9YXJ10T18LUGtRlzfARKUyR0VnrtoYG0aT3l6NB3kmvhTcFIFCOA8XelPJ08GeYQOcZHhJfmJSU1JsFaRhHVmNx48cxvP1aESihvQmcSKqRMuAZgVr+4m/YvosaXCcmCkN8MNIXFx2hhOr5Nz6gPQePqInGzooT0ZQl9ERZQUVVjXoNtg3u15tefm/pSZfFRGYQzfdDhw/2Guil3+6gAVv3qkiqJSqcpbR73xEljkb1e31tLZ0KFt0yugBA4FmQ8pAC4saPpXBTOC8EzARjzWSa8JOb3d18N+UXUomznGrq6tVziAxG8PBFgyD9/PmXacW3W+i++39BCxe8Sa9+8Ak97vGb4E3hOERgjSxySPtgqidymrho+TeEEgdEUP6Akb71q1xKq61XI37Xf55L6Q9PUS1c0NLFHxCm+NgoKmXfKi4mSpUnsBQ5WvqcqE7WtPNfg+spSFQeVlsKFM6bn5+fGhISMoZTWURrvTCJmZoOCDgxqdlTiFpYX1+/sl+/fu22PqLns9r54QS+JuYo2lAp7u/98Pasth40wL8vRm/5c6IYFxXqQz0/E2O/g5+r6/PT7EAftAiUHueq2nz74r+pFA6dDTZ/+CqVwLDmX7gdjn0c6UQosbnh/z1F9Sw+E6b8hIpcYZT76YdUfaSIDi1/23u+Yh6Rq2toUI8RdcWzeByvqaX9R47R3b95iXL/9We/7wPXXfPYi2pSss7//bCqjoJHD6UvB9tpetbXJx0/buoDlH+wjAYmJaiUr1+vrvTxy+ieoGfX5GT57Z/uMc5R+OnX9OZf3my+28O/yKcvuWefKTk5ucXC0V27dmV6zoMvqL35a/mWzV+gZ8405ePPQA0NDRn8Wpw7k85uhNJxttf3h48Io9h1Gp2Z71foeR9vneLcrak4N3Cc4fUxrQazCAJyNe6ASPd03TQTURRStx5sZqOxHVKoysoqJVBIySY/+gINmHg/Wa1Weu7J/68ECnRL6kdlbJ5vzD/RCz046MSPBdEU0kekfSgEvXbkUFq6Klf5VYiymqNaE0dZvWnfZ+u20f6yKr/vG+eOiQ5XURTEtKz4kNrOfzk2tvRZ8YXkX/pfNf38Or6sszw+0Vh+vpDaAE/0ABGx+9mNbdPwxcMUHGoFECcc6zHcMXF5Gp19CYXduD7qxegsgYAgamERMWrOZtOZD0xAgBbu3r37z9Q22OnMwB+uuXz9gp07dwZcIWiHFyl0PrB36zzrdR5hy997gL/wFfSjcVcrkXp32UrVNyqaTXMjnXvm4Qdo1d4K9RhTVHbkuCOcr7/7XgmP7ukh5UtFtXuOHnytSeOuolfeX6rOX1VT500pAdJMiFPsgCT6KMys+qhHson/2nfb/b53LdSq6rBKyirJYgml8qNH1PZG0lbQKYCRzV/y3r7ChL+iF8gn0jgFe+pUB3iEIMYQp7MoPD3l9SEs/AVddKbTSXwinLaoOQOzPJOyLxS9+d9ifWumPHUkOn4k5aIMjNAhHevbK4HGDh+ifKW9h44qY3wIG95LV+ZyqhdOsZ060X8claqAEgK1etE7VFXh9qERSRnC09hMqFSJAG8Lt5pVy5eCokPK27KwIDmPV6mKdDzHdTJ/PIGW/eU5uosjO0RUz9vC/dZJYdIxRvRKWaBw/gg+t1Hgqbv0Paf72IioLqAwNaGZX9N8nyEE69tYnJozMTo6elFrD/a8L4xWrqe2K+mAffIUXVgg2gsCKaIKiHSvmE3y8spqGpHSX00wBoigMNqHynDUQu05dJhCbHFKoACmphgCBTbnO9Q9UriGhpMb3UEEIWJo35KWMoDPd0Q9RvRVwgIVycY8yhFQkY708sVZ96h79Fb3hzXKvVJNiUfAIsIsdGz/Xjx01K/LyrNlZNo60KozLUYgBw4c0NgQRzpmp3aGhWcsRzKzW3GcIZxfUdtPjLZdBHMieRzJ9CYFCB1fpEyUjSZ22wr2UpwtSm1C2oVYCNXnEKvbxozkFO1T6sr+E0CKd6xob5PTGGUILs+oXnMQYYGQ4CDqztHUXo7SDO8Kx0Nson2m1qAk4Tf33kEtEZuYpMoPgJUjsuqyYo9oatkQJ3RFsFioQw/zQwzq6ursrTTx24pfnirt8whUTDsJlMLJ0AUGLXZYLM97TV17EAjLrGeTpj9z//Ov0Ls8uvbInDfVCN5eVQO1RXlRECikfpgjV7x/D+3IPXmkDfsBBMffED+2GxEWuinA5/IFxZ/lVTVNts2Ycitd00K5QgWFqTQPxERHUEHeOvVYJx7WdqFti+64kI3vYHKfKywGGMWz0/klJioqqkVfCO+JBWomtVNkxyKYd5E0/9P4vcykACAg6qRYqGbvHZmZ99i8BegiaUc7lT/+6l76ZGUOpd/9a6rTgunKSXeqKSd5ng4EvsBn2n+4WI3iAXhFtT6GuAH2w68azB4YaqWaj+6hpQtqssw+1eOvP/mgeg++BaOhETGkmX2irggrbeRUT0f9DWlz4Gzw43NqeteBwSIPb7GQqDqokJCQaE4Xh51JNMbHjva33Ujz+OHZjAZCeLI4jcqrr68v87wvnGsoXy/DuAQb121VBnDSz4EfZ5B7tLVVnMor7EgETDFnXW5WFqVmZnOKlLlxZ+Gc9Lseso0YPJCuvekWaohPVsdsWfVFEx/K4J3fP0p3P/6SEh34TC1R29Cgoqmrhw1SzyFKzYGR3sUW6Y3GMGXmtScepDse+4P3mMheA7yPYcYf3rVVvS/NJ/3gwC2bLi34O6VP8teV0iMu81qborVk0Hsiu6km0xklEOjR9WxLXUeNwk/MqeTHtuTk5LZYrmwOn+eh5hs5up3H7x9TkjBA0JpU1QYDvT0LX88HgdWqJU+lRw50Xrkr8waaM/sRirS7BQGjeQUb1530EnTjRCTVNS5GdeEMs4RidM3v6VFugLTPHByspszU+zHYsf94M/HCohBGCQSwdIr3Pu4aF037tm1Sj91tWhTKPKdLDI5C/H5mCH5wcHAeIgtqJf7Ma45GNE8BaatPgwnUp2qL7Jku5EBZSBu1T4ZYb/K3g6+Dn8OKM2ihg8/cizo4Adc+GAsZJLDo3DXhRvrGUeIdzUO5gT/uuP4aMnOKNiipp6ouR6pnVJu3BETIqJ0ywMif0eoFfaia11vd5ZmyE56QRMFWd3fQUB75qyk5rNoLp4weT/09ze900gOycvhcMJvNumcayFmBfw9O0/xVzrf4Er7ePRfpBOqVrT2QI7wY6uAElEi5l7SijOvSr1C9mSBSAJGKvzQPEdS4tFQK5RQPq8qgqtxfdNQcf6N/Lo8oRXr6UDWPpjDKCCISkr3bErvGYlkrNT2m1+Dh3sJS1rssEtqUAwcO4AtrP4OXLLwY58TZ7XZEUw66hAisSMqlTcPdXZk30vL8o97Nxpe/OePThymTG9FT74R45Q9VNBuhOxPgUSFdhFAhmjLAyCHm9Vli4lWqh+tgnh5qo7rY+1It6+KBHZuNEoSFHWVl445EXV0doqnW9o7XOc27VAcuLjoCqp8UO89TM8ddo6Ko9UXuyKmlKArcdPVwleJBqNDCBca5vygJZnrulh30xZr1p30fpWyco18VFncwRguNKCpx2FWUnNiF+vSMJyuL2XEWREfRUSWSXiHVTtsJsy3R6RIhNDRUO5Pe4U6ns9UpldC+BFIkNQ3/yxw3ukkUZZjS/hjs0/AOKRoiIURBKNiEIYrH+Y599Ni8N5WnceNVw1WJwalapaD2CeKE1jDAiKKw5t7AywYocTpaUkG79x1WxZxxMZHe0T2Joi4eZKHTi4eAKUFgw3wqDPM+fZNpUfYutQldBYqbVZYbwCiPjYpUjxE9IQLqFBnujn7qSJUR/PXfn9KCJcvpnRceo26xMUq8UGLgCyKx5tEXTHVzSISK0NB9AZi7D6BtBQe8BZwgPjaaQlx1FyqKEoQOQUBEUuFXZqpRm+tGXdEkijKquP0R6VmuCgKD/lHocIDniKjQmeDdz1bSvHeX0l+fmEHdO3dSkZE/vwoeVPPIyoimXvlgKW3Md5AteQjVm0KbCBR8KZQfoPpdRVG6/oxEUYJwMgEhUjwgl4H7MVeO8npRwDNh9yRQG4X5d8CY4Gv0Nsc9qs/hI/3yxxOoX88ElfZBzHwjJq8wsauzNHvNSdfYWriPz/G/FGwJp+jkIU32ofSgZ7dYlYru27YZRZx5NblZs0loN1zuf7tWp3CB2JepoxIQIqWRNiEyPIz2u6zebZij11LZAcRnUO+eKi3DnDtEQwaod8KCofCS0gb39y7aoGqogt3ZMQTKWLQBkVddfT3lbD7RMwpLud/xyO/UVJj4EeObXD/IpLF5Hk8N1ceNNM+ha/pEEtqVsLAwnf/dTtsCxwN6ZLV6+onQvgRIZ05KxRSYwpITfhEW4PQHBApCNX7UMCU8WEQUkRJAZ8+fPfcyPTJngYq2knp0bbKyMUYAcTz8KoARPIjVNcNSeORvg/e45197j6OxYyrNMwo3DRI5gtJcDSd6WWn6dEnz2p/y8nIy5sG1kl+eaRM9oX3o8MY5/CgOhmwR8T281eWgvLjpwgeIimbeOYHvB6iIaCiP7MHYRrTz+qJltHRljhIpdDjAcQ/ffbtXvHzBa+A3qd5SbKSjXQv6RuVs3qH2z39nCX20/BtVWd48zYNRjnYu6Kvu9aFyslRrFr2RJmg6baz5NiubhDYHRZAOhyOPhQopX2vEJyYyMvIrFqprZaTvwtLhRYr1ws4ZFFWaowjNU5DmuZcxd/tRzcUJ6duh4hJ6f1m2V5iM41586F6aOHYUJcTFeD0nlB74GuPwpTDCB7GCUKE8HKkhUjyI07x3lygfqlP/4U3eJwQKRjma7bmjPG0hwihL2sQV7GtlcMCWV52zeBgJ7QL+DXft2oVVXrKplZ0E+NhhUVFR6/Pz8+9pqfrcZwEHNScwUBdDuJB0eJHi3z077ht49AxdDjCJ2IiGJl3nnjwM7wji9E3eNjaz328iTE/9/Md05w8y3A3zdHQj1slZWa26HWDdPvwSopgzKMg98odpMxAnw6sCWJgBIM2DQMGHMoWc8LlieLTQEKgTdVv6NJ+1esSXOg+wz6Q3NDTMN5lMZ+I3oZf8ioKCguzGxsaVWFLM2IH2KYWFhZmeligQKh2LOrBQSSlJGxIIdVJ2/A/iBAGYnjle+U4QKkOc4Cu9/elX7De9QoOSEumJn/4P3T7+KnWMscaeUf+E54iSUHQJcTJxmIbSA2NVZLXIqNXs9aqM3uYYETQFh1C3UTc38aGslhD2sKxNBCos0kYsSlRdXgY/zamZ9LFt7EsFxFJlbQ26CLCIQGyyfXpAtQq0f2GxavIa18mzE9Bf/GmOvFYG+lp455OOH0np/BdMc1eWP/mz/1EThZHWoZGc0RsK6RgECnP1/vn8r1XNUwmLElqyIEJS3hKLTrDnvjmdIsNbvP5v/+FeCRkChQjKV6BQamBP6MwjeZWUOHAw9R95NYWYLap1MXwpwH/cp1etaTuB8qxpR4J/2JvSOT17yLMAQ3uByCqbhDYhcCrOGSVQmIcX5RYKRDlYnfjjle507Olf3KkWCEXahs6bCbHnNniDpdpfef8Tr0CFRnZqsr+xUff2MefkgOLCTKQdPcxRlWe5dk0JlHQ8OI8gUj527NgGp9OJpnJttU5ek0tQO/VOv1QJKJGCeW1MdUF0g17nRu9yTIPpl5igHmMicainxS+ExpgAjFE6LI+F9sMPTrlFddX0hzsye1l5W/CgOg8bc5JAAaMAFLVRCV060fEDu0+0L3aXHiykNsYziuXwk4qcEeHh4Zhk29q6onansrJSLS9ObUBsbCwizjkccUZzCnfWC4u2ACZt+xsNbMsRwktqtDEQRMphPFiQ9YUyzOExbdrp8AoUgGeE9fJSknsqjwkpXnMQeUF4cHuFIzAsiYWFFIZ4lsnae+hIkxFBwyRvXgvlC6a/oLq8cP0aNQXG40FNVAtItB/n/EvcFqLgM+xP50pbia+Bx5+ajdS4jYXKGRwc3CQ6RvS2f/9+Z21trYPOcQEInGv37t34921tKUWHp+MXc+onRGrhki9UNIWGcxAYX7B95h//7l1x2GgR3Pw4XyBGiLImP/aCumElGkOg0BuquUnuizt6iqEEm5nWLX3fWKHGwQI1rD0FylMugSb+2XQO4EtstVqzyeePwIV6Lz7ncrTFuQzwGfv06TObRSqJn7ZFu2a0/n3IXzfP+vp6dPpsi/7nEFX9TFoId3Q6vEgFhZz45XqCjXOAkTise9c8XUPB5fz3lpI1NMQ7Dw+rvrS07FRLoJK8eZmBL2i/MjC5O5Xv2U4r3/+HMsp5DHGexaoEykHtDMxhHm6/51y/0N27d0fzt2vpHISqrd6L77mobQRF4elRjl7mWM0YPZ7PyiPE5+PXX4te5/72ezpqzjuTPu0t0Zbn6ggExFC1eeTEUiy+8O4Lj6qizfiYKFUicD17Ul+v39LkWJQdrP7nn8hqMaspLig3wGKiD89ZoI6FsJUdr6SeXbuo9M53KSqkd7EpVzZZSMEXpHbdOXqqLD6oIifPAqQOj/+UTecZT6FhKtrm+i5vhFofpHJY3KA1y7R7RgyxGordt3EczsNfbicLR/bpznOq9+I5R15r+4m35blaOLfNs/pLKp9rKD43uVMrI70yPmuep+96dmtLDnxWl0n1fe/8b1HqWSor+wx/Dn7Pxdv2nMvP4WIiIETKMjJzIf9JnAqRGjVkIHXt5F515Y5HX/AWWvqCOip4VzDPUV6AHwL+on7MftNtY9LUoqJfc1p3DaeCMN8xehfZayBF9RxwUvSEtA6Le3bm6Kn8cJFXnDze0zysCUiCIJw1gdGZ00QLfZ8aK7U88dPJasSuOYZ3hf5OWMYKFeaYjzd25FA6XFpOA5N60frtu1UqiNdj5A4pnq9AIWpK6GyjPj1iyVRxRPlOqxe/Q8X79zqxorI1TO8tAiUI505AiFRNDeUhctm6e5+qgTKWO1crGc+aftLxEKhtBe65fRjpg1gdKz/urixnrwrtW46VVaj9D0y+hWpKD5Or3r1aMebgpfTtQTZTDR3ekkMr3v4rrfvPRyeJ04VcIl0QAonAiKTyslRqNf/dJarUoNJnXTx4TP6McXc7lWJysv/kW6pgUOl5/QwWKYWziCOsBKo/uof++8YcFTVhKk59bU22TvosESdBaB8CZ45XaqbNHKqtSB/SP/XdFx5Tm0qc5fTrP71Orz05Q3lL5VE9OXWLUZFR2e6mCzQYPhXYylHWg7/7C21f/Df1HAb8pr1HKdhs9prhLExzrVZ6S0RJENqXwKk4RzSVnvmrnM07Vqi2KV98Q0tWrKY3nv6liqYQLcV3H6pG5tQtxt0dE3VOVUf3EaKwRV9+Q9NuG88RU6Ia1cMNntTQfnY18meY4RYLzYU41ZIgCO1NwM2WRzkCR1O2Q8Wl9PlfnlUCtXFnIaXf/Wuyj5tMuinE7+saK8uoZNOqJi2HIVDREeFK4NiKd1qtem+JnATh/BJQc/eARvoSjqamIlUzijk35TtU94GEyGCKiI0jXQv2FnOqFWIa66m6VCdb6kjanruKGmrdMVJpeaXTWXHcqeumPM3kmicCJQjnn4ATKVWOoNNUREAGmNrCBrcyu0EIe0shoe6mdfV1NbzvROKGlM6k6W/pGmXV5kgrX0G40ARkczS05J0x5ZaMP866R619h4UVSNPHsgAN5eHM3i7d1EvTdJuua05NY5+JXGW6i/IoiLJlUQRBuLgITJHCwgYubcOYKy6zuScEawtrchZNJ0EQOhwB22bWLVS0GJGSxUoTxU8SBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQLin+Dz5IwjUsPBVBAAAAAElFTkSuQmCC', }, -} +}; diff --git a/ui/app/pages/swaps/loading-swaps-quotes/loading-swaps-quotes.js b/ui/app/pages/swaps/loading-swaps-quotes/loading-swaps-quotes.js index 684466f27a..0a2359bae9 100644 --- a/ui/app/pages/swaps/loading-swaps-quotes/loading-swaps-quotes.js +++ b/ui/app/pages/swaps/loading-swaps-quotes/loading-swaps-quotes.js @@ -1,21 +1,21 @@ -import EventEmitter from 'events' -import React, { useState, useEffect, useRef, useContext } from 'react' -import { useDispatch, useSelector } from 'react-redux' -import PropTypes from 'prop-types' -import { shuffle } from 'lodash' -import { useHistory } from 'react-router-dom' -import classnames from 'classnames' +import EventEmitter from 'events'; +import React, { useState, useEffect, useRef, useContext } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import PropTypes from 'prop-types'; +import { shuffle } from 'lodash'; +import { useHistory } from 'react-router-dom'; +import classnames from 'classnames'; import { navigateBackToBuildQuote, getFetchParams, getQuotesFetchStartTime, -} from '../../../ducks/swaps/swaps' -import { I18nContext } from '../../../contexts/i18n' -import { MetaMetricsContext } from '../../../contexts/metametrics.new' -import Mascot from '../../../components/ui/mascot' -import SwapsFooter from '../swaps-footer' -import BackgroundAnimation from './background-animation' -import AggregatorLogo from './aggregator-logo' +} from '../../../ducks/swaps/swaps'; +import { I18nContext } from '../../../contexts/i18n'; +import { MetaMetricsContext } from '../../../contexts/metametrics.new'; +import Mascot from '../../../components/ui/mascot'; +import SwapsFooter from '../swaps-footer'; +import BackgroundAnimation from './background-animation'; +import AggregatorLogo from './aggregator-logo'; // These locations reference where we want the top-left corner of the logo div to appear in relation to the // centre point of the fox @@ -26,22 +26,23 @@ const AGGREGATOR_LOCATIONS = [ { x: 50, y: 0 }, { x: -135, y: 46 }, { x: 40, y: 46 }, -] +]; function getRandomLocations(numberOfLocations) { - const randomLocations = shuffle(AGGREGATOR_LOCATIONS) + const randomLocations = shuffle(AGGREGATOR_LOCATIONS); if (numberOfLocations <= AGGREGATOR_LOCATIONS.length) { - return randomLocations.slice(0, numberOfLocations) + return randomLocations.slice(0, numberOfLocations); } - const numberOfExtraLocations = numberOfLocations - AGGREGATOR_LOCATIONS.length - return [...randomLocations, ...getRandomLocations(numberOfExtraLocations)] + const numberOfExtraLocations = + numberOfLocations - AGGREGATOR_LOCATIONS.length; + return [...randomLocations, ...getRandomLocations(numberOfExtraLocations)]; } function getMascotTarget(aggregatorName, centerPoint, aggregatorLocationMap) { - const location = aggregatorLocationMap[aggregatorName] + const location = aggregatorLocationMap[aggregatorName]; if (!location || !centerPoint) { - return centerPoint ?? {} + return centerPoint ?? {}; } // The aggregator logos are 94px x 40px. For the fox to look at the center of each logo, the target needs to be @@ -50,7 +51,7 @@ function getMascotTarget(aggregatorName, centerPoint, aggregatorLocationMap) { return { x: location.x + centerPoint.x + 47, y: location.y + centerPoint.y + 20, - } + }; } export default function LoadingSwapsQuotes({ @@ -58,14 +59,14 @@ export default function LoadingSwapsQuotes({ loadingComplete, onDone, }) { - const t = useContext(I18nContext) - const metaMetricsEvent = useContext(MetaMetricsContext) - const dispatch = useDispatch() - const history = useHistory() - const animationEventEmitter = useRef(new EventEmitter()) - - const fetchParams = useSelector(getFetchParams) - const quotesFetchStartTime = useSelector(getQuotesFetchStartTime) + const t = useContext(I18nContext); + const metaMetricsEvent = useContext(MetaMetricsContext); + const dispatch = useDispatch(); + const history = useHistory(); + const animationEventEmitter = useRef(new EventEmitter()); + + const fetchParams = useSelector(getFetchParams); + const quotesFetchStartTime = useSelector(getQuotesFetchStartTime); const quotesRequestCancelledEventConfig = { event: 'Quotes Request Cancelled', category: 'swaps', @@ -78,34 +79,34 @@ export default function LoadingSwapsQuotes({ custom_slippage: fetchParams?.slippage !== 2, response_time: Date.now() - quotesFetchStartTime, }, - } + }; const [aggregatorNames] = useState(() => shuffle(Object.keys(aggregatorMetadata)), - ) - const numberOfQuotes = aggregatorNames.length - const mascotContainer = useRef() - const currentMascotContainer = mascotContainer.current + ); + const numberOfQuotes = aggregatorNames.length; + const mascotContainer = useRef(); + const currentMascotContainer = mascotContainer.current; - const [quoteCount, updateQuoteCount] = useState(0) + const [quoteCount, updateQuoteCount] = useState(0); // is an array of randomized items from AGGREGATOR_LOCATIONS, containing // numberOfQuotes number of items it is randomized so that the order in // which the fox looks at locations is random const [aggregatorLocations] = useState(() => getRandomLocations(numberOfQuotes), - ) + ); const _aggregatorLocationMap = aggregatorNames.reduce( (nameLocationMap, name, index) => ({ ...nameLocationMap, [name]: aggregatorLocations[index], }), {}, - ) - const [aggregatorLocationMap] = useState(_aggregatorLocationMap) - const [midPointTarget, setMidpointTarget] = useState(null) + ); + const [aggregatorLocationMap] = useState(_aggregatorLocationMap); + const [midPointTarget, setMidpointTarget] = useState(null); useEffect(() => { - let timeoutLength + let timeoutLength; // The below logic simulates a sequential loading of the aggregator quotes, even though we are fetching them all with a single call. // This is to give the user a sense of progress. The callback passed to `setTimeout` updates the quoteCount and therefore causes @@ -114,27 +115,27 @@ export default function LoadingSwapsQuotes({ // If loading is complete and all logos + aggregator names have been shown, give the user 1.2 seconds to read the // "Finalizing message" and prepare for the screen change if (quoteCount === numberOfQuotes && loadingComplete) { - timeoutLength = 1200 + timeoutLength = 1200; } else if (loadingComplete) { // If loading is complete, but the quoteCount is not, we quickly display the remaining logos/names/fox looks. 0.5s each - timeoutLength = 500 + timeoutLength = 500; } else { // If loading is not complete, we display remaining logos/names/fox looks at random intervals between 0.5s and 2s, to simulate the // sort of loading a user would experience in most async scenarios - timeoutLength = 500 + Math.floor(Math.random() * 1500) + timeoutLength = 500 + Math.floor(Math.random() * 1500); } const quoteCountTimeout = setTimeout(() => { if (quoteCount < numberOfQuotes) { - updateQuoteCount(quoteCount + 1) + updateQuoteCount(quoteCount + 1); } else if (quoteCount === numberOfQuotes && loadingComplete) { - onDone() + onDone(); } - }, timeoutLength) + }, timeoutLength); return function cleanup() { - clearTimeout(quoteCountTimeout) - } - }, [quoteCount, loadingComplete, onDone, numberOfQuotes]) + clearTimeout(quoteCountTimeout); + }; + }, [quoteCount, loadingComplete, onDone, numberOfQuotes]); useEffect(() => { if (currentMascotContainer) { @@ -143,11 +144,11 @@ export default function LoadingSwapsQuotes({ left, width, height, - } = currentMascotContainer.getBoundingClientRect() - const center = { x: left + width / 2, y: top + height / 2 } - setMidpointTarget(center) + } = currentMascotContainer.getBoundingClientRect(); + const center = { x: left + width / 2, y: top + height / 2 }; + setMidpointTarget(center); } - }, [currentMascotContainer]) + }, [currentMascotContainer]); return (
    @@ -226,13 +227,13 @@ export default function LoadingSwapsQuotes({ { - metaMetricsEvent(quotesRequestCancelledEventConfig) - await dispatch(navigateBackToBuildQuote(history)) + metaMetricsEvent(quotesRequestCancelledEventConfig); + await dispatch(navigateBackToBuildQuote(history)); }} hideCancel />
    - ) + ); } LoadingSwapsQuotes.propTypes = { @@ -244,4 +245,4 @@ LoadingSwapsQuotes.propTypes = { icon: PropTypes.string, }), ), -} +}; diff --git a/ui/app/pages/swaps/main-quote-summary/index.js b/ui/app/pages/swaps/main-quote-summary/index.js index 47c9cd3cb1..235070e293 100644 --- a/ui/app/pages/swaps/main-quote-summary/index.js +++ b/ui/app/pages/swaps/main-quote-summary/index.js @@ -1 +1 @@ -export { default } from './main-quote-summary' +export { default } from './main-quote-summary'; diff --git a/ui/app/pages/swaps/main-quote-summary/main-quote-summary.js b/ui/app/pages/swaps/main-quote-summary/main-quote-summary.js index 20aadf6fc4..9257c53e36 100644 --- a/ui/app/pages/swaps/main-quote-summary/main-quote-summary.js +++ b/ui/app/pages/swaps/main-quote-summary/main-quote-summary.js @@ -1,21 +1,21 @@ -import React from 'react' -import PropTypes from 'prop-types' -import BigNumber from 'bignumber.js' -import { calcTokenAmount } from '../../../helpers/utils/token-util' -import { toPrecisionWithoutTrailingZeros } from '../../../helpers/utils/util' -import Tooltip from '../../../components/ui/tooltip' -import UrlIcon from '../../../components/ui/url-icon' -import ExchangeRateDisplay from '../exchange-rate-display' -import { formatSwapsValueForDisplay } from '../swaps.util' +import React from 'react'; +import PropTypes from 'prop-types'; +import BigNumber from 'bignumber.js'; +import { calcTokenAmount } from '../../../helpers/utils/token-util'; +import { toPrecisionWithoutTrailingZeros } from '../../../helpers/utils/util'; +import Tooltip from '../../../components/ui/tooltip'; +import UrlIcon from '../../../components/ui/url-icon'; +import ExchangeRateDisplay from '../exchange-rate-display'; +import { formatSwapsValueForDisplay } from '../swaps.util'; function getFontSizesAndLineHeights(fontSizeScore) { if (fontSizeScore <= 9) { - return [60, 48] + return [60, 48]; } if (fontSizeScore <= 13) { - return [40, 32] + return [40, 32]; } - return [26, 15] + return [26, 15]; } export default function MainQuoteSummary({ @@ -31,21 +31,21 @@ export default function MainQuoteSummary({ const sourceAmount = toPrecisionWithoutTrailingZeros( calcTokenAmount(sourceValue, sourceDecimals).toString(10), 12, - ) + ); const destinationAmount = calcTokenAmount( destinationValue, destinationDecimals, - ) + ); - const amountToDisplay = formatSwapsValueForDisplay(destinationAmount) - const amountDigitLength = amountToDisplay.match(/\d+/gu).join('').length + const amountToDisplay = formatSwapsValueForDisplay(destinationAmount); + const amountDigitLength = amountToDisplay.match(/\d+/gu).join('').length; const [numberFontSize, lineHeight] = getFontSizesAndLineHeights( amountDigitLength, - ) - let ellipsedAmountToDisplay = amountToDisplay + ); + let ellipsedAmountToDisplay = amountToDisplay; if (amountDigitLength > 20) { - ellipsedAmountToDisplay = `${amountToDisplay.slice(0, 20)}...` + ellipsedAmountToDisplay = `${amountToDisplay.slice(0, 20)}...`; } return ( @@ -122,7 +122,7 @@ export default function MainQuoteSummary({ - ) + ); } MainQuoteSummary.propTypes = { @@ -143,4 +143,4 @@ MainQuoteSummary.propTypes = { destinationSymbol: PropTypes.string.isRequired, sourceIconUrl: PropTypes.string, destinationIconUrl: PropTypes.string, -} +}; diff --git a/ui/app/pages/swaps/main-quote-summary/main-quote-summary.stories.js b/ui/app/pages/swaps/main-quote-summary/main-quote-summary.stories.js index 0f5ca998d2..487034ed46 100644 --- a/ui/app/pages/swaps/main-quote-summary/main-quote-summary.stories.js +++ b/ui/app/pages/swaps/main-quote-summary/main-quote-summary.stories.js @@ -1,10 +1,10 @@ -import React from 'react' -import { text, number } from '@storybook/addon-knobs' -import MainQuoteSummary from './main-quote-summary' +import React from 'react'; +import { text, number } from '@storybook/addon-knobs'; +import MainQuoteSummary from './main-quote-summary'; export default { title: 'MainQuoteSummary', -} +}; export const BestQuote = () => { return ( @@ -27,5 +27,5 @@ export const BestQuote = () => { destinationIconUrl=".storybook/images/sai.svg" /> - ) -} + ); +}; diff --git a/ui/app/pages/swaps/main-quote-summary/quote-backdrop.js b/ui/app/pages/swaps/main-quote-summary/quote-backdrop.js index bb2653a62e..77bd75fd68 100644 --- a/ui/app/pages/swaps/main-quote-summary/quote-backdrop.js +++ b/ui/app/pages/swaps/main-quote-summary/quote-backdrop.js @@ -1,5 +1,5 @@ -import React from 'react' -import PropTypes from 'prop-types' +import React from 'react'; +import PropTypes from 'prop-types'; export default function QuotesBackdrop({ withTopTab }) { return ( @@ -80,9 +80,9 @@ export default function QuotesBackdrop({ withTopTab }) { - ) + ); } QuotesBackdrop.propTypes = { withTopTab: PropTypes.bool, -} +}; diff --git a/ui/app/pages/swaps/searchable-item-list/index.js b/ui/app/pages/swaps/searchable-item-list/index.js index 2a15a8de3b..981085f9ad 100644 --- a/ui/app/pages/swaps/searchable-item-list/index.js +++ b/ui/app/pages/swaps/searchable-item-list/index.js @@ -1 +1 @@ -export { default } from './searchable-item-list' +export { default } from './searchable-item-list'; diff --git a/ui/app/pages/swaps/searchable-item-list/item-list/index.js b/ui/app/pages/swaps/searchable-item-list/item-list/index.js index 420fdc9e57..36306eb32d 100644 --- a/ui/app/pages/swaps/searchable-item-list/item-list/index.js +++ b/ui/app/pages/swaps/searchable-item-list/item-list/index.js @@ -1 +1 @@ -export { default } from './item-list.component' +export { default } from './item-list.component'; diff --git a/ui/app/pages/swaps/searchable-item-list/item-list/item-list.component.js b/ui/app/pages/swaps/searchable-item-list/item-list/item-list.component.js index 4ef6aeeb5f..0601c72423 100644 --- a/ui/app/pages/swaps/searchable-item-list/item-list/item-list.component.js +++ b/ui/app/pages/swaps/searchable-item-list/item-list/item-list.component.js @@ -1,8 +1,8 @@ -import React from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import Identicon from '../../../../components/ui/identicon' -import UrlIcon from '../../../../components/ui/url-icon' +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import Identicon from '../../../../components/ui/identicon'; +import UrlIcon from '../../../../components/ui/url-icon'; export default function ItemList({ results = [], @@ -32,10 +32,10 @@ export default function ItemList({ > {results.slice(0, maxListItems).map((result, i) => { if (hideItemIf?.(result)) { - return null + return null; } - const onClick = () => onClickItem?.(result) + const onClick = () => onClickItem?.(result); const { iconUrl, identiconAddress, @@ -46,7 +46,7 @@ export default function ItemList({ rightPrimaryLabel, rightSecondaryLabel, IconComponent, - } = result + } = result; return (
    - ) + ); })} - ) + ); } ItemList.propTypes = { @@ -127,4 +127,4 @@ ItemList.propTypes = { hideRightLabels: PropTypes.bool, hideItemIf: PropTypes.func, listContainerClassName: PropTypes.string, -} +}; diff --git a/ui/app/pages/swaps/searchable-item-list/list-item-search/index.js b/ui/app/pages/swaps/searchable-item-list/list-item-search/index.js index cfa646b5ae..6f816c391e 100644 --- a/ui/app/pages/swaps/searchable-item-list/list-item-search/index.js +++ b/ui/app/pages/swaps/searchable-item-list/list-item-search/index.js @@ -1 +1 @@ -export { default } from './list-item-search.component' +export { default } from './list-item-search.component'; diff --git a/ui/app/pages/swaps/searchable-item-list/list-item-search/list-item-search.component.js b/ui/app/pages/swaps/searchable-item-list/list-item-search/list-item-search.component.js index d73e3a9b96..e9e322f40e 100644 --- a/ui/app/pages/swaps/searchable-item-list/list-item-search/list-item-search.component.js +++ b/ui/app/pages/swaps/searchable-item-list/list-item-search/list-item-search.component.js @@ -1,15 +1,15 @@ -import React, { useState, useEffect, useRef } from 'react' -import PropTypes from 'prop-types' -import Fuse from 'fuse.js' -import InputAdornment from '@material-ui/core/InputAdornment' -import TextField from '../../../../components/ui/text-field' -import { usePrevious } from '../../../../hooks/usePrevious' +import React, { useState, useEffect, useRef } from 'react'; +import PropTypes from 'prop-types'; +import Fuse from 'fuse.js'; +import InputAdornment from '@material-ui/core/InputAdornment'; +import TextField from '../../../../components/ui/text-field'; +import { usePrevious } from '../../../../hooks/usePrevious'; const renderAdornment = () => ( -) +); export default function ListItemSearch({ onSearch, @@ -19,18 +19,18 @@ export default function ListItemSearch({ searchPlaceholderText, defaultToAll, }) { - const fuseRef = useRef() - const [searchQuery, setSearchQuery] = useState('') + const fuseRef = useRef(); + const [searchQuery, setSearchQuery] = useState(''); const handleSearch = (newSearchQuery) => { - setSearchQuery(newSearchQuery) - const fuseSearchResult = fuseRef.current.search(newSearchQuery) + setSearchQuery(newSearchQuery); + const fuseSearchResult = fuseRef.current.search(newSearchQuery); onSearch({ searchQuery: newSearchQuery, results: defaultToAll && newSearchQuery === '' ? listToSearch : fuseSearchResult, - }) - } + }); + }; useEffect(() => { if (!fuseRef.current) { @@ -42,22 +42,22 @@ export default function ListItemSearch({ maxPatternLength: 32, minMatchCharLength: 1, keys: fuseSearchKeys, - }) + }); } - }, [fuseSearchKeys, listToSearch]) + }, [fuseSearchKeys, listToSearch]); - const previousListToSearch = usePrevious(listToSearch) || [] + const previousListToSearch = usePrevious(listToSearch) || []; useEffect(() => { if ( fuseRef.current && searchQuery && previousListToSearch !== listToSearch ) { - fuseRef.current.setCollection(listToSearch) - const fuseSearchResult = fuseRef.current.search(searchQuery) - onSearch({ searchQuery, results: fuseSearchResult }) + fuseRef.current.setCollection(listToSearch); + const fuseSearchResult = fuseRef.current.search(searchQuery); + onSearch({ searchQuery, results: fuseSearchResult }); } - }, [listToSearch, searchQuery, onSearch, previousListToSearch]) + }, [listToSearch, searchQuery, onSearch, previousListToSearch]); return ( - ) + ); } ListItemSearch.propTypes = { @@ -83,4 +83,4 @@ ListItemSearch.propTypes = { fuseSearchKeys: PropTypes.arrayOf(PropTypes.object).isRequired, searchPlaceholderText: PropTypes.string, defaultToAll: PropTypes.bool, -} +}; diff --git a/ui/app/pages/swaps/searchable-item-list/searchable-item-list.js b/ui/app/pages/swaps/searchable-item-list/searchable-item-list.js index 2f92c113e9..ba871339e8 100644 --- a/ui/app/pages/swaps/searchable-item-list/searchable-item-list.js +++ b/ui/app/pages/swaps/searchable-item-list/searchable-item-list.js @@ -1,7 +1,7 @@ -import React, { useState, useRef } from 'react' -import PropTypes from 'prop-types' -import ItemList from './item-list' -import ListItemSearch from './list-item-search' +import React, { useState, useRef } from 'react'; +import PropTypes from 'prop-types'; +import ItemList from './item-list'; +import ListItemSearch from './list-item-search'; export default function SearchableItemList({ className, @@ -18,10 +18,10 @@ export default function SearchableItemList({ hideItemIf, listContainerClassName, }) { - const itemListRef = useRef() + const itemListRef = useRef(); - const [results, setResults] = useState(defaultToAll ? itemsToSearch : []) - const [searchQuery, setSearchQuery] = useState('') + const [results, setResults] = useState(defaultToAll ? itemsToSearch : []); + const [searchQuery, setSearchQuery] = useState(''); return (
    @@ -32,8 +32,8 @@ export default function SearchableItemList({ searchQuery: newSearchQuery = '', results: newResults = [], }) => { - setSearchQuery(newSearchQuery) - setResults(newResults) + setSearchQuery(newSearchQuery); + setResults(newResults); }} error={itemSelectorError} searchPlaceholderText={searchPlaceholderText} @@ -52,7 +52,7 @@ export default function SearchableItemList({ listContainerClassName={listContainerClassName} />
    - ) + ); } SearchableItemList.propTypes = { @@ -74,4 +74,4 @@ SearchableItemList.propTypes = { hideRightLabels: PropTypes.bool, hideItemIf: PropTypes.func, listContainerClassName: PropTypes.string, -} +}; diff --git a/ui/app/pages/swaps/select-quote-popover/index.js b/ui/app/pages/swaps/select-quote-popover/index.js index 6ffabdf2db..288e4acbd2 100644 --- a/ui/app/pages/swaps/select-quote-popover/index.js +++ b/ui/app/pages/swaps/select-quote-popover/index.js @@ -1 +1 @@ -export { default } from './select-quote-popover' +export { default } from './select-quote-popover'; diff --git a/ui/app/pages/swaps/select-quote-popover/mock-quote-data.js b/ui/app/pages/swaps/select-quote-popover/mock-quote-data.js index f6c2dbd5f8..93d49281ac 100644 --- a/ui/app/pages/swaps/select-quote-popover/mock-quote-data.js +++ b/ui/app/pages/swaps/select-quote-popover/mock-quote-data.js @@ -89,6 +89,6 @@ const quoteDataRows = [ sourceTokenSymbol: 'ETH', sourceTokenValue: '250000000000000000', }, -] +]; -export default quoteDataRows +export default quoteDataRows; diff --git a/ui/app/pages/swaps/select-quote-popover/quote-details/index.js b/ui/app/pages/swaps/select-quote-popover/quote-details/index.js index ffe541b1e6..544808b12a 100644 --- a/ui/app/pages/swaps/select-quote-popover/quote-details/index.js +++ b/ui/app/pages/swaps/select-quote-popover/quote-details/index.js @@ -1 +1 @@ -export { default } from './quote-details' +export { default } from './quote-details'; diff --git a/ui/app/pages/swaps/select-quote-popover/quote-details/quote-details.js b/ui/app/pages/swaps/select-quote-popover/quote-details/quote-details.js index 96692f3a85..6d96123e0a 100644 --- a/ui/app/pages/swaps/select-quote-popover/quote-details/quote-details.js +++ b/ui/app/pages/swaps/select-quote-popover/quote-details/quote-details.js @@ -1,8 +1,8 @@ -import React, { useContext } from 'react' -import PropTypes from 'prop-types' -import { I18nContext } from '../../../../contexts/i18n' -import InfoTooltip from '../../../../components/ui/info-tooltip' -import ExchangeRateDisplay from '../../exchange-rate-display' +import React, { useContext } from 'react'; +import PropTypes from 'prop-types'; +import { I18nContext } from '../../../../contexts/i18n'; +import InfoTooltip from '../../../../components/ui/info-tooltip'; +import ExchangeRateDisplay from '../../exchange-rate-display'; const QuoteDetails = ({ slippage, @@ -16,7 +16,7 @@ const QuoteDetails = ({ networkFees, metaMaskFee, }) => { - const t = useContext(I18nContext) + const t = useContext(I18nContext); return (
    @@ -91,8 +91,8 @@ const QuoteDetails = ({
    - ) -} + ); +}; QuoteDetails.propTypes = { slippage: PropTypes.number.isRequired, @@ -105,6 +105,6 @@ QuoteDetails.propTypes = { feeInEth: PropTypes.string.isRequired, networkFees: PropTypes.string.isRequired, metaMaskFee: PropTypes.number.isRequired, -} +}; -export default QuoteDetails +export default QuoteDetails; diff --git a/ui/app/pages/swaps/select-quote-popover/select-quote-popover-constants.js b/ui/app/pages/swaps/select-quote-popover/select-quote-popover-constants.js index 8d25a5b938..d2754208e2 100644 --- a/ui/app/pages/swaps/select-quote-popover/select-quote-popover-constants.js +++ b/ui/app/pages/swaps/select-quote-popover/select-quote-popover-constants.js @@ -1,4 +1,4 @@ -import PropTypes from 'prop-types' +import PropTypes from 'prop-types'; export const QUOTE_DATA_ROWS_PROPTYPES_SHAPE = PropTypes.shape({ aggId: PropTypes.string.isRequired, @@ -14,4 +14,4 @@ export const QUOTE_DATA_ROWS_PROPTYPES_SHAPE = PropTypes.shape({ sourceTokenDecimals: PropTypes.number.isRequired, sourceTokenSymbol: PropTypes.string.isRequired, sourceTokenValue: PropTypes.string.isRequired, -}) +}); diff --git a/ui/app/pages/swaps/select-quote-popover/select-quote-popover.js b/ui/app/pages/swaps/select-quote-popover/select-quote-popover.js index cc5314f283..c3efcba48a 100644 --- a/ui/app/pages/swaps/select-quote-popover/select-quote-popover.js +++ b/ui/app/pages/swaps/select-quote-popover/select-quote-popover.js @@ -1,11 +1,11 @@ -import React, { useState, useCallback, useContext } from 'react' -import PropTypes from 'prop-types' -import { I18nContext } from '../../../contexts/i18n' -import Popover from '../../../components/ui/popover' -import Button from '../../../components/ui/button' -import QuoteDetails from './quote-details' -import SortList from './sort-list' -import { QUOTE_DATA_ROWS_PROPTYPES_SHAPE } from './select-quote-popover-constants' +import React, { useState, useCallback, useContext } from 'react'; +import PropTypes from 'prop-types'; +import { I18nContext } from '../../../contexts/i18n'; +import Popover from '../../../components/ui/popover'; +import Button from '../../../components/ui/button'; +import QuoteDetails from './quote-details'; +import SortList from './sort-list'; +import { QUOTE_DATA_ROWS_PROPTYPES_SHAPE } from './select-quote-popover-constants'; const SelectQuotePopover = ({ quoteDataRows = [], @@ -15,45 +15,45 @@ const SelectQuotePopover = ({ initialAggId, onQuoteDetailsIsOpened, }) => { - const t = useContext(I18nContext) + const t = useContext(I18nContext); - const [sortDirection, setSortDirection] = useState(1) - const [sortColumn, setSortColumn] = useState(null) + const [sortDirection, setSortDirection] = useState(1); + const [sortColumn, setSortColumn] = useState(null); - const [selectedAggId, setSelectedAggId] = useState(initialAggId) - const [contentView, setContentView] = useState('sortList') - const [viewingAgg, setViewingAgg] = useState(null) + const [selectedAggId, setSelectedAggId] = useState(initialAggId); + const [contentView, setContentView] = useState('sortList'); + const [viewingAgg, setViewingAgg] = useState(null); const onSubmitClick = useCallback(() => { - onSubmit(selectedAggId) - onClose() - }, [selectedAggId, onClose, onSubmit]) + onSubmit(selectedAggId); + onClose(); + }, [selectedAggId, onClose, onSubmit]); const closeQuoteDetails = useCallback(() => { - setViewingAgg(null) - setContentView('sortList') - }, []) + setViewingAgg(null); + setContentView('sortList'); + }, []); const onRowClick = useCallback((aggId) => setSelectedAggId(aggId), [ setSelectedAggId, - ]) + ]); const onCaretClick = useCallback( (aggId) => { - const agg = quoteDataRows.find((quote) => quote.aggId === aggId) - setContentView('quoteDetails') - onQuoteDetailsIsOpened() - setViewingAgg(agg) + const agg = quoteDataRows.find((quote) => quote.aggId === aggId); + setContentView('quoteDetails'); + onQuoteDetailsIsOpened(); + setViewingAgg(agg); }, [quoteDataRows, onQuoteDetailsIsOpened], - ) + ); const CustomBackground = useCallback( () => (
    ), [onClose], - ) + ); const footer = ( <>
    - ) + ); } SlippageButtons.propTypes = { onSelect: PropTypes.func.isRequired, maxAllowedSlippage: PropTypes.number.isRequired, -} +}; diff --git a/ui/app/pages/swaps/slippage-buttons/slippage-buttons.stories.js b/ui/app/pages/swaps/slippage-buttons/slippage-buttons.stories.js index 035513596b..63671fe95f 100644 --- a/ui/app/pages/swaps/slippage-buttons/slippage-buttons.stories.js +++ b/ui/app/pages/swaps/slippage-buttons/slippage-buttons.stories.js @@ -1,13 +1,13 @@ -import React from 'react' -import { action } from '@storybook/addon-actions' -import SlippageButtons from '.' +import React from 'react'; +import { action } from '@storybook/addon-actions'; +import SlippageButtons from '.'; export default { title: 'SlippageButtons', -} +}; export const Default = () => (
    -) +); diff --git a/ui/app/pages/swaps/swaps-footer/index.js b/ui/app/pages/swaps/swaps-footer/index.js index 5672e3c1b4..0c529e3a3f 100644 --- a/ui/app/pages/swaps/swaps-footer/index.js +++ b/ui/app/pages/swaps/swaps-footer/index.js @@ -1 +1 @@ -export { default } from './swaps-footer' +export { default } from './swaps-footer'; diff --git a/ui/app/pages/swaps/swaps-footer/swaps-footer.js b/ui/app/pages/swaps/swaps-footer/swaps-footer.js index 62a3e2a706..faefa85dbc 100644 --- a/ui/app/pages/swaps/swaps-footer/swaps-footer.js +++ b/ui/app/pages/swaps/swaps-footer/swaps-footer.js @@ -1,9 +1,9 @@ -import React, { useContext } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { I18nContext } from '../../../contexts/i18n' +import React, { useContext } from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import { I18nContext } from '../../../contexts/i18n'; -import PageContainerFooter from '../../../components/ui/page-container/page-container-footer' +import PageContainerFooter from '../../../components/ui/page-container/page-container-footer'; export default function SwapsFooter({ onCancel, @@ -15,7 +15,7 @@ export default function SwapsFooter({ showTopBorder, className = '', }) { - const t = useContext(I18nContext) + const t = useContext(I18nContext); return (
    @@ -55,7 +55,7 @@ export default function SwapsFooter({
    )} - ) + ); } SwapsFooter.propTypes = { @@ -67,4 +67,4 @@ SwapsFooter.propTypes = { showTermsOfService: PropTypes.bool, showTopBorder: PropTypes.bool, className: PropTypes.string, -} +}; diff --git a/ui/app/pages/swaps/swaps-gas-customization-modal/index.js b/ui/app/pages/swaps/swaps-gas-customization-modal/index.js index 645372331c..a54988ab9e 100644 --- a/ui/app/pages/swaps/swaps-gas-customization-modal/index.js +++ b/ui/app/pages/swaps/swaps-gas-customization-modal/index.js @@ -1 +1 @@ -export { default } from './swaps-gas-customization-modal.container' +export { default } from './swaps-gas-customization-modal.container'; diff --git a/ui/app/pages/swaps/swaps-gas-customization-modal/swaps-gas-customization-modal.component.js b/ui/app/pages/swaps/swaps-gas-customization-modal/swaps-gas-customization-modal.component.js index 1347529dcd..5a0a2dfe96 100644 --- a/ui/app/pages/swaps/swaps-gas-customization-modal/swaps-gas-customization-modal.component.js +++ b/ui/app/pages/swaps/swaps-gas-customization-modal/swaps-gas-customization-modal.component.js @@ -1,18 +1,18 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import PageContainer from '../../../components/ui/page-container' -import { Tabs, Tab } from '../../../components/ui/tabs' -import { calcGasTotal } from '../../send/send.utils' -import { sumHexWEIsToUnformattedFiat } from '../../../helpers/utils/conversions.util' -import AdvancedGasInputs from '../../../components/app/gas-customization/advanced-gas-inputs' -import BasicTabContent from '../../../components/app/gas-customization/gas-modal-page-container/basic-tab-content' -import { GAS_ESTIMATE_TYPES } from '../../../helpers/constants/common' +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import PageContainer from '../../../components/ui/page-container'; +import { Tabs, Tab } from '../../../components/ui/tabs'; +import { calcGasTotal } from '../../send/send.utils'; +import { sumHexWEIsToUnformattedFiat } from '../../../helpers/utils/conversions.util'; +import AdvancedGasInputs from '../../../components/app/gas-customization/advanced-gas-inputs'; +import BasicTabContent from '../../../components/app/gas-customization/gas-modal-page-container/basic-tab-content'; +import { GAS_ESTIMATE_TYPES } from '../../../helpers/constants/common'; export default class GasModalPageContainer extends Component { static contextTypes = { t: PropTypes.func, trackEvent: PropTypes.func, - } + }; static propTypes = { insufficientBalance: PropTypes.bool, @@ -42,17 +42,17 @@ export default class GasModalPageContainer extends Component { setSwapsCustomizationModalLimit: PropTypes.func, gasEstimateLoadingHasFailed: PropTypes.bool, minimumGasLimit: PropTypes.number.isRequired, - } + }; state = { gasSpeedType: '', - } + }; setGasSpeedType(gasEstimateType) { if (gasEstimateType === GAS_ESTIMATE_TYPES.AVERAGE) { - this.setState({ gasSpeedType: 'average' }) + this.setState({ gasSpeedType: 'average' }); } else { - this.setState({ gasSpeedType: 'fast' }) + this.setState({ gasSpeedType: 'fast' }); } } @@ -62,12 +62,12 @@ export default class GasModalPageContainer extends Component { gasPriceButtonGroupProps={{ ...gasPriceButtonGroupProps, handleGasPriceSelection: ({ gasPrice, gasEstimateType }) => { - this.setGasSpeedType(gasEstimateType) - this.props.setSwapsCustomizationModalPrice(gasPrice) + this.setGasSpeedType(gasEstimateType); + this.props.setSwapsCustomizationModalPrice(gasPrice); }, }} /> - ) + ); } renderAdvancedTabContent() { @@ -81,7 +81,7 @@ export default class GasModalPageContainer extends Component { customGasPrice, customGasLimit, minimumGasLimit, - } = this.props + } = this.props; return (
    @@ -99,12 +99,12 @@ export default class GasModalPageContainer extends Component {
    { - this.setState({ gasSpeedType: 'custom' }) - setSwapsCustomizationModalPrice(updatedPrice) + this.setState({ gasSpeedType: 'custom' }); + setSwapsCustomizationModalPrice(updatedPrice); }} updateCustomGasLimit={(updatedLimit) => { - this.setState({ gasSpeedType: 'custom' }) - setSwapsCustomizationModalLimit(updatedLimit) + this.setState({ gasSpeedType: 'custom' }); + setSwapsCustomizationModalLimit(updatedLimit); }} customGasPrice={customGasPrice} customGasLimit={customGasLimit} @@ -116,7 +116,7 @@ export default class GasModalPageContainer extends Component {
    - ) + ); } renderInfoRows( @@ -170,7 +170,7 @@ export default class GasModalPageContainer extends Component { - ) + ); } renderTabs() { @@ -184,7 +184,7 @@ export default class GasModalPageContainer extends Component { extraInfoRow, }, gasEstimateLoadingHasFailed, - } = this.props + } = this.props; const basicTabInfo = { name: this.context.t('basic'), @@ -192,15 +192,15 @@ export default class GasModalPageContainer extends Component { ...gasPriceButtonGroupProps, handleGasPriceSelection: this.props.setSwapsCustomizationModalPrice, }), - } + }; const advancedTabInfo = { name: this.context.t('advanced'), content: this.renderAdvancedTabContent(), - } + }; const tabsToRender = gasEstimateLoadingHasFailed ? [advancedTabInfo] - : [basicTabInfo, advancedTabInfo] + : [basicTabInfo, advancedTabInfo]; return ( @@ -219,7 +219,7 @@ export default class GasModalPageContainer extends Component { ))} - ) + ); } render() { @@ -229,7 +229,7 @@ export default class GasModalPageContainer extends Component { disableSave, customGasPrice, customGasLimit, - } = this.props + } = this.props; return (
    @@ -241,7 +241,10 @@ export default class GasModalPageContainer extends Component { onCancel={() => cancelAndClose()} onClose={() => cancelAndClose()} onSubmit={() => { - const newSwapGasTotal = calcGasTotal(customGasLimit, customGasPrice) + const newSwapGasTotal = calcGasTotal( + customGasLimit, + customGasPrice, + ); this.context.trackEvent({ event: 'Gas Fees Changed', @@ -254,14 +257,14 @@ export default class GasModalPageContainer extends Component { this.props.usdConversionRate, )?.slice(1), }, - }) - onSubmit(customGasLimit, customGasPrice) + }); + onSubmit(customGasLimit, customGasPrice); }} submitText={this.context.t('save')} headerCloseText={this.context.t('close')} hideCancel />
    - ) + ); } } diff --git a/ui/app/pages/swaps/swaps-gas-customization-modal/swaps-gas-customization-modal.container.js b/ui/app/pages/swaps/swaps-gas-customization-modal/swaps-gas-customization-modal.container.js index deea5c4b03..2a717fc36c 100644 --- a/ui/app/pages/swaps/swaps-gas-customization-modal/swaps-gas-customization-modal.container.js +++ b/ui/app/pages/swaps/swaps-gas-customization-modal/swaps-gas-customization-modal.container.js @@ -1,6 +1,6 @@ -import { connect } from 'react-redux' -import BigNumber from 'bignumber.js' -import { hideModal, customSwapsGasParamsUpdated } from '../../../store/actions' +import { connect } from 'react-redux'; +import BigNumber from 'bignumber.js'; +import { hideModal, customSwapsGasParamsUpdated } from '../../../store/actions'; import { conversionRateSelector as getConversionRate, getCurrentCurrency, @@ -8,7 +8,7 @@ import { getDefaultActiveButtonIndex, getRenderableGasButtonData, getUSDConversionRate, -} from '../../../selectors' +} from '../../../selectors'; import { getSwapsCustomizationModalPrice, @@ -20,22 +20,22 @@ import { swapCustomGasModalLimitEdited, shouldShowCustomPriceTooLowWarning, swapCustomGasModalClosed, -} from '../../../ducks/swaps/swaps' +} from '../../../ducks/swaps/swaps'; import { addHexes, getValueFromWeiHex, sumHexWEIsToRenderableFiat, -} from '../../../helpers/utils/conversions.util' -import { formatETHFee } from '../../../helpers/utils/formatters' -import { calcGasTotal, isBalanceSufficient } from '../../send/send.utils' -import SwapsGasCustomizationModalComponent from './swaps-gas-customization-modal.component' +} from '../../../helpers/utils/conversions.util'; +import { formatETHFee } from '../../../helpers/utils/formatters'; +import { calcGasTotal, isBalanceSufficient } from '../../send/send.utils'; +import SwapsGasCustomizationModalComponent from './swaps-gas-customization-modal.component'; const mapStateToProps = (state) => { - const currentCurrency = getCurrentCurrency(state) - const conversionRate = getConversionRate(state) + const currentCurrency = getCurrentCurrency(state); + const conversionRate = getConversionRate(state); - const { modalState: { props: modalProps } = {} } = state.appState.modal || {} + const { modalState: { props: modalProps } = {} } = state.appState.modal || {}; const { value, customGasLimitMessage = '', @@ -44,18 +44,18 @@ const mapStateToProps = (state) => { initialGasPrice, initialGasLimit, minimumGasLimit, - } = modalProps - const buttonDataLoading = swapGasPriceEstimateIsLoading(state) + } = modalProps; + const buttonDataLoading = swapGasPriceEstimateIsLoading(state); - const swapsCustomizationModalPrice = getSwapsCustomizationModalPrice(state) - const swapsCustomizationModalLimit = getSwapsCustomizationModalLimit(state) + const swapsCustomizationModalPrice = getSwapsCustomizationModalPrice(state); + const swapsCustomizationModalLimit = getSwapsCustomizationModalLimit(state); - const customGasPrice = swapsCustomizationModalPrice || initialGasPrice - const customGasLimit = swapsCustomizationModalLimit || initialGasLimit + const customGasPrice = swapsCustomizationModalPrice || initialGasPrice; + const customGasLimit = swapsCustomizationModalLimit || initialGasLimit; - const customGasTotal = calcGasTotal(customGasLimit, customGasPrice) + const customGasTotal = calcGasTotal(customGasLimit, customGasPrice); - const swapsGasPriceEstimates = getSwapGasPriceEstimateData(state) + const swapsGasPriceEstimates = getSwapGasPriceEstimateData(state); const { averageEstimateData, fastEstimateData } = getRenderableGasButtonData( swapsGasPriceEstimates, @@ -63,36 +63,36 @@ const mapStateToProps = (state) => { true, conversionRate, currentCurrency, - ) - const gasButtonInfo = [averageEstimateData, fastEstimateData] + ); + const gasButtonInfo = [averageEstimateData, fastEstimateData]; const newTotalFiat = sumHexWEIsToRenderableFiat( [value, customGasTotal, customTotalSupplement], currentCurrency, conversionRate, - ) + ); - const balance = getCurrentEthBalance(state) + const balance = getCurrentEthBalance(state); const newTotalEth = sumHexWEIsToRenderableEth([ value, customGasTotal, customTotalSupplement, - ]) + ]); - const sendAmount = sumHexWEIsToRenderableEth([value, '0x0']) + const sendAmount = sumHexWEIsToRenderableEth([value, '0x0']); const insufficientBalance = !isBalanceSufficient({ amount: value, gasTotal: customGasTotal, balance, conversionRate, - }) + }); const customGasLimitTooLow = new BigNumber(customGasLimit, 16).lt( minimumGasLimit, 10, - ) + ); return { customGasPrice, @@ -130,41 +130,41 @@ const mapStateToProps = (state) => { usdConversionRate: getUSDConversionRate(state), disableSave: insufficientBalance || customGasLimitTooLow, minimumGasLimit, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { cancelAndClose: () => { - dispatch(swapCustomGasModalClosed()) - dispatch(hideModal()) + dispatch(swapCustomGasModalClosed()); + dispatch(hideModal()); }, onSubmit: async (gasLimit, gasPrice) => { - await dispatch(customSwapsGasParamsUpdated(gasLimit, gasPrice)) - dispatch(swapCustomGasModalClosed()) - dispatch(hideModal()) + await dispatch(customSwapsGasParamsUpdated(gasLimit, gasPrice)); + dispatch(swapCustomGasModalClosed()); + dispatch(hideModal()); }, setSwapsCustomizationModalPrice: (newPrice) => { - dispatch(swapCustomGasModalPriceEdited(newPrice)) + dispatch(swapCustomGasModalPriceEdited(newPrice)); }, setSwapsCustomizationModalLimit: (newLimit) => { - dispatch(swapCustomGasModalLimitEdited(newLimit)) + dispatch(swapCustomGasModalLimitEdited(newLimit)); }, - } -} + }; +}; export default connect( mapStateToProps, mapDispatchToProps, -)(SwapsGasCustomizationModalComponent) +)(SwapsGasCustomizationModalComponent); function sumHexWEIsToRenderableEth(hexWEIs) { - const hexWEIsSum = hexWEIs.filter(Boolean).reduce(addHexes) + const hexWEIsSum = hexWEIs.filter(Boolean).reduce(addHexes); return formatETHFee( getValueFromWeiHex({ value: hexWEIsSum, toCurrency: 'ETH', numberOfDecimals: 6, }), - ) + ); } diff --git a/ui/app/pages/swaps/swaps-util-test-constants.js b/ui/app/pages/swaps/swaps-util-test-constants.js index b1ec1dbc59..6bf2207c65 100644 --- a/ui/app/pages/swaps/swaps-util-test-constants.js +++ b/ui/app/pages/swaps/swaps-util-test-constants.js @@ -1,12 +1,13 @@ -import { ETH_SWAPS_TOKEN_OBJECT } from '../../helpers/constants/swaps' +import { ETH_SWAPS_TOKEN_OBJECT } from '../../helpers/constants/swaps'; export const TRADES_BASE_PROD_URL = - 'https://api.metaswap.codefi.network/trades?' -export const TOKENS_BASE_PROD_URL = 'https://api.metaswap.codefi.network/tokens' + 'https://api.metaswap.codefi.network/trades?'; +export const TOKENS_BASE_PROD_URL = + 'https://api.metaswap.codefi.network/tokens'; export const AGGREGATOR_METADATA_BASE_PROD_URL = - 'https://api.metaswap.codefi.network/aggregatorMetadata' + 'https://api.metaswap.codefi.network/aggregatorMetadata'; export const TOP_ASSET_BASE_PROD_URL = - 'https://api.metaswap.codefi.network/topAssets' + 'https://api.metaswap.codefi.network/topAssets'; export const TOKENS = [ { @@ -82,7 +83,7 @@ export const TOKENS = [ address: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', }, ETH_SWAPS_TOKEN_OBJECT, -] +]; export const MOCK_TRADE_RESPONSE_1 = [ { @@ -151,12 +152,12 @@ export const MOCK_TRADE_RESPONSE_1 = [ aggregator: 'zeroEx', aggType: 'AGG', }, -] +]; export const MOCK_TRADE_RESPONSE_2 = MOCK_TRADE_RESPONSE_1.map((trade) => ({ ...trade, sourceAmount: '20000000000000000', -})) +})); export const AGGREGATOR_METADATA = { agg1: { @@ -169,7 +170,7 @@ export const AGGREGATOR_METADATA = { title: 'agg2', icon: 'data:image/png;base64,iVBORw0KGgoAAA', }, -} +}; export const TOP_ASSETS = [ { @@ -192,4 +193,4 @@ export const TOP_ASSETS = [ symbol: 'SNX', address: '0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f', }, -] +]; diff --git a/ui/app/pages/swaps/swaps.util.js b/ui/app/pages/swaps/swaps.util.js index 0fcc5d8a28..934caf509a 100644 --- a/ui/app/pages/swaps/swaps.util.js +++ b/ui/app/pages/swaps/swaps.util.js @@ -1,56 +1,59 @@ -import log from 'loglevel' -import BigNumber from 'bignumber.js' -import abi from 'human-standard-token-abi' -import { isValidAddress } from 'ethereumjs-util' -import { ETH_SWAPS_TOKEN_OBJECT } from '../../helpers/constants/swaps' -import { calcTokenValue, calcTokenAmount } from '../../helpers/utils/token-util' +import log from 'loglevel'; +import BigNumber from 'bignumber.js'; +import abi from 'human-standard-token-abi'; +import { isValidAddress } from 'ethereumjs-util'; +import { ETH_SWAPS_TOKEN_OBJECT } from '../../helpers/constants/swaps'; +import { + calcTokenValue, + calcTokenAmount, +} from '../../helpers/utils/token-util'; import { constructTxParams, toPrecisionWithoutTrailingZeros, -} from '../../helpers/utils/util' +} from '../../helpers/utils/util'; import { decimalToHex, getValueFromWeiHex, -} from '../../helpers/utils/conversions.util' +} from '../../helpers/utils/conversions.util'; -import { subtractCurrencies } from '../../helpers/utils/conversion-util' -import { formatCurrency } from '../../helpers/utils/confirm-tx.util' -import fetchWithCache from '../../helpers/utils/fetch-with-cache' +import { subtractCurrencies } from '../../helpers/utils/conversion-util'; +import { formatCurrency } from '../../helpers/utils/confirm-tx.util'; +import fetchWithCache from '../../helpers/utils/fetch-with-cache'; -import { calcGasTotal } from '../send/send.utils' +import { calcGasTotal } from '../send/send.utils'; const TOKEN_TRANSFER_LOG_TOPIC_HASH = - '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef' + '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'; -const CACHE_REFRESH_ONE_HOUR = 3600000 +const CACHE_REFRESH_ONE_HOUR = 3600000; -const METASWAP_API_HOST = 'https://api.metaswap.codefi.network' +const METASWAP_API_HOST = 'https://api.metaswap.codefi.network'; const getBaseApi = function (type) { switch (type) { case 'trade': - return `${METASWAP_API_HOST}/trades?` + return `${METASWAP_API_HOST}/trades?`; case 'tokens': - return `${METASWAP_API_HOST}/tokens` + return `${METASWAP_API_HOST}/tokens`; case 'topAssets': - return `${METASWAP_API_HOST}/topAssets` + return `${METASWAP_API_HOST}/topAssets`; case 'featureFlag': - return `${METASWAP_API_HOST}/featureFlag` + return `${METASWAP_API_HOST}/featureFlag`; case 'aggregatorMetadata': - return `${METASWAP_API_HOST}/aggregatorMetadata` + return `${METASWAP_API_HOST}/aggregatorMetadata`; case 'gasPrices': - return `${METASWAP_API_HOST}/gasPrices` + return `${METASWAP_API_HOST}/gasPrices`; case 'refreshTime': - return `${METASWAP_API_HOST}/quoteRefreshRate` + return `${METASWAP_API_HOST}/quoteRefreshRate`; default: - throw new Error('getBaseApi requires an api call type') + throw new Error('getBaseApi requires an api call type'); } -} +}; -const validHex = (string) => Boolean(string?.match(/^0x[a-f0-9]+$/u)) -const truthyString = (string) => Boolean(string?.length) +const validHex = (string) => Boolean(string?.match(/^0x[a-f0-9]+$/u)); +const truthyString = (string) => Boolean(string?.length); const truthyDigitString = (string) => - truthyString(string) && Boolean(string.match(/^\d+$/u)) + truthyString(string) && Boolean(string.match(/^\d+$/u)); const QUOTE_VALIDATORS = [ { @@ -121,7 +124,7 @@ const QUOTE_VALIDATORS = [ type: 'number|undefined', validator: (gasEstimate) => gasEstimate === undefined || gasEstimate > 0, }, -] +]; const TOKEN_VALIDATORS = [ { @@ -139,9 +142,9 @@ const TOKEN_VALIDATORS = [ type: 'string|number', validator: (string) => Number(string) >= 0 && Number(string) <= 36, }, -] +]; -const TOP_ASSET_VALIDATORS = TOKEN_VALIDATORS.slice(0, 2) +const TOP_ASSET_VALIDATORS = TOKEN_VALIDATORS.slice(0, 2); const AGGREGATOR_METADATA_VALIDATORS = [ { @@ -159,10 +162,10 @@ const AGGREGATOR_METADATA_VALIDATORS = [ type: 'string', validator: (string) => Boolean(string.match(/^data:image/u)), }, -] +]; const isValidDecimalNumber = (string) => - !isNaN(string) && string.match(/^[.0-9]+$/u) && !isNaN(parseFloat(string)) + !isNaN(string) && string.match(/^[.0-9]+$/u) && !isNaN(parseFloat(string)); const SWAP_GAS_PRICE_VALIDATOR = [ { @@ -180,25 +183,25 @@ const SWAP_GAS_PRICE_VALIDATOR = [ type: 'string', validator: isValidDecimalNumber, }, -] +]; function validateData(validators, object, urlUsed) { return validators.every(({ property, type, validator }) => { - const types = type.split('|') + const types = type.split('|'); const valid = types.some((_type) => typeof object[property] === _type) && - (!validator || validator(object[property])) + (!validator || validator(object[property])); if (!valid) { log.error( `response to GET ${urlUsed} invalid for property ${property}; value was:`, object[property], '| type was: ', typeof object[property], - ) + ); } - return valid - }) + return valid; + }); } export async function fetchTradesInfo({ @@ -217,19 +220,19 @@ export async function fetchTradesInfo({ slippage, timeout: 10000, walletAddress: fromAddress, - } + }; if (exchangeList) { - urlParams.exchangeList = exchangeList + urlParams.exchangeList = exchangeList; } - const queryString = new URLSearchParams(urlParams).toString() - const tradeURL = `${getBaseApi('trade')}${queryString}` + const queryString = new URLSearchParams(urlParams).toString(); + const tradeURL = `${getBaseApi('trade')}${queryString}`; const tradesResponse = await fetchWithCache( tradeURL, { method: 'GET' }, { cacheRefreshTime: 0, timeout: 15000 }, - ) + ); const newQuotes = tradesResponse.reduce((aggIdTradeMap, quote) => { if ( quote.trade && @@ -242,14 +245,14 @@ export async function fetchTradesInfo({ data: quote.trade.data, amount: decimalToHex(quote.trade.value), gas: decimalToHex(quote.maxGas), - }) + }); - let { approvalNeeded } = quote + let { approvalNeeded } = quote; if (approvalNeeded) { approvalNeeded = constructTxParams({ ...approvalNeeded, - }) + }); } return { @@ -260,39 +263,39 @@ export async function fetchTradesInfo({ trade: constructedTrade, approvalNeeded, }, - } + }; } - return aggIdTradeMap - }, {}) + return aggIdTradeMap; + }, {}); - return newQuotes + return newQuotes; } export async function fetchTokens() { - const tokenUrl = getBaseApi('tokens') + const tokenUrl = getBaseApi('tokens'); const tokens = await fetchWithCache( tokenUrl, { method: 'GET' }, { cacheRefreshTime: CACHE_REFRESH_ONE_HOUR }, - ) + ); const filteredTokens = tokens.filter((token) => { return ( validateData(TOKEN_VALIDATORS, token, tokenUrl) && token.address !== ETH_SWAPS_TOKEN_OBJECT.address - ) - }) - filteredTokens.push(ETH_SWAPS_TOKEN_OBJECT) - return filteredTokens + ); + }); + filteredTokens.push(ETH_SWAPS_TOKEN_OBJECT); + return filteredTokens; } export async function fetchAggregatorMetadata() { - const aggregatorMetadataUrl = getBaseApi('aggregatorMetadata') + const aggregatorMetadataUrl = getBaseApi('aggregatorMetadata'); const aggregators = await fetchWithCache( aggregatorMetadataUrl, { method: 'GET' }, { cacheRefreshTime: CACHE_REFRESH_ONE_HOUR }, - ) - const filteredAggregators = {} + ); + const filteredAggregators = {}; for (const aggKey in aggregators) { if ( validateData( @@ -301,26 +304,26 @@ export async function fetchAggregatorMetadata() { aggregatorMetadataUrl, ) ) { - filteredAggregators[aggKey] = aggregators[aggKey] + filteredAggregators[aggKey] = aggregators[aggKey]; } } - return filteredAggregators + return filteredAggregators; } export async function fetchTopAssets() { - const topAssetsUrl = getBaseApi('topAssets') + const topAssetsUrl = getBaseApi('topAssets'); const response = await fetchWithCache( topAssetsUrl, { method: 'GET' }, { cacheRefreshTime: CACHE_REFRESH_ONE_HOUR }, - ) + ); const topAssetsMap = response.reduce((_topAssetsMap, asset, index) => { if (validateData(TOP_ASSET_VALIDATORS, asset, topAssetsUrl)) { - return { ..._topAssetsMap, [asset.address]: { index: String(index) } } + return { ..._topAssetsMap, [asset.address]: { index: String(index) } }; } - return _topAssetsMap - }, {}) - return topAssetsMap + return _topAssetsMap; + }, {}); + return topAssetsMap; } export async function fetchSwapsFeatureLiveness() { @@ -328,8 +331,8 @@ export async function fetchSwapsFeatureLiveness() { getBaseApi('featureFlag'), { method: 'GET' }, { cacheRefreshTime: 600000 }, - ) - return status?.active + ); + return status?.active; } export async function fetchSwapsQuoteRefreshTime() { @@ -337,66 +340,66 @@ export async function fetchSwapsQuoteRefreshTime() { getBaseApi('refreshTime'), { method: 'GET' }, { cacheRefreshTime: 600000 }, - ) + ); // We presently use milliseconds in the UI if (typeof response?.seconds === 'number' && response.seconds > 0) { - return response.seconds * 1000 + return response.seconds * 1000; } throw new Error( `MetaMask - refreshTime provided invalid response: ${response}`, - ) + ); } export async function fetchTokenPrice(address) { - const query = `contract_addresses=${address}&vs_currencies=eth` + const query = `contract_addresses=${address}&vs_currencies=eth`; const prices = await fetchWithCache( `https://api.coingecko.com/api/v3/simple/token_price/ethereum?${query}`, { method: 'GET' }, { cacheRefreshTime: 60000 }, - ) - return prices && prices[address]?.eth + ); + return prices && prices[address]?.eth; } export async function fetchTokenBalance(address, userAddress) { - const tokenContract = global.eth.contract(abi).at(address) + const tokenContract = global.eth.contract(abi).at(address); const tokenBalancePromise = tokenContract ? tokenContract.balanceOf(userAddress) - : Promise.resolve() - const usersToken = await tokenBalancePromise - return usersToken + : Promise.resolve(); + const usersToken = await tokenBalancePromise; + return usersToken; } export async function fetchSwapsGasPrices() { - const gasPricesUrl = getBaseApi('gasPrices') + const gasPricesUrl = getBaseApi('gasPrices'); const response = await fetchWithCache( gasPricesUrl, { method: 'GET' }, { cacheRefreshTime: 15000 }, - ) + ); const responseIsValid = validateData( SWAP_GAS_PRICE_VALIDATOR, response, gasPricesUrl, - ) + ); if (!responseIsValid) { - throw new Error(`${gasPricesUrl} response is invalid`) + throw new Error(`${gasPricesUrl} response is invalid`); } const { SafeGasPrice: safeLow, ProposeGasPrice: average, FastGasPrice: fast, - } = response + } = response; return { safeLow, average, fast, - } + }; } export function getRenderableNetworkFeesForQuote( @@ -411,36 +414,36 @@ export function getRenderableNetworkFeesForQuote( ) { const totalGasLimitForCalculation = new BigNumber(tradeGas || '0x0', 16) .plus(approveGas || '0x0', 16) - .toString(16) - const gasTotalInWeiHex = calcGasTotal(totalGasLimitForCalculation, gasPrice) + .toString(16); + const gasTotalInWeiHex = calcGasTotal(totalGasLimitForCalculation, gasPrice); const nonGasFee = new BigNumber(tradeValue, 16) .minus(sourceSymbol === 'ETH' ? sourceAmount : 0, 10) - .toString(16) + .toString(16); const totalWeiCost = new BigNumber(gasTotalInWeiHex, 16) .plus(nonGasFee, 16) - .toString(16) + .toString(16); const ethFee = getValueFromWeiHex({ value: totalWeiCost, toDenomination: 'ETH', numberOfDecimals: 5, - }) + }); const rawNetworkFees = getValueFromWeiHex({ value: totalWeiCost, toCurrency: currentCurrency, conversionRate, numberOfDecimals: 2, - }) - const formattedNetworkFee = formatCurrency(rawNetworkFees, currentCurrency) + }); + const formattedNetworkFee = formatCurrency(rawNetworkFees, currentCurrency); return { rawNetworkFees, rawEthFee: ethFee, feeInFiat: formattedNetworkFee, feeInEth: `${ethFee} ETH`, nonGasFee, - } + }; } export function quotesToRenderableData( @@ -464,15 +467,15 @@ export function quotesToRenderableData( averageGas, fee, trade, - } = quote + } = quote; const sourceValue = calcTokenAmount( sourceAmount, sourceTokenInfo.decimals, - ).toString(10) + ).toString(10); const destinationValue = calcTokenAmount( destinationAmount, destinationTokenInfo.decimals, - ).toPrecision(8) + ).toPrecision(8); const { feeInFiat, @@ -488,15 +491,15 @@ export function quotesToRenderableData( trade.value, sourceTokenInfo.symbol, sourceAmount, - ) + ); - const slippageMultiplier = new BigNumber(100 - slippage).div(100) + const slippageMultiplier = new BigNumber(100 - slippage).div(100); const minimumAmountReceived = new BigNumber(destinationValue) .times(slippageMultiplier) - .toFixed(6) + .toFixed(6); const tokenConversionRate = - tokenConversionRates[destinationTokenInfo.address] + tokenConversionRates[destinationTokenInfo.address]; const ethValueOfTrade = destinationTokenInfo.symbol === 'ETH' ? calcTokenAmount( @@ -508,20 +511,20 @@ export function quotesToRenderableData( calcTokenAmount(destinationAmount, destinationTokenInfo.decimals), 10, ) - .minus(rawEthFee, 10) + .minus(rawEthFee, 10); - let liquiditySourceKey - let renderedSlippage = slippage + let liquiditySourceKey; + let renderedSlippage = slippage; if (aggType === 'AGG') { - liquiditySourceKey = 'swapAggregator' + liquiditySourceKey = 'swapAggregator'; } else if (aggType === 'RFQ') { - liquiditySourceKey = 'swapRequestForQuotation' - renderedSlippage = 0 + liquiditySourceKey = 'swapRequestForQuotation'; + renderedSlippage = 0; } else if (aggType === 'DEX') { - liquiditySourceKey = 'swapDecentralizedExchange' + liquiditySourceKey = 'swapDecentralizedExchange'; } else { - liquiditySourceKey = 'swapUnknown' + liquiditySourceKey = 'swapUnknown'; } return { @@ -546,8 +549,8 @@ export function quotesToRenderableData( ethValueOfTrade, minimumAmountReceived, metaMaskFee: fee, - } - }) + }; + }); } export function getSwapsTokensReceivedFromTxMeta( @@ -558,7 +561,7 @@ export function getSwapsTokensReceivedFromTxMeta( tokenDecimals, approvalTxMeta, ) { - const txReceipt = txMeta?.txReceipt + const txReceipt = txMeta?.txReceipt; if (tokenSymbol === 'ETH') { if ( !txReceipt || @@ -566,21 +569,21 @@ export function getSwapsTokensReceivedFromTxMeta( !txMeta.postTxBalance || !txMeta.preTxBalance ) { - return null + return null; } - let approvalTxGasCost = '0x0' + let approvalTxGasCost = '0x0'; if (approvalTxMeta && approvalTxMeta.txReceipt) { approvalTxGasCost = calcGasTotal( approvalTxMeta.txReceipt.gasUsed, approvalTxMeta.txParams.gasPrice, - ) + ); } - const gasCost = calcGasTotal(txReceipt.gasUsed, txMeta.txParams.gasPrice) + const gasCost = calcGasTotal(txReceipt.gasUsed, txMeta.txParams.gasPrice); const totalGasCost = new BigNumber(gasCost, 16) .plus(approvalTxGasCost, 16) - .toString(16) + .toString(16); const preTxBalanceLessGasCost = subtractCurrencies( txMeta.preTxBalance, @@ -590,7 +593,7 @@ export function getSwapsTokensReceivedFromTxMeta( bBase: 16, toNumericBase: 'hex', }, - ) + ); const ethReceived = subtractCurrencies( txMeta.postTxBalance, @@ -603,40 +606,40 @@ export function getSwapsTokensReceivedFromTxMeta( toNumericBase: 'dec', numberOfDecimals: 6, }, - ) - return ethReceived + ); + return ethReceived; } - const txReceiptLogs = txReceipt?.logs + const txReceiptLogs = txReceipt?.logs; if (txReceiptLogs && txReceipt?.status !== '0x0') { const tokenTransferLog = txReceiptLogs.find((txReceiptLog) => { const isTokenTransfer = txReceiptLog.topics && - txReceiptLog.topics[0] === TOKEN_TRANSFER_LOG_TOPIC_HASH - const isTransferFromGivenToken = txReceiptLog.address === tokenAddress + txReceiptLog.topics[0] === TOKEN_TRANSFER_LOG_TOPIC_HASH; + const isTransferFromGivenToken = txReceiptLog.address === tokenAddress; const isTransferFromGivenAddress = txReceiptLog.topics && txReceiptLog.topics[2] && - txReceiptLog.topics[2].match(accountAddress.slice(2)) + txReceiptLog.topics[2].match(accountAddress.slice(2)); return ( isTokenTransfer && isTransferFromGivenToken && isTransferFromGivenAddress - ) - }) + ); + }); return tokenTransferLog ? toPrecisionWithoutTrailingZeros( calcTokenAmount(tokenTransferLog.data, tokenDecimals).toString(10), 6, ) - : '' + : ''; } - return null + return null; } export function formatSwapsValueForDisplay(destinationAmount) { - let amountToDisplay = toPrecisionWithoutTrailingZeros(destinationAmount, 12) + let amountToDisplay = toPrecisionWithoutTrailingZeros(destinationAmount, 12); if (amountToDisplay.match(/e[+-]/u)) { - amountToDisplay = new BigNumber(amountToDisplay).toFixed() + amountToDisplay = new BigNumber(amountToDisplay).toFixed(); } - return amountToDisplay + return amountToDisplay; } diff --git a/ui/app/pages/swaps/swaps.util.test.js b/ui/app/pages/swaps/swaps.util.test.js index 77bab19059..f3ee2a497d 100644 --- a/ui/app/pages/swaps/swaps.util.test.js +++ b/ui/app/pages/swaps/swaps.util.test.js @@ -1,5 +1,5 @@ -import { strict as assert } from 'assert' -import proxyquire from 'proxyquire' +import { strict as assert } from 'assert'; +import proxyquire from 'proxyquire'; import { TRADES_BASE_PROD_URL, TOKENS_BASE_PROD_URL, @@ -9,41 +9,41 @@ import { MOCK_TRADE_RESPONSE_2, AGGREGATOR_METADATA, TOP_ASSETS, -} from './swaps-util-test-constants' +} from './swaps-util-test-constants'; const swapsUtils = proxyquire('./swaps.util.js', { '../../helpers/utils/fetch-with-cache': { default: (url, fetchObject) => { - assert.strictEqual(fetchObject.method, 'GET') + assert.strictEqual(fetchObject.method, 'GET'); if (url.match(TRADES_BASE_PROD_URL)) { assert.strictEqual( url, 'https://api.metaswap.codefi.network/trades?destinationToken=0xE41d2489571d322189246DaFA5ebDe1F4699F498&sourceToken=0x617b3f8050a0BD94b6b1da02B4384eE5B4DF13F4&sourceAmount=2000000000000000000000000000000000000&slippage=3&timeout=10000&walletAddress=0xmockAddress', - ) - return Promise.resolve(MOCK_TRADE_RESPONSE_2) + ); + return Promise.resolve(MOCK_TRADE_RESPONSE_2); } if (url.match(TOKENS_BASE_PROD_URL)) { - assert.strictEqual(url, TOKENS_BASE_PROD_URL) - return Promise.resolve(TOKENS) + assert.strictEqual(url, TOKENS_BASE_PROD_URL); + return Promise.resolve(TOKENS); } if (url.match(AGGREGATOR_METADATA_BASE_PROD_URL)) { - assert.strictEqual(url, AGGREGATOR_METADATA_BASE_PROD_URL) - return Promise.resolve(AGGREGATOR_METADATA) + assert.strictEqual(url, AGGREGATOR_METADATA_BASE_PROD_URL); + return Promise.resolve(AGGREGATOR_METADATA); } if (url.match(TOP_ASSET_BASE_PROD_URL)) { - assert.strictEqual(url, TOP_ASSET_BASE_PROD_URL) - return Promise.resolve(TOP_ASSETS) + assert.strictEqual(url, TOP_ASSET_BASE_PROD_URL); + return Promise.resolve(TOP_ASSETS); } - return Promise.resolve() + return Promise.resolve(); }, }, -}) +}); const { fetchTradesInfo, fetchTokens, fetchAggregatorMetadata, fetchTopAssets, -} = swapsUtils +} = swapsUtils; describe('Swaps Util', function () { describe('fetchTradesInfo', function () { @@ -80,13 +80,13 @@ describe('Swaps Util', function () { averageGas: 1, slippage: '3', }, - } + }; const expectedResult2 = { zeroEx: { ...expectedResult1.zeroEx, sourceAmount: '20000000000000000', }, - } + }; it('should fetch trade info on prod', async function () { const result = await fetchTradesInfo({ TOKENS, @@ -99,34 +99,34 @@ describe('Swaps Util', function () { sourceDecimals: TOKENS[0].decimals, sourceTokenInfo: { ...TOKENS[0] }, destinationTokenInfo: { ...TOKENS[1] }, - }) - assert.deepStrictEqual(result, expectedResult2) - }) - }) + }); + assert.deepStrictEqual(result, expectedResult2); + }); + }); describe('fetchTokens', function () { it('should fetch tokens', async function () { - const result = await fetchTokens(true) - assert.deepStrictEqual(result, TOKENS) - }) + const result = await fetchTokens(true); + assert.deepStrictEqual(result, TOKENS); + }); it('should fetch tokens on prod', async function () { - const result = await fetchTokens(false) - assert.deepStrictEqual(result, TOKENS) - }) - }) + const result = await fetchTokens(false); + assert.deepStrictEqual(result, TOKENS); + }); + }); describe('fetchAggregatorMetadata', function () { it('should fetch aggregator metadata', async function () { - const result = await fetchAggregatorMetadata(true) - assert.deepStrictEqual(result, AGGREGATOR_METADATA) - }) + const result = await fetchAggregatorMetadata(true); + assert.deepStrictEqual(result, AGGREGATOR_METADATA); + }); it('should fetch aggregator metadata on prod', async function () { - const result = await fetchAggregatorMetadata(false) - assert.deepStrictEqual(result, AGGREGATOR_METADATA) - }) - }) + const result = await fetchAggregatorMetadata(false); + assert.deepStrictEqual(result, AGGREGATOR_METADATA); + }); + }); describe('fetchTopAssets', function () { const expectedResult = { @@ -145,15 +145,15 @@ describe('Swaps Util', function () { '0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f': { index: '4', }, - } + }; it('should fetch top assets', async function () { - const result = await fetchTopAssets(true) - assert.deepStrictEqual(result, expectedResult) - }) + const result = await fetchTopAssets(true); + assert.deepStrictEqual(result, expectedResult); + }); it('should fetch top assets on prod', async function () { - const result = await fetchTopAssets(false) - assert.deepStrictEqual(result, expectedResult) - }) - }) -}) + const result = await fetchTopAssets(false); + assert.deepStrictEqual(result, expectedResult); + }); + }); +}); diff --git a/ui/app/pages/swaps/view-quote/index.js b/ui/app/pages/swaps/view-quote/index.js index 7e6d2fc6cd..4a412aa905 100644 --- a/ui/app/pages/swaps/view-quote/index.js +++ b/ui/app/pages/swaps/view-quote/index.js @@ -1 +1 @@ -export { default } from './view-quote' +export { default } from './view-quote'; diff --git a/ui/app/pages/swaps/view-quote/tests/view-quote-price-difference.test.js b/ui/app/pages/swaps/view-quote/tests/view-quote-price-difference.test.js index 1fc66284b0..ae41cd7940 100644 --- a/ui/app/pages/swaps/view-quote/tests/view-quote-price-difference.test.js +++ b/ui/app/pages/swaps/view-quote/tests/view-quote-price-difference.test.js @@ -1,13 +1,13 @@ -import assert from 'assert' -import React from 'react' -import { shallow } from 'enzyme' -import { Provider } from 'react-redux' -import configureMockStore from 'redux-mock-store' -import { NETWORK_TYPE_RPC } from '../../../../../../shared/constants/network' -import ViewQuotePriceDifference from '../view-quote-price-difference' +import assert from 'assert'; +import React from 'react'; +import { shallow } from 'enzyme'; +import { Provider } from 'react-redux'; +import configureMockStore from 'redux-mock-store'; +import { NETWORK_TYPE_RPC } from '../../../../../../shared/constants/network'; +import ViewQuotePriceDifference from '../view-quote-price-difference'; describe('View Price Quote Difference', function () { - const t = (key) => `translate ${key}` + const t = (key) => `translate ${key}`; const state = { metamask: { @@ -17,9 +17,9 @@ describe('View Price Quote Difference', function () { currentCurrency: 'usd', conversionRate: 600.0, }, - } + }; - const store = configureMockStore()(state) + const store = configureMockStore()(state); // Sample transaction is 1 $ETH to ~42.880915 $LINK const DEFAULT_PROPS = { @@ -84,9 +84,9 @@ describe('View Price Quote Difference', function () { }, sourceTokenValue: '1', destinationTokenValue: '42.947749', - } + }; - let component + let component; function renderComponent(props) { component = shallow( @@ -95,56 +95,56 @@ describe('View Price Quote Difference', function () { { context: { t }, }, - ) + ); } afterEach(function () { - component.unmount() - }) + component.unmount(); + }); it('does not render when there is no quote', function () { - const props = { ...DEFAULT_PROPS, usedQuote: null } - renderComponent(props) + const props = { ...DEFAULT_PROPS, usedQuote: null }; + renderComponent(props); const wrappingDiv = component.find( '.view-quote__price-difference-warning-wrapper', - ) - assert.strictEqual(wrappingDiv.length, 0) - }) + ); + assert.strictEqual(wrappingDiv.length, 0); + }); it('does not render when the item is in the low bucket', function () { - const props = { ...DEFAULT_PROPS } - props.usedQuote.priceSlippage.bucket = 'low' + const props = { ...DEFAULT_PROPS }; + props.usedQuote.priceSlippage.bucket = 'low'; - renderComponent(props) + renderComponent(props); const wrappingDiv = component.find( '.view-quote__price-difference-warning-wrapper', - ) - assert.strictEqual(wrappingDiv.length, 0) - }) + ); + assert.strictEqual(wrappingDiv.length, 0); + }); it('displays an error when in medium bucket', function () { - const props = { ...DEFAULT_PROPS } - props.usedQuote.priceSlippage.bucket = 'medium' + const props = { ...DEFAULT_PROPS }; + props.usedQuote.priceSlippage.bucket = 'medium'; - renderComponent(props) - assert.strictEqual(component.html().includes('medium'), true) - }) + renderComponent(props); + assert.strictEqual(component.html().includes('medium'), true); + }); it('displays an error when in high bucket', function () { - const props = { ...DEFAULT_PROPS } - props.usedQuote.priceSlippage.bucket = 'high' + const props = { ...DEFAULT_PROPS }; + props.usedQuote.priceSlippage.bucket = 'high'; - renderComponent(props) - assert.strictEqual(component.html().includes('high'), true) - }) + renderComponent(props); + assert.strictEqual(component.html().includes('high'), true); + }); it('displays a fiat error when calculationError is present', function () { - const props = { ...DEFAULT_PROPS, priceSlippageUnknownFiatValue: true } + const props = { ...DEFAULT_PROPS, priceSlippageUnknownFiatValue: true }; props.usedQuote.priceSlippage.calculationError = - 'Could not determine price.' + 'Could not determine price.'; - renderComponent(props) - assert.strictEqual(component.html().includes('fiat-error'), true) - }) -}) + renderComponent(props); + assert.strictEqual(component.html().includes('fiat-error'), true); + }); +}); diff --git a/ui/app/pages/swaps/view-quote/view-quote-price-difference.js b/ui/app/pages/swaps/view-quote/view-quote-price-difference.js index bf229b8da7..b7589a5678 100644 --- a/ui/app/pages/swaps/view-quote/view-quote-price-difference.js +++ b/ui/app/pages/swaps/view-quote/view-quote-price-difference.js @@ -1,11 +1,11 @@ -import React, { useContext } from 'react' +import React, { useContext } from 'react'; -import PropTypes from 'prop-types' -import classnames from 'classnames' -import { I18nContext } from '../../../contexts/i18n' +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import { I18nContext } from '../../../contexts/i18n'; -import ActionableMessage from '../actionable-message' -import Tooltip from '../../../components/ui/tooltip' +import ActionableMessage from '../actionable-message'; +import Tooltip from '../../../components/ui/tooltip'; export default function ViewQuotePriceDifference(props) { const { @@ -18,25 +18,25 @@ export default function ViewQuotePriceDifference(props) { priceSlippageFromDestination, priceDifferencePercentage, priceSlippageUnknownFiatValue, - } = props + } = props; - const t = useContext(I18nContext) + const t = useContext(I18nContext); - let priceDifferenceTitle = '' - let priceDifferenceMessage = '' - let priceDifferenceClass = '' - let priceDifferenceAcknowledgementText = '' + let priceDifferenceTitle = ''; + let priceDifferenceMessage = ''; + let priceDifferenceClass = ''; + let priceDifferenceAcknowledgementText = ''; if (priceSlippageUnknownFiatValue) { // A calculation error signals we cannot determine dollar value - priceDifferenceMessage = t('swapPriceDifferenceUnavailable') - priceDifferenceClass = 'fiat-error' + priceDifferenceMessage = t('swapPriceDifferenceUnavailable'); + priceDifferenceClass = 'fiat-error'; priceDifferenceAcknowledgementText = t( 'swapPriceDifferenceAcknowledgementNoFiat', - ) + ); } else { priceDifferenceTitle = t('swapPriceDifferenceTitle', [ priceDifferencePercentage, - ]) + ]); priceDifferenceMessage = t('swapPriceDifference', [ sourceTokenValue, // Number of source token to swap usedQuote.sourceTokenInfo.symbol, // Source token symbol @@ -44,9 +44,11 @@ export default function ViewQuotePriceDifference(props) { destinationTokenValue, // Number of destination tokens in return usedQuote.destinationTokenInfo.symbol, // Destination token symbol, priceSlippageFromDestination, // Destination tokens total value - ]) - priceDifferenceClass = usedQuote.priceSlippage.bucket - priceDifferenceAcknowledgementText = t('swapPriceDifferenceAcknowledgement') + ]); + priceDifferenceClass = usedQuote.priceSlippage.bucket; + priceDifferenceAcknowledgementText = t( + 'swapPriceDifferenceAcknowledgement', + ); } return ( @@ -70,7 +72,7 @@ export default function ViewQuotePriceDifference(props) {
    - ) + ); } ViewQuotePriceDifference.propTypes = { @@ -102,4 +104,4 @@ ViewQuotePriceDifference.propTypes = { priceSlippageFromDestination: PropTypes.string, priceDifferencePercentage: PropTypes.number, priceSlippageUnknownFiatValue: PropTypes.bool, -} +}; diff --git a/ui/app/pages/swaps/view-quote/view-quote.js b/ui/app/pages/swaps/view-quote/view-quote.js index 466fb83775..2c5c43865d 100644 --- a/ui/app/pages/swaps/view-quote/view-quote.js +++ b/ui/app/pages/swaps/view-quote/view-quote.js @@ -1,17 +1,17 @@ -import React, { useState, useContext, useMemo, useEffect, useRef } from 'react' -import { useSelector, useDispatch } from 'react-redux' -import { useHistory } from 'react-router-dom' -import BigNumber from 'bignumber.js' -import { isEqual } from 'lodash' -import classnames from 'classnames' -import { I18nContext } from '../../../contexts/i18n' -import SelectQuotePopover from '../select-quote-popover' -import { useEthFiatAmount } from '../../../hooks/useEthFiatAmount' -import { useEqualityCheck } from '../../../hooks/useEqualityCheck' -import { useNewMetricEvent } from '../../../hooks/useMetricEvent' -import { useSwapsEthToken } from '../../../hooks/useSwapsEthToken' -import { MetaMetricsContext } from '../../../contexts/metametrics.new' -import FeeCard from '../fee-card' +import React, { useState, useContext, useMemo, useEffect, useRef } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { useHistory } from 'react-router-dom'; +import BigNumber from 'bignumber.js'; +import { isEqual } from 'lodash'; +import classnames from 'classnames'; +import { I18nContext } from '../../../contexts/i18n'; +import SelectQuotePopover from '../select-quote-popover'; +import { useEthFiatAmount } from '../../../hooks/useEthFiatAmount'; +import { useEqualityCheck } from '../../../hooks/useEqualityCheck'; +import { useNewMetricEvent } from '../../../hooks/useMetricEvent'; +import { useSwapsEthToken } from '../../../hooks/useSwapsEthToken'; +import { MetaMetricsContext } from '../../../contexts/metametrics.new'; +import FeeCard from '../fee-card'; import { FALLBACK_GAS_MULTIPLIER, getQuotes, @@ -30,146 +30,146 @@ import { getBackgroundSwapRouteState, swapsQuoteSelected, getSwapsQuoteRefreshTime, -} from '../../../ducks/swaps/swaps' +} from '../../../ducks/swaps/swaps'; import { conversionRateSelector, getSelectedAccount, getCurrentCurrency, getTokenExchangeRates, -} from '../../../selectors' -import { toPrecisionWithoutTrailingZeros } from '../../../helpers/utils/util' -import { getTokens } from '../../../ducks/metamask/metamask' +} from '../../../selectors'; +import { toPrecisionWithoutTrailingZeros } from '../../../helpers/utils/util'; +import { getTokens } from '../../../ducks/metamask/metamask'; import { safeRefetchQuotes, setCustomApproveTxData, setSwapsErrorKey, showModal, -} from '../../../store/actions' +} from '../../../store/actions'; import { ASSET_ROUTE, BUILD_QUOTE_ROUTE, DEFAULT_ROUTE, SWAPS_ERROR_ROUTE, AWAITING_SWAP_ROUTE, -} from '../../../helpers/constants/routes' -import { getTokenData } from '../../../helpers/utils/transactions.util' +} from '../../../helpers/constants/routes'; +import { getTokenData } from '../../../helpers/utils/transactions.util'; import { calcTokenAmount, calcTokenValue, getTokenValueParam, -} from '../../../helpers/utils/token-util' +} from '../../../helpers/utils/token-util'; import { decimalToHex, hexToDecimal, getValueFromWeiHex, -} from '../../../helpers/utils/conversions.util' -import MainQuoteSummary from '../main-quote-summary' -import { calcGasTotal } from '../../send/send.utils' -import { getCustomTxParamsData } from '../../confirm-approve/confirm-approve.util' -import ActionableMessage from '../actionable-message' +} from '../../../helpers/utils/conversions.util'; +import MainQuoteSummary from '../main-quote-summary'; +import { calcGasTotal } from '../../send/send.utils'; +import { getCustomTxParamsData } from '../../confirm-approve/confirm-approve.util'; +import ActionableMessage from '../actionable-message'; import { quotesToRenderableData, getRenderableNetworkFeesForQuote, -} from '../swaps.util' -import { useTokenTracker } from '../../../hooks/useTokenTracker' -import { QUOTES_EXPIRED_ERROR } from '../../../helpers/constants/swaps' -import CountdownTimer from '../countdown-timer' -import SwapsFooter from '../swaps-footer' -import ViewQuotePriceDifference from './view-quote-price-difference' +} from '../swaps.util'; +import { useTokenTracker } from '../../../hooks/useTokenTracker'; +import { QUOTES_EXPIRED_ERROR } from '../../../helpers/constants/swaps'; +import CountdownTimer from '../countdown-timer'; +import SwapsFooter from '../swaps-footer'; +import ViewQuotePriceDifference from './view-quote-price-difference'; export default function ViewQuote() { - const history = useHistory() - const dispatch = useDispatch() - const t = useContext(I18nContext) - const metaMetricsEvent = useContext(MetaMetricsContext) + const history = useHistory(); + const dispatch = useDispatch(); + const t = useContext(I18nContext); + const metaMetricsEvent = useContext(MetaMetricsContext); - const [dispatchedSafeRefetch, setDispatchedSafeRefetch] = useState(false) - const [submitClicked, setSubmitClicked] = useState(false) - const [selectQuotePopoverShown, setSelectQuotePopoverShown] = useState(false) - const [warningHidden, setWarningHidden] = useState(false) - const [originalApproveAmount, setOriginalApproveAmount] = useState(null) + const [dispatchedSafeRefetch, setDispatchedSafeRefetch] = useState(false); + const [submitClicked, setSubmitClicked] = useState(false); + const [selectQuotePopoverShown, setSelectQuotePopoverShown] = useState(false); + const [warningHidden, setWarningHidden] = useState(false); + const [originalApproveAmount, setOriginalApproveAmount] = useState(null); const [ acknowledgedPriceDifference, setAcknowledgedPriceDifference, - ] = useState(false) + ] = useState(false); - const routeState = useSelector(getBackgroundSwapRouteState) - const quotes = useSelector(getQuotes, isEqual) + const routeState = useSelector(getBackgroundSwapRouteState); + const quotes = useSelector(getQuotes, isEqual); useEffect(() => { if (!Object.values(quotes).length) { - history.push(BUILD_QUOTE_ROUTE) + history.push(BUILD_QUOTE_ROUTE); } else if (routeState === 'awaiting') { - history.push(AWAITING_SWAP_ROUTE) + history.push(AWAITING_SWAP_ROUTE); } - }, [history, quotes, routeState]) + }, [history, quotes, routeState]); - const quotesLastFetched = useSelector(getQuotesLastFetched) + const quotesLastFetched = useSelector(getQuotesLastFetched); // Select necessary data - const gasPrice = useSelector(getUsedSwapsGasPrice) - const customMaxGas = useSelector(getCustomSwapsGas) - const tokenConversionRates = useSelector(getTokenExchangeRates) - const memoizedTokenConversionRates = useEqualityCheck(tokenConversionRates) - const { balance: ethBalance } = useSelector(getSelectedAccount) - const conversionRate = useSelector(conversionRateSelector) - const currentCurrency = useSelector(getCurrentCurrency) - const swapsTokens = useSelector(getTokens) - const balanceError = useSelector(getBalanceError) - const fetchParams = useSelector(getFetchParams) - const approveTxParams = useSelector(getApproveTxParams) - const selectedQuote = useSelector(getSelectedQuote) - const topQuote = useSelector(getTopQuote) - const usedQuote = selectedQuote || topQuote - const tradeValue = usedQuote?.trade?.value ?? '0x0' - const swapsQuoteRefreshTime = useSelector(getSwapsQuoteRefreshTime) - - const { isBestQuote } = usedQuote - - const fetchParamsSourceToken = fetchParams?.sourceToken + const gasPrice = useSelector(getUsedSwapsGasPrice); + const customMaxGas = useSelector(getCustomSwapsGas); + const tokenConversionRates = useSelector(getTokenExchangeRates); + const memoizedTokenConversionRates = useEqualityCheck(tokenConversionRates); + const { balance: ethBalance } = useSelector(getSelectedAccount); + const conversionRate = useSelector(conversionRateSelector); + const currentCurrency = useSelector(getCurrentCurrency); + const swapsTokens = useSelector(getTokens); + const balanceError = useSelector(getBalanceError); + const fetchParams = useSelector(getFetchParams); + const approveTxParams = useSelector(getApproveTxParams); + const selectedQuote = useSelector(getSelectedQuote); + const topQuote = useSelector(getTopQuote); + const usedQuote = selectedQuote || topQuote; + const tradeValue = usedQuote?.trade?.value ?? '0x0'; + const swapsQuoteRefreshTime = useSelector(getSwapsQuoteRefreshTime); + + const { isBestQuote } = usedQuote; + + const fetchParamsSourceToken = fetchParams?.sourceToken; const usedGasLimit = usedQuote?.gasEstimateWithRefund || - `0x${decimalToHex(usedQuote?.averageGas || 0)}` + `0x${decimalToHex(usedQuote?.averageGas || 0)}`; - const gasLimitForMax = usedQuote?.gasEstimate || `0x0` + const gasLimitForMax = usedQuote?.gasEstimate || `0x0`; const usedGasLimitWithMultiplier = new BigNumber(gasLimitForMax, 16) .times(usedQuote?.gasMultiplier || FALLBACK_GAS_MULTIPLIER, 10) .round(0) - .toString(16) + .toString(16); const nonCustomMaxGasLimit = usedQuote?.gasEstimate ? usedGasLimitWithMultiplier - : `0x${decimalToHex(usedQuote?.maxGas || 0)}` - const maxGasLimit = customMaxGas || nonCustomMaxGasLimit + : `0x${decimalToHex(usedQuote?.maxGas || 0)}`; + const maxGasLimit = customMaxGas || nonCustomMaxGasLimit; - const gasTotalInWeiHex = calcGasTotal(maxGasLimit, gasPrice) + const gasTotalInWeiHex = calcGasTotal(maxGasLimit, gasPrice); - const { tokensWithBalances } = useTokenTracker(swapsTokens) - const swapsEthToken = useSwapsEthToken() + const { tokensWithBalances } = useTokenTracker(swapsTokens); + const swapsEthToken = useSwapsEthToken(); const balanceToken = fetchParamsSourceToken === swapsEthToken.address ? swapsEthToken : tokensWithBalances.find( ({ address }) => address === fetchParamsSourceToken, - ) + ); - const selectedFromToken = balanceToken || usedQuote.sourceTokenInfo + const selectedFromToken = balanceToken || usedQuote.sourceTokenInfo; const tokenBalance = tokensWithBalances?.length && calcTokenAmount( selectedFromToken.balance || '0x0', selectedFromToken.decimals, - ).toFixed(9) + ).toFixed(9); - const approveData = getTokenData(approveTxParams?.data) - const approveValue = approveData && getTokenValueParam(approveData) + const approveData = getTokenData(approveTxParams?.data); + const approveValue = approveData && getTokenValueParam(approveData); const approveAmount = approveValue && selectedFromToken?.decimals !== undefined && - calcTokenAmount(approveValue, selectedFromToken.decimals).toFixed(9) - const approveGas = approveTxParams?.gas + calcTokenAmount(approveValue, selectedFromToken.decimals).toFixed(9); + const approveGas = approveTxParams?.gas; const renderablePopoverData = useMemo(() => { return quotesToRenderableData( @@ -179,7 +179,7 @@ export default function ViewQuote() { currentCurrency, approveGas, memoizedTokenConversionRates, - ) + ); }, [ quotes, gasPrice, @@ -187,12 +187,12 @@ export default function ViewQuote() { currentCurrency, approveGas, memoizedTokenConversionRates, - ]) + ]); const renderableDataForUsedQuote = renderablePopoverData.find( (renderablePopoverDatum) => renderablePopoverDatum.aggId === usedQuote.aggregator, - ) + ); const { destinationTokenDecimals, @@ -203,7 +203,7 @@ export default function ViewQuote() { sourceTokenSymbol, sourceTokenValue, sourceTokenIconUrl, - } = renderableDataForUsedQuote + } = renderableDataForUsedQuote; const { feeInFiat, feeInEth } = getRenderableNetworkFeesForQuote( usedGasLimit, @@ -214,7 +214,7 @@ export default function ViewQuote() { tradeValue, sourceTokenSymbol, usedQuote.sourceAmount, - ) + ); const { feeInFiat: maxFeeInFiat, @@ -229,18 +229,18 @@ export default function ViewQuote() { tradeValue, sourceTokenSymbol, usedQuote.sourceAmount, - ) + ); - const tokenCost = new BigNumber(usedQuote.sourceAmount) + const tokenCost = new BigNumber(usedQuote.sourceAmount); const ethCost = new BigNumber(usedQuote.trade.value || 0, 10).plus( new BigNumber(gasTotalInWeiHex, 16), - ) + ); const insufficientTokens = (tokensWithBalances?.length || balanceError) && - tokenCost.gt(new BigNumber(selectedFromToken.balance || '0x0')) + tokenCost.gt(new BigNumber(selectedFromToken.balance || '0x0')); - const insufficientEth = ethCost.gt(new BigNumber(ethBalance || '0x0')) + const insufficientEth = ethCost.gt(new BigNumber(ethBalance || '0x0')); const tokenBalanceNeeded = insufficientTokens ? toPrecisionWithoutTrailingZeros( @@ -249,7 +249,7 @@ export default function ViewQuote() { .toString(10), 6, ) - : null + : null; const ethBalanceNeeded = insufficientEth ? toPrecisionWithoutTrailingZeros( @@ -259,30 +259,30 @@ export default function ViewQuote() { .toString(10), 6, ) - : null + : null; - const destinationToken = useSelector(getDestinationTokenInfo) + const destinationToken = useSelector(getDestinationTokenInfo); useEffect(() => { if (insufficientTokens || insufficientEth) { - dispatch(setBalanceError(true)) + dispatch(setBalanceError(true)); } else if (balanceError && !insufficientTokens && !insufficientEth) { - dispatch(setBalanceError(false)) + dispatch(setBalanceError(false)); } - }, [insufficientTokens, insufficientEth, balanceError, dispatch]) + }, [insufficientTokens, insufficientEth, balanceError, dispatch]); useEffect(() => { - const currentTime = Date.now() - const timeSinceLastFetched = currentTime - quotesLastFetched + const currentTime = Date.now(); + const timeSinceLastFetched = currentTime - quotesLastFetched; if ( timeSinceLastFetched > swapsQuoteRefreshTime && !dispatchedSafeRefetch ) { - setDispatchedSafeRefetch(true) - dispatch(safeRefetchQuotes()) + setDispatchedSafeRefetch(true); + dispatch(safeRefetchQuotes()); } else if (timeSinceLastFetched > swapsQuoteRefreshTime) { - dispatch(setSwapsErrorKey(QUOTES_EXPIRED_ERROR)) - history.push(SWAPS_ERROR_ROUTE) + dispatch(setSwapsErrorKey(QUOTES_EXPIRED_ERROR)); + history.push(SWAPS_ERROR_ROUTE); } }, [ quotesLastFetched, @@ -290,19 +290,19 @@ export default function ViewQuote() { dispatch, history, swapsQuoteRefreshTime, - ]) + ]); useEffect(() => { if (!originalApproveAmount && approveAmount) { - setOriginalApproveAmount(approveAmount) + setOriginalApproveAmount(approveAmount); } - }, [originalApproveAmount, approveAmount]) + }, [originalApproveAmount, approveAmount]); const showInsufficientWarning = - (balanceError || tokenBalanceNeeded || ethBalanceNeeded) && !warningHidden + (balanceError || tokenBalanceNeeded || ethBalanceNeeded) && !warningHidden; - const numberOfQuotes = Object.values(quotes).length - const bestQuoteReviewedEventSent = useRef() + const numberOfQuotes = Object.values(quotes).length; + const bestQuoteReviewedEventSent = useRef(); const eventObjectBase = { token_from: sourceTokenSymbol, token_from_amount: sourceTokenValue, @@ -314,7 +314,7 @@ export default function ViewQuote() { response_time: fetchParams?.responseTime, best_quote_source: topQuote?.aggregator, available_quotes: numberOfQuotes, - } + }; const allAvailableQuotesOpened = useNewMetricEvent({ event: 'All Available Quotes Opened', @@ -327,7 +327,7 @@ export default function ViewQuote() { ? null : usedQuote?.aggregator, }, - }) + }); const quoteDetailsOpened = useNewMetricEvent({ event: 'Quote Details Opened', category: 'swaps', @@ -339,7 +339,7 @@ export default function ViewQuote() { ? null : usedQuote?.aggregator, }, - }) + }); const editSpendLimitOpened = useNewMetricEvent({ event: 'Edit Spend Limit Opened', category: 'swaps', @@ -349,13 +349,13 @@ export default function ViewQuote() { custom_spend_limit_amount: originalApproveAmount === approveAmount ? null : approveAmount, }, - }) + }); const bestQuoteReviewedEvent = useNewMetricEvent({ event: 'Best Quote Reviewed', category: 'swaps', sensitiveProperties: { ...eventObjectBase, network_fees: feeInFiat }, - }) + }); useEffect(() => { if ( !bestQuoteReviewedEventSent.current && @@ -370,8 +370,8 @@ export default function ViewQuote() { feeInFiat, ].every((dep) => dep !== null && dep !== undefined) ) { - bestQuoteReviewedEventSent.current = true - bestQuoteReviewedEvent() + bestQuoteReviewedEventSent.current = true; + bestQuoteReviewedEvent(); } }, [ sourceTokenSymbol, @@ -383,12 +383,12 @@ export default function ViewQuote() { numberOfQuotes, feeInFiat, bestQuoteReviewedEvent, - ]) + ]); - const metaMaskFee = usedQuote.fee + const metaMaskFee = usedQuote.fee; const onFeeCardTokenApprovalClick = () => { - editSpendLimitOpened() + editSpendLimitOpened(); dispatch( showModal({ name: 'EDIT_APPROVAL_PERMISSION', @@ -398,17 +398,17 @@ export default function ViewQuote() { const customPermissionAmount = newCustomPermissionAmount === '' ? originalApproveAmount - : newCustomPermissionAmount + : newCustomPermissionAmount; const newData = getCustomTxParamsData(approveTxParams.data, { customPermissionAmount, decimals: selectedFromToken.decimals, - }) + }); if ( customPermissionAmount?.length && approveTxParams.data !== newData ) { - dispatch(setCustomApproveTxData(newData)) + dispatch(setCustomApproveTxData(newData)); } }, tokenAmount: originalApproveAmount, @@ -421,27 +421,27 @@ export default function ViewQuote() { selectedFromToken.decimals, ), }), - ) - } + ); + }; - const nonGasFeeIsPositive = new BigNumber(nonGasFee, 16).gt(0) - const approveGasTotal = calcGasTotal(approveGas || '0x0', gasPrice) + const nonGasFeeIsPositive = new BigNumber(nonGasFee, 16).gt(0); + const approveGasTotal = calcGasTotal(approveGas || '0x0', gasPrice); const extraNetworkFeeTotalInHexWEI = new BigNumber(nonGasFee, 16) .plus(approveGasTotal, 16) - .toString(16) + .toString(16); const extraNetworkFeeTotalInEth = getValueFromWeiHex({ value: extraNetworkFeeTotalInHexWEI, toDenomination: 'ETH', numberOfDecimals: 4, - }) + }); - let extraInfoRowLabel = '' + let extraInfoRowLabel = ''; if (approveGas && nonGasFeeIsPositive) { - extraInfoRowLabel = t('approvalAndAggregatorTxFeeCost') + extraInfoRowLabel = t('approvalAndAggregatorTxFeeCost'); } else if (approveGas) { - extraInfoRowLabel = t('approvalTxGasCost') + extraInfoRowLabel = t('approvalTxGasCost'); } else if (nonGasFeeIsPositive) { - extraInfoRowLabel = t('aggregatorFeeCost') + extraInfoRowLabel = t('aggregatorFeeCost'); } const onFeeCardMaxRowClick = () => @@ -463,13 +463,13 @@ export default function ViewQuote() { initialGasLimit: maxGasLimit, minimumGasLimit: new BigNumber(nonCustomMaxGasLimit, 16).toNumber(), }), - ) + ); const tokenApprovalTextComponent = ( {sourceTokenSymbol} - ) + ); const actionableInsufficientMessage = t('swapApproveNeedMoreTokens', [ @@ -478,25 +478,25 @@ export default function ViewQuote() { tokenBalanceNeeded && !(sourceTokenSymbol === 'ETH') ? sourceTokenSymbol : 'ETH', - ]) + ]); // Price difference warning - let viewQuotePriceDifferenceComponent = null + let viewQuotePriceDifferenceComponent = null; const priceSlippageFromSource = useEthFiatAmount( usedQuote?.priceSlippage?.sourceAmountInETH || 0, - ) + ); const priceSlippageFromDestination = useEthFiatAmount( usedQuote?.priceSlippage?.destinationAmountInEth || 0, - ) + ); // We cannot present fiat value if there is a calculation error or no slippage // from source or destination const priceSlippageUnknownFiatValue = !priceSlippageFromSource || !priceSlippageFromDestination || - usedQuote?.priceSlippage?.calculationError + usedQuote?.priceSlippage?.calculationError; - let priceDifferencePercentage = 0 + let priceDifferencePercentage = 0; if (usedQuote?.priceSlippage?.ratio) { priceDifferencePercentage = parseFloat( new BigNumber(usedQuote.priceSlippage.ratio, 10) @@ -504,14 +504,14 @@ export default function ViewQuote() { .times(100, 10) .toFixed(2), 10, - ) + ); } const shouldShowPriceDifferenceWarning = !showInsufficientWarning && usedQuote && (['high', 'medium'].includes(usedQuote.priceSlippage.bucket) || - priceSlippageUnknownFiatValue) + priceSlippageUnknownFiatValue); if (shouldShowPriceDifferenceWarning) { viewQuotePriceDifferenceComponent = ( @@ -524,18 +524,18 @@ export default function ViewQuote() { priceDifferencePercentage={priceDifferencePercentage} priceSlippageUnknownFiatValue={priceSlippageUnknownFiatValue} onAcknowledgementClick={() => { - setAcknowledgedPriceDifference(true) + setAcknowledgedPriceDifference(true); }} acknowledged={acknowledgedPriceDifference} /> - ) + ); } const disableSubmissionDueToPriceWarning = - shouldShowPriceDifferenceWarning && !acknowledgedPriceDifference + shouldShowPriceDifferenceWarning && !acknowledgedPriceDifference; const isShowingWarning = - showInsufficientWarning || shouldShowPriceDifferenceWarning + showInsufficientWarning || shouldShowPriceDifferenceWarning; return (
    @@ -614,8 +614,8 @@ export default function ViewQuote() { isBestQuote={isBestQuote} numberOfQuotes={Object.values(quotes).length} onQuotesClick={() => { - allAvailableQuotesOpened() - setSelectQuotePopoverShown(true) + allAvailableQuotesOpened(); + setSelectQuotePopoverShown(true); }} tokenConversionRate={ destinationTokenSymbol === 'ETH' @@ -627,13 +627,13 @@ export default function ViewQuote() {
    { - setSubmitClicked(true) + setSubmitClicked(true); if (!balanceError) { - dispatch(signAndSendTransactions(history, metaMetricsEvent)) + dispatch(signAndSendTransactions(history, metaMetricsEvent)); } else if (destinationToken.symbol === 'ETH') { - history.push(DEFAULT_ROUTE) + history.push(DEFAULT_ROUTE); } else { - history.push(`${ASSET_ROUTE}/${destinationToken.address}`) + history.push(`${ASSET_ROUTE}/${destinationToken.address}`); } }} submitText={t('swap')} @@ -649,5 +649,5 @@ export default function ViewQuote() { showTopBorder /> - ) + ); } diff --git a/ui/app/pages/unlock-page/index.js b/ui/app/pages/unlock-page/index.js index 1f4c6ead9c..2eac68721e 100644 --- a/ui/app/pages/unlock-page/index.js +++ b/ui/app/pages/unlock-page/index.js @@ -1,3 +1,3 @@ -import UnlockPage from './unlock-page.container' +import UnlockPage from './unlock-page.container'; -export default UnlockPage +export default UnlockPage; diff --git a/ui/app/pages/unlock-page/tests/unlock-page.test.js b/ui/app/pages/unlock-page/tests/unlock-page.test.js index 34b258469f..37bff5c345 100644 --- a/ui/app/pages/unlock-page/tests/unlock-page.test.js +++ b/ui/app/pages/unlock-page/tests/unlock-page.test.js @@ -1,11 +1,11 @@ -import assert from 'assert' -import React from 'react' -import sinon from 'sinon' -import { mount } from 'enzyme' -import UnlockPage from '..' +import assert from 'assert'; +import React from 'react'; +import sinon from 'sinon'; +import { mount } from 'enzyme'; +import UnlockPage from '..'; describe('Unlock Page', function () { - let wrapper + let wrapper; const props = { history: { @@ -17,47 +17,47 @@ describe('Unlock Page', function () { onSubmit: sinon.spy(), forceUpdateMetamaskState: sinon.spy(), showOptInModal: sinon.spy(), - } + }; beforeEach(function () { wrapper = mount(, { context: { t: (str) => str, }, - }) - }) + }); + }); after(function () { - sinon.restore() - }) + sinon.restore(); + }); it('renders', function () { - assert.strictEqual(wrapper.length, 1) - }) + assert.strictEqual(wrapper.length, 1); + }); it('changes password and submits', function () { - const passwordField = wrapper.find({ type: 'password', id: 'password' }) - const loginButton = wrapper.find({ type: 'submit' }).last() + const passwordField = wrapper.find({ type: 'password', id: 'password' }); + const loginButton = wrapper.find({ type: 'submit' }).last(); - const event = { target: { value: 'password' } } - assert.strictEqual(wrapper.instance().state.password, '') - passwordField.last().simulate('change', event) - assert.strictEqual(wrapper.instance().state.password, 'password') + const event = { target: { value: 'password' } }; + assert.strictEqual(wrapper.instance().state.password, ''); + passwordField.last().simulate('change', event); + assert.strictEqual(wrapper.instance().state.password, 'password'); - loginButton.simulate('click') - assert(props.onSubmit.calledOnce) - }) + loginButton.simulate('click'); + assert(props.onSubmit.calledOnce); + }); it('clicks imports seed button', function () { - const importSeedButton = wrapper.find('.unlock-page__link--import') + const importSeedButton = wrapper.find('.unlock-page__link--import'); - importSeedButton.simulate('click') - assert(props.onImport.calledOnce) - }) + importSeedButton.simulate('click'); + assert(props.onImport.calledOnce); + }); it('clicks restore', function () { - const restoreFromSeedButton = wrapper.find('.unlock-page__link').at(0) - restoreFromSeedButton.simulate('click') - assert(props.onRestore.calledOnce) - }) -}) + const restoreFromSeedButton = wrapper.find('.unlock-page__link').at(0); + restoreFromSeedButton.simulate('click'); + assert(props.onRestore.calledOnce); + }); +}); diff --git a/ui/app/pages/unlock-page/unlock-page.component.js b/ui/app/pages/unlock-page/unlock-page.component.js index 17776f7bd3..bbf18716cc 100644 --- a/ui/app/pages/unlock-page/unlock-page.component.js +++ b/ui/app/pages/unlock-page/unlock-page.component.js @@ -1,17 +1,17 @@ -import { EventEmitter } from 'events' -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import Button from '@material-ui/core/Button' -import getCaretCoordinates from 'textarea-caret' -import TextField from '../../components/ui/text-field' -import Mascot from '../../components/ui/mascot' -import { DEFAULT_ROUTE } from '../../helpers/constants/routes' +import { EventEmitter } from 'events'; +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import Button from '@material-ui/core/Button'; +import getCaretCoordinates from 'textarea-caret'; +import TextField from '../../components/ui/text-field'; +import Mascot from '../../components/ui/mascot'; +import { DEFAULT_ROUTE } from '../../helpers/constants/routes'; export default class UnlockPage extends Component { static contextTypes = { metricsEvent: PropTypes.func, t: PropTypes.func, - } + }; static propTypes = { history: PropTypes.object.isRequired, @@ -21,42 +21,42 @@ export default class UnlockPage extends Component { onSubmit: PropTypes.func, forceUpdateMetamaskState: PropTypes.func, showOptInModal: PropTypes.func, - } + }; state = { password: '', error: null, - } + }; - submitting = false + submitting = false; - animationEventEmitter = new EventEmitter() + animationEventEmitter = new EventEmitter(); UNSAFE_componentWillMount() { - const { isUnlocked, history } = this.props + const { isUnlocked, history } = this.props; if (isUnlocked) { - history.push(DEFAULT_ROUTE) + history.push(DEFAULT_ROUTE); } } handleSubmit = async (event) => { - event.preventDefault() - event.stopPropagation() + event.preventDefault(); + event.stopPropagation(); - const { password } = this.state - const { onSubmit, forceUpdateMetamaskState, showOptInModal } = this.props + const { password } = this.state; + const { onSubmit, forceUpdateMetamaskState, showOptInModal } = this.props; if (password === '' || this.submitting) { - return + return; } - this.setState({ error: null }) - this.submitting = true + this.setState({ error: null }); + this.submitting = true; try { - await onSubmit(password) - const newState = await forceUpdateMetamaskState() + await onSubmit(password); + const newState = await forceUpdateMetamaskState(); this.context.metricsEvent({ eventOpts: { category: 'Navigation', @@ -64,17 +64,17 @@ export default class UnlockPage extends Component { name: 'Success', }, isNewVisit: true, - }) + }); if ( newState.participateInMetaMetrics === null || newState.participateInMetaMetrics === undefined ) { - showOptInModal() + showOptInModal(); } } catch ({ message }) { if (message === 'Incorrect password') { - const newState = await forceUpdateMetamaskState() + const newState = await forceUpdateMetamaskState(); this.context.metricsEvent({ eventOpts: { category: 'Navigation', @@ -85,26 +85,26 @@ export default class UnlockPage extends Component { numberOfTokens: newState.tokens.length, numberOfAccounts: Object.keys(newState.accounts).length, }, - }) + }); } - this.setState({ error: message }) - this.submitting = false + this.setState({ error: message }); + this.submitting = false; } - } + }; handleInputChange({ target }) { - this.setState({ password: target.value, error: null }) + this.setState({ password: target.value, error: null }); // tell mascot to look at page action if (target.getBoundingClientRect) { - const element = target - const boundingRect = element.getBoundingClientRect() - const coordinates = getCaretCoordinates(element, element.selectionEnd) + const element = target; + const boundingRect = element.getBoundingClientRect(); + const coordinates = getCaretCoordinates(element, element.selectionEnd); this.animationEventEmitter.emit('point', { x: boundingRect.left + coordinates.left - element.scrollLeft, y: boundingRect.top + coordinates.top - element.scrollTop, - }) + }); } } @@ -117,7 +117,7 @@ export default class UnlockPage extends Component { fontWeight: '400', boxShadow: 'none', borderRadius: '4px', - } + }; return ( - ) + ); } render() { - const { password, error } = this.state - const { t } = this.context - const { onImport, onRestore } = this.props + const { password, error } = this.state; + const { t } = this.context; + const { onImport, onRestore } = this.props; return (
    @@ -180,6 +180,6 @@ export default class UnlockPage extends Component {
    - ) + ); } } diff --git a/ui/app/pages/unlock-page/unlock-page.container.js b/ui/app/pages/unlock-page/unlock-page.container.js index 9284ebebaa..dbc20eaeaa 100644 --- a/ui/app/pages/unlock-page/unlock-page.container.js +++ b/ui/app/pages/unlock-page/unlock-page.container.js @@ -1,29 +1,29 @@ -import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom' -import { compose } from 'redux' -import { getEnvironmentType } from '../../../../app/scripts/lib/util' -import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app' +import { connect } from 'react-redux'; +import { withRouter } from 'react-router-dom'; +import { compose } from 'redux'; +import { getEnvironmentType } from '../../../../app/scripts/lib/util'; +import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app'; import { DEFAULT_ROUTE, RESTORE_VAULT_ROUTE, -} from '../../helpers/constants/routes' +} from '../../helpers/constants/routes'; import { tryUnlockMetamask, forgotPassword, markPasswordForgotten, forceUpdateMetamaskState, showModal, -} from '../../store/actions' -import UnlockPage from './unlock-page.component' +} from '../../store/actions'; +import UnlockPage from './unlock-page.component'; const mapStateToProps = (state) => { const { metamask: { isUnlocked }, - } = state + } = state; return { isUnlocked, - } -} + }; +}; const mapDispatchToProps = (dispatch) => { return { @@ -33,8 +33,8 @@ const mapDispatchToProps = (dispatch) => { forceUpdateMetamaskState: () => forceUpdateMetamaskState(dispatch), showOptInModal: () => dispatch(showModal({ name: 'METAMETRICS_OPT_IN_MODAL' })), - } -} + }; +}; const mergeProps = (stateProps, dispatchProps, ownProps) => { const { @@ -43,22 +43,22 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { // eslint-disable-next-line no-shadow tryUnlockMetamask, ...restDispatchProps - } = dispatchProps - const { history, onSubmit: ownPropsSubmit, ...restOwnProps } = ownProps + } = dispatchProps; + const { history, onSubmit: ownPropsSubmit, ...restOwnProps } = ownProps; const onImport = async () => { - await markPasswordForgotten() - history.push(RESTORE_VAULT_ROUTE) + await markPasswordForgotten(); + history.push(RESTORE_VAULT_ROUTE); if (getEnvironmentType() === ENVIRONMENT_TYPE_POPUP) { - global.platform.openExtensionInBrowser(RESTORE_VAULT_ROUTE) + global.platform.openExtensionInBrowser(RESTORE_VAULT_ROUTE); } - } + }; const onSubmit = async (password) => { - await tryUnlockMetamask(password) - history.push(DEFAULT_ROUTE) - } + await tryUnlockMetamask(password); + history.push(DEFAULT_ROUTE); + }; return { ...stateProps, @@ -68,10 +68,10 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { onRestore: onImport, onSubmit: ownPropsSubmit || onSubmit, history, - } -} + }; +}; export default compose( withRouter, connect(mapStateToProps, mapDispatchToProps, mergeProps), -)(UnlockPage) +)(UnlockPage); diff --git a/ui/app/selectors/confirm-transaction.js b/ui/app/selectors/confirm-transaction.js index 3dc77d7d1f..030da5f8e7 100644 --- a/ui/app/selectors/confirm-transaction.js +++ b/ui/app/selectors/confirm-transaction.js @@ -1,6 +1,6 @@ -import { createSelector } from 'reselect' -import txHelper from '../../lib/tx-helper' -import { calcTokenAmount } from '../helpers/utils/token-util' +import { createSelector } from 'reselect'; +import txHelper from '../../lib/tx-helper'; +import { calcTokenAmount } from '../helpers/utils/token-util'; import { roundExponential, getValueFromWeiHex, @@ -8,21 +8,21 @@ import { getTransactionFee, addFiat, addEth, -} from '../helpers/utils/confirm-tx.util' -import { sumHexes } from '../helpers/utils/transactions.util' -import { getNativeCurrency } from '.' +} from '../helpers/utils/confirm-tx.util'; +import { sumHexes } from '../helpers/utils/transactions.util'; +import { getNativeCurrency } from '.'; -const unapprovedTxsSelector = (state) => state.metamask.unapprovedTxs -const unapprovedMsgsSelector = (state) => state.metamask.unapprovedMsgs +const unapprovedTxsSelector = (state) => state.metamask.unapprovedTxs; +const unapprovedMsgsSelector = (state) => state.metamask.unapprovedMsgs; const unapprovedPersonalMsgsSelector = (state) => - state.metamask.unapprovedPersonalMsgs + state.metamask.unapprovedPersonalMsgs; const unapprovedDecryptMsgsSelector = (state) => - state.metamask.unapprovedDecryptMsgs + state.metamask.unapprovedDecryptMsgs; const unapprovedEncryptionPublicKeyMsgsSelector = (state) => - state.metamask.unapprovedEncryptionPublicKeyMsgs + state.metamask.unapprovedEncryptionPublicKeyMsgs; const unapprovedTypedMessagesSelector = (state) => - state.metamask.unapprovedTypedMessages -const networkSelector = (state) => state.metamask.network + state.metamask.unapprovedTypedMessages; +const networkSelector = (state) => state.metamask.network; export const unconfirmedTransactionsListSelector = createSelector( unapprovedTxsSelector, @@ -50,7 +50,7 @@ export const unconfirmedTransactionsListSelector = createSelector( unapprovedTypedMessages, network, ) || [], -) +); export const unconfirmedTransactionsHashSelector = createSelector( unapprovedTxsSelector, @@ -71,17 +71,17 @@ export const unconfirmedTransactionsHashSelector = createSelector( ) => { const filteredUnapprovedTxs = Object.keys(unapprovedTxs).reduce( (acc, address) => { - const { metamaskNetworkId } = unapprovedTxs[address] - const transactions = { ...acc } + const { metamaskNetworkId } = unapprovedTxs[address]; + const transactions = { ...acc }; if (metamaskNetworkId === network) { - transactions[address] = unapprovedTxs[address] + transactions[address] = unapprovedTxs[address]; } - return transactions + return transactions; }, {}, - ) + ); return { ...filteredUnapprovedTxs, @@ -90,19 +90,19 @@ export const unconfirmedTransactionsHashSelector = createSelector( ...unapprovedDecryptMsgs, ...unapprovedEncryptionPublicKeyMsgs, ...unapprovedTypedMessages, - } + }; }, -) +); -const unapprovedMsgCountSelector = (state) => state.metamask.unapprovedMsgCount +const unapprovedMsgCountSelector = (state) => state.metamask.unapprovedMsgCount; const unapprovedPersonalMsgCountSelector = (state) => - state.metamask.unapprovedPersonalMsgCount + state.metamask.unapprovedPersonalMsgCount; const unapprovedDecryptMsgCountSelector = (state) => - state.metamask.unapprovedDecryptMsgCount + state.metamask.unapprovedDecryptMsgCount; const unapprovedEncryptionPublicKeyMsgCountSelector = (state) => - state.metamask.unapprovedEncryptionPublicKeyMsgCount + state.metamask.unapprovedEncryptionPublicKeyMsgCount; const unapprovedTypedMessagesCountSelector = (state) => - state.metamask.unapprovedTypedMessagesCount + state.metamask.unapprovedTypedMessagesCount; export const unconfirmedTransactionsCountSelector = createSelector( unapprovedTxsSelector, @@ -123,10 +123,10 @@ export const unconfirmedTransactionsCountSelector = createSelector( ) => { const filteredUnapprovedTxIds = Object.keys(unapprovedTxs).filter( (txId) => { - const { metamaskNetworkId } = unapprovedTxs[txId] - return metamaskNetworkId === network + const { metamaskNetworkId } = unapprovedTxs[txId]; + return metamaskNetworkId === network; }, - ) + ); return ( filteredUnapprovedTxIds.length + @@ -135,85 +135,86 @@ export const unconfirmedTransactionsCountSelector = createSelector( unapprovedPersonalMsgCount + unapprovedDecryptMsgCount + unapprovedEncryptionPublicKeyMsgCount - ) + ); }, -) +); -export const currentCurrencySelector = (state) => state.metamask.currentCurrency -export const conversionRateSelector = (state) => state.metamask.conversionRate +export const currentCurrencySelector = (state) => + state.metamask.currentCurrency; +export const conversionRateSelector = (state) => state.metamask.conversionRate; -export const txDataSelector = (state) => state.confirmTransaction.txData -const tokenDataSelector = (state) => state.confirmTransaction.tokenData -const tokenPropsSelector = (state) => state.confirmTransaction.tokenProps +export const txDataSelector = (state) => state.confirmTransaction.txData; +const tokenDataSelector = (state) => state.confirmTransaction.tokenData; +const tokenPropsSelector = (state) => state.confirmTransaction.tokenProps; const contractExchangeRatesSelector = (state) => - state.metamask.contractExchangeRates + state.metamask.contractExchangeRates; const tokenDecimalsSelector = createSelector( tokenPropsSelector, (tokenProps) => tokenProps && tokenProps.tokenDecimals, -) +); const tokenDataArgsSelector = createSelector( tokenDataSelector, (tokenData) => (tokenData && tokenData.args) || [], -) +); const txParamsSelector = createSelector( txDataSelector, (txData) => (txData && txData.txParams) || {}, -) +); export const tokenAddressSelector = createSelector( txParamsSelector, (txParams) => txParams && txParams.to, -) +); -const TOKEN_PARAM_TO = '_to' -const TOKEN_PARAM_VALUE = '_value' +const TOKEN_PARAM_TO = '_to'; +const TOKEN_PARAM_VALUE = '_value'; export const sendTokenTokenAmountAndToAddressSelector = createSelector( tokenDataArgsSelector, tokenDecimalsSelector, (args, tokenDecimals) => { - let toAddress = '' - let tokenAmount = '0' + let toAddress = ''; + let tokenAmount = '0'; // Token params here are ethers BigNumbers, which have a different // interface than bignumber.js if (args && args.length) { - toAddress = args[TOKEN_PARAM_TO] - let value = args[TOKEN_PARAM_VALUE].toString() + toAddress = args[TOKEN_PARAM_TO]; + let value = args[TOKEN_PARAM_VALUE].toString(); if (tokenDecimals) { // bignumber.js return value - value = calcTokenAmount(value, tokenDecimals).toFixed() + value = calcTokenAmount(value, tokenDecimals).toFixed(); } - tokenAmount = roundExponential(value) + tokenAmount = roundExponential(value); } return { toAddress, tokenAmount, - } + }; }, -) +); export const contractExchangeRateSelector = createSelector( contractExchangeRatesSelector, tokenAddressSelector, (contractExchangeRates, tokenAddress) => contractExchangeRates[tokenAddress], -) +); export const transactionFeeSelector = function (state, txData) { - const currentCurrency = currentCurrencySelector(state) - const conversionRate = conversionRateSelector(state) - const nativeCurrency = getNativeCurrency(state) + const currentCurrency = currentCurrencySelector(state); + const conversionRate = conversionRateSelector(state); + const nativeCurrency = getNativeCurrency(state); const { txParams: { value = '0x0', gas: gasLimit = '0x0', gasPrice = '0x0' } = {}, - } = txData + } = txData; const fiatTransactionAmount = getValueFromWeiHex({ value, @@ -221,16 +222,16 @@ export const transactionFeeSelector = function (state, txData) { toCurrency: currentCurrency, conversionRate, numberOfDecimals: 2, - }) + }); const ethTransactionAmount = getValueFromWeiHex({ value, fromCurrency: nativeCurrency, toCurrency: nativeCurrency, conversionRate, numberOfDecimals: 6, - }) + }); - const hexTransactionFee = getHexGasTotal({ gasLimit, gasPrice }) + const hexTransactionFee = getHexGasTotal({ gasLimit, gasPrice }); const fiatTransactionFee = getTransactionFee({ value: hexTransactionFee, @@ -238,21 +239,21 @@ export const transactionFeeSelector = function (state, txData) { toCurrency: currentCurrency, numberOfDecimals: 2, conversionRate, - }) + }); const ethTransactionFee = getTransactionFee({ value: hexTransactionFee, fromCurrency: nativeCurrency, toCurrency: nativeCurrency, numberOfDecimals: 6, conversionRate, - }) + }); const fiatTransactionTotal = addFiat( fiatTransactionFee, fiatTransactionAmount, - ) - const ethTransactionTotal = addEth(ethTransactionFee, ethTransactionAmount) - const hexTransactionTotal = sumHexes(value, hexTransactionFee) + ); + const ethTransactionTotal = addEth(ethTransactionFee, ethTransactionAmount); + const hexTransactionTotal = sumHexes(value, hexTransactionFee); return { hexTransactionAmount: value, @@ -264,5 +265,5 @@ export const transactionFeeSelector = function (state, txData) { fiatTransactionTotal, ethTransactionTotal, hexTransactionTotal, - } -} + }; +}; diff --git a/ui/app/selectors/custom-gas.js b/ui/app/selectors/custom-gas.js index 8b1df8b892..b6662c03be 100644 --- a/ui/app/selectors/custom-gas.js +++ b/ui/app/selectors/custom-gas.js @@ -1,38 +1,38 @@ -import { addHexPrefix } from '../../../app/scripts/lib/util' +import { addHexPrefix } from '../../../app/scripts/lib/util'; import { conversionUtil, conversionGreaterThan, -} from '../helpers/utils/conversion-util' -import { formatCurrency } from '../helpers/utils/confirm-tx.util' -import { decEthToConvertedCurrency as ethTotalToConvertedCurrency } from '../helpers/utils/conversions.util' -import { formatETHFee } from '../helpers/utils/formatters' -import { calcGasTotal } from '../pages/send/send.utils' +} from '../helpers/utils/conversion-util'; +import { formatCurrency } from '../helpers/utils/confirm-tx.util'; +import { decEthToConvertedCurrency as ethTotalToConvertedCurrency } from '../helpers/utils/conversions.util'; +import { formatETHFee } from '../helpers/utils/formatters'; +import { calcGasTotal } from '../pages/send/send.utils'; -import { GAS_ESTIMATE_TYPES } from '../helpers/constants/common' -import { getCurrentCurrency, getIsMainnet, getPreferences } from '.' +import { GAS_ESTIMATE_TYPES } from '../helpers/constants/common'; +import { getCurrentCurrency, getIsMainnet, getPreferences } from '.'; -const NUMBER_OF_DECIMALS_SM_BTNS = 5 +const NUMBER_OF_DECIMALS_SM_BTNS = 5; export function getCustomGasLimit(state) { - return state.gas.customData.limit + return state.gas.customData.limit; } export function getCustomGasPrice(state) { - return state.gas.customData.price + return state.gas.customData.price; } export function getBasicGasEstimateLoadingStatus(state) { - return state.gas.basicEstimateIsLoading + return state.gas.basicEstimateIsLoading; } export function getAveragePriceEstimateInHexWEI(state) { - const averagePriceEstimate = state.gas.basicEstimates.average - return getGasPriceInHexWei(averagePriceEstimate || '0x0') + const averagePriceEstimate = state.gas.basicEstimates.average; + return getGasPriceInHexWei(averagePriceEstimate || '0x0'); } export function getFastPriceEstimateInHexWEI(state) { - const fastPriceEstimate = state.gas.basicEstimates.fast - return getGasPriceInHexWei(fastPriceEstimate || '0x0') + const fastPriceEstimate = state.gas.basicEstimates.fast; + return getGasPriceInHexWei(fastPriceEstimate || '0x0'); } export function getDefaultActiveButtonIndex( @@ -42,7 +42,7 @@ export function getDefaultActiveButtonIndex( ) { return gasButtonInfo .map(({ priceInHexWei }) => priceInHexWei) - .lastIndexOf(addHexPrefix(customGasPriceInHex || gasPrice)) + .lastIndexOf(addHexPrefix(customGasPriceInHex || gasPrice)); } export function getSafeLowEstimate(state) { @@ -50,22 +50,22 @@ export function getSafeLowEstimate(state) { gas: { basicEstimates: { safeLow }, }, - } = state + } = state; - return safeLow + return safeLow; } export function isCustomPriceSafe(state) { - const safeLow = getSafeLowEstimate(state) + const safeLow = getSafeLowEstimate(state); - const customGasPrice = getCustomGasPrice(state) + const customGasPrice = getCustomGasPrice(state); if (!customGasPrice) { - return true + return true; } if (safeLow === null) { - return false + return false; } const customPriceSafe = conversionGreaterThan( @@ -76,9 +76,9 @@ export function isCustomPriceSafe(state) { toDenomination: 'GWEI', }, { value: safeLow, fromNumericBase: 'dec' }, - ) + ); - return customPriceSafe + return customPriceSafe; } export function basicPriceEstimateToETHTotal( @@ -91,16 +91,16 @@ export function basicPriceEstimateToETHTotal( toNumericBase: 'dec', fromDenomination: 'GWEI', numberOfDecimals, - }) + }); } export function getRenderableEthFee(estimate, gasLimit, numberOfDecimals = 9) { const value = conversionUtil(estimate, { fromNumericBase: 'dec', toNumericBase: 'hex', - }) - const fee = basicPriceEstimateToETHTotal(value, gasLimit, numberOfDecimals) - return formatETHFee(fee) + }); + const fee = basicPriceEstimateToETHTotal(value, gasLimit, numberOfDecimals); + return formatETHFee(fee); } export function getRenderableConvertedCurrencyFee( @@ -112,14 +112,14 @@ export function getRenderableConvertedCurrencyFee( const value = conversionUtil(estimate, { fromNumericBase: 'dec', toNumericBase: 'hex', - }) - const fee = basicPriceEstimateToETHTotal(value, gasLimit) + }); + const fee = basicPriceEstimateToETHTotal(value, gasLimit); const feeInCurrency = ethTotalToConvertedCurrency( fee, convertedCurrency, conversionRate, - ) - return formatCurrency(feeInCurrency, convertedCurrency) + ); + return formatCurrency(feeInCurrency, convertedCurrency); } export function priceEstimateToWei(priceEstimate) { @@ -129,15 +129,15 @@ export function priceEstimateToWei(priceEstimate) { fromDenomination: 'GWEI', toDenomination: 'WEI', numberOfDecimals: 9, - }) + }); } export function getGasPriceInHexWei(price) { const value = conversionUtil(price, { fromNumericBase: 'dec', toNumericBase: 'hex', - }) - return addHexPrefix(priceEstimateToWei(value)) + }); + return addHexPrefix(priceEstimateToWei(value)); } export function getRenderableGasButtonData( @@ -147,7 +147,7 @@ export function getRenderableGasButtonData( conversionRate, currentCurrency, ) { - const { safeLow, average, fast } = estimates + const { safeLow, average, fast } = estimates; const slowEstimateData = { gasEstimateType: GAS_ESTIMATE_TYPES.SLOW, @@ -161,7 +161,7 @@ export function getRenderableGasButtonData( ) : '', priceInHexWei: getGasPriceInHexWei(safeLow), - } + }; const averageEstimateData = { gasEstimateType: GAS_ESTIMATE_TYPES.AVERAGE, feeInPrimaryCurrency: getRenderableEthFee(average, gasLimit), @@ -174,7 +174,7 @@ export function getRenderableGasButtonData( ) : '', priceInHexWei: getGasPriceInHexWei(average), - } + }; const fastEstimateData = { gasEstimateType: GAS_ESTIMATE_TYPES.FAST, feeInPrimaryCurrency: getRenderableEthFee(fast, gasLimit), @@ -187,25 +187,25 @@ export function getRenderableGasButtonData( ) : '', priceInHexWei: getGasPriceInHexWei(fast), - } + }; return { slowEstimateData, averageEstimateData, fastEstimateData, - } + }; } export function getRenderableBasicEstimateData(state, gasLimit) { if (getBasicGasEstimateLoadingStatus(state)) { - return [] + return []; } - const { showFiatInTestnets } = getPreferences(state) - const isMainnet = getIsMainnet(state) - const showFiat = isMainnet || Boolean(showFiatInTestnets) - const { conversionRate } = state.metamask - const currentCurrency = getCurrentCurrency(state) + const { showFiatInTestnets } = getPreferences(state); + const isMainnet = getIsMainnet(state); + const showFiat = isMainnet || Boolean(showFiatInTestnets); + const { conversionRate } = state.metamask; + const currentCurrency = getCurrentCurrency(state); const { slowEstimateData, @@ -217,28 +217,28 @@ export function getRenderableBasicEstimateData(state, gasLimit) { showFiat, conversionRate, currentCurrency, - ) + ); - return [slowEstimateData, averageEstimateData, fastEstimateData] + return [slowEstimateData, averageEstimateData, fastEstimateData]; } export function getRenderableEstimateDataForSmallButtonsFromGWEI(state) { if (getBasicGasEstimateLoadingStatus(state)) { - return [] + return []; } - const { showFiatInTestnets } = getPreferences(state) - const isMainnet = getIsMainnet(state) - const showFiat = isMainnet || Boolean(showFiatInTestnets) + const { showFiatInTestnets } = getPreferences(state); + const isMainnet = getIsMainnet(state); + const showFiat = isMainnet || Boolean(showFiatInTestnets); const gasLimit = - state.metamask.send.gasLimit || getCustomGasLimit(state) || '0x5208' - const { conversionRate } = state.metamask - const currentCurrency = getCurrentCurrency(state) + state.metamask.send.gasLimit || getCustomGasLimit(state) || '0x5208'; + const { conversionRate } = state.metamask; + const currentCurrency = getCurrentCurrency(state); const { gas: { basicEstimates: { safeLow, average, fast }, }, - } = state + } = state; return [ { @@ -295,5 +295,5 @@ export function getRenderableEstimateDataForSmallButtonsFromGWEI(state) { ), priceInHexWei: getGasPriceInHexWei(fast, true), }, - ] + ]; } diff --git a/ui/app/selectors/first-time-flow.js b/ui/app/selectors/first-time-flow.js index 284a4bca1b..b56bdc8617 100644 --- a/ui/app/selectors/first-time-flow.js +++ b/ui/app/selectors/first-time-flow.js @@ -2,34 +2,34 @@ import { INITIALIZE_CREATE_PASSWORD_ROUTE, INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE, DEFAULT_ROUTE, -} from '../helpers/constants/routes' +} from '../helpers/constants/routes'; export function getFirstTimeFlowTypeRoute(state) { - const { firstTimeFlowType } = state.metamask + const { firstTimeFlowType } = state.metamask; - let nextRoute + let nextRoute; if (firstTimeFlowType === 'create') { - nextRoute = INITIALIZE_CREATE_PASSWORD_ROUTE + nextRoute = INITIALIZE_CREATE_PASSWORD_ROUTE; } else if (firstTimeFlowType === 'import') { - nextRoute = INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE + nextRoute = INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE; } else { - nextRoute = DEFAULT_ROUTE + nextRoute = DEFAULT_ROUTE; } - return nextRoute + return nextRoute; } export const getOnboardingInitiator = (state) => { - const { onboardingTabs } = state.metamask + const { onboardingTabs } = state.metamask; if (!onboardingTabs || Object.keys(onboardingTabs).length !== 1) { - return null + return null; } - const location = Object.keys(onboardingTabs)[0] - const tabId = onboardingTabs[location] + const location = Object.keys(onboardingTabs)[0]; + const tabId = onboardingTabs[location]; return { location, tabId, - } -} + }; +}; diff --git a/ui/app/selectors/index.js b/ui/app/selectors/index.js index c9e5f2f6aa..b82c59c05e 100644 --- a/ui/app/selectors/index.js +++ b/ui/app/selectors/index.js @@ -1,7 +1,7 @@ -export * from './confirm-transaction' -export * from './custom-gas' -export * from './first-time-flow' -export * from './permissions' -export * from './selectors' -export * from './send' -export * from './transactions' +export * from './confirm-transaction'; +export * from './custom-gas'; +export * from './first-time-flow'; +export * from './permissions'; +export * from './selectors'; +export * from './send'; +export * from './transactions'; diff --git a/ui/app/selectors/permissions.js b/ui/app/selectors/permissions.js index e6dfa4db52..6b104f2e19 100644 --- a/ui/app/selectors/permissions.js +++ b/ui/app/selectors/permissions.js @@ -1,10 +1,10 @@ -import { forOwn } from 'lodash' -import { CAVEAT_NAMES } from '../../../shared/constants/permissions' +import { forOwn } from 'lodash'; +import { CAVEAT_NAMES } from '../../../shared/constants/permissions'; import { getMetaMaskAccountsOrdered, getOriginOfCurrentTab, getSelectedAddress, -} from '.' +} from '.'; // selectors @@ -15,7 +15,7 @@ import { * @returns {Object} The permissions domains object. */ export function getPermissionDomains(state) { - return state.metamask.domains || {} + return state.metamask.domains || {}; } /** @@ -25,7 +25,7 @@ export function getPermissionDomains(state) { * @returns {Object} The permission domains metadata object. */ export function getPermissionDomainsMetadata(state) { - return state.metamask.domainMetadata || {} + return state.metamask.domainMetadata || {}; } /** @@ -39,7 +39,7 @@ export function getPermissionDomainsMetadata(state) { export function getPermittedAccounts(state, origin) { return getAccountsFromPermission( getAccountsPermissionFromDomain(domainSelector(state, origin)), - ) + ); } /** @@ -50,7 +50,7 @@ export function getPermittedAccounts(state, origin) { * @returns {Array} An empty array or an array of accounts. */ export function getPermittedAccountsForCurrentTab(state) { - return getPermittedAccounts(state, getOriginOfCurrentTab(state)) + return getPermittedAccounts(state, getOriginOfCurrentTab(state)); } /** @@ -60,16 +60,16 @@ export function getPermittedAccountsForCurrentTab(state) { * @returns {Object} Permitted accounts by origin. */ export function getPermittedAccountsByOrigin(state) { - const domains = getPermissionDomains(state) + const domains = getPermissionDomains(state); return Object.keys(domains).reduce((acc, domainKey) => { const accounts = getAccountsFromPermission( getAccountsPermissionFromDomain(domains[domainKey]), - ) + ); if (accounts.length > 0) { - acc[domainKey] = accounts + acc[domainKey] = accounts; } - return acc - }, {}) + return acc; + }, {}); } /** @@ -83,19 +83,19 @@ export function getPermittedAccountsByOrigin(state) { * @returns {Array} An array of connected domain objects. */ export function getConnectedDomainsForSelectedAddress(state) { - const { selectedAddress } = state.metamask - const domains = getPermissionDomains(state) - const domainMetadata = getPermissionDomainsMetadata(state) + const { selectedAddress } = state.metamask; + const domains = getPermissionDomains(state); + const domainMetadata = getPermissionDomainsMetadata(state); - const connectedDomains = [] + const connectedDomains = []; forOwn(domains, (domainValue, domainKey) => { - const exposedAccounts = getAccountsFromDomain(domainValue) + const exposedAccounts = getAccountsFromDomain(domainValue); if (!exposedAccounts.includes(selectedAddress)) { - return + return; } - const { extensionId, name, icon, host } = domainMetadata[domainKey] || {} + const { extensionId, name, icon, host } = domainMetadata[domainKey] || {}; connectedDomains.push({ extensionId, @@ -103,10 +103,10 @@ export function getConnectedDomainsForSelectedAddress(state) { name, icon, host, - }) - }) + }); + }); - return connectedDomains + return connectedDomains; } /** @@ -120,32 +120,32 @@ export function getConnectedDomainsForSelectedAddress(state) { * connected domain info. */ export function getAddressConnectedDomainMap(state) { - const domainMetadata = getPermissionDomainsMetadata(state) - const accountsMap = getPermittedAccountsByOrigin(state) - const addressConnectedIconMap = {} + const domainMetadata = getPermissionDomainsMetadata(state); + const accountsMap = getPermittedAccountsByOrigin(state); + const addressConnectedIconMap = {}; Object.keys(accountsMap).forEach((domainKey) => { - const { icon, name } = domainMetadata[domainKey] || {} + const { icon, name } = domainMetadata[domainKey] || {}; accountsMap[domainKey].forEach((address) => { - const nameToRender = name || domainKey + const nameToRender = name || domainKey; addressConnectedIconMap[address] = addressConnectedIconMap[address] ? { ...addressConnectedIconMap[address], [domainKey]: { icon, name: nameToRender }, } - : { [domainKey]: { icon, name: nameToRender } } - }) - }) + : { [domainKey]: { icon, name: nameToRender } }; + }); + }); - return addressConnectedIconMap + return addressConnectedIconMap; } // selector helpers function getAccountsFromDomain(domain) { - return getAccountsFromPermission(getAccountsPermissionFromDomain(domain)) + return getAccountsFromPermission(getAccountsPermissionFromDomain(domain)); } function getAccountsPermissionFromDomain(domain = {}) { @@ -153,14 +153,14 @@ function getAccountsPermissionFromDomain(domain = {}) { ? domain.permissions.find( (perm) => perm.parentCapability === 'eth_accounts', ) - : {} + : {}; } function getAccountsFromPermission(accountsPermission) { - const accountsCaveat = getAccountsCaveatFromPermission(accountsPermission) + const accountsCaveat = getAccountsCaveatFromPermission(accountsPermission); return accountsCaveat && Array.isArray(accountsCaveat.value) ? accountsCaveat.value - : [] + : []; } function getAccountsCaveatFromPermission(accountsPermission = {}) { @@ -169,21 +169,21 @@ function getAccountsCaveatFromPermission(accountsPermission = {}) { accountsPermission.caveats.find( (c) => c.name === CAVEAT_NAMES.exposedAccounts, ) - ) + ); } function domainSelector(state, origin) { - return origin && state.metamask.domains?.[origin] + return origin && state.metamask.domains?.[origin]; } export function getAccountToConnectToActiveTab(state) { - const selectedAddress = getSelectedAddress(state) - const connectedAccounts = getPermittedAccountsForCurrentTab(state) + const selectedAddress = getSelectedAddress(state); + const connectedAccounts = getPermittedAccountsForCurrentTab(state); const { metamask: { identities }, - } = state - const numberOfAccounts = Object.keys(identities).length + } = state; + const numberOfAccounts = Object.keys(identities).length; if ( connectedAccounts.length && @@ -193,24 +193,24 @@ export function getAccountToConnectToActiveTab(state) { connectedAccounts.findIndex((address) => address === selectedAddress) === -1 ) { - return identities[selectedAddress] + return identities[selectedAddress]; } } - return undefined + return undefined; } export function getOrderedConnectedAccountsForActiveTab(state) { const { activeTab, metamask: { permissionsHistory }, - } = state + } = state; const permissionsHistoryByAccount = // eslint-disable-next-line camelcase - permissionsHistory[activeTab.origin]?.eth_accounts?.accounts - const orderedAccounts = getMetaMaskAccountsOrdered(state) - const connectedAccounts = getPermittedAccountsForCurrentTab(state) + permissionsHistory[activeTab.origin]?.eth_accounts?.accounts; + const orderedAccounts = getMetaMaskAccountsOrdered(state); + const connectedAccounts = getPermittedAccountsForCurrentTab(state); return orderedAccounts .filter((account) => connectedAccounts.includes(account.address)) @@ -221,73 +221,73 @@ export function getOrderedConnectedAccountsForActiveTab(state) { .sort( ({ lastSelected: lastSelectedA }, { lastSelected: lastSelectedB }) => { if (lastSelectedA === lastSelectedB) { - return 0 + return 0; } else if (lastSelectedA === undefined) { - return 1 + return 1; } else if (lastSelectedB === undefined) { - return -1 + return -1; } - return lastSelectedB - lastSelectedA + return lastSelectedB - lastSelectedA; }, - ) + ); } export function getPermissionsForActiveTab(state) { - const { activeTab, metamask } = state - const { domains = {} } = metamask + const { activeTab, metamask } = state; + const { domains = {} } = metamask; return domains[activeTab.origin]?.permissions?.map(({ parentCapability }) => { return { key: parentCapability, - } - }) + }; + }); } export function activeTabHasPermissions(state) { - const { activeTab, metamask } = state - const { domains = {} } = metamask + const { activeTab, metamask } = state; + const { domains = {} } = metamask; - return Boolean(domains[activeTab.origin]?.permissions?.length > 0) + return Boolean(domains[activeTab.origin]?.permissions?.length > 0); } export function getLastConnectedInfo(state) { - const { permissionsHistory = {} } = state.metamask + const { permissionsHistory = {} } = state.metamask; return Object.keys(permissionsHistory).reduce((acc, origin) => { const ethAccountsHistory = JSON.parse( JSON.stringify(permissionsHistory[origin].eth_accounts), - ) + ); return { ...acc, [origin]: ethAccountsHistory, - } - }, {}) + }; + }, {}); } export function getPermissionsMetadataHostCounts(state) { - const metadata = getPermissionDomainsMetadata(state) + const metadata = getPermissionDomainsMetadata(state); return Object.values(metadata).reduce((counts, { host }) => { if (host) { if (counts[host]) { - counts[host] += 1 + counts[host] += 1; } else { - counts[host] = 1 + counts[host] = 1; } } - return counts - }, {}) + return counts; + }, {}); } export function getPermissionsRequests(state) { - return state.metamask.permissionsRequests || [] + return state.metamask.permissionsRequests || []; } export function getPermissionsRequestCount(state) { - const permissionsRequests = getPermissionsRequests(state) - return permissionsRequests.length + const permissionsRequests = getPermissionsRequests(state); + return permissionsRequests.length; } export function getFirstPermissionRequest(state) { - const requests = getPermissionsRequests(state) - return requests && requests[0] ? requests[0] : null + const requests = getPermissionsRequests(state); + return requests && requests[0] ? requests[0] : null; } diff --git a/ui/app/selectors/selectors.js b/ui/app/selectors/selectors.js index 9db335a85f..9e8711e2f7 100644 --- a/ui/app/selectors/selectors.js +++ b/ui/app/selectors/selectors.js @@ -1,70 +1,70 @@ -import { stripHexPrefix } from 'ethereumjs-util' -import { createSelector } from 'reselect' -import { addHexPrefix } from '../../../app/scripts/lib/util' -import { MAINNET, NETWORK_TYPE_RPC } from '../../../shared/constants/network' +import { stripHexPrefix } from 'ethereumjs-util'; +import { createSelector } from 'reselect'; +import { addHexPrefix } from '../../../app/scripts/lib/util'; +import { MAINNET, NETWORK_TYPE_RPC } from '../../../shared/constants/network'; import { shortenAddress, checksumAddress, getAccountByAddress, -} from '../helpers/utils/util' -import { getPermissionsRequestCount } from './permissions' +} from '../helpers/utils/util'; +import { getPermissionsRequestCount } from './permissions'; export function getNetworkIdentifier(state) { const { metamask: { provider: { type, nickname, rpcUrl }, }, - } = state + } = state; - return nickname || rpcUrl || type + return nickname || rpcUrl || type; } export function getMetricsNetworkIdentifier(state) { - const { provider } = state.metamask - return provider.type === NETWORK_TYPE_RPC ? provider.rpcUrl : provider.type + const { provider } = state.metamask; + return provider.type === NETWORK_TYPE_RPC ? provider.rpcUrl : provider.type; } export function getCurrentChainId(state) { - const { chainId } = state.metamask.provider - return chainId + const { chainId } = state.metamask.provider; + return chainId; } export function getCurrentKeyring(state) { - const identity = getSelectedIdentity(state) + const identity = getSelectedIdentity(state); if (!identity) { - return null + return null; } - const simpleAddress = stripHexPrefix(identity.address).toLowerCase() + const simpleAddress = stripHexPrefix(identity.address).toLowerCase(); const keyring = state.metamask.keyrings.find((kr) => { return ( kr.accounts.includes(simpleAddress) || kr.accounts.includes(identity.address) - ) - }) + ); + }); - return keyring + return keyring; } export function getAccountType(state) { - const currentKeyring = getCurrentKeyring(state) - const type = currentKeyring && currentKeyring.type + const currentKeyring = getCurrentKeyring(state); + const type = currentKeyring && currentKeyring.type; switch (type) { case 'Trezor Hardware': case 'Ledger Hardware': - return 'hardware' + return 'hardware'; case 'Simple Key Pair': - return 'imported' + return 'imported'; default: - return 'default' + return 'default'; } } export function getCurrentNetworkId(state) { - return state.metamask.network + return state.metamask.network; } export const getMetaMaskAccounts = createSelector( @@ -80,53 +80,53 @@ export const getMetaMaskAccounts = createSelector( ...account, balance: cachedBalances && cachedBalances[accountID], }, - } + }; } return { ...selectedAccounts, [accountID]: account, - } + }; }, {}, ), -) +); export function getSelectedAddress(state) { - return state.metamask.selectedAddress + return state.metamask.selectedAddress; } export function getSelectedIdentity(state) { - const selectedAddress = getSelectedAddress(state) - const { identities } = state.metamask + const selectedAddress = getSelectedAddress(state); + const { identities } = state.metamask; - return identities[selectedAddress] + return identities[selectedAddress]; } export function getNumberOfAccounts(state) { - return Object.keys(state.metamask.accounts).length + return Object.keys(state.metamask.accounts).length; } export function getNumberOfTokens(state) { - const { tokens } = state.metamask - return tokens ? tokens.length : 0 + const { tokens } = state.metamask; + return tokens ? tokens.length : 0; } export function getMetaMaskKeyrings(state) { - return state.metamask.keyrings + return state.metamask.keyrings; } export function getMetaMaskIdentities(state) { - return state.metamask.identities + return state.metamask.identities; } export function getMetaMaskAccountsRaw(state) { - return state.metamask.accounts + return state.metamask.accounts; } export function getMetaMaskCachedBalances(state) { - const network = getCurrentNetworkId(state) + const network = getCurrentNetworkId(state); - return state.metamask.cachedBalances[network] + return state.metamask.cachedBalances[network]; } /** @@ -141,76 +141,76 @@ export const getMetaMaskAccountsOrdered = createSelector( .reduce((list, keyring) => list.concat(keyring.accounts), []) .filter((address) => Boolean(identities[address])) .map((address) => ({ ...identities[address], ...accounts[address] })), -) +); export function isBalanceCached(state) { const selectedAccountBalance = - state.metamask.accounts[getSelectedAddress(state)].balance - const cachedBalance = getSelectedAccountCachedBalance(state) + state.metamask.accounts[getSelectedAddress(state)].balance; + const cachedBalance = getSelectedAccountCachedBalance(state); - return Boolean(!selectedAccountBalance && cachedBalance) + return Boolean(!selectedAccountBalance && cachedBalance); } export function getSelectedAccountCachedBalance(state) { - const cachedBalances = state.metamask.cachedBalances[state.metamask.network] - const selectedAddress = getSelectedAddress(state) + const cachedBalances = state.metamask.cachedBalances[state.metamask.network]; + const selectedAddress = getSelectedAddress(state); - return cachedBalances && cachedBalances[selectedAddress] + return cachedBalances && cachedBalances[selectedAddress]; } export function getSelectedAccount(state) { - const accounts = getMetaMaskAccounts(state) - const selectedAddress = getSelectedAddress(state) + const accounts = getMetaMaskAccounts(state); + const selectedAddress = getSelectedAddress(state); - return accounts[selectedAddress] + return accounts[selectedAddress]; } export function getTargetAccount(state, targetAddress) { - const accounts = getMetaMaskAccounts(state) - return accounts[targetAddress] + const accounts = getMetaMaskAccounts(state); + return accounts[targetAddress]; } export const getTokenExchangeRates = (state) => - state.metamask.contractExchangeRates + state.metamask.contractExchangeRates; export function getAssetImages(state) { - const assetImages = state.metamask.assetImages || {} - return assetImages + const assetImages = state.metamask.assetImages || {}; + return assetImages; } export function getAddressBook(state) { - const chainId = getCurrentChainId(state) + const chainId = getCurrentChainId(state); if (!state.metamask.addressBook[chainId]) { - return [] + return []; } - return Object.values(state.metamask.addressBook[chainId]) + return Object.values(state.metamask.addressBook[chainId]); } export function getAddressBookEntry(state, address) { - const addressBook = getAddressBook(state) + const addressBook = getAddressBook(state); const entry = addressBook.find( (contact) => contact.address === checksumAddress(address), - ) - return entry + ); + return entry; } export function getAddressBookEntryName(state, address) { const entry = - getAddressBookEntry(state, address) || state.metamask.identities[address] - return entry && entry.name !== '' ? entry.name : shortenAddress(address) + getAddressBookEntry(state, address) || state.metamask.identities[address]; + return entry && entry.name !== '' ? entry.name : shortenAddress(address); } export function accountsWithSendEtherInfoSelector(state) { - const accounts = getMetaMaskAccounts(state) - const identities = getMetaMaskIdentities(state) + const accounts = getMetaMaskAccounts(state); + const identities = getMetaMaskIdentities(state); const accountsWithSendEtherInfo = Object.entries(identities).map( ([key, identity]) => { - return { ...identity, ...accounts[key] } + return { ...identity, ...accounts[key] }; }, - ) + ); - return accountsWithSendEtherInfo + return accountsWithSendEtherInfo; } export function getAccountsWithLabels(state) { @@ -221,31 +221,31 @@ export function getAccountsWithLabels(state) { label: name, balance, }), - ) + ); } export function getCurrentAccountWithSendEtherInfo(state) { - const currentAddress = getSelectedAddress(state) - const accounts = accountsWithSendEtherInfoSelector(state) + const currentAddress = getSelectedAddress(state); + const accounts = accountsWithSendEtherInfoSelector(state); - return getAccountByAddress(accounts, currentAddress) + return getAccountByAddress(accounts, currentAddress); } export function getTargetAccountWithSendEtherInfo(state, targetAddress) { - const accounts = accountsWithSendEtherInfoSelector(state) - return getAccountByAddress(accounts, targetAddress) + const accounts = accountsWithSendEtherInfoSelector(state); + return getAccountByAddress(accounts, targetAddress); } export function getCurrentEthBalance(state) { - return getCurrentAccountWithSendEtherInfo(state).balance + return getCurrentAccountWithSendEtherInfo(state).balance; } export function getGasIsLoading(state) { - return state.appState.gasIsLoading + return state.appState.gasIsLoading; } export function getCurrentCurrency(state) { - return state.metamask.currentCurrency + return state.metamask.currentCurrency; } export function getTotalUnapprovedCount(state) { @@ -255,7 +255,7 @@ export function getTotalUnapprovedCount(state) { unapprovedDecryptMsgCount = 0, unapprovedEncryptionPublicKeyMsgCount = 0, unapprovedTypedMessagesCount = 0, - } = state.metamask + } = state.metamask; return ( unapprovedMsgCount + @@ -266,48 +266,48 @@ export function getTotalUnapprovedCount(state) { getUnapprovedTxCount(state) + getPermissionsRequestCount(state) + getSuggestedTokenCount(state) - ) + ); } function getUnapprovedTxCount(state) { - const { unapprovedTxs = {} } = state.metamask - return Object.keys(unapprovedTxs).length + const { unapprovedTxs = {} } = state.metamask; + return Object.keys(unapprovedTxs).length; } function getSuggestedTokenCount(state) { - const { suggestedTokens = {} } = state.metamask - return Object.keys(suggestedTokens).length + const { suggestedTokens = {} } = state.metamask; + return Object.keys(suggestedTokens).length; } export function getIsMainnet(state) { - const networkType = getNetworkIdentifier(state) - return networkType === MAINNET + const networkType = getNetworkIdentifier(state); + return networkType === MAINNET; } export function getPreferences({ metamask }) { - return metamask.preferences + return metamask.preferences; } export function getShouldShowFiat(state) { - const isMainNet = getIsMainnet(state) - const { showFiatInTestnets } = getPreferences(state) - return Boolean(isMainNet || showFiatInTestnets) + const isMainNet = getIsMainnet(state); + const { showFiatInTestnets } = getPreferences(state); + return Boolean(isMainNet || showFiatInTestnets); } export function getAdvancedInlineGasShown(state) { - return Boolean(state.metamask.featureFlags.advancedInlineGas) + return Boolean(state.metamask.featureFlags.advancedInlineGas); } export function getUseNonceField(state) { - return Boolean(state.metamask.useNonceField) + return Boolean(state.metamask.useNonceField); } export function getCustomNonceValue(state) { - return String(state.metamask.customNonceValue) + return String(state.metamask.customNonceValue); } export function getDomainMetadata(state) { - return state.metamask.domainMetadata + return state.metamask.domainMetadata; } export const getBackgroundMetaMetricState = (state) => { @@ -318,45 +318,45 @@ export const getBackgroundMetaMetricState = (state) => { numberOfTokens: getNumberOfTokens(state), numberOfAccounts: getNumberOfAccounts(state), participateInMetaMetrics: state.metamask.participateInMetaMetrics, - } -} + }; +}; export function getRpcPrefsForCurrentProvider(state) { - const { frequentRpcListDetail, provider } = state.metamask + const { frequentRpcListDetail, provider } = state.metamask; const selectRpcInfo = frequentRpcListDetail.find( (rpcInfo) => rpcInfo.rpcUrl === provider.rpcUrl, - ) - const { rpcPrefs = {} } = selectRpcInfo || {} - return rpcPrefs + ); + const { rpcPrefs = {} } = selectRpcInfo || {}; + return rpcPrefs; } export function getKnownMethodData(state, data) { if (!data) { - return null + return null; } - const prefixedData = addHexPrefix(data) - const fourBytePrefix = prefixedData.slice(0, 10) - const { knownMethodData } = state.metamask + const prefixedData = addHexPrefix(data); + const fourBytePrefix = prefixedData.slice(0, 10); + const { knownMethodData } = state.metamask; - return knownMethodData && knownMethodData[fourBytePrefix] + return knownMethodData && knownMethodData[fourBytePrefix]; } export function getFeatureFlags(state) { - return state.metamask.featureFlags + return state.metamask.featureFlags; } export function getOriginOfCurrentTab(state) { - return state.activeTab.origin + return state.activeTab.origin; } export function getIpfsGateway(state) { - return state.metamask.ipfsGateway + return state.metamask.ipfsGateway; } export function getUSDConversionRate(state) { - return state.metamask.usdConversionRate + return state.metamask.usdConversionRate; } export function getWeb3ShimUsageStateForOrigin(state, origin) { - return state.metamask.web3ShimUsageOrigins[origin] + return state.metamask.web3ShimUsageOrigins[origin]; } diff --git a/ui/app/selectors/send.js b/ui/app/selectors/send.js index 799215cc99..c7a2c870fd 100644 --- a/ui/app/selectors/send.js +++ b/ui/app/selectors/send.js @@ -1,164 +1,166 @@ -import abi from 'human-standard-token-abi' -import { calcGasTotal } from '../pages/send/send.utils' +import abi from 'human-standard-token-abi'; +import { calcGasTotal } from '../pages/send/send.utils'; import { accountsWithSendEtherInfoSelector, getAddressBook, getSelectedAccount, getTargetAccount, getAveragePriceEstimateInHexWEI, -} from '.' +} from '.'; export function getBlockGasLimit(state) { - return state.metamask.currentBlockGasLimit + return state.metamask.currentBlockGasLimit; } export function getConversionRate(state) { - return state.metamask.conversionRate + return state.metamask.conversionRate; } export function getNativeCurrency(state) { - return state.metamask.nativeCurrency + return state.metamask.nativeCurrency; } export function getCurrentNetwork(state) { - return state.metamask.network + return state.metamask.network; } export function getGasLimit(state) { - return state.metamask.send.gasLimit || '0' + return state.metamask.send.gasLimit || '0'; } export function getGasPrice(state) { - return state.metamask.send.gasPrice || getAveragePriceEstimateInHexWEI(state) + return state.metamask.send.gasPrice || getAveragePriceEstimateInHexWEI(state); } export function getGasTotal(state) { - return calcGasTotal(getGasLimit(state), getGasPrice(state)) + return calcGasTotal(getGasLimit(state), getGasPrice(state)); } export function getPrimaryCurrency(state) { - const sendToken = getSendToken(state) - return sendToken?.symbol + const sendToken = getSendToken(state); + return sendToken?.symbol; } export function getSendToken(state) { - return state.metamask.send.token + return state.metamask.send.token; } export function getSendTokenAddress(state) { - return getSendToken(state)?.address + return getSendToken(state)?.address; } export function getSendTokenContract(state) { - const sendTokenAddress = getSendTokenAddress(state) - return sendTokenAddress ? global.eth.contract(abi).at(sendTokenAddress) : null + const sendTokenAddress = getSendTokenAddress(state); + return sendTokenAddress + ? global.eth.contract(abi).at(sendTokenAddress) + : null; } export function getSendAmount(state) { - return state.metamask.send.amount + return state.metamask.send.amount; } export function getSendHexData(state) { - return state.metamask.send.data + return state.metamask.send.data; } export function getSendHexDataFeatureFlagState(state) { - return state.metamask.featureFlags.sendHexData + return state.metamask.featureFlags.sendHexData; } export function getSendEditingTransactionId(state) { - return state.metamask.send.editingTransactionId + return state.metamask.send.editingTransactionId; } export function getSendErrors(state) { - return state.send.errors + return state.send.errors; } export function sendAmountIsInError(state) { - return Boolean(state.send.errors.amount) + return Boolean(state.send.errors.amount); } export function getSendFrom(state) { - return state.metamask.send.from + return state.metamask.send.from; } export function getSendFromBalance(state) { - const fromAccount = getSendFromObject(state) - return fromAccount.balance + const fromAccount = getSendFromObject(state); + return fromAccount.balance; } export function getSendFromObject(state) { - const fromAddress = getSendFrom(state) + const fromAddress = getSendFrom(state); return fromAddress ? getTargetAccount(state, fromAddress) - : getSelectedAccount(state) + : getSelectedAccount(state); } export function getSendMaxModeState(state) { - return state.metamask.send.maxModeOn + return state.metamask.send.maxModeOn; } export function getSendTo(state) { - return state.metamask.send.to + return state.metamask.send.to; } export function getSendToNickname(state) { - return state.metamask.send.toNickname + return state.metamask.send.toNickname; } export function getSendToAccounts(state) { - const fromAccounts = accountsWithSendEtherInfoSelector(state) - const addressBookAccounts = getAddressBook(state) - return [...fromAccounts, ...addressBookAccounts] + const fromAccounts = accountsWithSendEtherInfoSelector(state); + const addressBookAccounts = getAddressBook(state); + return [...fromAccounts, ...addressBookAccounts]; } export function getTokenBalance(state) { - return state.metamask.send.tokenBalance + return state.metamask.send.tokenBalance; } export function getSendEnsResolution(state) { - return state.metamask.send.ensResolution + return state.metamask.send.ensResolution; } export function getSendEnsResolutionError(state) { - return state.metamask.send.ensResolutionError + return state.metamask.send.ensResolutionError; } export function getUnapprovedTxs(state) { - return state.metamask.unapprovedTxs + return state.metamask.unapprovedTxs; } export function getQrCodeData(state) { - return state.appState.qrCodeData + return state.appState.qrCodeData; } export function getGasLoadingError(state) { - return state.send.errors.gasLoading + return state.send.errors.gasLoading; } export function gasFeeIsInError(state) { - return Boolean(state.send.errors.gasFee) + return Boolean(state.send.errors.gasFee); } export function getGasButtonGroupShown(state) { - return state.send.gasButtonGroupShown + return state.send.gasButtonGroupShown; } export function getTitleKey(state) { - const isEditing = Boolean(getSendEditingTransactionId(state)) - const isToken = Boolean(getSendToken(state)) + const isEditing = Boolean(getSendEditingTransactionId(state)); + const isToken = Boolean(getSendToken(state)); if (!getSendTo(state)) { - return 'addRecipient' + return 'addRecipient'; } if (isEditing) { - return 'edit' + return 'edit'; } else if (isToken) { - return 'sendTokens' + return 'sendTokens'; } - return 'sendETH' + return 'sendETH'; } export function isSendFormInError(state) { - return Object.values(getSendErrors(state)).some((n) => n) + return Object.values(getSendErrors(state)).some((n) => n); } diff --git a/ui/app/selectors/tests/confirm-transaction.test.js b/ui/app/selectors/tests/confirm-transaction.test.js index df8b3ae863..7380000377 100644 --- a/ui/app/selectors/tests/confirm-transaction.test.js +++ b/ui/app/selectors/tests/confirm-transaction.test.js @@ -1,20 +1,20 @@ -import assert from 'assert' -import { TRANSACTION_CATEGORIES } from '../../../../shared/constants/transaction' +import assert from 'assert'; +import { TRANSACTION_CATEGORIES } from '../../../../shared/constants/transaction'; import { unconfirmedTransactionsCountSelector, sendTokenTokenAmountAndToAddressSelector, contractExchangeRateSelector, conversionRateSelector, -} from '../confirm-transaction' +} from '../confirm-transaction'; const getEthersArrayLikeFromObj = (obj) => { - const arr = [] + const arr = []; Object.keys(obj).forEach((key) => { - arr.push([obj[key]]) - arr[key] = obj[key] - }) - return arr -} + arr.push([obj[key]]); + arr[key] = obj[key]; + }); + return arr; +}; describe('Confirm Transaction Selector', function () { describe('unconfirmedTransactionsCountSelector', function () { @@ -33,12 +33,12 @@ describe('Confirm Transaction Selector', function () { unapprovedTypedMessagesCount: 1, network: 'test', }, - } + }; it('returns number of txs in unapprovedTxs state with the same network plus unapproved signing method counts', function () { - assert.strictEqual(unconfirmedTransactionsCountSelector(state), 4) - }) - }) + assert.strictEqual(unconfirmedTransactionsCountSelector(state), 4); + }); + }); describe('sendTokenTokenAmountAndToAddressSelector', function () { const state = { @@ -55,15 +55,15 @@ describe('Confirm Transaction Selector', function () { tokenSymbol: 'META', }, }, - } + }; it('returns token address and calculated token amount', function () { assert.deepStrictEqual(sendTokenTokenAmountAndToAddressSelector(state), { toAddress: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', tokenAmount: '0.01', - }) - }) - }) + }); + }); + }); describe('contractExchangeRateSelector', function () { const state = { @@ -79,19 +79,19 @@ describe('Confirm Transaction Selector', function () { }, }, }, - } + }; it('returns contract exchange rate in metamask state based on confirm transaction txParams token recipient', function () { - assert.strictEqual(contractExchangeRateSelector(state), '10') - }) - }) + assert.strictEqual(contractExchangeRateSelector(state), '10'); + }); + }); describe('conversionRateSelector', function () { it('returns conversionRate from state', function () { const state = { metamask: { conversionRate: 556.12 }, - } - assert.strictEqual(conversionRateSelector(state), 556.12) - }) - }) -}) + }; + assert.strictEqual(conversionRateSelector(state), 556.12); + }); + }); +}); diff --git a/ui/app/selectors/tests/custom-gas.test.js b/ui/app/selectors/tests/custom-gas.test.js index cd5d9686e3..e0a94eaf50 100644 --- a/ui/app/selectors/tests/custom-gas.test.js +++ b/ui/app/selectors/tests/custom-gas.test.js @@ -1,27 +1,27 @@ -import assert from 'assert' -import proxyquire from 'proxyquire' +import assert from 'assert'; +import proxyquire from 'proxyquire'; const { getCustomGasLimit, getCustomGasPrice, getRenderableBasicEstimateData, getRenderableEstimateDataForSmallButtonsFromGWEI, -} = proxyquire('../custom-gas', {}) +} = proxyquire('../custom-gas', {}); describe('custom-gas selectors', function () { describe('getCustomGasPrice()', function () { it('should return gas.customData.price', function () { - const mockState = { gas: { customData: { price: 'mockPrice' } } } - assert.strictEqual(getCustomGasPrice(mockState), 'mockPrice') - }) - }) + const mockState = { gas: { customData: { price: 'mockPrice' } } }; + assert.strictEqual(getCustomGasPrice(mockState), 'mockPrice'); + }); + }); describe('getCustomGasLimit()', function () { it('should return gas.customData.limit', function () { - const mockState = { gas: { customData: { limit: 'mockLimit' } } } - assert.strictEqual(getCustomGasLimit(mockState), 'mockLimit') - }) - }) + const mockState = { gas: { customData: { limit: 'mockLimit' } } }; + assert.strictEqual(getCustomGasLimit(mockState), 'mockLimit'); + }); + }); describe('getRenderableBasicEstimateData()', function () { const tests = [ @@ -260,7 +260,7 @@ describe('custom-gas selectors', function () { }, }, }, - ] + ]; it('should return renderable data about basic estimates', function () { tests.forEach((test) => { assert.deepStrictEqual( @@ -270,10 +270,10 @@ describe('custom-gas selectors', function () { test.useFastestButtons, ), test.expectedResult, - ) - }) - }) - }) + ); + }); + }); + }); describe('getRenderableEstimateDataForSmallButtonsFromGWEI()', function () { const tests = [ @@ -509,14 +509,14 @@ describe('custom-gas selectors', function () { }, }, }, - ] + ]; it('should return renderable data about basic estimates appropriate for buttons with less info', function () { tests.forEach((test) => { assert.deepStrictEqual( getRenderableEstimateDataForSmallButtonsFromGWEI(test.mockState), test.expectedResult, - ) - }) - }) - }) -}) + ); + }); + }); + }); +}); diff --git a/ui/app/selectors/tests/permissions.test.js b/ui/app/selectors/tests/permissions.test.js index 4750afa60f..c9d3036034 100644 --- a/ui/app/selectors/tests/permissions.test.js +++ b/ui/app/selectors/tests/permissions.test.js @@ -1,9 +1,9 @@ -import assert from 'assert' +import assert from 'assert'; import { getConnectedDomainsForSelectedAddress, getOrderedConnectedAccountsForActiveTab, getPermissionsForActiveTab, -} from '../permissions' +} from '../permissions'; describe('selectors', function () { describe('getConnectedDomainsForSelectedAddress', function () { @@ -62,8 +62,8 @@ describe('selectors', function () { }, }, }, - } - const extensionId = undefined + }; + const extensionId = undefined; assert.deepStrictEqual(getConnectedDomainsForSelectedAddress(mockState), [ { extensionId, @@ -79,8 +79,8 @@ describe('selectors', function () { origin: 'https://remix.ethereum.org', host: 'remix.ethereum.org', }, - ]) - }) + ]); + }); it('should return the list of connected domains when there are 2 connected accounts', function () { const mockState = { @@ -140,8 +140,8 @@ describe('selectors', function () { }, }, }, - } - const extensionId = undefined + }; + const extensionId = undefined; assert.deepStrictEqual(getConnectedDomainsForSelectedAddress(mockState), [ { extensionId, @@ -150,9 +150,9 @@ describe('selectors', function () { origin: 'https://remix.ethereum.org', host: 'remix.ethereum.com', }, - ]) - }) - }) + ]); + }); + }); describe('getConnectedAccountsForActiveTab', function () { const mockState = { @@ -276,7 +276,7 @@ describe('selectors', function () { }, }, }, - } + }; it('should return connected accounts sorted by last selected, then by keyring controller order', function () { assert.deepStrictEqual( @@ -311,9 +311,9 @@ describe('selectors', function () { lastActive: 1586359844192, }, ], - ) - }) - }) + ); + }); + }); describe('getPermissionsForActiveTab', function () { const mockState = { @@ -415,14 +415,14 @@ describe('selectors', function () { }, }, }, - } + }; it('should return a list of permissions strings', function () { assert.deepStrictEqual(getPermissionsForActiveTab(mockState), [ { key: 'eth_accounts', }, - ]) - }) - }) -}) + ]); + }); + }); +}); diff --git a/ui/app/selectors/tests/selectors.test.js b/ui/app/selectors/tests/selectors.test.js index be03752a9f..46058fe129 100644 --- a/ui/app/selectors/tests/selectors.test.js +++ b/ui/app/selectors/tests/selectors.test.js @@ -1,6 +1,6 @@ -import assert from 'assert' -import * as selectors from '../selectors' -import mockState from '../../../../test/data/mock-state.json' +import assert from 'assert'; +import * as selectors from '../selectors'; +import mockState from '../../../../test/data/mock-state.json'; describe('Selectors', function () { describe('#getSelectedAddress', function () { @@ -8,43 +8,43 @@ describe('Selectors', function () { assert.strictEqual( selectors.getSelectedAddress({ metamask: {} }), undefined, - ) - }) + ); + }); it('returns selectedAddress', function () { - const selectedAddress = '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc' + const selectedAddress = '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'; assert.strictEqual( selectors.getSelectedAddress({ metamask: { selectedAddress } }), selectedAddress, - ) - }) - }) + ); + }); + }); it('returns selected identity', function () { assert.deepStrictEqual(selectors.getSelectedIdentity(mockState), { address: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', name: 'Test Account', - }) - }) + }); + }); it('returns selected account', function () { - const account = selectors.getSelectedAccount(mockState) - assert.strictEqual(account.balance, '0x0') + const account = selectors.getSelectedAccount(mockState); + assert.strictEqual(account.balance, '0x0'); assert.strictEqual( account.address, '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', - ) - }) + ); + }); describe('#getTokenExchangeRates', function () { it('returns token exchange rates', function () { - const tokenExchangeRates = selectors.getTokenExchangeRates(mockState) + const tokenExchangeRates = selectors.getTokenExchangeRates(mockState); assert.deepStrictEqual(tokenExchangeRates, { '0x108cf70c7d384c552f42c07c41c0e1e46d77ea0d': 0.00039345803819379796, '0xd8f6a2ffb0fc5952d16c9768b71cfd35b6399aa5': 0.00008189274407698049, - }) - }) - }) + }); + }); + }); describe('#getAddressBook', function () { it('should return the address book', function () { @@ -56,47 +56,47 @@ describe('Selectors', function () { memo: '', name: 'Address Book Account 1', }, - ]) - }) - }) + ]); + }); + }); it('returns accounts with balance, address, and name from identity and accounts in state', function () { const accountsWithSendEther = selectors.accountsWithSendEtherInfoSelector( mockState, - ) - assert.strictEqual(accountsWithSendEther.length, 2) - assert.strictEqual(accountsWithSendEther[0].balance, '0x0') + ); + assert.strictEqual(accountsWithSendEther.length, 2); + assert.strictEqual(accountsWithSendEther[0].balance, '0x0'); assert.strictEqual( accountsWithSendEther[0].address, '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', - ) - assert.strictEqual(accountsWithSendEther[0].name, 'Test Account') - }) + ); + assert.strictEqual(accountsWithSendEther[0].name, 'Test Account'); + }); it('returns selected account with balance, address, and name from accountsWithSendEtherInfoSelector', function () { const currentAccountwithSendEther = selectors.getCurrentAccountWithSendEtherInfo( mockState, - ) - assert.strictEqual(currentAccountwithSendEther.balance, '0x0') + ); + assert.strictEqual(currentAccountwithSendEther.balance, '0x0'); assert.strictEqual( currentAccountwithSendEther.address, '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', - ) - assert.strictEqual(currentAccountwithSendEther.name, 'Test Account') - }) + ); + assert.strictEqual(currentAccountwithSendEther.name, 'Test Account'); + }); it('#getGasIsLoading', function () { - const gasIsLoading = selectors.getGasIsLoading(mockState) - assert.strictEqual(gasIsLoading, false) - }) + const gasIsLoading = selectors.getGasIsLoading(mockState); + assert.strictEqual(gasIsLoading, false); + }); it('#getCurrentCurrency', function () { - const currentCurrency = selectors.getCurrentCurrency(mockState) - assert.strictEqual(currentCurrency, 'usd') - }) + const currentCurrency = selectors.getCurrentCurrency(mockState); + assert.strictEqual(currentCurrency, 'usd'); + }); it('#getTotalUnapprovedCount', function () { - const totalUnapprovedCount = selectors.getTotalUnapprovedCount(mockState) - assert.strictEqual(totalUnapprovedCount, 1) - }) -}) + const totalUnapprovedCount = selectors.getTotalUnapprovedCount(mockState); + assert.strictEqual(totalUnapprovedCount, 1); + }); +}); diff --git a/ui/app/selectors/tests/send-selectors-test-data.js b/ui/app/selectors/tests/send-selectors-test-data.js index bfa015e58e..19a91e9d3d 100644 --- a/ui/app/selectors/tests/send-selectors-test-data.js +++ b/ui/app/selectors/tests/send-selectors-test-data.js @@ -1,4 +1,4 @@ -import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction' +import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'; const state = { metamask: { @@ -214,6 +214,6 @@ const state = { toDropdownOpen: false, errors: { someError: null }, }, -} +}; -export default state +export default state; diff --git a/ui/app/selectors/tests/send.test.js b/ui/app/selectors/tests/send.test.js index eeb080e3b8..2dc9598acb 100644 --- a/ui/app/selectors/tests/send.test.js +++ b/ui/app/selectors/tests/send.test.js @@ -1,10 +1,10 @@ -import assert from 'assert' -import sinon from 'sinon' +import assert from 'assert'; +import sinon from 'sinon'; import { accountsWithSendEtherInfoSelector, getCurrentAccountWithSendEtherInfo, -} from '..' -import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction' +} from '..'; +import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'; import { getBlockGasLimit, getConversionRate, @@ -34,22 +34,22 @@ import { getGasButtonGroupShown, getTitleKey, isSendFormInError, -} from '../send' -import mockState from './send-selectors-test-data' +} from '../send'; +import mockState from './send-selectors-test-data'; describe('send selectors', function () { - const tempGlobalEth = { ...global.eth } + const tempGlobalEth = { ...global.eth }; beforeEach(function () { global.eth = { contract: sinon.stub().returns({ at: (address) => `mockAt:${address}`, }), - } - }) + }; + }); afterEach(function () { - global.eth = tempGlobalEth - }) + global.eth = tempGlobalEth; + }); describe('accountsWithSendEtherInfoSelector()', function () { it('should return an array of account objects with name info from identities', function () { @@ -82,21 +82,21 @@ describe('send selectors', function () { address: '0xd85a4b6a394794842887b8284293d69163007bbb', name: 'Send Account 4', }, - ]) - }) - }) + ]); + }); + }); describe('getBlockGasLimit', function () { it('should return the current block gas limit', function () { - assert.deepStrictEqual(getBlockGasLimit(mockState), '0x4c1878') - }) - }) + assert.deepStrictEqual(getBlockGasLimit(mockState), '0x4c1878'); + }); + }); describe('getConversionRate()', function () { it('should return the eth conversion rate', function () { - assert.deepStrictEqual(getConversionRate(mockState), 1200.88200327) - }) - }) + assert.deepStrictEqual(getConversionRate(mockState), 1200.88200327); + }); + }); describe('getCurrentAccountWithSendEtherInfo()', function () { it('should return the currently selected account with identity info', function () { @@ -106,39 +106,39 @@ describe('send selectors', function () { nonce: '0x0', address: '0xd85a4b6a394794842887b8284293d69163007bbb', name: 'Send Account 4', - }) - }) - }) + }); + }); + }); describe('getNativeCurrency()', function () { it('should return the ticker symbol of the selected network', function () { - assert.strictEqual(getNativeCurrency(mockState), 'ETH') - }) - }) + assert.strictEqual(getNativeCurrency(mockState), 'ETH'); + }); + }); describe('getCurrentNetwork()', function () { it('should return the id of the currently selected network', function () { - assert.strictEqual(getCurrentNetwork(mockState), '3') - }) - }) + assert.strictEqual(getCurrentNetwork(mockState), '3'); + }); + }); describe('getGasLimit()', function () { it('should return the send.gasLimit', function () { - assert.strictEqual(getGasLimit(mockState), '0xFFFF') - }) - }) + assert.strictEqual(getGasLimit(mockState), '0xFFFF'); + }); + }); describe('getGasPrice()', function () { it('should return the send.gasPrice', function () { - assert.strictEqual(getGasPrice(mockState), '0xaa') - }) - }) + assert.strictEqual(getGasPrice(mockState), '0xaa'); + }); + }); describe('getGasTotal()', function () { it('should return the send.gasTotal', function () { - assert.strictEqual(getGasTotal(mockState), 'a9ff56') - }) - }) + assert.strictEqual(getGasTotal(mockState), 'a9ff56'); + }); + }); describe('getPrimaryCurrency()', function () { it('should return the symbol of the send token', function () { @@ -147,9 +147,9 @@ describe('send selectors', function () { metamask: { send: { token: { symbol: 'DEF' } } }, }), 'DEF', - ) - }) - }) + ); + }); + }); describe('getSendToken()', function () { it('should return the current send token if set', function () { @@ -170,9 +170,9 @@ describe('send selectors', function () { decimals: 4, symbol: 'DEF', }, - ) - }) - }) + ); + }); + }); describe('getSendTokenContract()', function () { it('should return the contract at the send token address', function () { @@ -189,55 +189,55 @@ describe('send selectors', function () { }, }), 'mockAt:0x8d6b81208414189a58339873ab429b6c47ab92d3', - ) - }) + ); + }); it('should return null if send token is not set', function () { - const modifiedMetamaskState = { ...mockState.metamask, send: {} } + const modifiedMetamaskState = { ...mockState.metamask, send: {} }; assert.strictEqual( getSendTokenContract({ ...mockState, metamask: modifiedMetamaskState }), null, - ) - }) - }) + ); + }); + }); describe('getSendAmount()', function () { it('should return the send.amount', function () { - assert.strictEqual(getSendAmount(mockState), '0x080') - }) - }) + assert.strictEqual(getSendAmount(mockState), '0x080'); + }); + }); describe('getSendEditingTransactionId()', function () { it('should return the send.editingTransactionId', function () { - assert.strictEqual(getSendEditingTransactionId(mockState), 97531) - }) - }) + assert.strictEqual(getSendEditingTransactionId(mockState), 97531); + }); + }); describe('getSendErrors()', function () { it('should return the send.errors', function () { - assert.deepStrictEqual(getSendErrors(mockState), { someError: null }) - }) - }) + assert.deepStrictEqual(getSendErrors(mockState), { someError: null }); + }); + }); describe('getSendHexDataFeatureFlagState()', function () { it('should return the sendHexData feature flag state', function () { - assert.deepStrictEqual(getSendHexDataFeatureFlagState(mockState), true) - }) - }) + assert.deepStrictEqual(getSendHexDataFeatureFlagState(mockState), true); + }); + }); describe('getSendFrom()', function () { it('should return the send.from', function () { assert.deepStrictEqual( getSendFrom(mockState), '0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb', - ) - }) - }) + ); + }); + }); describe('getSendFromBalance()', function () { it('should get the send.from balance if it exists', function () { - assert.strictEqual(getSendFromBalance(mockState), '0x37452b1315889f80') - }) + assert.strictEqual(getSendFromBalance(mockState), '0x37452b1315889f80'); + }); it('should get the selected account balance if the send.from does not exist', function () { const editedMockState = { @@ -247,10 +247,10 @@ describe('send selectors', function () { from: null, }, }, - } - assert.strictEqual(getSendFromBalance(editedMockState), '0x0') - }) - }) + }; + assert.strictEqual(getSendFromBalance(editedMockState), '0x0'); + }); + }); describe('getSendFromObject()', function () { it('should return send.from if it exists', function () { @@ -259,8 +259,8 @@ describe('send selectors', function () { balance: '0x37452b1315889f80', code: '0x', nonce: '0xa', - }) - }) + }); + }); it('should return the current account if send.from does not exist', function () { const editedMockState = { @@ -270,27 +270,27 @@ describe('send selectors', function () { from: null, }, }, - } + }; assert.deepStrictEqual(getSendFromObject(editedMockState), { code: '0x', balance: '0x0', nonce: '0x0', address: '0xd85a4b6a394794842887b8284293d69163007bbb', - }) - }) - }) + }); + }); + }); describe('getSendMaxModeState()', function () { it('should return send.maxModeOn', function () { - assert.strictEqual(getSendMaxModeState(mockState), false) - }) - }) + assert.strictEqual(getSendMaxModeState(mockState), false); + }); + }); describe('getSendTo()', function () { it('should return send.to', function () { - assert.strictEqual(getSendTo(mockState), '0x987fedabc') - }) - }) + assert.strictEqual(getSendTo(mockState), '0x987fedabc'); + }); + }); describe('getSendToAccounts()', function () { it('should return an array including all the users accounts and the address book', function () { @@ -328,15 +328,15 @@ describe('send selectors', function () { name: 'Address Book Account 1', chainId: '0x3', }, - ]) - }) - }) + ]); + }); + }); describe('getTokenBalance()', function () { it('should', function () { - assert.strictEqual(getTokenBalance(mockState), 3434) - }) - }) + assert.strictEqual(getTokenBalance(mockState), 3434); + }); + }); describe('getUnapprovedTxs()', function () { it('should return the unapproved txs', function () { @@ -360,9 +360,9 @@ describe('send selectors', function () { maxCost: 'de234b52e4a0800', gasPrice: '4a817c800', }, - }) - }) - }) + }); + }); + }); describe('send-amount-row selectors', function () { describe('sendAmountIsInError()', function () { @@ -373,10 +373,10 @@ describe('send selectors', function () { amount: 'abc', }, }, - } + }; - assert.strictEqual(sendAmountIsInError(state), true) - }) + assert.strictEqual(sendAmountIsInError(state), true); + }); it('should return false if send.errors.amount is falsy', function () { const state = { @@ -385,12 +385,12 @@ describe('send selectors', function () { amount: null, }, }, - } + }; - assert.strictEqual(sendAmountIsInError(state), false) - }) - }) - }) + assert.strictEqual(sendAmountIsInError(state), false); + }); + }); + }); describe('send-gas-row selectors', function () { describe('getGasLoadingError()', function () { @@ -401,11 +401,11 @@ describe('send selectors', function () { gasLoading: 'abc', }, }, - } + }; - assert.strictEqual(getGasLoadingError(state), 'abc') - }) - }) + assert.strictEqual(getGasLoadingError(state), 'abc'); + }); + }); describe('gasFeeIsInError()', function () { it('should return true if send.errors.gasFee is truthy', function () { @@ -415,10 +415,10 @@ describe('send selectors', function () { gasFee: 'def', }, }, - } + }; - assert.strictEqual(gasFeeIsInError(state), true) - }) + assert.strictEqual(gasFeeIsInError(state), true); + }); it('should return false send.errors.gasFee is falsely', function () { const state = { @@ -427,11 +427,11 @@ describe('send selectors', function () { gasFee: null, }, }, - } + }; - assert.strictEqual(gasFeeIsInError(state), false) - }) - }) + assert.strictEqual(gasFeeIsInError(state), false); + }); + }); describe('getGasButtonGroupShown()', function () { it('should return send.gasButtonGroupShown', function () { @@ -439,12 +439,12 @@ describe('send selectors', function () { send: { gasButtonGroupShown: 'foobar', }, - } + }; - assert.strictEqual(getGasButtonGroupShown(state), 'foobar') - }) - }) - }) + assert.strictEqual(getGasButtonGroupShown(state), 'foobar'); + }); + }); + }); describe('send-header selectors', function () { const getMetamaskSendMockState = (send) => { @@ -452,16 +452,16 @@ describe('send selectors', function () { metamask: { send: { ...send }, }, - } - } + }; + }; describe('getTitleKey()', function () { it('should return the correct key when "to" is empty', function () { assert.strictEqual( getTitleKey(getMetamaskSendMockState({})), 'addRecipient', - ) - }) + ); + }); it('should return the correct key when getSendEditingTransactionId is truthy', function () { assert.strictEqual( @@ -473,8 +473,8 @@ describe('send selectors', function () { }), ), 'edit', - ) - }) + ); + }); it('should return the correct key when getSendEditingTransactionId is falsy and getSendToken is truthy', function () { assert.strictEqual( @@ -486,8 +486,8 @@ describe('send selectors', function () { }), ), 'sendTokens', - ) - }) + ); + }); it('should return the correct key when getSendEditingTransactionId is falsy and getSendToken is falsy', function () { assert.strictEqual( @@ -499,17 +499,17 @@ describe('send selectors', function () { }), ), 'sendETH', - ) - }) - }) - }) + ); + }); + }); + }); describe('send-footer selectors', function () { const getSendMockState = (send) => { return { send: { ...send }, - } - } + }; + }; describe('isSendFormInError()', function () { it('should return true if any of the values of the object returned by getSendErrors are truthy', function () { @@ -520,8 +520,8 @@ describe('send selectors', function () { }), ), true, - ) - }) + ); + }); it('should return false if all of the values of the object returned by getSendErrors are falsy', function () { assert.strictEqual( @@ -531,7 +531,7 @@ describe('send selectors', function () { }), ), false, - ) + ); assert.strictEqual( isSendFormInError( getSendMockState({ @@ -539,8 +539,8 @@ describe('send selectors', function () { }), ), false, - ) - }) - }) - }) -}) + ); + }); + }); + }); +}); diff --git a/ui/app/selectors/tests/transactions.test.js b/ui/app/selectors/tests/transactions.test.js index 5930553920..c38dd4d302 100644 --- a/ui/app/selectors/tests/transactions.test.js +++ b/ui/app/selectors/tests/transactions.test.js @@ -1,5 +1,5 @@ -import { strict as assert } from 'assert' -import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction' +import { strict as assert } from 'assert'; +import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'; import { unapprovedMessagesSelector, transactionsSelector, @@ -7,7 +7,7 @@ import { nonceSortedPendingTransactionsSelector, nonceSortedCompletedTransactionsSelector, submittedPendingTransactionsSelector, -} from '../transactions' +} from '../transactions'; describe('Transaction Selectors', function () { describe('unapprovedMessagesSelector', function () { @@ -22,7 +22,7 @@ describe('Transaction Selectors', function () { time: 1, status: TRANSACTION_STATUSES.UNAPPROVED, type: 'eth_sign', - } + }; const state = { metamask: { @@ -30,13 +30,13 @@ describe('Transaction Selectors', function () { 1: msg, }, }, - } + }; - const msgSelector = unapprovedMessagesSelector(state) + const msgSelector = unapprovedMessagesSelector(state); - assert(Array.isArray(msgSelector)) - assert.deepStrictEqual(msgSelector, [msg]) - }) + assert(Array.isArray(msgSelector)); + assert.deepStrictEqual(msgSelector, [msg]); + }); it('returns personal sign from unapprovedPersonalMsgsSelector', function () { const msg = { @@ -49,7 +49,7 @@ describe('Transaction Selectors', function () { time: 1, status: TRANSACTION_STATUSES.UNAPPROVED, type: 'personal_sign', - } + }; const state = { metamask: { @@ -57,13 +57,13 @@ describe('Transaction Selectors', function () { 1: msg, }, }, - } + }; - const msgSelector = unapprovedMessagesSelector(state) + const msgSelector = unapprovedMessagesSelector(state); - assert(Array.isArray(msgSelector)) - assert.deepStrictEqual(msgSelector, [msg]) - }) + assert(Array.isArray(msgSelector)); + assert.deepStrictEqual(msgSelector, [msg]); + }); it('returns typed message from unapprovedTypedMessagesSelector', function () { const msg = { @@ -77,7 +77,7 @@ describe('Transaction Selectors', function () { time: 1, status: TRANSACTION_STATUSES.UNAPPROVED, type: 'eth_signTypedData', - } + }; const state = { metamask: { @@ -85,14 +85,14 @@ describe('Transaction Selectors', function () { 1: msg, }, }, - } + }; - const msgSelector = unapprovedMessagesSelector(state) + const msgSelector = unapprovedMessagesSelector(state); - assert(Array.isArray(msgSelector)) - assert.deepStrictEqual(msgSelector, [msg]) - }) - }) + assert(Array.isArray(msgSelector)); + assert.deepStrictEqual(msgSelector, [msg]); + }); + }); describe('transactionsSelector', function () { it('selects the currentNetworkTxList', function () { @@ -124,18 +124,18 @@ describe('Transaction Selectors', function () { }, ], }, - } + }; const orderedTxList = state.metamask.currentNetworkTxList.sort( (a, b) => b.time - a.time, - ) + ); - const selectedTx = transactionsSelector(state) + const selectedTx = transactionsSelector(state); - assert(Array.isArray(selectedTx)) - assert.deepStrictEqual(selectedTx, orderedTxList) - }) - }) + assert(Array.isArray(selectedTx)); + assert.deepStrictEqual(selectedTx, orderedTxList); + }); + }); describe('nonceSortedTransactionsSelector', function () { it('returns transaction group nonce sorted tx from from selectedTxList wit', function () { @@ -147,7 +147,7 @@ describe('Transaction Selectors', function () { to: '0xRecipient', nonce: '0x0', }, - } + }; const tx2 = { id: 1, @@ -157,7 +157,7 @@ describe('Transaction Selectors', function () { to: '0xRecipient', nonce: '0x1', }, - } + }; const state = { metamask: { @@ -170,7 +170,7 @@ describe('Transaction Selectors', function () { }, currentNetworkTxList: [tx1, tx2], }, - } + }; const expectedResult = [ { @@ -189,14 +189,14 @@ describe('Transaction Selectors', function () { hasRetried: false, hasCancelled: false, }, - ] + ]; assert.deepStrictEqual( nonceSortedTransactionsSelector(state), expectedResult, - ) - }) - }) + ); + }); + }); describe('Sorting Transactions Selectors', function () { const submittedTx = { @@ -208,7 +208,7 @@ describe('Transaction Selectors', function () { nonce: '0x0', }, status: TRANSACTION_STATUSES.SUBMITTED, - } + }; const unapprovedTx = { id: 1, @@ -219,7 +219,7 @@ describe('Transaction Selectors', function () { nonce: '0x1', }, status: TRANSACTION_STATUSES.UNAPPROVED, - } + }; const approvedTx = { id: 2, @@ -230,7 +230,7 @@ describe('Transaction Selectors', function () { nonce: '0x2', }, status: TRANSACTION_STATUSES.APPROVED, - } + }; const confirmedTx = { id: 3, @@ -241,7 +241,7 @@ describe('Transaction Selectors', function () { nonce: '0x3', }, status: TRANSACTION_STATUSES.CONFIRMED, - } + }; const state = { metamask: { @@ -259,7 +259,7 @@ describe('Transaction Selectors', function () { confirmedTx, ], }, - } + }; it('nonceSortedPendingTransactionsSelector', function () { const expectedResult = [ @@ -287,13 +287,13 @@ describe('Transaction Selectors', function () { hasRetried: false, hasCancelled: false, }, - ] + ]; assert.deepStrictEqual( nonceSortedPendingTransactionsSelector(state), expectedResult, - ) - }) + ); + }); it('nonceSortedCompletedTransactionsSelector', function () { const expectedResult = [ @@ -305,20 +305,20 @@ describe('Transaction Selectors', function () { hasRetried: false, hasCancelled: false, }, - ] + ]; assert.deepStrictEqual( nonceSortedCompletedTransactionsSelector(state), expectedResult, - ) - }) + ); + }); it('submittedPendingTransactionsSelector', function () { - const expectedResult = [submittedTx] + const expectedResult = [submittedTx]; assert.deepStrictEqual( submittedPendingTransactionsSelector(state), expectedResult, - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/ui/app/selectors/transactions.js b/ui/app/selectors/transactions.js index 9436d56c1a..f9a8539d66 100644 --- a/ui/app/selectors/transactions.js +++ b/ui/app/selectors/transactions.js @@ -1,42 +1,42 @@ -import { createSelector } from 'reselect' +import { createSelector } from 'reselect'; import { PRIORITY_STATUS_HASH, PENDING_STATUS_HASH, -} from '../helpers/constants/transactions' -import { hexToDecimal } from '../helpers/utils/conversions.util' -import txHelper from '../../lib/tx-helper' +} from '../helpers/constants/transactions'; +import { hexToDecimal } from '../helpers/utils/conversions.util'; +import txHelper from '../../lib/tx-helper'; import { TRANSACTION_CATEGORIES, TRANSACTION_STATUSES, TRANSACTION_TYPES, -} from '../../../shared/constants/transaction' -import { getSelectedAddress } from '.' +} from '../../../shared/constants/transaction'; +import { getSelectedAddress } from '.'; export const incomingTxListSelector = (state) => { - const { showIncomingTransactions } = state.metamask.featureFlags + const { showIncomingTransactions } = state.metamask.featureFlags; if (!showIncomingTransactions) { - return [] + return []; } - const { network } = state.metamask - const selectedAddress = getSelectedAddress(state) + const { network } = state.metamask; + const selectedAddress = getSelectedAddress(state); return Object.values(state.metamask.incomingTransactions).filter( ({ metamaskNetworkId, txParams }) => txParams.to === selectedAddress && metamaskNetworkId === network, - ) -} -export const unapprovedMsgsSelector = (state) => state.metamask.unapprovedMsgs + ); +}; +export const unapprovedMsgsSelector = (state) => state.metamask.unapprovedMsgs; export const currentNetworkTxListSelector = (state) => - state.metamask.currentNetworkTxList + state.metamask.currentNetworkTxList; export const unapprovedPersonalMsgsSelector = (state) => - state.metamask.unapprovedPersonalMsgs + state.metamask.unapprovedPersonalMsgs; export const unapprovedDecryptMsgsSelector = (state) => - state.metamask.unapprovedDecryptMsgs + state.metamask.unapprovedDecryptMsgs; export const unapprovedEncryptionPublicKeyMsgsSelector = (state) => - state.metamask.unapprovedEncryptionPublicKeyMsgs + state.metamask.unapprovedEncryptionPublicKeyMsgs; export const unapprovedTypedMessagesSelector = (state) => - state.metamask.unapprovedTypedMessages -export const networkSelector = (state) => state.metamask.network + state.metamask.unapprovedTypedMessages; +export const networkSelector = (state) => state.metamask.network; export const selectedAddressTxListSelector = createSelector( getSelectedAddress, @@ -44,9 +44,9 @@ export const selectedAddressTxListSelector = createSelector( (selectedAddress, transactions = []) => { return transactions.filter( ({ txParams }) => txParams.from === selectedAddress, - ) + ); }, -) +); export const unapprovedMessagesSelector = createSelector( unapprovedMsgsSelector, @@ -72,25 +72,25 @@ export const unapprovedMessagesSelector = createSelector( unapprovedTypedMessages, network, ) || [], -) +); export const transactionSubSelector = createSelector( unapprovedMessagesSelector, incomingTxListSelector, (unapprovedMessages = [], incomingTxList = []) => { - return unapprovedMessages.concat(incomingTxList) + return unapprovedMessages.concat(incomingTxList); }, -) +); export const transactionsSelector = createSelector( transactionSubSelector, selectedAddressTxListSelector, (subSelectorTxList = [], selectedAddressTxList = []) => { - const txsToRender = selectedAddressTxList.concat(subSelectorTxList) + const txsToRender = selectedAddressTxList.concat(subSelectorTxList); - return txsToRender.sort((a, b) => b.time - a.time) + return txsToRender.sort((a, b) => b.time - a.time); }, -) +); /** * @name insertOrderedNonce @@ -102,19 +102,19 @@ export const transactionsSelector = createSelector( * @returns {string[]} */ const insertOrderedNonce = (nonces, nonceToInsert) => { - let insertIndex = nonces.length + let insertIndex = nonces.length; for (let i = 0; i < nonces.length; i++) { - const nonce = nonces[i] + const nonce = nonces[i]; if (Number(hexToDecimal(nonce)) > Number(hexToDecimal(nonceToInsert))) { - insertIndex = i - break + insertIndex = i; + break; } } - nonces.splice(insertIndex, 0, nonceToInsert) -} + nonces.splice(insertIndex, 0, nonceToInsert); +}; /** * @name insertTransactionByTime @@ -126,21 +126,21 @@ const insertOrderedNonce = (nonces, nonceToInsert) => { * @returns {Object[]} */ const insertTransactionByTime = (transactions, transaction) => { - const { time } = transaction + const { time } = transaction; - let insertIndex = transactions.length + let insertIndex = transactions.length; for (let i = 0; i < transactions.length; i++) { - const tx = transactions[i] + const tx = transactions[i]; if (tx.time > time) { - insertIndex = i - break + insertIndex = i; + break; } } - transactions.splice(insertIndex, 0, transaction) -} + transactions.splice(insertIndex, 0, transaction); +}; /** * Contains transactions and properties associated with those transactions of the same nonce. @@ -166,22 +166,22 @@ const insertTransactionByTime = (transactions, transaction) => { const insertTransactionGroupByTime = (transactionGroups, transactionGroup) => { const { primaryTransaction: { time: groupToInsertTime } = {}, - } = transactionGroup + } = transactionGroup; - let insertIndex = transactionGroups.length + let insertIndex = transactionGroups.length; for (let i = 0; i < transactionGroups.length; i++) { - const txGroup = transactionGroups[i] - const { primaryTransaction: { time } = {} } = txGroup + const txGroup = transactionGroups[i]; + const { primaryTransaction: { time } = {} } = txGroup; if (time > groupToInsertTime) { - insertIndex = i - break + insertIndex = i; + break; } } - transactionGroups.splice(insertIndex, 0, transactionGroup) -} + transactionGroups.splice(insertIndex, 0, transactionGroup); +}; /** * @name mergeNonNonceTransactionGroups @@ -198,9 +198,9 @@ const mergeNonNonceTransactionGroups = ( nonNonceTransactionGroups, ) => { nonNonceTransactionGroups.forEach((transactionGroup) => { - insertTransactionGroupByTime(orderedTransactionGroups, transactionGroup) - }) -} + insertTransactionGroupByTime(orderedTransactionGroups, transactionGroup); + }); +}; /** * @name nonceSortedTransactionsSelector @@ -210,10 +210,10 @@ const mergeNonNonceTransactionGroups = ( export const nonceSortedTransactionsSelector = createSelector( transactionsSelector, (transactions = []) => { - const unapprovedTransactionGroups = [] - const incomingTransactionGroups = [] - const orderedNonces = [] - const nonceToTransactionsMap = {} + const unapprovedTransactionGroups = []; + const incomingTransactionGroups = []; + const orderedNonces = []; + const nonceToTransactionsMap = {}; transactions.forEach((transaction) => { const { @@ -222,7 +222,7 @@ export const nonceSortedTransactionsSelector = createSelector( type, time: txTime, transactionCategory, - } = transaction + } = transaction; if ( typeof nonce === 'undefined' || @@ -234,30 +234,30 @@ export const nonceSortedTransactionsSelector = createSelector( primaryTransaction: transaction, hasRetried: false, hasCancelled: false, - } + }; if (transactionCategory === TRANSACTION_CATEGORIES.INCOMING) { - incomingTransactionGroups.push(transactionGroup) + incomingTransactionGroups.push(transactionGroup); } else { insertTransactionGroupByTime( unapprovedTransactionGroups, transactionGroup, - ) + ); } } else if (nonce in nonceToTransactionsMap) { - const nonceProps = nonceToTransactionsMap[nonce] - insertTransactionByTime(nonceProps.transactions, transaction) + const nonceProps = nonceToTransactionsMap[nonce]; + insertTransactionByTime(nonceProps.transactions, transaction); const { primaryTransaction: { time: primaryTxTime = 0 } = {}, - } = nonceProps + } = nonceProps; const previousPrimaryIsNetworkFailure = nonceProps.primaryTransaction.status === TRANSACTION_STATUSES.FAILED && - nonceProps.primaryTransaction?.txReceipt?.status !== '0x0' + nonceProps.primaryTransaction?.txReceipt?.status !== '0x0'; const currentTransactionIsOnChainFailure = - transaction?.txReceipt?.status === '0x0' + transaction?.txReceipt?.status === '0x0'; if ( status === TRANSACTION_STATUSES.CONFIRMED || @@ -265,25 +265,25 @@ export const nonceSortedTransactionsSelector = createSelector( previousPrimaryIsNetworkFailure || (txTime > primaryTxTime && status in PRIORITY_STATUS_HASH) ) { - nonceProps.primaryTransaction = transaction + nonceProps.primaryTransaction = transaction; } const { initialTransaction: { time: initialTxTime = 0 } = {}, - } = nonceProps + } = nonceProps; // Used to display the transaction action, since we don't want to overwrite the action if // it was replaced with a cancel attempt transaction. if (txTime < initialTxTime) { - nonceProps.initialTransaction = transaction + nonceProps.initialTransaction = transaction; } if (type === TRANSACTION_TYPES.RETRY) { - nonceProps.hasRetried = true + nonceProps.hasRetried = true; } if (type === TRANSACTION_TYPES.CANCEL) { - nonceProps.hasCancelled = true + nonceProps.hasCancelled = true; } } else { nonceToTransactionsMap[nonce] = { @@ -293,22 +293,22 @@ export const nonceSortedTransactionsSelector = createSelector( primaryTransaction: transaction, hasRetried: transaction.type === TRANSACTION_TYPES.RETRY, hasCancelled: transaction.type === TRANSACTION_TYPES.CANCEL, - } + }; - insertOrderedNonce(orderedNonces, nonce) + insertOrderedNonce(orderedNonces, nonce); } - }) + }); const orderedTransactionGroups = orderedNonces.map( (nonce) => nonceToTransactionsMap[nonce], - ) + ); mergeNonNonceTransactionGroups( orderedTransactionGroups, incomingTransactionGroups, - ) - return unapprovedTransactionGroups.concat(orderedTransactionGroups) + ); + return unapprovedTransactionGroups.concat(orderedTransactionGroups); }, -) +); /** * @name nonceSortedPendingTransactionsSelector @@ -323,7 +323,7 @@ export const nonceSortedPendingTransactionsSelector = createSelector( ({ primaryTransaction }) => primaryTransaction.status in PENDING_STATUS_HASH, ), -) +); /** * @name nonceSortedCompletedTransactionsSelector @@ -340,7 +340,7 @@ export const nonceSortedCompletedTransactionsSelector = createSelector( !(primaryTransaction.status in PENDING_STATUS_HASH), ) .reverse(), -) +); export const submittedPendingTransactionsSelector = createSelector( transactionsSelector, @@ -348,4 +348,4 @@ export const submittedPendingTransactionsSelector = createSelector( transactions.filter( (transaction) => transaction.status === TRANSACTION_STATUSES.SUBMITTED, ), -) +); diff --git a/ui/app/store/actionConstants.js b/ui/app/store/actionConstants.js index e6fdb7f022..5cdaf608c6 100644 --- a/ui/app/store/actionConstants.js +++ b/ui/app/store/actionConstants.js @@ -1,116 +1,116 @@ -export const GO_HOME = 'GO_HOME' +export const GO_HOME = 'GO_HOME'; // modal state -export const MODAL_OPEN = 'UI_MODAL_OPEN' -export const MODAL_CLOSE = 'UI_MODAL_CLOSE' +export const MODAL_OPEN = 'UI_MODAL_OPEN'; +export const MODAL_CLOSE = 'UI_MODAL_CLOSE'; // notification state -export const CLOSE_NOTIFICATION_WINDOW = 'CLOSE_NOTIFICATION_WINDOW' +export const CLOSE_NOTIFICATION_WINDOW = 'CLOSE_NOTIFICATION_WINDOW'; // sidebar state -export const SIDEBAR_OPEN = 'UI_SIDEBAR_OPEN' -export const SIDEBAR_CLOSE = 'UI_SIDEBAR_CLOSE' +export const SIDEBAR_OPEN = 'UI_SIDEBAR_OPEN'; +export const SIDEBAR_CLOSE = 'UI_SIDEBAR_CLOSE'; // alert state -export const ALERT_OPEN = 'UI_ALERT_OPEN' -export const ALERT_CLOSE = 'UI_ALERT_CLOSE' -export const QR_CODE_DETECTED = 'UI_QR_CODE_DETECTED' +export const ALERT_OPEN = 'UI_ALERT_OPEN'; +export const ALERT_CLOSE = 'UI_ALERT_CLOSE'; +export const QR_CODE_DETECTED = 'UI_QR_CODE_DETECTED'; // network dropdown open -export const NETWORK_DROPDOWN_OPEN = 'UI_NETWORK_DROPDOWN_OPEN' -export const NETWORK_DROPDOWN_CLOSE = 'UI_NETWORK_DROPDOWN_CLOSE' +export const NETWORK_DROPDOWN_OPEN = 'UI_NETWORK_DROPDOWN_OPEN'; +export const NETWORK_DROPDOWN_CLOSE = 'UI_NETWORK_DROPDOWN_CLOSE'; // remote state -export const UPDATE_METAMASK_STATE = 'UPDATE_METAMASK_STATE' -export const SELECTED_ADDRESS_CHANGED = 'SELECTED_ADDRESS_CHANGED' -export const FORGOT_PASSWORD = 'FORGOT_PASSWORD' -export const CLOSE_WELCOME_SCREEN = 'CLOSE_WELCOME_SCREEN' +export const UPDATE_METAMASK_STATE = 'UPDATE_METAMASK_STATE'; +export const SELECTED_ADDRESS_CHANGED = 'SELECTED_ADDRESS_CHANGED'; +export const FORGOT_PASSWORD = 'FORGOT_PASSWORD'; +export const CLOSE_WELCOME_SCREEN = 'CLOSE_WELCOME_SCREEN'; // unlock screen -export const UNLOCK_IN_PROGRESS = 'UNLOCK_IN_PROGRESS' -export const UNLOCK_FAILED = 'UNLOCK_FAILED' -export const UNLOCK_SUCCEEDED = 'UNLOCK_SUCCEEDED' -export const LOCK_METAMASK = 'LOCK_METAMASK' +export const UNLOCK_IN_PROGRESS = 'UNLOCK_IN_PROGRESS'; +export const UNLOCK_FAILED = 'UNLOCK_FAILED'; +export const UNLOCK_SUCCEEDED = 'UNLOCK_SUCCEEDED'; +export const LOCK_METAMASK = 'LOCK_METAMASK'; // error handling -export const DISPLAY_WARNING = 'DISPLAY_WARNING' -export const HIDE_WARNING = 'HIDE_WARNING' +export const DISPLAY_WARNING = 'DISPLAY_WARNING'; +export const HIDE_WARNING = 'HIDE_WARNING'; // accounts screen -export const SHOW_ACCOUNT_DETAIL = 'SHOW_ACCOUNT_DETAIL' -export const SHOW_ACCOUNTS_PAGE = 'SHOW_ACCOUNTS_PAGE' -export const SHOW_CONF_TX_PAGE = 'SHOW_CONF_TX_PAGE' -export const SET_CURRENT_FIAT = 'SET_CURRENT_FIAT' +export const SHOW_ACCOUNT_DETAIL = 'SHOW_ACCOUNT_DETAIL'; +export const SHOW_ACCOUNTS_PAGE = 'SHOW_ACCOUNTS_PAGE'; +export const SHOW_CONF_TX_PAGE = 'SHOW_CONF_TX_PAGE'; +export const SET_CURRENT_FIAT = 'SET_CURRENT_FIAT'; // account detail screen -export const SHOW_SEND_TOKEN_PAGE = 'SHOW_SEND_TOKEN_PAGE' -export const SHOW_PRIVATE_KEY = 'SHOW_PRIVATE_KEY' -export const SET_ACCOUNT_LABEL = 'SET_ACCOUNT_LABEL' -export const CLEAR_ACCOUNT_DETAILS = 'CLEAR_ACCOUNT_DETAILS' +export const SHOW_SEND_TOKEN_PAGE = 'SHOW_SEND_TOKEN_PAGE'; +export const SHOW_PRIVATE_KEY = 'SHOW_PRIVATE_KEY'; +export const SET_ACCOUNT_LABEL = 'SET_ACCOUNT_LABEL'; +export const CLEAR_ACCOUNT_DETAILS = 'CLEAR_ACCOUNT_DETAILS'; // tx conf screen -export const COMPLETED_TX = 'COMPLETED_TX' -export const TRANSACTION_ERROR = 'TRANSACTION_ERROR' -export const UPDATE_TRANSACTION_PARAMS = 'UPDATE_TRANSACTION_PARAMS' -export const SET_NEXT_NONCE = 'SET_NEXT_NONCE' +export const COMPLETED_TX = 'COMPLETED_TX'; +export const TRANSACTION_ERROR = 'TRANSACTION_ERROR'; +export const UPDATE_TRANSACTION_PARAMS = 'UPDATE_TRANSACTION_PARAMS'; +export const SET_NEXT_NONCE = 'SET_NEXT_NONCE'; // send screen -export const UPDATE_GAS_LIMIT = 'UPDATE_GAS_LIMIT' -export const UPDATE_GAS_PRICE = 'UPDATE_GAS_PRICE' -export const UPDATE_GAS_TOTAL = 'UPDATE_GAS_TOTAL' -export const UPDATE_SEND_HEX_DATA = 'UPDATE_SEND_HEX_DATA' -export const UPDATE_SEND_TOKEN_BALANCE = 'UPDATE_SEND_TOKEN_BALANCE' -export const UPDATE_SEND_TO = 'UPDATE_SEND_TO' -export const UPDATE_SEND_AMOUNT = 'UPDATE_SEND_AMOUNT' -export const UPDATE_SEND_ERRORS = 'UPDATE_SEND_ERRORS' -export const UPDATE_MAX_MODE = 'UPDATE_MAX_MODE' -export const UPDATE_SEND = 'UPDATE_SEND' -export const UPDATE_SEND_TOKEN = 'UPDATE_SEND_TOKEN' -export const CLEAR_SEND = 'CLEAR_SEND' -export const GAS_LOADING_STARTED = 'GAS_LOADING_STARTED' -export const GAS_LOADING_FINISHED = 'GAS_LOADING_FINISHED' -export const UPDATE_SEND_ENS_RESOLUTION = 'UPDATE_SEND_ENS_RESOLUTION' +export const UPDATE_GAS_LIMIT = 'UPDATE_GAS_LIMIT'; +export const UPDATE_GAS_PRICE = 'UPDATE_GAS_PRICE'; +export const UPDATE_GAS_TOTAL = 'UPDATE_GAS_TOTAL'; +export const UPDATE_SEND_HEX_DATA = 'UPDATE_SEND_HEX_DATA'; +export const UPDATE_SEND_TOKEN_BALANCE = 'UPDATE_SEND_TOKEN_BALANCE'; +export const UPDATE_SEND_TO = 'UPDATE_SEND_TO'; +export const UPDATE_SEND_AMOUNT = 'UPDATE_SEND_AMOUNT'; +export const UPDATE_SEND_ERRORS = 'UPDATE_SEND_ERRORS'; +export const UPDATE_MAX_MODE = 'UPDATE_MAX_MODE'; +export const UPDATE_SEND = 'UPDATE_SEND'; +export const UPDATE_SEND_TOKEN = 'UPDATE_SEND_TOKEN'; +export const CLEAR_SEND = 'CLEAR_SEND'; +export const GAS_LOADING_STARTED = 'GAS_LOADING_STARTED'; +export const GAS_LOADING_FINISHED = 'GAS_LOADING_FINISHED'; +export const UPDATE_SEND_ENS_RESOLUTION = 'UPDATE_SEND_ENS_RESOLUTION'; export const UPDATE_SEND_ENS_RESOLUTION_ERROR = - 'UPDATE_SEND_ENS_RESOLUTION_ERROR' + 'UPDATE_SEND_ENS_RESOLUTION_ERROR'; // config screen -export const SET_RPC_TARGET = 'SET_RPC_TARGET' -export const SET_PROVIDER_TYPE = 'SET_PROVIDER_TYPE' -export const UPDATE_TOKENS = 'UPDATE_TOKENS' +export const SET_RPC_TARGET = 'SET_RPC_TARGET'; +export const SET_PROVIDER_TYPE = 'SET_PROVIDER_TYPE'; +export const UPDATE_TOKENS = 'UPDATE_TOKENS'; export const SET_HARDWARE_WALLET_DEFAULT_HD_PATH = - 'SET_HARDWARE_WALLET_DEFAULT_HD_PATH' + 'SET_HARDWARE_WALLET_DEFAULT_HD_PATH'; // loading overlay -export const SHOW_LOADING = 'SHOW_LOADING_INDICATION' -export const HIDE_LOADING = 'HIDE_LOADING_INDICATION' +export const SHOW_LOADING = 'SHOW_LOADING_INDICATION'; +export const HIDE_LOADING = 'HIDE_LOADING_INDICATION'; -export const BUY_ETH = 'BUY_ETH' +export const BUY_ETH = 'BUY_ETH'; -export const TOGGLE_ACCOUNT_MENU = 'TOGGLE_ACCOUNT_MENU' +export const TOGGLE_ACCOUNT_MENU = 'TOGGLE_ACCOUNT_MENU'; -export const SET_USE_BLOCKIE = 'SET_USE_BLOCKIE' -export const SET_USE_NONCEFIELD = 'SET_USE_NONCEFIELD' -export const UPDATE_CUSTOM_NONCE = 'UPDATE_CUSTOM_NONCE' -export const SET_IPFS_GATEWAY = 'SET_IPFS_GATEWAY' +export const SET_USE_BLOCKIE = 'SET_USE_BLOCKIE'; +export const SET_USE_NONCEFIELD = 'SET_USE_NONCEFIELD'; +export const UPDATE_CUSTOM_NONCE = 'UPDATE_CUSTOM_NONCE'; +export const SET_IPFS_GATEWAY = 'SET_IPFS_GATEWAY'; -export const SET_PARTICIPATE_IN_METAMETRICS = 'SET_PARTICIPATE_IN_METAMETRICS' -export const SET_METAMETRICS_SEND_COUNT = 'SET_METAMETRICS_SEND_COUNT' +export const SET_PARTICIPATE_IN_METAMETRICS = 'SET_PARTICIPATE_IN_METAMETRICS'; +export const SET_METAMETRICS_SEND_COUNT = 'SET_METAMETRICS_SEND_COUNT'; // locale -export const SET_CURRENT_LOCALE = 'SET_CURRENT_LOCALE' +export const SET_CURRENT_LOCALE = 'SET_CURRENT_LOCALE'; // Feature Flags -export const UPDATE_FEATURE_FLAGS = 'UPDATE_FEATURE_FLAGS' +export const UPDATE_FEATURE_FLAGS = 'UPDATE_FEATURE_FLAGS'; // Preferences -export const UPDATE_PREFERENCES = 'UPDATE_PREFERENCES' +export const UPDATE_PREFERENCES = 'UPDATE_PREFERENCES'; // Onboarding -export const COMPLETE_ONBOARDING = 'COMPLETE_ONBOARDING' +export const COMPLETE_ONBOARDING = 'COMPLETE_ONBOARDING'; -export const SET_MOUSE_USER_STATE = 'SET_MOUSE_USER_STATE' +export const SET_MOUSE_USER_STATE = 'SET_MOUSE_USER_STATE'; // Network -export const SET_PENDING_TOKENS = 'SET_PENDING_TOKENS' -export const CLEAR_PENDING_TOKENS = 'CLEAR_PENDING_TOKENS' +export const SET_PENDING_TOKENS = 'SET_PENDING_TOKENS'; +export const CLEAR_PENDING_TOKENS = 'CLEAR_PENDING_TOKENS'; -export const SET_FIRST_TIME_FLOW_TYPE = 'SET_FIRST_TIME_FLOW_TYPE' +export const SET_FIRST_TIME_FLOW_TYPE = 'SET_FIRST_TIME_FLOW_TYPE'; -export const SET_SELECTED_SETTINGS_RPC_URL = 'SET_SELECTED_SETTINGS_RPC_URL' -export const SET_NETWORKS_TAB_ADD_MODE = 'SET_NETWORKS_TAB_ADD_MODE' +export const SET_SELECTED_SETTINGS_RPC_URL = 'SET_SELECTED_SETTINGS_RPC_URL'; +export const SET_NETWORKS_TAB_ADD_MODE = 'SET_NETWORKS_TAB_ADD_MODE'; -export const LOADING_METHOD_DATA_STARTED = 'LOADING_METHOD_DATA_STARTED' -export const LOADING_METHOD_DATA_FINISHED = 'LOADING_METHOD_DATA_FINISHED' +export const LOADING_METHOD_DATA_STARTED = 'LOADING_METHOD_DATA_STARTED'; +export const LOADING_METHOD_DATA_FINISHED = 'LOADING_METHOD_DATA_FINISHED'; -export const LOADING_TOKEN_PARAMS_STARTED = 'LOADING_TOKEN_PARAMS_STARTED' -export const LOADING_TOKEN_PARAMS_FINISHED = 'LOADING_TOKEN_PARAMS_FINISHED' +export const LOADING_TOKEN_PARAMS_STARTED = 'LOADING_TOKEN_PARAMS_STARTED'; +export const LOADING_TOKEN_PARAMS_FINISHED = 'LOADING_TOKEN_PARAMS_FINISHED'; -export const SET_REQUEST_ACCOUNT_TABS = 'SET_REQUEST_ACCOUNT_TABS' -export const SET_CURRENT_WINDOW_TAB = 'SET_CURRENT_WINDOW_TAB' -export const SET_OPEN_METAMASK_TAB_IDS = 'SET_OPEN_METAMASK_TAB_IDS' +export const SET_REQUEST_ACCOUNT_TABS = 'SET_REQUEST_ACCOUNT_TABS'; +export const SET_CURRENT_WINDOW_TAB = 'SET_CURRENT_WINDOW_TAB'; +export const SET_OPEN_METAMASK_TAB_IDS = 'SET_OPEN_METAMASK_TAB_IDS'; diff --git a/ui/app/store/actions.js b/ui/app/store/actions.js index 9cf6196d8c..e8187d723a 100644 --- a/ui/app/store/actions.js +++ b/ui/app/store/actions.js @@ -1,222 +1,225 @@ -import abi from 'human-standard-token-abi' -import pify from 'pify' -import log from 'loglevel' -import { capitalize } from 'lodash' -import getBuyEthUrl from '../../../app/scripts/lib/buy-eth-url' -import { checksumAddress } from '../helpers/utils/util' -import { calcTokenBalance, estimateGasForSend } from '../pages/send/send.utils' +import abi from 'human-standard-token-abi'; +import pify from 'pify'; +import log from 'loglevel'; +import { capitalize } from 'lodash'; +import getBuyEthUrl from '../../../app/scripts/lib/buy-eth-url'; +import { checksumAddress } from '../helpers/utils/util'; +import { calcTokenBalance, estimateGasForSend } from '../pages/send/send.utils'; import { fetchLocale, loadRelativeTimeFormatLocaleData, -} from '../helpers/utils/i18n-helper' -import { getMethodDataAsync } from '../helpers/utils/transactions.util' -import { fetchSymbolAndDecimals } from '../helpers/utils/token-util' -import switchDirection from '../helpers/utils/switch-direction' -import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../shared/constants/app' -import { hasUnconfirmedTransactions } from '../helpers/utils/confirm-tx.util' -import { setCustomGasLimit } from '../ducks/gas/gas.duck' -import txHelper from '../../lib/tx-helper' -import { getEnvironmentType, addHexPrefix } from '../../../app/scripts/lib/util' +} from '../helpers/utils/i18n-helper'; +import { getMethodDataAsync } from '../helpers/utils/transactions.util'; +import { fetchSymbolAndDecimals } from '../helpers/utils/token-util'; +import switchDirection from '../helpers/utils/switch-direction'; +import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../shared/constants/app'; +import { hasUnconfirmedTransactions } from '../helpers/utils/confirm-tx.util'; +import { setCustomGasLimit } from '../ducks/gas/gas.duck'; +import txHelper from '../../lib/tx-helper'; +import { + getEnvironmentType, + addHexPrefix, +} from '../../../app/scripts/lib/util'; import { getPermittedAccountsForCurrentTab, getSelectedAddress, -} from '../selectors' -import { switchedToUnconnectedAccount } from '../ducks/alerts/unconnected-account' -import { getUnconnectedAccountAlertEnabledness } from '../ducks/metamask/metamask' -import { LISTED_CONTRACT_ADDRESSES } from '../../../shared/constants/tokens' -import * as actionConstants from './actionConstants' - -let background = null -let promisifiedBackground = null +} from '../selectors'; +import { switchedToUnconnectedAccount } from '../ducks/alerts/unconnected-account'; +import { getUnconnectedAccountAlertEnabledness } from '../ducks/metamask/metamask'; +import { LISTED_CONTRACT_ADDRESSES } from '../../../shared/constants/tokens'; +import * as actionConstants from './actionConstants'; + +let background = null; +let promisifiedBackground = null; export function _setBackgroundConnection(backgroundConnection) { - background = backgroundConnection - promisifiedBackground = pify(background) + background = backgroundConnection; + promisifiedBackground = pify(background); } export function goHome() { return { type: actionConstants.GO_HOME, - } + }; } // async actions export function tryUnlockMetamask(password) { return (dispatch) => { - dispatch(showLoadingIndication()) - dispatch(unlockInProgress()) - log.debug(`background.submitPassword`) + dispatch(showLoadingIndication()); + dispatch(unlockInProgress()); + log.debug(`background.submitPassword`); return new Promise((resolve, reject) => { background.submitPassword(password, (error) => { if (error) { - reject(error) - return + reject(error); + return; } - resolve() - }) + resolve(); + }); }) .then(() => { - dispatch(unlockSucceeded()) - return forceUpdateMetamaskState(dispatch) + dispatch(unlockSucceeded()); + return forceUpdateMetamaskState(dispatch); }) .then(() => { return new Promise((resolve, reject) => { background.verifySeedPhrase((err) => { if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } - resolve() - }) - }) + resolve(); + }); + }); }) .then(() => { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); }) .catch((err) => { - dispatch(unlockFailed(err.message)) - dispatch(hideLoadingIndication()) - return Promise.reject(err) - }) - } + dispatch(unlockFailed(err.message)); + dispatch(hideLoadingIndication()); + return Promise.reject(err); + }); + }; } export function createNewVaultAndRestore(password, seed) { return (dispatch) => { - dispatch(showLoadingIndication()) - log.debug(`background.createNewVaultAndRestore`) - let vault + dispatch(showLoadingIndication()); + log.debug(`background.createNewVaultAndRestore`); + let vault; return new Promise((resolve, reject) => { background.createNewVaultAndRestore(password, seed, (err, _vault) => { if (err) { - reject(err) - return + reject(err); + return; } - vault = _vault - resolve() - }) + vault = _vault; + resolve(); + }); }) .then(() => dispatch(unMarkPasswordForgotten())) .then(() => { - dispatch(showAccountsPage()) - dispatch(hideLoadingIndication()) - return vault + dispatch(showAccountsPage()); + dispatch(hideLoadingIndication()); + return vault; }) .catch((err) => { - dispatch(displayWarning(err.message)) - dispatch(hideLoadingIndication()) - return Promise.reject(err) - }) - } + dispatch(displayWarning(err.message)); + dispatch(hideLoadingIndication()); + return Promise.reject(err); + }); + }; } export function createNewVaultAndGetSeedPhrase(password) { return async (dispatch) => { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); try { - await createNewVault(password) - const seedWords = await verifySeedPhrase() - return seedWords + await createNewVault(password); + const seedWords = await verifySeedPhrase(); + return seedWords; } catch (error) { - dispatch(displayWarning(error.message)) - throw new Error(error.message) + dispatch(displayWarning(error.message)); + throw new Error(error.message); } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - } + }; } export function unlockAndGetSeedPhrase(password) { return async (dispatch) => { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); try { - await submitPassword(password) - const seedWords = await verifySeedPhrase() - await forceUpdateMetamaskState(dispatch) - return seedWords + await submitPassword(password); + const seedWords = await verifySeedPhrase(); + await forceUpdateMetamaskState(dispatch); + return seedWords; } catch (error) { - dispatch(displayWarning(error.message)) - throw new Error(error.message) + dispatch(displayWarning(error.message)); + throw new Error(error.message); } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - } + }; } export function submitPassword(password) { return new Promise((resolve, reject) => { background.submitPassword(password, (error) => { if (error) { - reject(error) - return + reject(error); + return; } - resolve() - }) - }) + resolve(); + }); + }); } export function createNewVault(password) { return new Promise((resolve, reject) => { background.createNewVaultAndKeychain(password, (error) => { if (error) { - reject(error) - return + reject(error); + return; } - resolve(true) - }) - }) + resolve(true); + }); + }); } export function verifyPassword(password) { return new Promise((resolve, reject) => { background.verifyPassword(password, (error) => { if (error) { - reject(error) - return + reject(error); + return; } - resolve(true) - }) - }) + resolve(true); + }); + }); } export function verifySeedPhrase() { return new Promise((resolve, reject) => { background.verifySeedPhrase((error, seedWords) => { if (error) { - reject(error) - return + reject(error); + return; } - resolve(seedWords) - }) - }) + resolve(seedWords); + }); + }); } export function requestRevealSeedWords(password) { return async (dispatch) => { - dispatch(showLoadingIndication()) - log.debug(`background.verifyPassword`) + dispatch(showLoadingIndication()); + log.debug(`background.verifyPassword`); try { - await verifyPassword(password) - const seedWords = await verifySeedPhrase() - return seedWords + await verifyPassword(password); + const seedWords = await verifySeedPhrase(); + return seedWords; } catch (error) { - dispatch(displayWarning(error.message)) - throw new Error(error.message) + dispatch(displayWarning(error.message)); + throw new Error(error.message); } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - } + }; } export function tryReverseResolveAddress(address) { @@ -224,222 +227,229 @@ export function tryReverseResolveAddress(address) { return new Promise((resolve) => { background.tryReverseResolveAddress(address, (err) => { if (err) { - log.error(err) + log.error(err); } - resolve() - }) - }) - } + resolve(); + }); + }); + }; } export function fetchInfoToSync() { return (dispatch) => { - log.debug(`background.fetchInfoToSync`) + log.debug(`background.fetchInfoToSync`); return new Promise((resolve, reject) => { background.fetchInfoToSync((err, result) => { if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } - resolve(result) - }) - }) - } + resolve(result); + }); + }); + }; } export function resetAccount() { return (dispatch) => { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); return new Promise((resolve, reject) => { background.resetAccount((err, account) => { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } - log.info(`Transaction history reset for ${account}`) - dispatch(showAccountsPage()) - resolve(account) - }) - }) - } + log.info(`Transaction history reset for ${account}`); + dispatch(showAccountsPage()); + resolve(account); + }); + }); + }; } export function removeAccount(address) { return async (dispatch) => { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); try { await new Promise((resolve, reject) => { background.removeAccount(address, (error, account) => { if (error) { - reject(error) - return + reject(error); + return; } - resolve(account) - }) - }) - await forceUpdateMetamaskState(dispatch) + resolve(account); + }); + }); + await forceUpdateMetamaskState(dispatch); } catch (error) { - dispatch(displayWarning(error.message)) - throw error + dispatch(displayWarning(error.message)); + throw error; } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - log.info(`Account removed: ${address}`) - dispatch(showAccountsPage()) - } + log.info(`Account removed: ${address}`); + dispatch(showAccountsPage()); + }; } export function importNewAccount(strategy, args) { return async (dispatch) => { - let newState - dispatch(showLoadingIndication('This may take a while, please be patient.')) + let newState; + dispatch( + showLoadingIndication('This may take a while, please be patient.'), + ); try { - log.debug(`background.importAccountWithStrategy`) - await promisifiedBackground.importAccountWithStrategy(strategy, args) - log.debug(`background.getState`) - newState = await promisifiedBackground.getState() + log.debug(`background.importAccountWithStrategy`); + await promisifiedBackground.importAccountWithStrategy(strategy, args); + log.debug(`background.getState`); + newState = await promisifiedBackground.getState(); } catch (err) { - dispatch(displayWarning(err.message)) - throw err + dispatch(displayWarning(err.message)); + throw err; } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - dispatch(updateMetamaskState(newState)) + dispatch(updateMetamaskState(newState)); if (newState.selectedAddress) { dispatch({ type: actionConstants.SHOW_ACCOUNT_DETAIL, value: newState.selectedAddress, - }) + }); } - return newState - } + return newState; + }; } export function addNewAccount() { - log.debug(`background.addNewAccount`) + log.debug(`background.addNewAccount`); return async (dispatch, getState) => { - const oldIdentities = getState().metamask.identities - dispatch(showLoadingIndication()) + const oldIdentities = getState().metamask.identities; + dispatch(showLoadingIndication()); - let newIdentities + let newIdentities; try { - const { identities } = await promisifiedBackground.addNewAccount() - newIdentities = identities + const { identities } = await promisifiedBackground.addNewAccount(); + newIdentities = identities; } catch (error) { - dispatch(displayWarning(error.message)) - throw error + dispatch(displayWarning(error.message)); + throw error; } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } const newAccountAddress = Object.keys(newIdentities).find( (address) => !oldIdentities[address], - ) - await forceUpdateMetamaskState(dispatch) - return newAccountAddress - } + ); + await forceUpdateMetamaskState(dispatch); + return newAccountAddress; + }; } export function checkHardwareStatus(deviceName, hdPath) { - log.debug(`background.checkHardwareStatus`, deviceName, hdPath) + log.debug(`background.checkHardwareStatus`, deviceName, hdPath); return async (dispatch) => { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); - let unlocked + let unlocked; try { unlocked = await promisifiedBackground.checkHardwareStatus( deviceName, hdPath, - ) + ); } catch (error) { - log.error(error) - dispatch(displayWarning(error.message)) - throw error + log.error(error); + dispatch(displayWarning(error.message)); + throw error; } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - await forceUpdateMetamaskState(dispatch) - return unlocked - } + await forceUpdateMetamaskState(dispatch); + return unlocked; + }; } export function forgetDevice(deviceName) { - log.debug(`background.forgetDevice`, deviceName) + log.debug(`background.forgetDevice`, deviceName); return async (dispatch) => { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); try { - await promisifiedBackground.forgetDevice(deviceName) + await promisifiedBackground.forgetDevice(deviceName); } catch (error) { - log.error(error) - dispatch(displayWarning(error.message)) - throw error + log.error(error); + dispatch(displayWarning(error.message)); + throw error; } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - await forceUpdateMetamaskState(dispatch) - } + await forceUpdateMetamaskState(dispatch); + }; } export function connectHardware(deviceName, page, hdPath) { - log.debug(`background.connectHardware`, deviceName, page, hdPath) + log.debug(`background.connectHardware`, deviceName, page, hdPath); return async (dispatch) => { dispatch( showLoadingIndication(`Looking for your ${capitalize(deviceName)}...`), - ) + ); - let accounts + let accounts; try { accounts = await promisifiedBackground.connectHardware( deviceName, page, hdPath, - ) + ); } catch (error) { - log.error(error) - dispatch(displayWarning(error.message)) - throw error + log.error(error); + dispatch(displayWarning(error.message)); + throw error; } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - await forceUpdateMetamaskState(dispatch) - return accounts - } + await forceUpdateMetamaskState(dispatch); + return accounts; + }; } export function unlockHardwareWalletAccount(index, deviceName, hdPath) { - log.debug(`background.unlockHardwareWalletAccount`, index, deviceName, hdPath) + log.debug( + `background.unlockHardwareWalletAccount`, + index, + deviceName, + hdPath, + ); return (dispatch) => { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); return new Promise((resolve, reject) => { background.unlockHardwareWalletAccount( index, deviceName, hdPath, (err) => { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); if (err) { - log.error(err) - dispatch(displayWarning(err.message)) - reject(err) - return + log.error(err); + dispatch(displayWarning(err.message)); + reject(err); + return; } - resolve() + resolve(); }, - ) - }) - } + ); + }); + }; } export function showQrScanner() { @@ -448,23 +458,23 @@ export function showQrScanner() { showModal({ name: 'QR_SCANNER', }), - ) - } + ); + }; } export function setCurrentCurrency(currencyCode) { return async (dispatch) => { - dispatch(showLoadingIndication()) - log.debug(`background.setCurrentCurrency`) - let data + dispatch(showLoadingIndication()); + log.debug(`background.setCurrentCurrency`); + let data; try { - data = await promisifiedBackground.setCurrentCurrency(currencyCode) + data = await promisifiedBackground.setCurrentCurrency(currencyCode); } catch (error) { - log.error(error.stack) - dispatch(displayWarning(error.message)) - return + log.error(error.stack); + dispatch(displayWarning(error.message)); + return; } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } dispatch({ @@ -474,180 +484,180 @@ export function setCurrentCurrency(currencyCode) { conversionRate: data.conversionRate, conversionDate: data.conversionDate, }, - }) - } + }); + }; } export function signMsg(msgData) { - log.debug('action - signMsg') + log.debug('action - signMsg'); return async (dispatch) => { - dispatch(showLoadingIndication()) - log.debug(`actions calling background.signMessage`) - let newState + dispatch(showLoadingIndication()); + log.debug(`actions calling background.signMessage`); + let newState; try { - newState = await promisifiedBackground.signMessage(msgData) + newState = await promisifiedBackground.signMessage(msgData); } catch (error) { - log.error(error) - dispatch(displayWarning(error.message)) - throw error + log.error(error); + dispatch(displayWarning(error.message)); + throw error; } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - dispatch(updateMetamaskState(newState)) - dispatch(completedTx(msgData.metamaskId)) - dispatch(closeCurrentNotificationWindow()) - return msgData - } + dispatch(updateMetamaskState(newState)); + dispatch(completedTx(msgData.metamaskId)); + dispatch(closeCurrentNotificationWindow()); + return msgData; + }; } export function signPersonalMsg(msgData) { - log.debug('action - signPersonalMsg') + log.debug('action - signPersonalMsg'); return async (dispatch) => { - dispatch(showLoadingIndication()) - log.debug(`actions calling background.signPersonalMessage`) + dispatch(showLoadingIndication()); + log.debug(`actions calling background.signPersonalMessage`); - let newState + let newState; try { - newState = await promisifiedBackground.signPersonalMessage(msgData) + newState = await promisifiedBackground.signPersonalMessage(msgData); } catch (error) { - log.error(error) - dispatch(displayWarning(error.message)) - throw error + log.error(error); + dispatch(displayWarning(error.message)); + throw error; } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - dispatch(updateMetamaskState(newState)) - dispatch(completedTx(msgData.metamaskId)) - dispatch(closeCurrentNotificationWindow()) - return msgData - } + dispatch(updateMetamaskState(newState)); + dispatch(completedTx(msgData.metamaskId)); + dispatch(closeCurrentNotificationWindow()); + return msgData; + }; } export function decryptMsgInline(decryptedMsgData) { - log.debug('action - decryptMsgInline') + log.debug('action - decryptMsgInline'); return async (dispatch) => { - log.debug(`actions calling background.decryptMessageInline`) + log.debug(`actions calling background.decryptMessageInline`); - let newState + let newState; try { newState = await promisifiedBackground.decryptMessageInline( decryptedMsgData, - ) + ); } catch (error) { - log.error(error) - dispatch(displayWarning(error.message)) - throw error + log.error(error); + dispatch(displayWarning(error.message)); + throw error; } - dispatch(updateMetamaskState(newState)) - return newState.unapprovedDecryptMsgs[decryptedMsgData.metamaskId] - } + dispatch(updateMetamaskState(newState)); + return newState.unapprovedDecryptMsgs[decryptedMsgData.metamaskId]; + }; } export function decryptMsg(decryptedMsgData) { - log.debug('action - decryptMsg') + log.debug('action - decryptMsg'); return async (dispatch) => { - dispatch(showLoadingIndication()) - log.debug(`actions calling background.decryptMessage`) + dispatch(showLoadingIndication()); + log.debug(`actions calling background.decryptMessage`); - let newState + let newState; try { - newState = await promisifiedBackground.decryptMessage(decryptedMsgData) + newState = await promisifiedBackground.decryptMessage(decryptedMsgData); } catch (error) { - log.error(error) - dispatch(displayWarning(error.message)) - throw error + log.error(error); + dispatch(displayWarning(error.message)); + throw error; } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - dispatch(updateMetamaskState(newState)) - dispatch(completedTx(decryptedMsgData.metamaskId)) - dispatch(closeCurrentNotificationWindow()) - return decryptedMsgData - } + dispatch(updateMetamaskState(newState)); + dispatch(completedTx(decryptedMsgData.metamaskId)); + dispatch(closeCurrentNotificationWindow()); + return decryptedMsgData; + }; } export function encryptionPublicKeyMsg(msgData) { - log.debug('action - encryptionPublicKeyMsg') + log.debug('action - encryptionPublicKeyMsg'); return async (dispatch) => { - dispatch(showLoadingIndication()) - log.debug(`actions calling background.encryptionPublicKey`) + dispatch(showLoadingIndication()); + log.debug(`actions calling background.encryptionPublicKey`); - let newState + let newState; try { - newState = await promisifiedBackground.encryptionPublicKey(msgData) + newState = await promisifiedBackground.encryptionPublicKey(msgData); } catch (error) { - log.error(error) - dispatch(displayWarning(error.message)) - throw error + log.error(error); + dispatch(displayWarning(error.message)); + throw error; } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - dispatch(updateMetamaskState(newState)) - dispatch(completedTx(msgData.metamaskId)) - dispatch(closeCurrentNotificationWindow()) - return msgData - } + dispatch(updateMetamaskState(newState)); + dispatch(completedTx(msgData.metamaskId)); + dispatch(closeCurrentNotificationWindow()); + return msgData; + }; } export function signTypedMsg(msgData) { - log.debug('action - signTypedMsg') + log.debug('action - signTypedMsg'); return async (dispatch) => { - dispatch(showLoadingIndication()) - log.debug(`actions calling background.signTypedMessage`) + dispatch(showLoadingIndication()); + log.debug(`actions calling background.signTypedMessage`); - let newState + let newState; try { - newState = await promisifiedBackground.signTypedMessage(msgData) + newState = await promisifiedBackground.signTypedMessage(msgData); } catch (error) { - log.error(error) - dispatch(displayWarning(error.message)) - throw error + log.error(error); + dispatch(displayWarning(error.message)); + throw error; } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - dispatch(updateMetamaskState(newState)) - dispatch(completedTx(msgData.metamaskId)) - dispatch(closeCurrentNotificationWindow()) - return msgData - } + dispatch(updateMetamaskState(newState)); + dispatch(completedTx(msgData.metamaskId)); + dispatch(closeCurrentNotificationWindow()); + return msgData; + }; } export function signTx(txData) { return (dispatch) => { global.ethQuery.sendTransaction(txData, (err) => { if (err) { - dispatch(displayWarning(err.message)) + dispatch(displayWarning(err.message)); } - }) - dispatch(showConfTxPage()) - } + }); + dispatch(showConfTxPage()); + }; } export function setGasLimit(gasLimit) { return { type: actionConstants.UPDATE_GAS_LIMIT, value: gasLimit, - } + }; } export function setGasPrice(gasPrice) { return { type: actionConstants.UPDATE_GAS_PRICE, value: gasPrice, - } + }; } export function setGasTotal(gasTotal) { return { type: actionConstants.UPDATE_GAS_TOTAL, value: gasTotal, - } + }; } export function updateGasData({ @@ -660,7 +670,7 @@ export function updateGasData({ data, }) { return (dispatch) => { - dispatch(gasLoadingStarted()) + dispatch(gasLoadingStarted()); return estimateGasForSend({ estimateGasMethod: promisifiedBackground.estimateGas, blockGasLimit, @@ -672,273 +682,273 @@ export function updateGasData({ data, }) .then((gas) => { - dispatch(setGasLimit(gas)) - dispatch(setCustomGasLimit(gas)) - dispatch(updateSendErrors({ gasLoadingError: null })) - dispatch(gasLoadingFinished()) + dispatch(setGasLimit(gas)); + dispatch(setCustomGasLimit(gas)); + dispatch(updateSendErrors({ gasLoadingError: null })); + dispatch(gasLoadingFinished()); }) .catch((err) => { - log.error(err) - dispatch(updateSendErrors({ gasLoadingError: 'gasLoadingError' })) - dispatch(gasLoadingFinished()) - }) - } + log.error(err); + dispatch(updateSendErrors({ gasLoadingError: 'gasLoadingError' })); + dispatch(gasLoadingFinished()); + }); + }; } export function gasLoadingStarted() { return { type: actionConstants.GAS_LOADING_STARTED, - } + }; } export function gasLoadingFinished() { return { type: actionConstants.GAS_LOADING_FINISHED, - } + }; } export function updateSendTokenBalance({ sendToken, tokenContract, address }) { return (dispatch) => { const tokenBalancePromise = tokenContract ? tokenContract.balanceOf(address) - : Promise.resolve() + : Promise.resolve(); return tokenBalancePromise .then((usersToken) => { if (usersToken) { - const newTokenBalance = calcTokenBalance({ sendToken, usersToken }) - dispatch(setSendTokenBalance(newTokenBalance)) + const newTokenBalance = calcTokenBalance({ sendToken, usersToken }); + dispatch(setSendTokenBalance(newTokenBalance)); } }) .catch((err) => { - log.error(err) - updateSendErrors({ tokenBalance: 'tokenBalanceError' }) - }) - } + log.error(err); + updateSendErrors({ tokenBalance: 'tokenBalanceError' }); + }); + }; } export function updateSendErrors(errorObject) { return { type: actionConstants.UPDATE_SEND_ERRORS, value: errorObject, - } + }; } export function setSendTokenBalance(tokenBalance) { return { type: actionConstants.UPDATE_SEND_TOKEN_BALANCE, value: tokenBalance, - } + }; } export function updateSendHexData(value) { return { type: actionConstants.UPDATE_SEND_HEX_DATA, value, - } + }; } export function updateSendTo(to, nickname = '') { return { type: actionConstants.UPDATE_SEND_TO, value: { to, nickname }, - } + }; } export function updateSendAmount(amount) { return { type: actionConstants.UPDATE_SEND_AMOUNT, value: amount, - } + }; } export function updateCustomNonce(value) { return { type: actionConstants.UPDATE_CUSTOM_NONCE, value, - } + }; } export function setMaxModeTo(bool) { return { type: actionConstants.UPDATE_MAX_MODE, value: bool, - } + }; } export function updateSend(newSend) { return { type: actionConstants.UPDATE_SEND, value: newSend, - } + }; } export function updateSendToken(token) { return { type: actionConstants.UPDATE_SEND_TOKEN, value: token, - } + }; } export function clearSend() { return { type: actionConstants.CLEAR_SEND, - } + }; } export function updateSendEnsResolution(ensResolution) { return { type: actionConstants.UPDATE_SEND_ENS_RESOLUTION, payload: ensResolution, - } + }; } export function updateSendEnsResolutionError(errorMessage) { return { type: actionConstants.UPDATE_SEND_ENS_RESOLUTION_ERROR, payload: errorMessage, - } + }; } export function signTokenTx(tokenAddress, toAddress, amount, txData) { return async (dispatch) => { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); try { - const token = global.eth.contract(abi).at(tokenAddress) - const txPromise = token.transfer(toAddress, addHexPrefix(amount), txData) - dispatch(showConfTxPage()) - dispatch(hideLoadingIndication()) - await txPromise + const token = global.eth.contract(abi).at(tokenAddress); + const txPromise = token.transfer(toAddress, addHexPrefix(amount), txData); + dispatch(showConfTxPage()); + dispatch(hideLoadingIndication()); + await txPromise; } catch (error) { - dispatch(hideLoadingIndication()) - dispatch(displayWarning(error.message)) + dispatch(hideLoadingIndication()); + dispatch(displayWarning(error.message)); } - } + }; } const updateMetamaskStateFromBackground = () => { - log.debug(`background.getState`) + log.debug(`background.getState`); return new Promise((resolve, reject) => { background.getState((error, newState) => { if (error) { - reject(error) - return + reject(error); + return; } - resolve(newState) - }) - }) -} + resolve(newState); + }); + }); +}; export function updateTransaction(txData, dontShowLoadingIndicator) { return async (dispatch) => { - !dontShowLoadingIndicator && dispatch(showLoadingIndication()) + !dontShowLoadingIndicator && dispatch(showLoadingIndication()); try { - await promisifiedBackground.updateTransaction(txData) + await promisifiedBackground.updateTransaction(txData); } catch (error) { - dispatch(updateTransactionParams(txData.id, txData.txParams)) - dispatch(hideLoadingIndication()) - dispatch(txError(error)) - dispatch(goHome()) - log.error(error.message) - throw error + dispatch(updateTransactionParams(txData.id, txData.txParams)); + dispatch(hideLoadingIndication()); + dispatch(txError(error)); + dispatch(goHome()); + log.error(error.message); + throw error; } try { - dispatch(updateTransactionParams(txData.id, txData.txParams)) - const newState = await updateMetamaskStateFromBackground() - dispatch(updateMetamaskState(newState)) - dispatch(showConfTxPage({ id: txData.id })) - return txData + dispatch(updateTransactionParams(txData.id, txData.txParams)); + const newState = await updateMetamaskStateFromBackground(); + dispatch(updateMetamaskState(newState)); + dispatch(showConfTxPage({ id: txData.id })); + return txData; } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - } + }; } export function addUnapprovedTransaction(txParams, origin) { - log.debug('background.addUnapprovedTransaction') + log.debug('background.addUnapprovedTransaction'); return () => { return new Promise((resolve, reject) => { background.addUnapprovedTransaction(txParams, origin, (err, txMeta) => { if (err) { - reject(err) - return + reject(err); + return; } - resolve(txMeta) - }) - }) - } + resolve(txMeta); + }); + }); + }; } export function updateAndApproveTx(txData, dontShowLoadingIndicator) { return (dispatch) => { - !dontShowLoadingIndicator && dispatch(showLoadingIndication()) + !dontShowLoadingIndicator && dispatch(showLoadingIndication()); return new Promise((resolve, reject) => { background.updateAndApproveTransaction(txData, (err) => { - dispatch(updateTransactionParams(txData.id, txData.txParams)) - dispatch(clearSend()) + dispatch(updateTransactionParams(txData.id, txData.txParams)); + dispatch(clearSend()); if (err) { - dispatch(txError(err)) - dispatch(goHome()) - log.error(err.message) - reject(err) - return + dispatch(txError(err)); + dispatch(goHome()); + log.error(err.message); + reject(err); + return; } - resolve(txData) - }) + resolve(txData); + }); }) .then(() => updateMetamaskStateFromBackground()) .then((newState) => dispatch(updateMetamaskState(newState))) .then(() => { - dispatch(clearSend()) - dispatch(completedTx(txData.id)) - dispatch(hideLoadingIndication()) - dispatch(updateCustomNonce('')) - dispatch(closeCurrentNotificationWindow()) + dispatch(clearSend()); + dispatch(completedTx(txData.id)); + dispatch(hideLoadingIndication()); + dispatch(updateCustomNonce('')); + dispatch(closeCurrentNotificationWindow()); - return txData + return txData; }) .catch((err) => { - dispatch(hideLoadingIndication()) - return Promise.reject(err) - }) - } + dispatch(hideLoadingIndication()); + return Promise.reject(err); + }); + }; } export function completedTx(id) { return (dispatch, getState) => { - const state = getState() + const state = getState(); const { unapprovedTxs, unapprovedMsgs, unapprovedPersonalMsgs, unapprovedTypedMessages, network, - } = state.metamask + } = state.metamask; const unconfirmedActions = txHelper( unapprovedTxs, unapprovedMsgs, unapprovedPersonalMsgs, unapprovedTypedMessages, network, - ) + ); const otherUnconfirmedActions = unconfirmedActions.filter( (tx) => tx.id !== id, - ) + ); dispatch({ type: actionConstants.COMPLETED_TX, value: { id, unconfirmedActionsCount: otherUnconfirmedActions.length, }, - }) - } + }); + }; } export function updateTransactionParams(id, txParams) { @@ -946,136 +956,136 @@ export function updateTransactionParams(id, txParams) { type: actionConstants.UPDATE_TRANSACTION_PARAMS, id, value: txParams, - } + }; } export function txError(err) { return { type: actionConstants.TRANSACTION_ERROR, message: err.message, - } + }; } export function cancelMsg(msgData) { return async (dispatch) => { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); - let newState + let newState; try { - newState = await promisifiedBackground.cancelMessage(msgData.id) + newState = await promisifiedBackground.cancelMessage(msgData.id); } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - dispatch(updateMetamaskState(newState)) - dispatch(completedTx(msgData.id)) - dispatch(closeCurrentNotificationWindow()) - return msgData - } + dispatch(updateMetamaskState(newState)); + dispatch(completedTx(msgData.id)); + dispatch(closeCurrentNotificationWindow()); + return msgData; + }; } export function cancelPersonalMsg(msgData) { return async (dispatch) => { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); - let newState + let newState; try { - newState = await promisifiedBackground.cancelPersonalMessage(msgData.id) + newState = await promisifiedBackground.cancelPersonalMessage(msgData.id); } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - dispatch(updateMetamaskState(newState)) - dispatch(completedTx(msgData.id)) - dispatch(closeCurrentNotificationWindow()) - return msgData - } + dispatch(updateMetamaskState(newState)); + dispatch(completedTx(msgData.id)); + dispatch(closeCurrentNotificationWindow()); + return msgData; + }; } export function cancelDecryptMsg(msgData) { return async (dispatch) => { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); - let newState + let newState; try { - newState = await promisifiedBackground.cancelDecryptMessage(msgData.id) + newState = await promisifiedBackground.cancelDecryptMessage(msgData.id); } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - dispatch(updateMetamaskState(newState)) - dispatch(completedTx(msgData.id)) - dispatch(closeCurrentNotificationWindow()) - return msgData - } + dispatch(updateMetamaskState(newState)); + dispatch(completedTx(msgData.id)); + dispatch(closeCurrentNotificationWindow()); + return msgData; + }; } export function cancelEncryptionPublicKeyMsg(msgData) { return async (dispatch) => { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); - let newState + let newState; try { newState = await promisifiedBackground.cancelEncryptionPublicKey( msgData.id, - ) + ); } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - dispatch(updateMetamaskState(newState)) - dispatch(completedTx(msgData.id)) - dispatch(closeCurrentNotificationWindow()) - return msgData - } + dispatch(updateMetamaskState(newState)); + dispatch(completedTx(msgData.id)); + dispatch(closeCurrentNotificationWindow()); + return msgData; + }; } export function cancelTypedMsg(msgData) { return async (dispatch) => { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); - let newState + let newState; try { - newState = await promisifiedBackground.cancelTypedMessage(msgData.id) + newState = await promisifiedBackground.cancelTypedMessage(msgData.id); } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - dispatch(updateMetamaskState(newState)) - dispatch(completedTx(msgData.id)) - dispatch(closeCurrentNotificationWindow()) - return msgData - } + dispatch(updateMetamaskState(newState)); + dispatch(completedTx(msgData.id)); + dispatch(closeCurrentNotificationWindow()); + return msgData; + }; } export function cancelTx(txData, _showLoadingIndication = true) { return (dispatch) => { - _showLoadingIndication && dispatch(showLoadingIndication()) + _showLoadingIndication && dispatch(showLoadingIndication()); return new Promise((resolve, reject) => { background.cancelTransaction(txData.id, (error) => { if (error) { - reject(error) - return + reject(error); + return; } - resolve() - }) + resolve(); + }); }) .then(() => updateMetamaskStateFromBackground()) .then((newState) => dispatch(updateMetamaskState(newState))) .then(() => { - dispatch(clearSend()) - dispatch(completedTx(txData.id)) - dispatch(hideLoadingIndication()) - dispatch(closeCurrentNotificationWindow()) + dispatch(clearSend()); + dispatch(completedTx(txData.id)); + dispatch(hideLoadingIndication()); + dispatch(closeCurrentNotificationWindow()); - return txData + return txData; }) .catch((error) => { - dispatch(hideLoadingIndication()) - throw error - }) - } + dispatch(hideLoadingIndication()); + throw error; + }); + }; } /** @@ -1085,41 +1095,41 @@ export function cancelTx(txData, _showLoadingIndication = true) { */ export function cancelTxs(txDataList) { return async (dispatch) => { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); try { - const txIds = txDataList.map(({ id }) => id) + const txIds = txDataList.map(({ id }) => id); const cancellations = txIds.map( (id) => new Promise((resolve, reject) => { background.cancelTransaction(id, (err) => { if (err) { - reject(err) - return + reject(err); + return; } - resolve() - }) + resolve(); + }); }), - ) + ); - await Promise.all(cancellations) + await Promise.all(cancellations); - const newState = await updateMetamaskStateFromBackground() - dispatch(updateMetamaskState(newState)) - dispatch(clearSend()) + const newState = await updateMetamaskStateFromBackground(); + dispatch(updateMetamaskState(newState)); + dispatch(clearSend()); txIds.forEach((id) => { - dispatch(completedTx(id)) - }) + dispatch(completedTx(id)); + }); } finally { if (getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION) { - global.platform.closeCurrentWindow() + global.platform.closeCurrentWindow(); } else { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } } - } + }; } export function markPasswordForgotten() { @@ -1128,43 +1138,43 @@ export function markPasswordForgotten() { await new Promise((resolve, reject) => { return background.markPasswordForgotten((error) => { if (error) { - reject(error) - return + reject(error); + return; } - resolve() - }) - }) + resolve(); + }); + }); } finally { // TODO: handle errors - dispatch(hideLoadingIndication()) - dispatch(forgotPassword()) - await forceUpdateMetamaskState(dispatch) + dispatch(hideLoadingIndication()); + dispatch(forgotPassword()); + await forceUpdateMetamaskState(dispatch); } - } + }; } export function unMarkPasswordForgotten() { return (dispatch) => { return new Promise((resolve) => { background.unMarkPasswordForgotten(() => { - dispatch(forgotPassword(false)) - resolve() - }) - }).then(() => forceUpdateMetamaskState(dispatch)) - } + dispatch(forgotPassword(false)); + resolve(); + }); + }).then(() => forceUpdateMetamaskState(dispatch)); + }; } export function forgotPassword(forgotPasswordState = true) { return { type: actionConstants.FORGOT_PASSWORD, value: forgotPasswordState, - } + }; } export function closeWelcomeScreen() { return { type: actionConstants.CLOSE_WELCOME_SCREEN, - } + }; } // @@ -1174,149 +1184,149 @@ export function closeWelcomeScreen() { export function unlockInProgress() { return { type: actionConstants.UNLOCK_IN_PROGRESS, - } + }; } export function unlockFailed(message) { return { type: actionConstants.UNLOCK_FAILED, value: message, - } + }; } export function unlockSucceeded(message) { return { type: actionConstants.UNLOCK_SUCCEEDED, value: message, - } + }; } export function updateMetamaskState(newState) { return (dispatch, getState) => { - const { metamask: currentState } = getState() + const { metamask: currentState } = getState(); - const { currentLocale, selectedAddress } = currentState + const { currentLocale, selectedAddress } = currentState; const { currentLocale: newLocale, selectedAddress: newSelectedAddress, - } = newState + } = newState; if (currentLocale && newLocale && currentLocale !== newLocale) { - dispatch(updateCurrentLocale(newLocale)) + dispatch(updateCurrentLocale(newLocale)); } if (selectedAddress !== newSelectedAddress) { - dispatch({ type: actionConstants.SELECTED_ADDRESS_CHANGED }) + dispatch({ type: actionConstants.SELECTED_ADDRESS_CHANGED }); } dispatch({ type: actionConstants.UPDATE_METAMASK_STATE, value: newState, - }) - } + }); + }; } const backgroundSetLocked = () => { return new Promise((resolve, reject) => { background.setLocked((error) => { if (error) { - reject(error) - return + reject(error); + return; } - resolve() - }) - }) -} + resolve(); + }); + }); +}; export function lockMetamask() { - log.debug(`background.setLocked`) + log.debug(`background.setLocked`); return (dispatch) => { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); return backgroundSetLocked() .then(() => updateMetamaskStateFromBackground()) .catch((error) => { - dispatch(displayWarning(error.message)) - return Promise.reject(error) + dispatch(displayWarning(error.message)); + return Promise.reject(error); }) .then((newState) => { - dispatch(updateMetamaskState(newState)) - dispatch(hideLoadingIndication()) - dispatch({ type: actionConstants.LOCK_METAMASK }) + dispatch(updateMetamaskState(newState)); + dispatch(hideLoadingIndication()); + dispatch({ type: actionConstants.LOCK_METAMASK }); }) .catch(() => { - dispatch(hideLoadingIndication()) - dispatch({ type: actionConstants.LOCK_METAMASK }) - }) - } + dispatch(hideLoadingIndication()); + dispatch({ type: actionConstants.LOCK_METAMASK }); + }); + }; } async function _setSelectedAddress(dispatch, address) { - log.debug(`background.setSelectedAddress`) - const tokens = await promisifiedBackground.setSelectedAddress(address) - dispatch(updateTokens(tokens)) + log.debug(`background.setSelectedAddress`); + const tokens = await promisifiedBackground.setSelectedAddress(address); + dispatch(updateTokens(tokens)); } export function setSelectedAddress(address) { return async (dispatch) => { - dispatch(showLoadingIndication()) - log.debug(`background.setSelectedAddress`) + dispatch(showLoadingIndication()); + log.debug(`background.setSelectedAddress`); try { - await _setSelectedAddress(dispatch, address) + await _setSelectedAddress(dispatch, address); } catch (error) { - dispatch(displayWarning(error.message)) - return + dispatch(displayWarning(error.message)); + return; } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - } + }; } export function showAccountDetail(address) { return async (dispatch, getState) => { - dispatch(showLoadingIndication()) - log.debug(`background.setSelectedAddress`) + dispatch(showLoadingIndication()); + log.debug(`background.setSelectedAddress`); - const state = getState() + const state = getState(); const unconnectedAccountAccountAlertIsEnabled = getUnconnectedAccountAlertEnabledness( state, - ) - const activeTabOrigin = state.activeTab.origin - const selectedAddress = getSelectedAddress(state) + ); + const activeTabOrigin = state.activeTab.origin; + const selectedAddress = getSelectedAddress(state); const permittedAccountsForCurrentTab = getPermittedAccountsForCurrentTab( state, - ) + ); const currentTabIsConnectedToPreviousAddress = Boolean(activeTabOrigin) && - permittedAccountsForCurrentTab.includes(selectedAddress) + permittedAccountsForCurrentTab.includes(selectedAddress); const currentTabIsConnectedToNextAddress = Boolean(activeTabOrigin) && - permittedAccountsForCurrentTab.includes(address) + permittedAccountsForCurrentTab.includes(address); const switchingToUnconnectedAddress = currentTabIsConnectedToPreviousAddress && - !currentTabIsConnectedToNextAddress + !currentTabIsConnectedToNextAddress; try { - await _setSelectedAddress(dispatch, address) + await _setSelectedAddress(dispatch, address); } catch (error) { - dispatch(displayWarning(error.message)) - return + dispatch(displayWarning(error.message)); + return; } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } dispatch({ type: actionConstants.SHOW_ACCOUNT_DETAIL, value: address, - }) + }); if ( unconnectedAccountAccountAlertIsEnabled && switchingToUnconnectedAddress ) { - dispatch(switchedToUnconnectedAccount()) - await setUnconnectedAccountAlertShown(activeTabOrigin) + dispatch(switchedToUnconnectedAccount()); + await setUnconnectedAccountAlertShown(activeTabOrigin); } - } + }; } export function addPermittedAccount(origin, address) { @@ -1324,14 +1334,14 @@ export function addPermittedAccount(origin, address) { await new Promise((resolve, reject) => { background.addPermittedAccount(origin, address, (error) => { if (error) { - reject(error) - return + reject(error); + return; } - resolve() - }) - }) - await forceUpdateMetamaskState(dispatch) - } + resolve(); + }); + }); + await forceUpdateMetamaskState(dispatch); + }; } export function removePermittedAccount(origin, address) { @@ -1339,27 +1349,27 @@ export function removePermittedAccount(origin, address) { await new Promise((resolve, reject) => { background.removePermittedAccount(origin, address, (error) => { if (error) { - reject(error) - return + reject(error); + return; } - resolve() - }) - }) - await forceUpdateMetamaskState(dispatch) - } + resolve(); + }); + }); + await forceUpdateMetamaskState(dispatch); + }; } export function showAccountsPage() { return { type: actionConstants.SHOW_ACCOUNTS_PAGE, - } + }; } export function showConfTxPage({ id } = {}) { return { type: actionConstants.SHOW_CONF_TX_PAGE, id, - } + }; } export function addToken( @@ -1370,38 +1380,38 @@ export function addToken( dontShowLoadingIndicator, ) { return (dispatch) => { - !dontShowLoadingIndicator && dispatch(showLoadingIndication()) + !dontShowLoadingIndicator && dispatch(showLoadingIndication()); return new Promise((resolve, reject) => { background.addToken(address, symbol, decimals, image, (err, tokens) => { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } - dispatch(updateTokens(tokens)) - resolve(tokens) - }) - }) - } + dispatch(updateTokens(tokens)); + resolve(tokens); + }); + }); + }; } export function removeToken(address) { return (dispatch) => { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); return new Promise((resolve, reject) => { background.removeToken(address, (err, tokens) => { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } - dispatch(updateTokens(tokens)) - resolve(tokens) - }) - }) - } + dispatch(updateTokens(tokens)); + resolve(tokens); + }); + }); + }; } export function addTokens(tokens) { @@ -1411,62 +1421,62 @@ export function addTokens(tokens) { tokens.map(({ address, symbol, decimals }) => dispatch(addToken(address, symbol, decimals)), ), - ) + ); } return Promise.all( Object.entries(tokens).map(([_, { address, symbol, decimals }]) => dispatch(addToken(address, symbol, decimals)), ), - ) - } + ); + }; } export function removeSuggestedTokens() { return (dispatch) => { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); return new Promise((resolve) => { background.removeSuggestedTokens((err, suggestedTokens) => { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); if (err) { - dispatch(displayWarning(err.message)) + dispatch(displayWarning(err.message)); } - dispatch(clearPendingTokens()) + dispatch(clearPendingTokens()); if (getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION) { - global.platform.closeCurrentWindow() - return + global.platform.closeCurrentWindow(); + return; } - resolve(suggestedTokens) - }) + resolve(suggestedTokens); + }); }) .then(() => updateMetamaskStateFromBackground()) .then((suggestedTokens) => dispatch(updateMetamaskState({ ...suggestedTokens })), - ) - } + ); + }; } export function addKnownMethodData(fourBytePrefix, methodData) { return () => { - background.addKnownMethodData(fourBytePrefix, methodData) - } + background.addKnownMethodData(fourBytePrefix, methodData); + }; } export function updateTokens(newTokens) { return { type: actionConstants.UPDATE_TOKENS, newTokens, - } + }; } export function clearPendingTokens() { return { type: actionConstants.CLEAR_PENDING_TOKENS, - } + }; } export function createCancelTransaction(txId, customGasPrice) { - log.debug('background.cancelTransaction') - let newTxId + log.debug('background.cancelTransaction'); + let newTxId; return (dispatch) => { return new Promise((resolve, reject) => { @@ -1475,26 +1485,26 @@ export function createCancelTransaction(txId, customGasPrice) { customGasPrice, (err, newState) => { if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } - const { currentNetworkTxList } = newState - const { id } = currentNetworkTxList[currentNetworkTxList.length - 1] - newTxId = id - resolve(newState) + const { currentNetworkTxList } = newState; + const { id } = currentNetworkTxList[currentNetworkTxList.length - 1]; + newTxId = id; + resolve(newState); }, - ) + ); }) .then((newState) => dispatch(updateMetamaskState(newState))) - .then(() => newTxId) - } + .then(() => newTxId); + }; } export function createSpeedUpTransaction(txId, customGasPrice, customGasLimit) { - log.debug('background.createSpeedUpTransaction') - let newTx + log.debug('background.createSpeedUpTransaction'); + let newTx; return (dispatch) => { return new Promise((resolve, reject) => { @@ -1504,25 +1514,25 @@ export function createSpeedUpTransaction(txId, customGasPrice, customGasLimit) { customGasLimit, (err, newState) => { if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } - const { currentNetworkTxList } = newState - newTx = currentNetworkTxList[currentNetworkTxList.length - 1] - resolve(newState) + const { currentNetworkTxList } = newState; + newTx = currentNetworkTxList[currentNetworkTxList.length - 1]; + resolve(newState); }, - ) + ); }) .then((newState) => dispatch(updateMetamaskState(newState))) - .then(() => newTx) - } + .then(() => newTx); + }; } export function createRetryTransaction(txId, customGasPrice, customGasLimit) { - log.debug('background.createRetryTransaction') - let newTx + log.debug('background.createRetryTransaction'); + let newTx; return (dispatch) => { return new Promise((resolve, reject) => { @@ -1532,20 +1542,20 @@ export function createRetryTransaction(txId, customGasPrice, customGasLimit) { customGasLimit, (err, newState) => { if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } - const { currentNetworkTxList } = newState - newTx = currentNetworkTxList[currentNetworkTxList.length - 1] - resolve(newState) + const { currentNetworkTxList } = newState; + newTx = currentNetworkTxList[currentNetworkTxList.length - 1]; + resolve(newState); }, - ) + ); }) .then((newState) => dispatch(updateMetamaskState(newState))) - .then(() => newTx) - } + .then(() => newTx); + }; } // @@ -1554,24 +1564,24 @@ export function createRetryTransaction(txId, customGasPrice, customGasLimit) { export function setProviderType(type) { return async (dispatch) => { - log.debug(`background.setProviderType`, type) + log.debug(`background.setProviderType`, type); try { - await promisifiedBackground.setProviderType(type) + await promisifiedBackground.setProviderType(type); } catch (error) { - log.error(error) - dispatch(displayWarning('Had a problem changing networks!')) - return + log.error(error); + dispatch(displayWarning('Had a problem changing networks!')); + return; } - dispatch(updateProviderType(type)) - } + dispatch(updateProviderType(type)); + }; } export function updateProviderType(type) { return { type: actionConstants.SET_PROVIDER_TYPE, value: type, - } + }; } export function updateAndSetCustomRpc( @@ -1584,7 +1594,7 @@ export function updateAndSetCustomRpc( return async (dispatch) => { log.debug( `background.updateAndSetCustomRpc: ${newRpc} ${chainId} ${ticker} ${nickname}`, - ) + ); try { await promisifiedBackground.updateAndSetCustomRpc( @@ -1593,18 +1603,18 @@ export function updateAndSetCustomRpc( ticker, nickname || newRpc, rpcPrefs, - ) + ); } catch (error) { - log.error(error) - dispatch(displayWarning('Had a problem changing networks!')) - return + log.error(error); + dispatch(displayWarning('Had a problem changing networks!')); + return; } dispatch({ type: actionConstants.SET_RPC_TARGET, value: newRpc, - }) - } + }); + }; } export function editRpc( @@ -1616,13 +1626,13 @@ export function editRpc( rpcPrefs, ) { return async (dispatch) => { - log.debug(`background.delRpcTarget: ${oldRpc}`) + log.debug(`background.delRpcTarget: ${oldRpc}`); try { - promisifiedBackground.delCustomRpc(oldRpc) + promisifiedBackground.delCustomRpc(oldRpc); } catch (error) { - log.error(error) - dispatch(displayWarning('Had a problem removing network!')) - return + log.error(error); + dispatch(displayWarning('Had a problem removing network!')); + return; } try { @@ -1632,25 +1642,25 @@ export function editRpc( ticker, nickname || newRpc, rpcPrefs, - ) + ); } catch (error) { - log.error(error) - dispatch(displayWarning('Had a problem changing networks!')) - return + log.error(error); + dispatch(displayWarning('Had a problem changing networks!')); + return; } dispatch({ type: actionConstants.SET_RPC_TARGET, value: newRpc, - }) - } + }); + }; } export function setRpcTarget(newRpc, chainId, ticker = 'ETH', nickname) { return async (dispatch) => { log.debug( `background.setRpcTarget: ${newRpc} ${chainId} ${ticker} ${nickname}`, - ) + ); try { await promisifiedBackground.setCustomRpc( @@ -1658,66 +1668,66 @@ export function setRpcTarget(newRpc, chainId, ticker = 'ETH', nickname) { chainId, ticker, nickname || newRpc, - ) + ); } catch (error) { - log.error(error) - dispatch(displayWarning('Had a problem changing networks!')) + log.error(error); + dispatch(displayWarning('Had a problem changing networks!')); } - } + }; } export function rollbackToPreviousProvider() { return async (dispatch) => { try { - await promisifiedBackground.rollbackToPreviousProvider() + await promisifiedBackground.rollbackToPreviousProvider(); } catch (error) { - log.error(error) - dispatch(displayWarning('Had a problem changing networks!')) + log.error(error); + dispatch(displayWarning('Had a problem changing networks!')); } - } + }; } export function delRpcTarget(oldRpc) { return (dispatch) => { - log.debug(`background.delRpcTarget: ${oldRpc}`) + log.debug(`background.delRpcTarget: ${oldRpc}`); return new Promise((resolve, reject) => { background.delCustomRpc(oldRpc, (err) => { if (err) { - log.error(err) - dispatch(displayWarning('Had a problem removing network!')) - reject(err) - return + log.error(err); + dispatch(displayWarning('Had a problem removing network!')); + reject(err); + return; } - resolve() - }) - }) - } + resolve(); + }); + }); + }; } // Calls the addressBookController to add a new address. export function addToAddressBook(recipient, nickname = '', memo = '') { - log.debug(`background.addToAddressBook`) + log.debug(`background.addToAddressBook`); return async (dispatch, getState) => { - const { chainId } = getState().metamask.provider + const { chainId } = getState().metamask.provider; - let set + let set; try { set = await promisifiedBackground.setAddressBook( checksumAddress(recipient), nickname, chainId, memo, - ) + ); } catch (error) { - log.error(error) - dispatch(displayWarning('Address book failed to update')) - throw error + log.error(error); + dispatch(displayWarning('Address book failed to update')); + throw error; } if (!set) { - dispatch(displayWarning('Address book failed to update')) + dispatch(displayWarning('Address book failed to update')); } - } + }; } /** @@ -1725,40 +1735,40 @@ export function addToAddressBook(recipient, nickname = '', memo = '') { * @param {string} addressToRemove - Address of the entry to remove from the address book */ export function removeFromAddressBook(chainId, addressToRemove) { - log.debug(`background.removeFromAddressBook`) + log.debug(`background.removeFromAddressBook`); return async () => { await promisifiedBackground.removeFromAddressBook( chainId, checksumAddress(addressToRemove), - ) - } + ); + }; } export function showNetworkDropdown() { return { type: actionConstants.NETWORK_DROPDOWN_OPEN, - } + }; } export function hideNetworkDropdown() { return { type: actionConstants.NETWORK_DROPDOWN_CLOSE, - } + }; } export function showModal(payload) { return { type: actionConstants.MODAL_OPEN, payload, - } + }; } export function hideModal(payload) { return { type: actionConstants.MODAL_CLOSE, payload, - } + }; } export function closeCurrentNotificationWindow() { @@ -1767,17 +1777,17 @@ export function closeCurrentNotificationWindow() { getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION && !hasUnconfirmedTransactions(getState()) ) { - global.platform.closeCurrentWindow() + global.platform.closeCurrentWindow(); - dispatch(closeNotificationWindow()) + dispatch(closeNotificationWindow()); } - } + }; } export function closeNotificationWindow() { return { type: actionConstants.CLOSE_NOTIFICATION_WINDOW, - } + }; } export function showSidebar({ transitionName, type, props }) { @@ -1788,26 +1798,26 @@ export function showSidebar({ transitionName, type, props }) { type, props, }, - } + }; } export function hideSidebar() { return { type: actionConstants.SIDEBAR_CLOSE, - } + }; } export function showAlert(msg) { return { type: actionConstants.ALERT_OPEN, value: msg, - } + }; } export function hideAlert() { return { type: actionConstants.ALERT_CLOSE, - } + }; } /** @@ -1819,412 +1829,412 @@ export function qrCodeDetected(qrCodeData) { return { type: actionConstants.QR_CODE_DETECTED, value: qrCodeData, - } + }; } export function showLoadingIndication(message) { return { type: actionConstants.SHOW_LOADING, value: message, - } + }; } export function setHardwareWalletDefaultHdPath({ device, path }) { return { type: actionConstants.SET_HARDWARE_WALLET_DEFAULT_HD_PATH, value: { device, path }, - } + }; } export function hideLoadingIndication() { return { type: actionConstants.HIDE_LOADING, - } + }; } export function displayWarning(text) { return { type: actionConstants.DISPLAY_WARNING, value: text, - } + }; } export function hideWarning() { return { type: actionConstants.HIDE_WARNING, - } + }; } export function exportAccount(password, address) { return function (dispatch) { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); - log.debug(`background.verifyPassword`) + log.debug(`background.verifyPassword`); return new Promise((resolve, reject) => { background.verifyPassword(password, function (err) { if (err) { - log.error('Error in verifying password.') - dispatch(hideLoadingIndication()) - dispatch(displayWarning('Incorrect Password.')) - reject(err) - return + log.error('Error in verifying password.'); + dispatch(hideLoadingIndication()); + dispatch(displayWarning('Incorrect Password.')); + reject(err); + return; } - log.debug(`background.exportAccount`) + log.debug(`background.exportAccount`); background.exportAccount(address, function (err2, result) { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); if (err2) { - log.error(err2) - dispatch(displayWarning('Had a problem exporting the account.')) - reject(err2) - return + log.error(err2); + dispatch(displayWarning('Had a problem exporting the account.')); + reject(err2); + return; } - dispatch(showPrivateKey(result)) - resolve(result) - }) - }) - }) - } + dispatch(showPrivateKey(result)); + resolve(result); + }); + }); + }); + }; } export function exportAccounts(password, addresses) { return function (dispatch) { - log.debug(`background.submitPassword`) + log.debug(`background.submitPassword`); return new Promise((resolve, reject) => { background.submitPassword(password, function (err) { if (err) { - log.error('Error in submitting password.') - reject(err) - return + log.error('Error in submitting password.'); + reject(err); + return; } - log.debug(`background.exportAccounts`) + log.debug(`background.exportAccounts`); const accountPromises = addresses.map( (address) => new Promise((resolve2, reject2) => background.exportAccount(address, function (err2, result) { if (err2) { - log.error(err2) + log.error(err2); dispatch( displayWarning('Had a problem exporting the account.'), - ) - reject2(err2) - return + ); + reject2(err2); + return; } - resolve2(result) + resolve2(result); }), ), - ) - resolve(Promise.all(accountPromises)) - }) - }) - } + ); + resolve(Promise.all(accountPromises)); + }); + }); + }; } export function showPrivateKey(key) { return { type: actionConstants.SHOW_PRIVATE_KEY, value: key, - } + }; } export function setAccountLabel(account, label) { return (dispatch) => { - dispatch(showLoadingIndication()) - log.debug(`background.setAccountLabel`) + dispatch(showLoadingIndication()); + log.debug(`background.setAccountLabel`); return new Promise((resolve, reject) => { background.setAccountLabel(account, label, (err) => { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } dispatch({ type: actionConstants.SET_ACCOUNT_LABEL, value: { account, label }, - }) - resolve(account) - }) - }) - } + }); + resolve(account); + }); + }); + }; } export function clearAccountDetails() { return { type: actionConstants.CLEAR_ACCOUNT_DETAILS, - } + }; } export function showSendTokenPage() { return { type: actionConstants.SHOW_SEND_TOKEN_PAGE, - } + }; } export function buyEth(opts) { return (dispatch) => { - const url = getBuyEthUrl(opts) - global.platform.openTab({ url }) + const url = getBuyEthUrl(opts); + global.platform.openTab({ url }); dispatch({ type: actionConstants.BUY_ETH, - }) - } + }); + }; } export function setFeatureFlag(feature, activated, notificationType) { return (dispatch) => { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); return new Promise((resolve, reject) => { background.setFeatureFlag( feature, activated, (err, updatedFeatureFlags) => { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } - dispatch(updateFeatureFlags(updatedFeatureFlags)) - notificationType && dispatch(showModal({ name: notificationType })) - resolve(updatedFeatureFlags) + dispatch(updateFeatureFlags(updatedFeatureFlags)); + notificationType && dispatch(showModal({ name: notificationType })); + resolve(updatedFeatureFlags); }, - ) - }) - } + ); + }); + }; } export function updateFeatureFlags(updatedFeatureFlags) { return { type: actionConstants.UPDATE_FEATURE_FLAGS, value: updatedFeatureFlags, - } + }; } export function setPreference(preference, value) { return (dispatch) => { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); return new Promise((resolve, reject) => { background.setPreference(preference, value, (err, updatedPreferences) => { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } - dispatch(updatePreferences(updatedPreferences)) - resolve(updatedPreferences) - }) - }) - } + dispatch(updatePreferences(updatedPreferences)); + resolve(updatedPreferences); + }); + }); + }; } export function updatePreferences(value) { return { type: actionConstants.UPDATE_PREFERENCES, value, - } + }; } export function setDefaultHomeActiveTabName(value) { return async () => { - await promisifiedBackground.setDefaultHomeActiveTabName(value) - } + await promisifiedBackground.setDefaultHomeActiveTabName(value); + }; } export function setUseNativeCurrencyAsPrimaryCurrencyPreference(value) { - return setPreference('useNativeCurrencyAsPrimaryCurrency', value) + return setPreference('useNativeCurrencyAsPrimaryCurrency', value); } export function setShowFiatConversionOnTestnetsPreference(value) { - return setPreference('showFiatInTestnets', value) + return setPreference('showFiatInTestnets', value); } export function setAutoLockTimeLimit(value) { - return setPreference('autoLockTimeLimit', value) + return setPreference('autoLockTimeLimit', value); } export function setCompletedOnboarding() { return async (dispatch) => { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); try { - await promisifiedBackground.completeOnboarding() - dispatch(completeOnboarding()) + await promisifiedBackground.completeOnboarding(); + dispatch(completeOnboarding()); } catch (err) { - dispatch(displayWarning(err.message)) - throw err + dispatch(displayWarning(err.message)); + throw err; } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - } + }; } export function completeOnboarding() { return { type: actionConstants.COMPLETE_ONBOARDING, - } + }; } export function setMouseUserState(isMouseUser) { return { type: actionConstants.SET_MOUSE_USER_STATE, value: isMouseUser, - } + }; } export async function forceUpdateMetamaskState(dispatch) { - log.debug(`background.getState`) + log.debug(`background.getState`); - let newState + let newState; try { - newState = await promisifiedBackground.getState() + newState = await promisifiedBackground.getState(); } catch (error) { - dispatch(displayWarning(error.message)) - throw error + dispatch(displayWarning(error.message)); + throw error; } - dispatch(updateMetamaskState(newState)) - return newState + dispatch(updateMetamaskState(newState)); + return newState; } export function toggleAccountMenu() { return { type: actionConstants.TOGGLE_ACCOUNT_MENU, - } + }; } export function setParticipateInMetaMetrics(val) { return (dispatch) => { - log.debug(`background.setParticipateInMetaMetrics`) + log.debug(`background.setParticipateInMetaMetrics`); return new Promise((resolve, reject) => { background.setParticipateInMetaMetrics(val, (err, metaMetricsId) => { - log.debug(err) + log.debug(err); if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } dispatch({ type: actionConstants.SET_PARTICIPATE_IN_METAMETRICS, value: val, - }) - resolve([val, metaMetricsId]) - }) - }) - } + }); + resolve([val, metaMetricsId]); + }); + }); + }; } export function setMetaMetricsSendCount(val) { return (dispatch) => { - log.debug(`background.setMetaMetricsSendCount`) + log.debug(`background.setMetaMetricsSendCount`); return new Promise((resolve, reject) => { background.setMetaMetricsSendCount(val, (err) => { if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } dispatch({ type: actionConstants.SET_METAMETRICS_SEND_COUNT, value: val, - }) - resolve(val) - }) - }) - } + }); + resolve(val); + }); + }); + }; } export function setUseBlockie(val) { return (dispatch) => { - dispatch(showLoadingIndication()) - log.debug(`background.setUseBlockie`) + dispatch(showLoadingIndication()); + log.debug(`background.setUseBlockie`); background.setUseBlockie(val, (err) => { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); if (err) { - dispatch(displayWarning(err.message)) + dispatch(displayWarning(err.message)); } - }) + }); dispatch({ type: actionConstants.SET_USE_BLOCKIE, value: val, - }) - } + }); + }; } export function setUseNonceField(val) { return (dispatch) => { - dispatch(showLoadingIndication()) - log.debug(`background.setUseNonceField`) + dispatch(showLoadingIndication()); + log.debug(`background.setUseNonceField`); background.setUseNonceField(val, (err) => { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); if (err) { - dispatch(displayWarning(err.message)) + dispatch(displayWarning(err.message)); } - }) + }); dispatch({ type: actionConstants.SET_USE_NONCEFIELD, value: val, - }) - } + }); + }; } export function setUsePhishDetect(val) { return (dispatch) => { - dispatch(showLoadingIndication()) - log.debug(`background.setUsePhishDetect`) + dispatch(showLoadingIndication()); + log.debug(`background.setUsePhishDetect`); background.setUsePhishDetect(val, (err) => { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); if (err) { - dispatch(displayWarning(err.message)) + dispatch(displayWarning(err.message)); } - }) - } + }); + }; } export function setIpfsGateway(val) { return (dispatch) => { - dispatch(showLoadingIndication()) - log.debug(`background.setIpfsGateway`) + dispatch(showLoadingIndication()); + log.debug(`background.setIpfsGateway`); background.setIpfsGateway(val, (err) => { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); if (err) { - dispatch(displayWarning(err.message)) + dispatch(displayWarning(err.message)); } else { dispatch({ type: actionConstants.SET_IPFS_GATEWAY, value: val, - }) + }); } - }) - } + }); + }; } export function updateCurrentLocale(key) { return async (dispatch) => { - dispatch(showLoadingIndication()) + dispatch(showLoadingIndication()); try { - await loadRelativeTimeFormatLocaleData(key) - const localeMessages = await fetchLocale(key) - const textDirection = await promisifiedBackground.setCurrentLocale(key) - await switchDirection(textDirection) - dispatch(setCurrentLocale(key, localeMessages)) + await loadRelativeTimeFormatLocaleData(key); + const localeMessages = await fetchLocale(key); + const textDirection = await promisifiedBackground.setCurrentLocale(key); + await switchDirection(textDirection); + dispatch(setCurrentLocale(key, localeMessages)); } catch (error) { - dispatch(displayWarning(error.message)) - return + dispatch(displayWarning(error.message)); + return; } finally { - dispatch(hideLoadingIndication()) + dispatch(hideLoadingIndication()); } - } + }; } export function setCurrentLocale(locale, messages) { @@ -2234,12 +2244,12 @@ export function setCurrentLocale(locale, messages) { locale, messages, }, - } + }; } export function setPendingTokens(pendingTokens) { - const { customToken = {}, selectedTokens = {} } = pendingTokens - const { address, symbol, decimals } = customToken + const { customToken = {}, selectedTokens = {} } = pendingTokens; + const { address, symbol, decimals } = customToken; const tokens = address && symbol && decimals ? { @@ -2249,27 +2259,27 @@ export function setPendingTokens(pendingTokens) { isCustom: true, }, } - : selectedTokens + : selectedTokens; Object.keys(tokens).forEach((tokenAddress) => { tokens[tokenAddress].unlisted = !LISTED_CONTRACT_ADDRESSES.includes( tokenAddress.toLowerCase(), - ) - }) + ); + }); return { type: actionConstants.SET_PENDING_TOKENS, payload: tokens, - } + }; } // Swaps export function setSwapsLiveness(swapsFeatureIsLive) { return async (dispatch) => { - await promisifiedBackground.setSwapsLiveness(swapsFeatureIsLive) - await forceUpdateMetamaskState(dispatch) - } + await promisifiedBackground.setSwapsLiveness(swapsFeatureIsLive); + await forceUpdateMetamaskState(dispatch); + }; } export function fetchAndSetQuotes(fetchParams, fetchParamsMetaData) { @@ -2280,117 +2290,117 @@ export function fetchAndSetQuotes(fetchParams, fetchParamsMetaData) { ] = await promisifiedBackground.fetchAndSetQuotes( fetchParams, fetchParamsMetaData, - ) - await forceUpdateMetamaskState(dispatch) - return [quotes, selectedAggId] - } + ); + await forceUpdateMetamaskState(dispatch); + return [quotes, selectedAggId]; + }; } export function setSelectedQuoteAggId(aggId) { return async (dispatch) => { - await promisifiedBackground.setSelectedQuoteAggId(aggId) - await forceUpdateMetamaskState(dispatch) - } + await promisifiedBackground.setSelectedQuoteAggId(aggId); + await forceUpdateMetamaskState(dispatch); + }; } export function setSwapsTokens(tokens) { return async (dispatch) => { - await promisifiedBackground.setSwapsTokens(tokens) - await forceUpdateMetamaskState(dispatch) - } + await promisifiedBackground.setSwapsTokens(tokens); + await forceUpdateMetamaskState(dispatch); + }; } export function resetBackgroundSwapsState() { return async (dispatch) => { - const id = await promisifiedBackground.resetSwapsState() - await forceUpdateMetamaskState(dispatch) - return id - } + const id = await promisifiedBackground.resetSwapsState(); + await forceUpdateMetamaskState(dispatch); + return id; + }; } export function setCustomApproveTxData(data) { return async (dispatch) => { - await promisifiedBackground.setCustomApproveTxData(data) - await forceUpdateMetamaskState(dispatch) - } + await promisifiedBackground.setCustomApproveTxData(data); + await forceUpdateMetamaskState(dispatch); + }; } export function setSwapsTxGasPrice(gasPrice) { return async (dispatch) => { - await promisifiedBackground.setSwapsTxGasPrice(gasPrice) - await forceUpdateMetamaskState(dispatch) - } + await promisifiedBackground.setSwapsTxGasPrice(gasPrice); + await forceUpdateMetamaskState(dispatch); + }; } export function setSwapsTxGasLimit(gasLimit) { return async (dispatch) => { - await promisifiedBackground.setSwapsTxGasLimit(gasLimit, true) - await forceUpdateMetamaskState(dispatch) - } + await promisifiedBackground.setSwapsTxGasLimit(gasLimit, true); + await forceUpdateMetamaskState(dispatch); + }; } export function customSwapsGasParamsUpdated(gasLimit, gasPrice) { return async (dispatch) => { - await promisifiedBackground.setSwapsTxGasPrice(gasPrice) - await promisifiedBackground.setSwapsTxGasLimit(gasLimit, true) - await forceUpdateMetamaskState(dispatch) - } + await promisifiedBackground.setSwapsTxGasPrice(gasPrice); + await promisifiedBackground.setSwapsTxGasLimit(gasLimit, true); + await forceUpdateMetamaskState(dispatch); + }; } export function setTradeTxId(tradeTxId) { return async (dispatch) => { - await promisifiedBackground.setTradeTxId(tradeTxId) - await forceUpdateMetamaskState(dispatch) - } + await promisifiedBackground.setTradeTxId(tradeTxId); + await forceUpdateMetamaskState(dispatch); + }; } export function setApproveTxId(approveTxId) { return async (dispatch) => { - await promisifiedBackground.setApproveTxId(approveTxId) - await forceUpdateMetamaskState(dispatch) - } + await promisifiedBackground.setApproveTxId(approveTxId); + await forceUpdateMetamaskState(dispatch); + }; } export function safeRefetchQuotes() { return async (dispatch) => { - await promisifiedBackground.safeRefetchQuotes() - await forceUpdateMetamaskState(dispatch) - } + await promisifiedBackground.safeRefetchQuotes(); + await forceUpdateMetamaskState(dispatch); + }; } export function stopPollingForQuotes() { return async (dispatch) => { - await promisifiedBackground.stopPollingForQuotes() - await forceUpdateMetamaskState(dispatch) - } + await promisifiedBackground.stopPollingForQuotes(); + await forceUpdateMetamaskState(dispatch); + }; } export function setBackgroundSwapRouteState(routeState) { return async (dispatch) => { - await promisifiedBackground.setBackgroundSwapRouteState(routeState) - await forceUpdateMetamaskState(dispatch) - } + await promisifiedBackground.setBackgroundSwapRouteState(routeState); + await forceUpdateMetamaskState(dispatch); + }; } export function resetSwapsPostFetchState() { return async (dispatch) => { - await promisifiedBackground.resetPostFetchState() - await forceUpdateMetamaskState(dispatch) - } + await promisifiedBackground.resetPostFetchState(); + await forceUpdateMetamaskState(dispatch); + }; } export function setSwapsErrorKey(errorKey) { return async (dispatch) => { - await promisifiedBackground.setSwapsErrorKey(errorKey) - await forceUpdateMetamaskState(dispatch) - } + await promisifiedBackground.setSwapsErrorKey(errorKey); + await forceUpdateMetamaskState(dispatch); + }; } export function setInitialGasEstimate(initialAggId) { return async (dispatch) => { - await promisifiedBackground.setInitialGasEstimate(initialAggId) - await forceUpdateMetamaskState(dispatch) - } + await promisifiedBackground.setInitialGasEstimate(initialAggId); + await forceUpdateMetamaskState(dispatch); + }; } // Permissions @@ -2399,10 +2409,10 @@ export function requestAccountsPermissionWithId(origin) { return async (dispatch) => { const id = await promisifiedBackground.requestAccountsPermissionWithId( origin, - ) - await forceUpdateMetamaskState(dispatch) - return id - } + ); + await forceUpdateMetamaskState(dispatch); + return id; + }; } /** @@ -2412,8 +2422,8 @@ export function requestAccountsPermissionWithId(origin) { */ export function approvePermissionsRequest(request, accounts) { return () => { - background.approvePermissionsRequest(request, accounts) - } + background.approvePermissionsRequest(request, accounts); + }; } /** @@ -2425,14 +2435,14 @@ export function rejectPermissionsRequest(requestId) { return new Promise((resolve, reject) => { background.rejectPermissionsRequest(requestId, (err) => { if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } - forceUpdateMetamaskState(dispatch).then(resolve).catch(reject) - }) - }) - } + forceUpdateMetamaskState(dispatch).then(resolve).catch(reject); + }); + }); + }; } /** @@ -2440,8 +2450,8 @@ export function rejectPermissionsRequest(requestId) { */ export function removePermissionsFor(domains) { return () => { - background.removePermissionsFor(domains) - } + background.removePermissionsFor(domains); + }; } /** @@ -2449,98 +2459,98 @@ export function removePermissionsFor(domains) { */ export function clearPermissions() { return () => { - background.clearPermissions() - } + background.clearPermissions(); + }; } export function setFirstTimeFlowType(type) { return (dispatch) => { - log.debug(`background.setFirstTimeFlowType`) + log.debug(`background.setFirstTimeFlowType`); background.setFirstTimeFlowType(type, (err) => { if (err) { - dispatch(displayWarning(err.message)) + dispatch(displayWarning(err.message)); } - }) + }); dispatch({ type: actionConstants.SET_FIRST_TIME_FLOW_TYPE, value: type, - }) - } + }); + }; } export function setSelectedSettingsRpcUrl(newRpcUrl) { return { type: actionConstants.SET_SELECTED_SETTINGS_RPC_URL, value: newRpcUrl, - } + }; } export function setNetworksTabAddMode(isInAddMode) { return { type: actionConstants.SET_NETWORKS_TAB_ADD_MODE, value: isInAddMode, - } + }; } export function setLastActiveTime() { return (dispatch) => { background.setLastActiveTime((err) => { if (err) { - dispatch(displayWarning(err.message)) + dispatch(displayWarning(err.message)); } - }) - } + }); + }; } export function setConnectedStatusPopoverHasBeenShown() { return () => { background.setConnectedStatusPopoverHasBeenShown((err) => { if (err) { - throw new Error(err.message) + throw new Error(err.message); } - }) - } + }); + }; } export function setSwapsWelcomeMessageHasBeenShown() { return () => { background.setSwapsWelcomeMessageHasBeenShown((err) => { if (err) { - throw new Error(err.message) + throw new Error(err.message); } - }) - } + }); + }; } export async function setAlertEnabledness(alertId, enabledness) { - await promisifiedBackground.setAlertEnabledness(alertId, enabledness) + await promisifiedBackground.setAlertEnabledness(alertId, enabledness); } export async function setUnconnectedAccountAlertShown(origin) { - await promisifiedBackground.setUnconnectedAccountAlertShown(origin) + await promisifiedBackground.setUnconnectedAccountAlertShown(origin); } export async function setWeb3ShimUsageAlertDismissed(origin) { - await promisifiedBackground.setWeb3ShimUsageAlertDismissed(origin) + await promisifiedBackground.setWeb3ShimUsageAlertDismissed(origin); } export function loadingMethodDataStarted() { return { type: actionConstants.LOADING_METHOD_DATA_STARTED, - } + }; } export function loadingMethodDataFinished() { return { type: actionConstants.LOADING_METHOD_DATA_FINISHED, - } + }; } export function getContractMethodData(data = '') { return (dispatch, getState) => { - const prefixedData = addHexPrefix(data) - const fourBytePrefix = prefixedData.slice(0, 10) - const { knownMethodData } = getState().metamask + const prefixedData = addHexPrefix(data); + const fourBytePrefix = prefixedData.slice(0, 10); + const { knownMethodData } = getState().metamask; if ( (knownMethodData && @@ -2548,72 +2558,72 @@ export function getContractMethodData(data = '') { Object.keys(knownMethodData[fourBytePrefix]).length !== 0) || fourBytePrefix === '0x' ) { - return Promise.resolve(knownMethodData[fourBytePrefix]) + return Promise.resolve(knownMethodData[fourBytePrefix]); } - dispatch(loadingMethodDataStarted()) - log.debug(`loadingMethodData`) + dispatch(loadingMethodDataStarted()); + log.debug(`loadingMethodData`); return getMethodDataAsync(fourBytePrefix).then(({ name, params }) => { - dispatch(loadingMethodDataFinished()) - background.addKnownMethodData(fourBytePrefix, { name, params }) - return { name, params } - }) - } + dispatch(loadingMethodDataFinished()); + background.addKnownMethodData(fourBytePrefix, { name, params }); + return { name, params }; + }); + }; } export function loadingTokenParamsStarted() { return { type: actionConstants.LOADING_TOKEN_PARAMS_STARTED, - } + }; } export function loadingTokenParamsFinished() { return { type: actionConstants.LOADING_TOKEN_PARAMS_FINISHED, - } + }; } export function getTokenParams(tokenAddress) { return (dispatch, getState) => { - const existingTokens = getState().metamask.tokens + const existingTokens = getState().metamask.tokens; const existingToken = existingTokens.find( ({ address }) => tokenAddress === address, - ) + ); if (existingToken) { return Promise.resolve({ symbol: existingToken.symbol, decimals: existingToken.decimals, - }) + }); } - dispatch(loadingTokenParamsStarted()) - log.debug(`loadingTokenParams`) + dispatch(loadingTokenParamsStarted()); + log.debug(`loadingTokenParams`); return fetchSymbolAndDecimals(tokenAddress, existingTokens).then( ({ symbol, decimals }) => { - dispatch(addToken(tokenAddress, symbol, Number(decimals))) - dispatch(loadingTokenParamsFinished()) + dispatch(addToken(tokenAddress, symbol, Number(decimals))); + dispatch(loadingTokenParamsFinished()); }, - ) - } + ); + }; } export function setSeedPhraseBackedUp(seedPhraseBackupState) { return (dispatch) => { - log.debug(`background.setSeedPhraseBackedUp`) + log.debug(`background.setSeedPhraseBackedUp`); return new Promise((resolve, reject) => { background.setSeedPhraseBackedUp(seedPhraseBackupState, (err) => { if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } - forceUpdateMetamaskState(dispatch).then(resolve).catch(reject) - }) - }) - } + forceUpdateMetamaskState(dispatch).then(resolve).catch(reject); + }); + }); + }; } export function initializeThreeBox() { @@ -2621,14 +2631,14 @@ export function initializeThreeBox() { return new Promise((resolve, reject) => { background.initializeThreeBox((err) => { if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } - resolve() - }) - }) - } + resolve(); + }); + }); + }; } export function setShowRestorePromptToFalse() { @@ -2636,14 +2646,14 @@ export function setShowRestorePromptToFalse() { return new Promise((resolve, reject) => { background.setShowRestorePromptToFalse((err) => { if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } - resolve() - }) - }) - } + resolve(); + }); + }); + }; } export function turnThreeBoxSyncingOn() { @@ -2651,14 +2661,14 @@ export function turnThreeBoxSyncingOn() { return new Promise((resolve, reject) => { background.turnThreeBoxSyncingOn((err) => { if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } - resolve() - }) - }) - } + resolve(); + }); + }); + }; } export function restoreFromThreeBox(accountAddress) { @@ -2666,14 +2676,14 @@ export function restoreFromThreeBox(accountAddress) { return new Promise((resolve, reject) => { background.restoreFromThreeBox(accountAddress, (err) => { if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } - resolve() - }) - }) - } + resolve(); + }); + }); + }; } export function getThreeBoxLastUpdated() { @@ -2681,14 +2691,14 @@ export function getThreeBoxLastUpdated() { return new Promise((resolve, reject) => { background.getThreeBoxLastUpdated((err, lastUpdated) => { if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } - resolve(lastUpdated) - }) - }) - } + resolve(lastUpdated); + }); + }); + }; } export function setThreeBoxSyncingPermission(threeBoxSyncingAllowed) { @@ -2696,88 +2706,88 @@ export function setThreeBoxSyncingPermission(threeBoxSyncingAllowed) { return new Promise((resolve, reject) => { background.setThreeBoxSyncingPermission(threeBoxSyncingAllowed, (err) => { if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } - resolve() - }) - }) - } + resolve(); + }); + }); + }; } export function turnThreeBoxSyncingOnAndInitialize() { return async (dispatch) => { - await dispatch(setThreeBoxSyncingPermission(true)) - await dispatch(turnThreeBoxSyncingOn()) - await dispatch(initializeThreeBox(true)) - } + await dispatch(setThreeBoxSyncingPermission(true)); + await dispatch(turnThreeBoxSyncingOn()); + await dispatch(initializeThreeBox(true)); + }; } export function setNextNonce(nextNonce) { return { type: actionConstants.SET_NEXT_NONCE, value: nextNonce, - } + }; } export function getNextNonce() { return (dispatch, getState) => { - const address = getState().metamask.selectedAddress + const address = getState().metamask.selectedAddress; return new Promise((resolve, reject) => { background.getNextNonce(address, (err, nextNonce) => { if (err) { - dispatch(displayWarning(err.message)) - reject(err) - return + dispatch(displayWarning(err.message)); + reject(err); + return; } - dispatch(setNextNonce(nextNonce)) - resolve(nextNonce) - }) - }) - } + dispatch(setNextNonce(nextNonce)); + resolve(nextNonce); + }); + }); + }; } export function setRequestAccountTabIds(requestAccountTabIds) { return { type: actionConstants.SET_REQUEST_ACCOUNT_TABS, value: requestAccountTabIds, - } + }; } export function getRequestAccountTabIds() { return async (dispatch) => { - const requestAccountTabIds = await promisifiedBackground.getRequestAccountTabIds() - dispatch(setRequestAccountTabIds(requestAccountTabIds)) - } + const requestAccountTabIds = await promisifiedBackground.getRequestAccountTabIds(); + dispatch(setRequestAccountTabIds(requestAccountTabIds)); + }; } export function setOpenMetamaskTabsIDs(openMetaMaskTabIDs) { return { type: actionConstants.SET_OPEN_METAMASK_TAB_IDS, value: openMetaMaskTabIDs, - } + }; } export function getOpenMetamaskTabsIds() { return async (dispatch) => { - const openMetaMaskTabIDs = await promisifiedBackground.getOpenMetamaskTabsIds() - dispatch(setOpenMetamaskTabsIDs(openMetaMaskTabIDs)) - } + const openMetaMaskTabIDs = await promisifiedBackground.getOpenMetamaskTabsIds(); + dispatch(setOpenMetamaskTabsIDs(openMetaMaskTabIDs)); + }; } export function setCurrentWindowTab(currentWindowTab) { return { type: actionConstants.SET_CURRENT_WINDOW_TAB, value: currentWindowTab, - } + }; } export function getCurrentWindowTab() { return async (dispatch) => { - const currentWindowTab = await global.platform.currentTab() - dispatch(setCurrentWindowTab(currentWindowTab)) - } + const currentWindowTab = await global.platform.currentTab(); + dispatch(setCurrentWindowTab(currentWindowTab)); + }; } // MetaMetrics @@ -2794,7 +2804,7 @@ export function getCurrentWindowTab() { * @returns {Promise} */ export function trackMetaMetricsEvent(payload, options) { - return promisifiedBackground.trackMetaMetricsEvent(payload, options) + return promisifiedBackground.trackMetaMetricsEvent(payload, options); } /** @@ -2803,5 +2813,5 @@ export function trackMetaMetricsEvent(payload, options) { * @returns {void} */ export function trackMetaMetricsPage(payload, options) { - return promisifiedBackground.trackMetaMetricsPage(payload, options) + return promisifiedBackground.trackMetaMetricsPage(payload, options); } diff --git a/ui/app/store/store.js b/ui/app/store/store.js index 1feddc48e9..75cbbab107 100644 --- a/ui/app/store/store.js +++ b/ui/app/store/store.js @@ -1,7 +1,7 @@ -import { createStore, applyMiddleware } from 'redux' -import thunkMiddleware from 'redux-thunk' -import { composeWithDevTools } from 'remote-redux-devtools' -import rootReducer from '../ducks' +import { createStore, applyMiddleware } from 'redux'; +import thunkMiddleware from 'redux-thunk'; +import { composeWithDevTools } from 'remote-redux-devtools'; +import rootReducer from '../ducks'; export default function configureStore(initialState) { const composeEnhancers = composeWithDevTools({ @@ -9,10 +9,10 @@ export default function configureStore(initialState) { hostname: 'localhost', port: 8000, realtime: Boolean(process.env.METAMASK_DEBUG), - }) + }); return createStore( rootReducer, initialState, composeEnhancers(applyMiddleware(thunkMiddleware)), - ) + ); } diff --git a/ui/index.js b/ui/index.js index 660209804f..b21c629596 100644 --- a/ui/index.js +++ b/ui/index.js @@ -1,67 +1,67 @@ -import copyToClipboard from 'copy-to-clipboard' -import log from 'loglevel' -import { clone } from 'lodash' -import React from 'react' -import { render } from 'react-dom' -import { getEnvironmentType } from '../app/scripts/lib/util' -import { ALERT_TYPES } from '../shared/constants/alerts' -import { SENTRY_STATE } from '../app/scripts/lib/setupSentry' -import { ENVIRONMENT_TYPE_POPUP } from '../shared/constants/app' -import Root from './app/pages' -import * as actions from './app/store/actions' -import configureStore from './app/store/store' -import txHelper from './lib/tx-helper' +import copyToClipboard from 'copy-to-clipboard'; +import log from 'loglevel'; +import { clone } from 'lodash'; +import React from 'react'; +import { render } from 'react-dom'; +import { getEnvironmentType } from '../app/scripts/lib/util'; +import { ALERT_TYPES } from '../shared/constants/alerts'; +import { SENTRY_STATE } from '../app/scripts/lib/setupSentry'; +import { ENVIRONMENT_TYPE_POPUP } from '../shared/constants/app'; +import Root from './app/pages'; +import * as actions from './app/store/actions'; +import configureStore from './app/store/store'; +import txHelper from './lib/tx-helper'; import { fetchLocale, loadRelativeTimeFormatLocaleData, -} from './app/helpers/utils/i18n-helper' -import switchDirection from './app/helpers/utils/switch-direction' +} from './app/helpers/utils/i18n-helper'; +import switchDirection from './app/helpers/utils/switch-direction'; import { getPermittedAccountsForCurrentTab, getSelectedAddress, -} from './app/selectors' -import { ALERT_STATE } from './app/ducks/alerts' +} from './app/selectors'; +import { ALERT_STATE } from './app/ducks/alerts'; import { getUnconnectedAccountAlertEnabledness, getUnconnectedAccountAlertShown, -} from './app/ducks/metamask/metamask' +} from './app/ducks/metamask/metamask'; -log.setLevel(global.METAMASK_DEBUG ? 'debug' : 'warn') +log.setLevel(global.METAMASK_DEBUG ? 'debug' : 'warn'); export default function launchMetamaskUi(opts, cb) { - const { backgroundConnection } = opts - actions._setBackgroundConnection(backgroundConnection) + const { backgroundConnection } = opts; + actions._setBackgroundConnection(backgroundConnection); // check if we are unlocked first backgroundConnection.getState(function (err, metamaskState) { if (err) { - cb(err) - return + cb(err); + return; } startApp(metamaskState, backgroundConnection, opts).then((store) => { - setupDebuggingHelpers(store) - cb(null, store) - }) - }) + setupDebuggingHelpers(store); + cb(null, store); + }); + }); } async function startApp(metamaskState, backgroundConnection, opts) { // parse opts if (!metamaskState.featureFlags) { - metamaskState.featureFlags = {} + metamaskState.featureFlags = {}; } const currentLocaleMessages = metamaskState.currentLocale ? await fetchLocale(metamaskState.currentLocale) - : {} - const enLocaleMessages = await fetchLocale('en') + : {}; + const enLocaleMessages = await fetchLocale('en'); - await loadRelativeTimeFormatLocaleData('en') + await loadRelativeTimeFormatLocaleData('en'); if (metamaskState.currentLocale) { - await loadRelativeTimeFormatLocaleData(metamaskState.currentLocale) + await loadRelativeTimeFormatLocaleData(metamaskState.currentLocale); } if (metamaskState.textDirection === 'rtl') { - await switchDirection('rtl') + await switchDirection('rtl'); } const draftInitialState = { @@ -77,20 +77,20 @@ async function startApp(metamaskState, backgroundConnection, opts) { current: currentLocaleMessages, en: enLocaleMessages, }, - } + }; if (getEnvironmentType() === ENVIRONMENT_TYPE_POPUP) { - const { origin } = draftInitialState.activeTab + const { origin } = draftInitialState.activeTab; const permittedAccountsForCurrentTab = getPermittedAccountsForCurrentTab( draftInitialState, - ) - const selectedAddress = getSelectedAddress(draftInitialState) + ); + const selectedAddress = getSelectedAddress(draftInitialState); const unconnectedAccountAlertShownOrigins = getUnconnectedAccountAlertShown( draftInitialState, - ) + ); const unconnectedAccountAlertIsEnabled = getUnconnectedAccountAlertEnabledness( draftInitialState, - ) + ); if ( origin && @@ -101,12 +101,12 @@ async function startApp(metamaskState, backgroundConnection, opts) { ) { draftInitialState[ALERT_TYPES.unconnectedAccount] = { state: ALERT_STATE.OPEN, - } - actions.setUnconnectedAccountAlertShown(origin) + }; + actions.setUnconnectedAccountAlertShown(origin); } } - const store = configureStore(draftInitialState) + const store = configureStore(draftInitialState); // if unconfirmed txs, start on txConf page const unapprovedTxsAll = txHelper( @@ -117,37 +117,37 @@ async function startApp(metamaskState, backgroundConnection, opts) { metamaskState.unapprovedEncryptionPublicKeyMsgs, metamaskState.unapprovedTypedMessages, metamaskState.network, - ) - const numberOfUnapprovedTx = unapprovedTxsAll.length + ); + const numberOfUnapprovedTx = unapprovedTxsAll.length; if (numberOfUnapprovedTx > 0) { store.dispatch( actions.showConfTxPage({ id: unapprovedTxsAll[0].id, }), - ) + ); } backgroundConnection.on('update', function (state) { - store.dispatch(actions.updateMetamaskState(state)) - }) + store.dispatch(actions.updateMetamaskState(state)); + }); // global metamask api - used by tooling global.metamask = { updateCurrentLocale: (code) => { - store.dispatch(actions.updateCurrentLocale(code)) + store.dispatch(actions.updateCurrentLocale(code)); }, setProviderType: (type) => { - store.dispatch(actions.setProviderType(type)) + store.dispatch(actions.setProviderType(type)); }, setFeatureFlag: (key, value) => { - store.dispatch(actions.setFeatureFlag(key, value)) + store.dispatch(actions.setFeatureFlag(key, value)); }, - } + }; // start app - render(, opts.container) + render(, opts.container); - return store + return store; } /** @@ -165,54 +165,54 @@ async function startApp(metamaskState, backgroundConnection, opts) { function maskObject(object, mask) { return Object.keys(object).reduce((state, key) => { if (mask[key] === true) { - state[key] = object[key] + state[key] = object[key]; } else if (mask[key]) { - state[key] = maskObject(object[key], mask[key]) + state[key] = maskObject(object[key], mask[key]); } - return state - }, {}) + return state; + }, {}); } function setupDebuggingHelpers(store) { window.getCleanAppState = function () { - const state = clone(store.getState()) - state.version = global.platform.getVersion() - state.browser = window.navigator.userAgent - return state - } + const state = clone(store.getState()); + state.version = global.platform.getVersion(); + state.browser = window.navigator.userAgent; + return state; + }; window.getSentryState = function () { - const fullState = store.getState() - const debugState = maskObject(fullState, SENTRY_STATE) + const fullState = store.getState(); + const debugState = maskObject(fullState, SENTRY_STATE); return { browser: window.navigator.userAgent, store: debugState, version: global.platform.getVersion(), - } - } + }; + }; } window.logStateString = function (cb) { - const state = window.getCleanAppState() + const state = window.getCleanAppState(); global.platform.getPlatformInfo((err, platform) => { if (err) { - cb(err) - return + cb(err); + return; } - state.platform = platform - const stateString = JSON.stringify(state, null, 2) - cb(null, stateString) - }) -} + state.platform = platform; + const stateString = JSON.stringify(state, null, 2); + cb(null, stateString); + }); +}; window.logState = function (toClipboard) { return window.logStateString((err, result) => { if (err) { - console.error(err.message) + console.error(err.message); } else if (toClipboard) { - copyToClipboard(result) - console.log('State log copied') + copyToClipboard(result); + console.log('State log copied'); } else { - console.log(result) + console.log(result); } - }) -} + }); +}; diff --git a/ui/lib/account-link.js b/ui/lib/account-link.js index 0b9a3242d7..9d7014487c 100644 --- a/ui/lib/account-link.js +++ b/ui/lib/account-link.js @@ -3,25 +3,25 @@ export default function getAccountLink(address, network, rpcPrefs) { return `${rpcPrefs.blockExplorerUrl.replace( /\/+$/u, '', - )}/address/${address}` + )}/address/${address}`; } // eslint-disable-next-line radix - const net = parseInt(network) + const net = parseInt(network); switch (net) { case 1: // main net - return `https://etherscan.io/address/${address}` + return `https://etherscan.io/address/${address}`; case 2: // morden test net - return `https://morden.etherscan.io/address/${address}` + return `https://morden.etherscan.io/address/${address}`; case 3: // ropsten test net - return `https://ropsten.etherscan.io/address/${address}` + return `https://ropsten.etherscan.io/address/${address}`; case 4: // rinkeby test net - return `https://rinkeby.etherscan.io/address/${address}` + return `https://rinkeby.etherscan.io/address/${address}`; case 42: // kovan test net - return `https://kovan.etherscan.io/address/${address}` + return `https://kovan.etherscan.io/address/${address}`; case 5: // goerli test net - return `https://goerli.etherscan.io/address/${address}` + return `https://goerli.etherscan.io/address/${address}`; default: - return '' + return ''; } } diff --git a/ui/lib/etherscan-prefix-for-network.js b/ui/lib/etherscan-prefix-for-network.js index 82e92f3b1b..9fb740090c 100644 --- a/ui/lib/etherscan-prefix-for-network.js +++ b/ui/lib/etherscan-prefix-for-network.js @@ -1,4 +1,4 @@ -import * as networkEnums from '../../shared/constants/network' +import * as networkEnums from '../../shared/constants/network'; /** * Gets the etherscan.io URL prefix for a given network ID. @@ -9,15 +9,15 @@ import * as networkEnums from '../../shared/constants/network' export function getEtherscanNetworkPrefix(networkId) { switch (networkId) { case networkEnums.ROPSTEN_NETWORK_ID: - return 'ropsten.' + return 'ropsten.'; case networkEnums.RINKEBY_NETWORK_ID: - return 'rinkeby.' + return 'rinkeby.'; case networkEnums.KOVAN_NETWORK_ID: - return 'kovan.' + return 'kovan.'; case networkEnums.GOERLI_NETWORK_ID: - return 'goerli.' + return 'goerli.'; default: // also covers mainnet - return '' + return ''; } } diff --git a/ui/lib/icon-factory.js b/ui/lib/icon-factory.js index fa3f2bbf36..ca254317bd 100644 --- a/ui/lib/icon-factory.js +++ b/ui/lib/icon-factory.js @@ -1,69 +1,69 @@ -import { isValidAddress } from 'ethereumjs-util' -import contractMap from '@metamask/contract-metadata' -import { checksumAddress } from '../app/helpers/utils/util' +import { isValidAddress } from 'ethereumjs-util'; +import contractMap from '@metamask/contract-metadata'; +import { checksumAddress } from '../app/helpers/utils/util'; -let iconFactory +let iconFactory; export default function iconFactoryGenerator(jazzicon) { if (!iconFactory) { - iconFactory = new IconFactory(jazzicon) + iconFactory = new IconFactory(jazzicon); } - return iconFactory + return iconFactory; } function IconFactory(jazzicon) { - this.jazzicon = jazzicon - this.cache = {} + this.jazzicon = jazzicon; + this.cache = {}; } IconFactory.prototype.iconForAddress = function (address, diameter) { - const addr = checksumAddress(address) + const addr = checksumAddress(address); if (iconExistsFor(addr)) { - return imageElFor(addr) + return imageElFor(addr); } - return this.generateIdenticonSvg(address, diameter) -} + return this.generateIdenticonSvg(address, diameter); +}; // returns svg dom element IconFactory.prototype.generateIdenticonSvg = function (address, diameter) { - const cacheId = `${address}:${diameter}` + const cacheId = `${address}:${diameter}`; // check cache, lazily generate and populate cache const identicon = this.cache[cacheId] || - (this.cache[cacheId] = this.generateNewIdenticon(address, diameter)) + (this.cache[cacheId] = this.generateNewIdenticon(address, diameter)); // create a clean copy so you can modify it - const cleanCopy = identicon.cloneNode(true) - return cleanCopy -} + const cleanCopy = identicon.cloneNode(true); + return cleanCopy; +}; // creates a new identicon IconFactory.prototype.generateNewIdenticon = function (address, diameter) { - const numericRepresentation = jsNumberForAddress(address) - const identicon = this.jazzicon(diameter, numericRepresentation) - return identicon -} + const numericRepresentation = jsNumberForAddress(address); + const identicon = this.jazzicon(diameter, numericRepresentation); + return identicon; +}; // util function iconExistsFor(address) { return ( contractMap[address] && isValidAddress(address) && contractMap[address].logo - ) + ); } function imageElFor(address) { - const contract = contractMap[address] - const fileName = contract.logo - const path = `images/contract/${fileName}` - const img = document.createElement('img') - img.src = path - img.style.width = '100%' - return img + const contract = contractMap[address]; + const fileName = contract.logo; + const path = `images/contract/${fileName}`; + const img = document.createElement('img'); + img.src = path; + img.style.width = '100%'; + return img; } function jsNumberForAddress(address) { - const addr = address.slice(2, 10) - const seed = parseInt(addr, 16) - return seed + const addr = address.slice(2, 10); + const seed = parseInt(addr, 16); + return seed; } diff --git a/ui/lib/is-mobile-view.js b/ui/lib/is-mobile-view.js index d8ddb4d938..310d49d6ec 100644 --- a/ui/lib/is-mobile-view.js +++ b/ui/lib/is-mobile-view.js @@ -1,6 +1,6 @@ // Checks if viewport at invoke time fits mobile dimensions // isMobileView :: () => Bool const isMobileView = () => - window.matchMedia('screen and (max-width: 575px)').matches + window.matchMedia('screen and (max-width: 575px)').matches; -export default isMobileView +export default isMobileView; diff --git a/ui/lib/shallow-with-context.js b/ui/lib/shallow-with-context.js index ccc0a8b993..9cfb1bd759 100644 --- a/ui/lib/shallow-with-context.js +++ b/ui/lib/shallow-with-context.js @@ -1,7 +1,7 @@ -import { shallow } from 'enzyme' +import { shallow } from 'enzyme'; export default function shallowWithContext(jsxComponent) { return shallow(jsxComponent, { context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) }, - }) + }); } diff --git a/ui/lib/storage-helpers.js b/ui/lib/storage-helpers.js index 7371474055..a85d7fd483 100644 --- a/ui/lib/storage-helpers.js +++ b/ui/lib/storage-helpers.js @@ -1,23 +1,23 @@ -import localforage from 'localforage' +import localforage from 'localforage'; export async function getStorageItem(key) { try { - const serializedData = await localforage.getItem(key) + const serializedData = await localforage.getItem(key); if (serializedData === null) { - return undefined + return undefined; } - return JSON.parse(serializedData) + return JSON.parse(serializedData); } catch (err) { - return undefined + return undefined; } } export async function setStorageItem(key, value) { try { - const serializedData = JSON.stringify(value) - await localforage.setItem(key, serializedData) + const serializedData = JSON.stringify(value); + await localforage.setItem(key, serializedData); } catch (err) { - console.warn(err) + console.warn(err); } } diff --git a/ui/lib/test-timeout.js b/ui/lib/test-timeout.js index 9d9505f091..8c29780a12 100644 --- a/ui/lib/test-timeout.js +++ b/ui/lib/test-timeout.js @@ -1,5 +1,5 @@ export default function timeout(time) { return new Promise((resolve) => { - setTimeout(resolve, time || 1500) - }) + setTimeout(resolve, time || 1500); + }); } diff --git a/ui/lib/tx-helper.js b/ui/lib/tx-helper.js index 6493d67c81..698f0157a6 100644 --- a/ui/lib/tx-helper.js +++ b/ui/lib/tx-helper.js @@ -1,5 +1,5 @@ -import log from 'loglevel' -import { valuesFor } from '../app/helpers/utils/util' +import log from 'loglevel'; +import { valuesFor } from '../app/helpers/utils/util'; export default function txHelper( unapprovedTxs, @@ -10,7 +10,7 @@ export default function txHelper( typedMessages, network, ) { - log.debug('tx-helper called with params:') + log.debug('tx-helper called with params:'); log.debug({ unapprovedTxs, unapprovedMsgs, @@ -19,42 +19,42 @@ export default function txHelper( encryptionPublicKeyMsgs, typedMessages, network, - }) + }); const txValues = network ? valuesFor(unapprovedTxs).filter( (txMeta) => txMeta.metamaskNetworkId === network, ) - : valuesFor(unapprovedTxs) - log.debug(`tx helper found ${txValues.length} unapproved txs`) + : valuesFor(unapprovedTxs); + log.debug(`tx helper found ${txValues.length} unapproved txs`); - const msgValues = valuesFor(unapprovedMsgs) - log.debug(`tx helper found ${msgValues.length} unsigned messages`) - let allValues = txValues.concat(msgValues) + const msgValues = valuesFor(unapprovedMsgs); + log.debug(`tx helper found ${msgValues.length} unsigned messages`); + let allValues = txValues.concat(msgValues); - const personalValues = valuesFor(personalMsgs) + const personalValues = valuesFor(personalMsgs); log.debug( `tx helper found ${personalValues.length} unsigned personal messages`, - ) - allValues = allValues.concat(personalValues) + ); + allValues = allValues.concat(personalValues); - const decryptValues = valuesFor(decryptMsgs) - log.debug(`tx helper found ${decryptValues.length} decrypt requests`) - allValues = allValues.concat(decryptValues) + const decryptValues = valuesFor(decryptMsgs); + log.debug(`tx helper found ${decryptValues.length} decrypt requests`); + allValues = allValues.concat(decryptValues); - const encryptionPublicKeyValues = valuesFor(encryptionPublicKeyMsgs) + const encryptionPublicKeyValues = valuesFor(encryptionPublicKeyMsgs); log.debug( `tx helper found ${encryptionPublicKeyValues.length} encryptionPublicKey requests`, - ) - allValues = allValues.concat(encryptionPublicKeyValues) + ); + allValues = allValues.concat(encryptionPublicKeyValues); - const typedValues = valuesFor(typedMessages) - log.debug(`tx helper found ${typedValues.length} unsigned typed messages`) - allValues = allValues.concat(typedValues) + const typedValues = valuesFor(typedMessages); + log.debug(`tx helper found ${typedValues.length} unsigned typed messages`); + allValues = allValues.concat(typedValues); allValues = allValues.sort((a, b) => { - return a.time - b.time - }) + return a.time - b.time; + }); - return allValues + return allValues; } diff --git a/ui/lib/webcam-utils.js b/ui/lib/webcam-utils.js index 6c451fd21e..7dd4dd499a 100644 --- a/ui/lib/webcam-utils.js +++ b/ui/lib/webcam-utils.js @@ -1,41 +1,41 @@ -'use strict' +'use strict'; import { ENVIRONMENT_TYPE_POPUP, PLATFORM_BRAVE, PLATFORM_FIREFOX, -} from '../../shared/constants/app' -import { getEnvironmentType, getPlatform } from '../../app/scripts/lib/util' +} from '../../shared/constants/app'; +import { getEnvironmentType, getPlatform } from '../../app/scripts/lib/util'; class WebcamUtils { static async checkStatus() { - const isPopup = getEnvironmentType() === ENVIRONMENT_TYPE_POPUP + const isPopup = getEnvironmentType() === ENVIRONMENT_TYPE_POPUP; const isFirefoxOrBrave = - getPlatform() === (PLATFORM_FIREFOX || PLATFORM_BRAVE) + getPlatform() === (PLATFORM_FIREFOX || PLATFORM_BRAVE); - const devices = await window.navigator.mediaDevices.enumerateDevices() - const webcams = devices.filter((device) => device.kind === 'videoinput') - const hasWebcam = webcams.length > 0 + const devices = await window.navigator.mediaDevices.enumerateDevices(); + const webcams = devices.filter((device) => device.kind === 'videoinput'); + const hasWebcam = webcams.length > 0; // A non-empty-string label implies that the webcam has been granted permission, as // otherwise the label is kept blank to prevent fingerprinting const hasWebcamPermissions = webcams.some( (webcam) => webcam.label && webcam.label.length > 0, - ) + ); if (hasWebcam) { - let environmentReady = true + let environmentReady = true; if ((isFirefoxOrBrave && isPopup) || (isPopup && !hasWebcamPermissions)) { - environmentReady = false + environmentReady = false; } return { permissions: hasWebcamPermissions, environmentReady, - } + }; } - const error = new Error('No webcam found') - error.type = 'NO_WEBCAM_FOUND' - throw error + const error = new Error('No webcam found'); + error.type = 'NO_WEBCAM_FOUND'; + throw error; } } -export default WebcamUtils +export default WebcamUtils; diff --git a/yarn.lock b/yarn.lock index 4808fa604a..fff1a8a763 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2069,10 +2069,10 @@ web3 "^0.20.7" web3-provider-engine "^16.0.1" -"@metamask/eslint-config@^4.1.0": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@metamask/eslint-config/-/eslint-config-4.1.0.tgz#ace2357af2d9c7d04da40a337fc7f4a81a048921" - integrity sha512-oc4ONdFB1h2yxBebVj4ACYzGzArB8ZQKiFVNCDlYiTCyeQ/GR4+EUwg0KvlO33LlXCRbAhO3CX0nChbvIB8hEw== +"@metamask/eslint-config@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@metamask/eslint-config/-/eslint-config-5.0.0.tgz#70c1ca854ce9b3b1cabd89cb736e8bb36127d164" + integrity sha512-eZt17NofPMmtoNjmBGOhUdAmyL0C+2/smtqAkVhpzZsU2ZGv+4Kekn8p8gcNONOYN8EotpWUxGkN1CTdVLdWZw== "@metamask/eth-ledger-bridge-keyring@^0.2.6": version "0.2.6"